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