1/*
2 * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24package test.astro;
25
26import static java.lang.String.valueOf;
27import static jaxp.library.JAXPTestUtilities.USER_DIR;
28import static jaxp.library.JAXPTestUtilities.compareWithGold;
29import static org.testng.Assert.assertTrue;
30import static test.astro.AstroConstants.ASTROCAT;
31import static test.astro.AstroConstants.GOLDEN_DIR;
32
33import java.nio.file.Files;
34import java.nio.file.Paths;
35
36import javax.xml.transform.sax.TransformerHandler;
37
38import org.testng.annotations.BeforeClass;
39import org.testng.annotations.DataProvider;
40import org.testng.annotations.Listeners;
41import org.testng.annotations.Test;
42
43/*
44 * @test
45 * @library /javax/xml/jaxp/libs
46 * @run testng/othervm -DrunSecMngr=true test.astro.AstroTest
47 * @run testng/othervm test.astro.AstroTest
48 * @summary run astro application, test xslt
49 *
50 * There are vast amounts of textual astronomical data, typically user is
51 * interested in a small subset, which is the result from carrying out a query.
52 * A query can be composed of one or more filters, for example, the user could
53 * query the database for all stars of visual magnitude down to 6.5 that lie
54 * between right ascensions 0 h to 2 h, and between declinations of 45 to 90 degrees.
55 *
56 * Astro application uses JAXP to query astronomical data saved in an XML dataset.
57 * A FilterFactory implementation creates filter(A filter is an instance of a JAXP
58 * TransformerHandler) from an XSL stylesheet.
59 * A InputSourceFactory implementation creates a new sax input source from an XML file.
60 * AstroProcessor leverages InputSourceFactory to parse catalog.xml, which saves
61 * textual astronomical data, and then creates filters with specified parameters
62 * from FilterFactory, all of the filters are chained together, AstroProcessor
63 * appends the HTML filter at the end of filter chain, and hooks up the chain to
64 * the input source, finally processes and outputs to the user specified output file.
65 *
66 * AstroTest drives AstroProcessor to run the specified queries(total 4 in setup),
67 * and then compares the output with the golden files to determine PASS or FAIL.
68 * It provides variant implementations of FilterFactory and InputSourceFactory to
69 * AstroProcessor to test different JAXP classes and features.
70 *
71 */
72@Listeners({jaxp.library.FilePolicy.class})
73public class AstroTest {
74    private FiltersAndGolden[] data;
75
76    @BeforeClass
77    public void setup() throws Exception {
78        data = new FiltersAndGolden[4];
79        data[0] = new FiltersAndGolden(getGoldenFileName(1), astro -> astro.getRAFilter(0.106, 0.108));
80        data[1] = new FiltersAndGolden(getGoldenFileName(2), astro -> astro.getStellarTypeFilter("K0IIIbCN-0.5"));
81        data[2] = new FiltersAndGolden(getGoldenFileName(3), astro -> astro.getStellarTypeFilter("G"), astro -> astro.getDecFilter(-5.0, 60.0));
82        data[3] = new FiltersAndGolden(getGoldenFileName(4), astro -> astro.getRADECFilter(0.084, 0.096, -5.75, 14.0));
83    }
84
85    /*
86     * Provide permutations of InputSourceFactory and FilterFactory for test.
87     */
88    @DataProvider(name = "factories")
89    public Object[][] getQueryFactories() {
90        return new Object[][] {
91                { StreamFilterFactoryImpl.class, InputSourceFactoryImpl.class },
92                { SAXFilterFactoryImpl.class, InputSourceFactoryImpl.class },
93                { DOMFilterFactoryImpl.class, InputSourceFactoryImpl.class },
94                { TemplatesFilterFactoryImpl.class, InputSourceFactoryImpl.class },
95                { StreamFilterFactoryImpl.class, DOML3InputSourceFactoryImpl.class } };
96    }
97
98    @Test(dataProvider = "factories")
99    public void test(Class<FilterFactory> fFactClass, Class<InputSourceFactory> isFactClass) throws Exception {
100        System.out.println(fFactClass.getName() +" : " + isFactClass.getName());
101        AstroProcessor astro = new AstroProcessor(fFactClass, ASTROCAT, isFactClass);
102
103        for (int i = 0; i < data.length; i++) {
104            runProcess(astro, valueOf(i + 1), data[i].getGoldenFileName(), data[i].getFilters());
105        }
106    }
107
108    private void runProcess(AstroProcessor astro, String processNum, String goldenFileName, FilterCreator... filterCreators) throws Exception {
109        System.out.println("run process " + processNum);
110        TransformerHandler[] filters = new TransformerHandler[filterCreators.length];
111        for (int i = 0; i < filterCreators.length; i++)
112            filters[i] = filterCreators[i].createFilter(astro);
113
114        String outputfile = Files.createTempFile(Paths.get(USER_DIR), "query" + processNum + ".out.", null).toString();
115        System.out.println("output file: " + outputfile);
116        astro.process(outputfile, filters);
117        assertTrue(compareWithGold(goldenFileName, outputfile));
118    }
119
120    private String getGoldenFileName(int num) {
121        return GOLDEN_DIR + "query" + num + ".out";
122    }
123
124    @FunctionalInterface
125    private interface FilterCreator {
126        TransformerHandler createFilter(AstroProcessor astro) throws Exception;
127    }
128
129    private static class FiltersAndGolden {
130        private FilterCreator[] filters;
131        private String goldenFileName;
132
133        FiltersAndGolden(String goldenFileName, FilterCreator... filters) {
134            this.filters = filters;
135            this.goldenFileName = goldenFileName;
136        }
137
138        FilterCreator[] getFilters() {
139            return filters;
140        }
141
142        String getGoldenFileName() {
143            return goldenFileName;
144        }
145    }
146}
147