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