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