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 24 package convwatch; 25 26 import convwatch.GraphicalTestArguments; 27 import convwatch.OfficePrint; 28 import convwatch.ConvWatchCancelException; 29 import convwatch.FileHelper; 30 import java.io.File; 31 32 import helper.URLHelper; 33 import com.sun.star.lang.XComponent; 34 import com.sun.star.frame.XStorable; 35 import com.sun.star.beans.PropertyValue; 36 import com.sun.star.lang.XServiceInfo; 37 import com.sun.star.uno.UnoRuntime; 38 39 public class GraphicalDifferenceCheck 40 { 41 private static void showVersion() 42 { 43 // DEBUG only 44 if (FileHelper.isDebugEnabled()) 45 { 46 GlobalLogWriter.get().println(""); 47 GlobalLogWriter.get().println("+##############################+"); 48 GlobalLogWriter.get().println("##### THIS IS CONVWATCH #####"); 49 GlobalLogWriter.get().println("##### Debug Version 1.0015 #####"); 50 GlobalLogWriter.get().println("+##############################+"); 51 GlobalLogWriter.get().println(""); 52 } 53 } 54 55 /** 56 * Creates references form documents used by the graphical difference check 57 * 58 * @param _sInputPath the original document path 59 * @param _sReferencePath the directory where the document will print as file or export as pdf. 60 * 61 * @throws ConvWatchException if there are problems, see message 62 * 63 * Stops rest, if one creation of reference fails. 64 */ 65 public static void createReferences(String _sInputPath, String _sReferencePath, GraphicalTestArguments _aGTA) throws ConvWatchException 66 { 67 //! 68 // System.out.println("createReferences() InputPath: " + _sInputPath + " refpath: " + _sReferencePath); 69 showVersion(); 70 File aInputPath = new File(_sInputPath); 71 72 // System.out.println("Inputpath in file: " + aInputPath.getAbsolutePath()); 73 //! 74 // if (aInputPath.exists()) 75 // { 76 // System.out.println("Inputpath exists"); 77 // } 78 // else 79 // { 80 // System.out.println("Inputpath doesn't exists"); 81 // return; 82 // } 83 84 if (aInputPath.isDirectory()) 85 { 86 String fs = System.getProperty("file.separator"); 87 88 String sRemovePath = aInputPath.getAbsolutePath(); 89 // a whole directory 90 91 Object[] aList = DirectoryHelper.traverse(_sInputPath, FileHelper.getFileFilter(), _aGTA.includeSubDirectories()); 92 for (int i=0;i<aList.length;i++) 93 { 94 String sEntry = (String)aList[i]; 95 String sNewReferencePath = _sReferencePath + fs + FileHelper.removeFirstDirectorysAndBasenameFrom(sEntry, _sInputPath); 96 createOneReferenceFile(sEntry, sNewReferencePath, _aGTA); 97 } 98 } 99 else 100 { 101 //! 102 // System.out.println("No directory."); 103 createOneReferenceFile(_sInputPath, _sReferencePath, _aGTA); 104 } 105 } 106 107 108 /** 109 * Creates a reference for a single document used by the graphical difference check 110 * 111 * @param _sInputFile the original document 112 * @param _sReferencePath the directory where the document will print as file or export as pdf. 113 * 114 * @throws ConvWatchException if the are problems, see containing message 115 */ 116 public static boolean createOneReferenceFile(String _sInputFile, String _sReferencePath, GraphicalTestArguments _aGTA) throws ConvWatchException 117 { 118 showVersion(); 119 if (_aGTA != null) 120 { 121 _aGTA.setInputFile(_sInputFile); 122 } 123 return OfficePrint.buildReference(_aGTA, _sReferencePath, _sInputFile); 124 } 125 126 /** 127 * Check if a reference exist 128 * 129 * @param _sInputFile the original document 130 * @param _sReferencePath the directory where the document will print as file or export as pdf. 131 */ 132 public static boolean isReferenceExists(String _sInputFile, String _sReferencePath, GraphicalTestArguments _aGTA) 133 { 134 return OfficePrint.isReferenceExists(_aGTA, _sReferencePath, _sInputFile); 135 } 136 137 138 /** 139 * Used for the comparance of graphical differences. 140 * Method compares one document (_sInputFile) with an older document of the same name in the provided directory (_sReferencePath). 141 * 142 * @param _sInputPath the original document path 143 * @param _sOutputPath path where the same directory structure of the given input path will create. All the result documents 144 * needed very much disk space (up to 10MB per page). 145 * The path _sOutputPath must be writeable. 146 * @param _sReferencePath the directory where the document will print as file or export as pdf. 147 * @param _aGTA Helper class for lot of parameter to control the office. 148 * 149 * Disadvantage: stops rest if one test file has a problem. 150 */ 151 public static boolean check(String _sInputPath, String _sOutputPath, String _sReferencePath, GraphicalTestArguments _aGTA ) throws ConvWatchException 152 { 153 return check(_sInputPath, _sOutputPath, _sReferencePath, null, _aGTA); 154 } 155 156 /** 157 * Used for the comparance of graphical differences. 158 * Method compares one document (_sInputFile) with an older document of the same name in the provided directory (_sReferencePath). 159 * 160 * @param _sInputPath the original document path 161 * @param _sReferencePath the directory where the document will print as file or export as pdf. 162 * @param _sOutputPath path where the same directory structure of the given input path will create. All the result documents 163 * needed very much disk space (up to 10MB per page). 164 * The path _sOutputPath must be writeable. 165 * @param _sDiffPath Path to older differences. 166 * @param _aGTA Helper class for lot of parameter to control the office. 167 * 168 * 169 * Stops all, if one creation of reference fails 170 */ 171 public static boolean check(String _sInputPath, String _sOutputPath, String _sReferencePath, String _sDiffPath, GraphicalTestArguments _aGTA ) throws ConvWatchException 172 { 173 showVersion(); 174 175 boolean bOk = true; 176 177 File aInputPath = new File(_sInputPath); 178 if (aInputPath.isDirectory()) 179 { 180 String fs = System.getProperty("file.separator"); 181 // a whole directory 182 Object[] aList = DirectoryHelper.traverse(_sInputPath, FileHelper.getFileFilter(), _aGTA.includeSubDirectories()); 183 if (aList.length != 0) 184 { 185 for (int i=0;i<aList.length;i++) 186 { 187 String sEntry = (String)aList[i]; 188 String sNewSubDir = FileHelper.removeFirstDirectorysAndBasenameFrom(sEntry, _sInputPath); 189 String sNewReferencePath = _sReferencePath; 190 String sNewOutputPath = _sOutputPath; 191 String sNewDiffPath = _sDiffPath; 192 if (sNewSubDir.length() > 0) 193 { 194 if (sNewReferencePath != null) 195 { 196 sNewReferencePath = sNewReferencePath + fs + sNewSubDir; 197 } 198 199 sNewOutputPath = sNewOutputPath + fs + sNewSubDir; 200 if (sNewDiffPath != null) 201 { 202 sNewDiffPath = sNewDiffPath + fs + sNewSubDir; 203 } 204 } 205 bOk &= checkOneFile(sEntry, sNewOutputPath, sNewReferencePath, sNewDiffPath, _aGTA); 206 } 207 } 208 } 209 else 210 { 211 bOk = /* GraphicalDifferenceCheck.*/ checkOneFile(_sInputPath, _sOutputPath, _sReferencePath, _sDiffPath, _aGTA); 212 } 213 return bOk; 214 } 215 216 /** 217 * Used for the comparance of graphical differences. 218 * Method compares one document (_sInputFile) with an older document of the same name in the provided directory (_sReferencePath). 219 * 220 * The path _sOutputPath must be writeable 221 */ 222 public static boolean checkOneFile(String _sInputFile, String _sOutputPath, String _sReferencePath, GraphicalTestArguments _aGTA) throws ConvWatchException 223 { 224 return checkOneFile( _sInputFile, _sOutputPath, _sReferencePath, null, _aGTA); 225 } 226 227 228 /** 229 * Used for the comparance of graphical differences. 230 * Method compares one document (_sInputFile) with an older document of the same name in the provided directory (_sReferencePath). 231 * 232 * For scenarios, where a difference is known and further changes are of interest, differences itself can be compared. 233 * This functionality is provided by the difference path parameter (_sDiffPath). If set, the difference of the current comparance (between input and reference), 234 * will be compared with the (same named) difference document from a earlier comparance. 235 * 236 * The path _sOutputPath must be writeable 237 */ 238 public static boolean checkOneFile(String _sInputFile, String _sOutputPath, String _sReferencePath, String _sDiffPath, GraphicalTestArguments _aGTA ) throws ConvWatchException 239 { 240 showVersion(); 241 if (_aGTA != null) 242 { 243 _aGTA.setInputFile(_sInputFile); 244 } 245 246 boolean bOk = false; 247 if (_sDiffPath != null) 248 { 249 // check with an old diff 250 bOk = convwatch.ConvWatch.checkDiffDiff(_aGTA, _sOutputPath, _sInputFile, _sReferencePath, _sDiffPath); 251 } 252 else 253 { 254 // one file 255 bOk = convwatch.ConvWatch.check(_aGTA, _sOutputPath, _sInputFile, _sReferencePath); 256 } 257 return bOk; 258 } 259 260 /** 261 * Instead of providing a saved document for graphical comparance a StarOffice xComponent 262 * will be saved and afterwards compared. 263 * 264 * @param xComponent the test document to be compared as StarOffice component 265 * @param _sOutputPath Path where test results are supposed to been saved. The path _sOutputPath must be writeable. 266 * These documents need sufficient disk space (up to 10MB per page). 267 * A directory structure will be created, which is a mirrored from input path. 268 * 269 * @param _resultDocName Name by which the xComponent shall be saved as OpenOffice.org XML document. 270 * If provided without suffix, the suffix will be derived from the export filter. 271 * @param _sReferencePath the directory where the document will print as file or export as pdf. 272 * @param _aGTA Helper class for lot of parameter to control the office. 273 */ 274 public static boolean checkOneFile(XComponent xComponent, String _sOutputPath, String _resultDocName, String _sReferencePath, GraphicalTestArguments _aGTA ) throws ConvWatchException 275 { 276 showVersion(); 277 278 // one file 279 String sInputFile; 280 sInputFile = createInputFile(xComponent, _sOutputPath, _resultDocName); 281 sInputFile = FileHelper.getSystemPathFromFileURL(sInputFile); 282 return convwatch.ConvWatch.check(_aGTA, _sOutputPath, sInputFile, _sReferencePath); 283 } 284 285 286 // LLA: old! /** 287 // LLA: old! * Returns 'true' if a reference document on the specific output path exists. 288 // LLA: old! * The name of the document is corresponding to the input document, which can be 289 // LLA: old! * provided by a single name or path. 290 // LLA: old! * 291 // LLA: old! * @param inputPath the original document name (possibly including path) 292 // LLA: old! * @param referencePath the directory where the reference document will be stored 293 // LLA: old! 294 // LLA: old! */ 295 // LLA: old! public static boolean isReferencExistent(String inputDocumentPath, String referencePath) 296 // LLA: old! { 297 // LLA: old! // isolate the document name 298 // LLA: old! if(inputDocumentPath.indexOf(File.separator) != -1) 299 // LLA: old! inputDocumentPath = inputDocumentPath.substring(inputDocumentPath.lastIndexOf(File.separator) + 1, inputDocumentPath.length()); 300 // LLA: old! 301 // LLA: old! // exchange any arbitray suffix against the refence suffix (.prn) 302 // LLA: old! if(inputDocumentPath.indexOf('.') != -1) 303 // LLA: old! inputDocumentPath = inputDocumentPath.substring(0, inputDocumentPath.lastIndexOf('.')); 304 // LLA: old! inputDocumentPath = inputDocumentPath + ".prn"; 305 // LLA: old! System.out.println("GraphicalDifference CheckReferenceDocument: " + inputDocumentPath); 306 // LLA: old! 307 // LLA: old! File refFile = new File(referencePath + inputDocumentPath); 308 // LLA: old! if(refFile.exists()){ 309 // LLA: old! return true; 310 // LLA: old! }else 311 // LLA: old! return false; 312 // LLA: old! } 313 314 315 private static String createInputFile(XComponent xComponent, String _sOutputPath, String resultDocName) 316 throws ConvWatchCancelException 317 { 318 319 // find the adequate XML StarOffice output filter to save the document and adequate suffix 320 StringBuffer suffix = new StringBuffer(); 321 String exportFilter = getXMLOutputFilterforXComponent(xComponent, suffix); 322 if(resultDocName == null) 323 resultDocName = "OOoTestDocument"; 324 if(resultDocName.indexOf('.') == -1) 325 resultDocName = suffix.insert(0, resultDocName).toString(); 326 327 // create a result URL for storing the office document 328 String resultURL = URLHelper.getFileURLFromSystemPath(ensureEndingFileSep(_sOutputPath) + resultDocName); 329 330 XStorable xStorable = null; 331 xStorable = (com.sun.star.frame.XStorable)UnoRuntime.queryInterface(com.sun.star.frame.XStorable.class, xComponent); 332 if(xStorable == null) 333 { 334 throw new ConvWatchCancelException("com.sun.star.frame.XStorable could not be instantiated from the office."); 335 } 336 337 PropertyValue pvFilterName = new PropertyValue("FilterName", -1, exportFilter, com.sun.star.beans.PropertyState.getDefault()); 338 PropertyValue pvOverwrite = new PropertyValue("Overwrite", -1, new Boolean(true), com.sun.star.beans.PropertyState.getDefault()); 339 340 try 341 { 342 xStorable.storeAsURL(resultURL, new PropertyValue[]{pvFilterName, pvOverwrite}); 343 } 344 catch (com.sun.star.io.IOException e) 345 { 346 // wrap IOException 347 throw new ConvWatchCancelException("Wrap IOException caught, " + e.getMessage()); 348 } 349 350 GlobalLogWriter.get().println("Saving XComponent as " + resultURL); 351 352 return resultURL; 353 } 354 355 356 private static String getXMLOutputFilterforXComponent(XComponent xComponent, StringBuffer suffix){ 357 XServiceInfo xSI = (XServiceInfo) UnoRuntime.queryInterface(XServiceInfo.class, xComponent); 358 if (xSI.supportsService("com.sun.star.text.TextDocument")){ 359 resetBuffer(suffix, ".sxw"); 360 return "swriter: StarOffice XML (Writer)"; 361 }else if (xSI.supportsService("com.sun.star.sheet.SpreadsheetDocument")){ 362 resetBuffer(suffix, ".sxc"); 363 return "scalc: StarOffice XML (Calc)"; 364 }else if (xSI.supportsService("com.sun.star.presentation.PresentationDocument")){ 365 resetBuffer(suffix, ".sxi"); 366 return "simpress: StarOffice XML (Impress)"; 367 }else if(xSI.supportsService("com.sun.star.drawing.DrawingDocument")){ 368 resetBuffer(suffix, ".sxd"); 369 return "sdraw: StarOffice XML (Draw)"; 370 }else if (xSI.supportsService("com.sun.star.formula.FormulaProperties")){ 371 resetBuffer(suffix, ".sxm"); 372 return "smath: StarOffice XML (Math)"; 373 } 374 return null; 375 } 376 377 private static StringBuffer resetBuffer(StringBuffer sb, String suffix) 378 { 379 if(sb != null) 380 { 381 sb.replace(0, sb.length(), suffix); 382 } 383 return sb; 384 } 385 386 private static String ensureEndingFileSep(String s) 387 { 388 if(s != null && !s.equals("") && !s.endsWith(File.separator)) 389 { 390 s = s.trim() + File.separator; 391 } 392 else 393 { 394 if(s == null) 395 { 396 s = ""; 397 } 398 } 399 400 return s; 401 } 402 403 404 } 405