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