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