1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir package basicrunner.basichelper;
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir import com.sun.star.lang.XInitialization;
30*cdf0e10cSrcweir import com.sun.star.lang.XSingleServiceFactory;
31*cdf0e10cSrcweir import com.sun.star.lang.XServiceInfo;
32*cdf0e10cSrcweir import com.sun.star.lang.XTypeProvider;
33*cdf0e10cSrcweir import com.sun.star.uno.Type;
34*cdf0e10cSrcweir import com.sun.star.xml.sax.XDocumentHandler;
35*cdf0e10cSrcweir import com.sun.star.container.XNameAccess;
36*cdf0e10cSrcweir import com.sun.star.container.NoSuchElementException;
37*cdf0e10cSrcweir import java.util.Vector;
38*cdf0e10cSrcweir import util.XMLTools.Tag;
39*cdf0e10cSrcweir import util.XMLTools;
40*cdf0e10cSrcweir import java.io.StringWriter;
41*cdf0e10cSrcweir import java.io.PrintWriter;
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir /**
44*cdf0e10cSrcweir  * This class provides a handler of the BASIC test document.
45*cdf0e10cSrcweir  * @see com.sun.star.lang.XSingleServiceFactory
46*cdf0e10cSrcweir  * @see com.sun.star.lang.XServiceInfo
47*cdf0e10cSrcweir  */
48*cdf0e10cSrcweir public class DocumentHandler implements XServiceInfo, XSingleServiceFactory {
49*cdf0e10cSrcweir     /** The service name of this class **/
50*cdf0e10cSrcweir     static final String __serviceName = "basichelper.DocumentHandler";
51*cdf0e10cSrcweir     /** The actual handler of the document **/
52*cdf0e10cSrcweir     static DocumentHandlerImpl oDocumentHandler = null;
53*cdf0e10cSrcweir     /** A string writer **/
54*cdf0e10cSrcweir     private StringWriter writer;
55*cdf0e10cSrcweir     /** The log writer (just a wrapper around <code>writer</code>) **/
56*cdf0e10cSrcweir     private PrintWriter log;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir     /**
59*cdf0e10cSrcweir      * Create an instance of the document handler.
60*cdf0e10cSrcweir      * @param args A boolean value as <codde>args[0]</code> determines,
61*cdf0e10cSrcweir      *             if checked XML data is printed to the log.
62*cdf0e10cSrcweir      *             Default is false.
63*cdf0e10cSrcweir      * @return The document handler
64*cdf0e10cSrcweir      */
65*cdf0e10cSrcweir     public Object createInstanceWithArguments(Object[] args) {
66*cdf0e10cSrcweir         boolean printXML = false;
67*cdf0e10cSrcweir         if (args != null && args.length!=0 && args[0] instanceof Boolean)
68*cdf0e10cSrcweir             printXML = ((Boolean)args[0]).booleanValue();
69*cdf0e10cSrcweir         writer = new StringWriter();
70*cdf0e10cSrcweir         log = new PrintWriter(writer);
71*cdf0e10cSrcweir         oDocumentHandler = new DocumentHandlerImpl(log, printXML, writer);
72*cdf0e10cSrcweir         return oDocumentHandler;
73*cdf0e10cSrcweir     }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     /**
76*cdf0e10cSrcweir      * Create an instance of the document handler.
77*cdf0e10cSrcweir      * @return The document handler
78*cdf0e10cSrcweir      */
79*cdf0e10cSrcweir     public Object createInstance() {
80*cdf0e10cSrcweir         return createInstanceWithArguments(null);
81*cdf0e10cSrcweir     }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir     /** Get the unique id for this implementation
84*cdf0e10cSrcweir      * @return The id.
85*cdf0e10cSrcweir      */
86*cdf0e10cSrcweir     public byte[] getImplementationId() {
87*cdf0e10cSrcweir         return toString().getBytes();
88*cdf0e10cSrcweir     }
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir     /** Get all implemented types.
91*cdf0e10cSrcweir      * @return The implemented UNO types.
92*cdf0e10cSrcweir      */
93*cdf0e10cSrcweir     public Type[] getTypes() {
94*cdf0e10cSrcweir         Class interfaces[] = getClass().getInterfaces();
95*cdf0e10cSrcweir         Type types[] = new Type[interfaces.length];
96*cdf0e10cSrcweir         for(int i = 0; i < interfaces.length; ++ i)
97*cdf0e10cSrcweir             types[i] = new Type(interfaces[i]);
98*cdf0e10cSrcweir         return types;
99*cdf0e10cSrcweir     }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir     /** Is this servioce supported?
102*cdf0e10cSrcweir      * @param name The service name.
103*cdf0e10cSrcweir      * @return True, if the service is supported.
104*cdf0e10cSrcweir      */
105*cdf0e10cSrcweir     public boolean supportsService(String name) {
106*cdf0e10cSrcweir         return __serviceName.equals(name);
107*cdf0e10cSrcweir     }
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir     /**
110*cdf0e10cSrcweir      * Get all supported service names.
111*cdf0e10cSrcweir      * @return All supported servcices.
112*cdf0e10cSrcweir      */
113*cdf0e10cSrcweir     public String[] getSupportedServiceNames() {
114*cdf0e10cSrcweir         return new String[] {__serviceName};
115*cdf0e10cSrcweir     }
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir     /**
118*cdf0e10cSrcweir      * Get the implementation name of this class.
119*cdf0e10cSrcweir      * @return The implementation name.
120*cdf0e10cSrcweir      */
121*cdf0e10cSrcweir     public String getImplementationName() {
122*cdf0e10cSrcweir         return getClass().getName();
123*cdf0e10cSrcweir     }
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir /**
127*cdf0e10cSrcweir  * The actual implementation of the document handler
128*cdf0e10cSrcweir  * @see util.XMLTools.XMLChecker
129*cdf0e10cSrcweir  * @see com.sun.star.lang.XInitialization
130*cdf0e10cSrcweir  * @see com.sun.star.xml.sax.XDocumentHandler
131*cdf0e10cSrcweir  * @see com.sun.star.container.XNameAccess
132*cdf0e10cSrcweir  * @see com.sun.star.lang.XTypeProvider
133*cdf0e10cSrcweir  */
134*cdf0e10cSrcweir class DocumentHandlerImpl extends XMLTools.XMLChecker
135*cdf0e10cSrcweir                         implements XInitialization, XDocumentHandler,
136*cdf0e10cSrcweir                                                 XNameAccess, XTypeProvider {
137*cdf0e10cSrcweir     /** A string writer **/
138*cdf0e10cSrcweir     private StringWriter writer;
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir     /**
141*cdf0e10cSrcweir      * Constructor
142*cdf0e10cSrcweir      * @param log_ A log writer.
143*cdf0e10cSrcweir      * @param printXML Should XML data be printed to the log?
144*cdf0e10cSrcweir      * @param logWriter A wrapper around <code>log_</code> for convenience.
145*cdf0e10cSrcweir      */
146*cdf0e10cSrcweir     public DocumentHandlerImpl(PrintWriter log_,
147*cdf0e10cSrcweir                                     boolean printXML, StringWriter logWriter) {
148*cdf0e10cSrcweir         super(log_, printXML);
149*cdf0e10cSrcweir         writer = logWriter;
150*cdf0e10cSrcweir     }
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir     /**
153*cdf0e10cSrcweir      * Initialize this class with rules.
154*cdf0e10cSrcweir      * @param parm1 An array of filter rules:
155*cdf0e10cSrcweir      *              <code>processAction()</code> is called for every rule.
156*cdf0e10cSrcweir      * @throws com.sun.star.uno.Exception for an incorrect rule.
157*cdf0e10cSrcweir      */
158*cdf0e10cSrcweir     public void initialize(Object[] parm1) throws com.sun.star.uno.Exception {
159*cdf0e10cSrcweir         if (!(parm1[0] instanceof Object[])) return;
160*cdf0e10cSrcweir         for (int i=0; i<parm1.length; i++) {
161*cdf0e10cSrcweir             processActionForXMLChecker((Object[])parm1[i]);
162*cdf0e10cSrcweir         }
163*cdf0e10cSrcweir     }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir     /**
166*cdf0e10cSrcweir     * Method processes all filters received from basic tests.
167*cdf0e10cSrcweir     * Called by initialize().
168*cdf0e10cSrcweir     * @param filterRule An array building one filter rule.
169*cdf0e10cSrcweir     * @throws com.sun.star.uno.Exception for an incorrect rule.
170*cdf0e10cSrcweir     */
171*cdf0e10cSrcweir     private void processActionForXMLChecker(Object[] filterRule)
172*cdf0e10cSrcweir                                         throws com.sun.star.uno.Exception {
173*cdf0e10cSrcweir         int arrLen = filterRule.length;
174*cdf0e10cSrcweir         String oTagName;
175*cdf0e10cSrcweir         Object[] oTags;
176*cdf0e10cSrcweir         Object[] oTag;
177*cdf0e10cSrcweir         int tagsNum = arrLen-1;
178*cdf0e10cSrcweir         Vector allTags = new Vector();
179*cdf0e10cSrcweir         String CDATA = "";
180*cdf0e10cSrcweir         String action = "";
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir         // First element of rule is RuleName and should be String
183*cdf0e10cSrcweir         if (!(filterRule[0] instanceof String)) {
184*cdf0e10cSrcweir             throw new com.sun.star.uno.Exception("Error: incorrect filter rule "+
185*cdf0e10cSrcweir             "received from basic test! Rule name must be a String.");
186*cdf0e10cSrcweir         } else {
187*cdf0e10cSrcweir             action = (String) filterRule[0];
188*cdf0e10cSrcweir         }
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir         // Searching for character data and defining amount of tags received.
191*cdf0e10cSrcweir         for (int j=1; j<arrLen; j++) {
192*cdf0e10cSrcweir             if ( (filterRule[j] instanceof String) && (j != 1) ) {
193*cdf0e10cSrcweir                 CDATA = (String) filterRule[j];
194*cdf0e10cSrcweir                 tagsNum--;
195*cdf0e10cSrcweir             }
196*cdf0e10cSrcweir         }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir         // Adding received tags to internal array.
199*cdf0e10cSrcweir         oTags = new Object[tagsNum];
200*cdf0e10cSrcweir         for (int j=1; j<=tagsNum; j++) {
201*cdf0e10cSrcweir             if (filterRule[j] instanceof Object[]) {
202*cdf0e10cSrcweir                 oTags[j-1] = (Object[]) filterRule[j];
203*cdf0e10cSrcweir             }
204*cdf0e10cSrcweir         }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir         // Process all received tags for a given filter rule
207*cdf0e10cSrcweir         for (int i=0; i<oTags.length; i++) {
208*cdf0e10cSrcweir             if (oTags[i] instanceof Object[]) {
209*cdf0e10cSrcweir                 oTag = (Object[]) oTags[i];
210*cdf0e10cSrcweir                 oTagName = (String) oTag[0];
211*cdf0e10cSrcweir             } else if (oTags[i] instanceof Object) {
212*cdf0e10cSrcweir                 oTag = new Object[1];
213*cdf0e10cSrcweir                 oTag[0] = (Object) oTags[i];
214*cdf0e10cSrcweir                 oTagName = (String) oTag[0];
215*cdf0e10cSrcweir             } else {
216*cdf0e10cSrcweir                 throw new com.sun.star.uno.Exception("Error: invalid tag "+
217*cdf0e10cSrcweir                                     "received from basic test! Check tag "
218*cdf0e10cSrcweir                                     +i+" in rule '"+action+"'.");
219*cdf0e10cSrcweir             }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir             // Action for constructor Tag(TagName, attrName, attrValue)
222*cdf0e10cSrcweir             if (oTag.length == 3) {
223*cdf0e10cSrcweir                 if ((oTag[1] instanceof String)&&(oTag[2] instanceof String)) {
224*cdf0e10cSrcweir                     allTags.add(new Tag(oTagName,
225*cdf0e10cSrcweir                                     (String) oTag[1], (String) oTag[2]));
226*cdf0e10cSrcweir                 } else {
227*cdf0e10cSrcweir                     throw new com.sun.star.uno.Exception("Error: invalid tag '"+
228*cdf0e10cSrcweir                                     oTagName+"' received from basic test!");
229*cdf0e10cSrcweir                 }
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir             // Action for constructors:
232*cdf0e10cSrcweir             // Tag(TagName, String[][] attrValues )
233*cdf0e10cSrcweir             // Tag(TagName, String[] attrNames)
234*cdf0e10cSrcweir             // Tag(TagName, String attrName)
235*cdf0e10cSrcweir             //
236*cdf0e10cSrcweir             } else if (oTag.length == 2) {
237*cdf0e10cSrcweir                 if (oTag[1] instanceof String[][]) {
238*cdf0e10cSrcweir                     allTags.add(new Tag(oTagName, (String[][]) oTag[1]));
239*cdf0e10cSrcweir                 } else if (oTag[1] instanceof String[]) {
240*cdf0e10cSrcweir                     allTags.add(new Tag(oTagName, (String[]) oTag[1]));
241*cdf0e10cSrcweir                 } else if (oTag[1] instanceof String) {
242*cdf0e10cSrcweir                     allTags.add(new Tag(oTagName, (String) oTag[1]));
243*cdf0e10cSrcweir                 } else {
244*cdf0e10cSrcweir                     throw new com.sun.star.uno.Exception("Error: invalid tag '"+
245*cdf0e10cSrcweir                     oTagName+"' received from basic test!");
246*cdf0e10cSrcweir                 }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir             // Action for constructor Tag(TagName)
249*cdf0e10cSrcweir             } else if (oTag.length == 1) {
250*cdf0e10cSrcweir                 if (oTag[0] instanceof String) {
251*cdf0e10cSrcweir                     allTags.add(new Tag(oTagName));
252*cdf0e10cSrcweir                 } else {
253*cdf0e10cSrcweir                     throw new com.sun.star.uno.Exception("Error: invalid tag '"+
254*cdf0e10cSrcweir                     oTagName+"' received from basic test!");
255*cdf0e10cSrcweir                 }
256*cdf0e10cSrcweir             } else {
257*cdf0e10cSrcweir                 throw new com.sun.star.uno.Exception("Error: invalid tag '"+
258*cdf0e10cSrcweir                 oTagName+"' received from basic test!");
259*cdf0e10cSrcweir             }
260*cdf0e10cSrcweir         }
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir         // Adding tags to XMLChecker
263*cdf0e10cSrcweir         if ( action.equals((String)"TagExists") ) {
264*cdf0e10cSrcweir             for (int i=0; i<allTags.size(); i++) {
265*cdf0e10cSrcweir                 addTag((Tag)allTags.get(i));
266*cdf0e10cSrcweir             }
267*cdf0e10cSrcweir         } else if (action.equals((String)"TagEnclosed")) {
268*cdf0e10cSrcweir             addTagEnclosed((Tag) allTags.get(0), (Tag) allTags.get(1));
269*cdf0e10cSrcweir         } else if (action.equals((String)"CharsEnclosed")) {
270*cdf0e10cSrcweir             addCharactersEnclosed(CDATA, (Tag) allTags.get(0));
271*cdf0e10cSrcweir         } else {
272*cdf0e10cSrcweir             throw new com.sun.star.uno.Exception("Error: incorrect rule name '"+
273*cdf0e10cSrcweir             action+"' received from basic test!");
274*cdf0e10cSrcweir         }
275*cdf0e10cSrcweir     }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir     /**
278*cdf0e10cSrcweir      * Get the names of the elements.
279*cdf0e10cSrcweir      * @return element names.
280*cdf0e10cSrcweir      */
281*cdf0e10cSrcweir     public String[] getElementNames() {
282*cdf0e10cSrcweir         return new String[]{"XMLCode", "XMLIsCorrect"};
283*cdf0e10cSrcweir     }
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir     /**
286*cdf0e10cSrcweir      * Is this an element?
287*cdf0e10cSrcweir      * @param name Element name.
288*cdf0e10cSrcweir      * @return true, if <code>name>/code> is the name of an element.
289*cdf0e10cSrcweir      */
290*cdf0e10cSrcweir     public boolean hasByName(String name) {
291*cdf0e10cSrcweir         return (name.equals("XMLCode") || name.equals("XMLIsCorrect"));
292*cdf0e10cSrcweir     }
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir     /**
295*cdf0e10cSrcweir      * Get an element by its name.
296*cdf0e10cSrcweir      * @param name The element name.
297*cdf0e10cSrcweir      * @return The element with the specified <code>name</code>.
298*cdf0e10cSrcweir      * @throws NoSuchElementException Is thrown, if name does not exist.
299*cdf0e10cSrcweir      */
300*cdf0e10cSrcweir     public Object getByName(String name) throws NoSuchElementException{
301*cdf0e10cSrcweir         if (name.equals("XMLIsCorrect"))
302*cdf0e10cSrcweir             return new Boolean(this.check());
303*cdf0e10cSrcweir         else if (name.equals("XMLCode")) {
304*cdf0e10cSrcweir             return writer.getBuffer().toString();
305*cdf0e10cSrcweir         } else
306*cdf0e10cSrcweir             throw new NoSuchElementException();
307*cdf0e10cSrcweir     }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir     /**
310*cdf0e10cSrcweir      * Are there any elements?
311*cdf0e10cSrcweir      * @return Always true.
312*cdf0e10cSrcweir      */
313*cdf0e10cSrcweir     public boolean hasElements() {
314*cdf0e10cSrcweir         return true;
315*cdf0e10cSrcweir     }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir     /**
318*cdf0e10cSrcweir      * Get the element type.
319*cdf0e10cSrcweir      * @return The type.
320*cdf0e10cSrcweir      */
321*cdf0e10cSrcweir     public Type getElementType() {
322*cdf0e10cSrcweir         return new Type(Object.class);
323*cdf0e10cSrcweir     }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     /**
326*cdf0e10cSrcweir      * Get a unique id for this implementation.
327*cdf0e10cSrcweir      * @return The id.
328*cdf0e10cSrcweir      */
329*cdf0e10cSrcweir     public byte[] getImplementationId() {
330*cdf0e10cSrcweir         return toString().getBytes();
331*cdf0e10cSrcweir     }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir     /**
334*cdf0e10cSrcweir      * Return all implemented types of this class.
335*cdf0e10cSrcweir      * @return The implemented UNO types.
336*cdf0e10cSrcweir      */
337*cdf0e10cSrcweir     public Type[] getTypes() {
338*cdf0e10cSrcweir         Class interfaces[] = getClass().getInterfaces();
339*cdf0e10cSrcweir         Type types[] = new Type[interfaces.length];
340*cdf0e10cSrcweir         for(int i = 0; i < interfaces.length; ++ i)
341*cdf0e10cSrcweir             types[i] = new Type(interfaces[i]);
342*cdf0e10cSrcweir         return types;
343*cdf0e10cSrcweir     }
344*cdf0e10cSrcweir }
345