1 19 20 package org.netbeans.modules.xml.retriever; 21 22 import java.awt.event.ActionEvent ; 23 import java.io.File ; 24 import java.io.FileNotFoundException ; 25 import java.io.IOException ; 26 import java.net.URI ; 27 import java.net.URISyntaxException ; 28 import java.net.UnknownHostException ; 29 import java.text.DateFormat ; 30 import java.util.ArrayList ; 31 import java.util.Date ; 32 import java.util.HashMap ; 33 import java.util.LinkedList ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Stack ; 37 import java.util.StringTokenizer ; 38 import javax.swing.AbstractAction ; 39 import org.netbeans.api.progress.ProgressHandle; 40 import org.netbeans.api.progress.ProgressHandleFactory; 41 import org.netbeans.modules.xml.xam.locator.CatalogModelException; 42 import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModel; 43 import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModelFactory; 44 import org.openide.DialogDisplayer; 45 import org.openide.NotifyDescriptor; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileUtil; 48 import org.openide.util.Cancellable; 49 import org.openide.util.NbBundle; 50 import org.openide.windows.IOProvider; 51 import org.openide.windows.InputOutput; 52 import org.openide.windows.OutputWriter; 53 54 58 public class RetrieverEngine implements Runnable { 59 60 private LinkedList <RetrieveEntry> currentRetrievalList = new LinkedList <RetrieveEntry>(); 61 62 private File currentSaveRootFile = null; 63 64 private File fixedSaveRootFolder = null; 65 66 boolean startNewThread = true; 67 68 protected boolean showErrorPopup = true; 69 70 public RetrieverEngine(File fixedSaveRootFolder){ 71 this.fixedSaveRootFolder = fixedSaveRootFolder; 72 this.currentSaveRootFile = fixedSaveRootFolder; 73 } 74 75 public RetrieverEngine(File fixedSaveRootFolder, boolean startNewThread){ 76 this.fixedSaveRootFolder = fixedSaveRootFolder; 77 this.currentSaveRootFile = fixedSaveRootFolder; 78 this.startNewThread = startNewThread; 79 } 80 81 public void addResourceToRetrieve(RetrieveEntry rent) { 82 currentRetrievalList.add(rent); 83 } 84 85 Thread taskThread = null; 86 public void start(){ 87 if(startNewThread){ 88 taskThread = new Thread (this); 89 taskThread.start(); 90 }else{ 91 run(); 92 } 93 } 94 95 boolean STOP_PULL = false; 96 public void run() { 97 ProgressHandle ph = ProgressHandleFactory.createHandle( 98 NbBundle.getMessage(RetrieverEngine.class,"LBL_PROGRESSBAR_Retrieve_XML"), 99 new Cancellable(){ 100 public boolean cancel() { 101 synchronized(RetrieverEngine.this){ 102 if(!RetrieverEngine.this.STOP_PULL){ 103 RetrieverEngine.this.STOP_PULL = true; 104 } 106 } 107 return true; 108 } 109 }, new AbstractAction (){ 110 public void actionPerformed(ActionEvent e) { 111 getOPWindow().setOutputVisible(true); 112 getOPWindow().select(); 113 } 114 }); 115 ph.start(); 116 ph.switchToIndeterminate(); 117 try{ 118 pullRecursively(); 119 }finally{ 120 ph.finish(); 121 } 122 } 123 124 boolean firstTime = true; 125 String firstAddressParentStr = null; 126 private void pullRecursively() { 127 synchronized(RetrieverEngine.class){ 128 while(!currentRetrievalList.isEmpty() && !STOP_PULL){ 129 RetrieveEntry rent =currentRetrievalList.getFirst(); 131 currentRetrievalList.removeFirst(); 133 RetrieverTask rt = new RetrieverTask(rent, this); 134 135 if(firstTime){ 136 firstAddressParentStr = rent.getCurrentAddress().substring(0, rent.getCurrentAddress().lastIndexOf("/")); 137 firstTime = false; 138 } 139 140 updateDownloadingInfo(rent); 141 142 HashMap <String ,File > storedFileMap = null;; 143 try { 144 storedFileMap = rt.goGetIt(); 145 } catch (URISyntaxException ex) { 146 handleException(rent, ex); 149 continue; 150 } catch (IOException ex) { 151 handleException(rent, ex); 154 continue; 155 } 156 157 158 if(!rent.isRecursive()) 159 continue; 160 161 if(storedFileMap == null){ 162 continue; 163 } 164 String effectiveSrcAddr = storedFileMap.keySet().iterator().next(); 165 File storedFile = storedFileMap.get(effectiveSrcAddr); 166 167 rent.setSaveFile(storedFile); 168 rent.setEffectiveAddress(effectiveSrcAddr); 169 170 updateDownloadedInfo(rent); 171 172 createCatalogIfRequired(rent); 173 174 DocumentTypeParser dtp = DocumentParserFactory.getParser(rent.getDocType()); 175 List <String > thisFileRefs = null;; 176 try { 177 thisFileRefs = dtp.getAllLocationOfReferencedEntities(storedFile); 178 } catch (Exception ex) { 180 continue; 183 } 184 for(String ref: thisFileRefs){ 185 currentRetrievalList.addLast(new RetrieveEntry(effectiveSrcAddr, 186 ref, storedFile, null, rent.getDocType(), rent.isRecursive())); 187 } 188 printList(); 189 } 190 closeOPOuts(); 191 } 192 } 193 194 private void printList() { 195 for(RetrieveEntry rent: currentRetrievalList){ 196 } 198 } 199 200 public File getCurrentSaveRootFile() { 201 return currentSaveRootFile; 202 } 203 204 public void getCurrentSaveRootFile(File currentSaveRootFile) { 205 this.currentSaveRootFile = currentSaveRootFile; 206 } 207 208 private String getCorrectFolderName(int folderIndex){ 209 StringTokenizer stok = new StringTokenizer (firstAddressParentStr, "/"); 210 Stack <String > stack = new Stack <String >(); 211 while(stok.hasMoreTokens()) 212 stack.push(stok.nextToken()); 213 for(int i = 1; i < folderIndex ; i++) 214 stack.pop(); 215 return stack.pop(); 216 } 217 218 int currentPushCount = 0; 219 int previousPushCount = 0; 220 void pushDownRoot(int pushCount) { 221 File newTmpRoot = new File (currentSaveRootFile.getParent()+File.separator+System.currentTimeMillis()); 222 File leafFolder = newTmpRoot; 223 leafFolder.mkdirs(); 224 for(int i = pushCount;i >= 2; i--){ 225 leafFolder = new File (leafFolder.toString()+File.separator+getCorrectFolderName(currentPushCount+i)); 226 leafFolder.mkdirs(); 227 } 228 leafFolder = new File (leafFolder.toString()+File.separator+getCorrectFolderName(currentPushCount+1)); 229 File movedRoot = leafFolder; 230 while(!currentSaveRootFile.renameTo(movedRoot)){ 232 try { 233 Thread.sleep(500); 234 } catch (InterruptedException ex) { 235 } 236 } 237 while(!newTmpRoot.renameTo(currentSaveRootFile)){ 238 try { 239 Thread.sleep(500); 240 } catch (InterruptedException ex) { 241 } 242 } 243 244 File newRoot = currentSaveRootFile; 245 for(int i = pushCount;i >= 1; i--) 246 newRoot = new File (newRoot.toString()+File.separator+getCorrectFolderName(currentPushCount+i)); 247 correctAllEntriesInTheList(newRoot); 248 previousPushCount = currentPushCount; 249 currentPushCount += pushCount; 250 } 251 252 File getNewFileForOld(File oldFile, int pushCount) { 253 File newRoot = currentSaveRootFile; 254 for(int i = pushCount;i >= 1; i--) 255 newRoot = new File (newRoot.toString()+File.separator+getCorrectFolderName(previousPushCount+i)); 256 String oldPath = oldFile.toString(); 257 String newPath = new String (new StringBuffer (oldPath).replace(0, currentSaveRootFile.toString().length(),newRoot.toString())); 258 File newFile = new File (newPath); 259 return newFile; 260 } 261 262 private void correctAllEntriesInTheList(File newRoot) { 263 for(RetrieveEntry rent : currentRetrievalList){ 264 String oldPath = rent.getLocalBaseFile().toString(); 265 String newPath = new String (new StringBuffer (oldPath).replace(0, currentSaveRootFile.toString().length(),newRoot.toString())); 266 File newLocalBaseFile = new File (newPath); 267 rent.setLocalBaseFile(newLocalBaseFile); 268 } 269 for(RetrieveEntry rent : retrievedList){ 270 String oldPath = rent.getSaveFile().toString(); 271 String newPath = new String (new StringBuffer (oldPath).replace(0, currentSaveRootFile.toString().length(),newRoot.toString())); 272 File newLocalBaseFile = new File (newPath); 273 rent.setSaveFile(newLocalBaseFile); 274 } 275 } 276 277 public File getFixedSaveRootFolder() { 278 return fixedSaveRootFolder; 279 } 280 281 private void handleException(RetrieveEntry rent, Exception ex) { 282 if(audits == null) 283 audits = new HashMap <RetrieveEntry, Exception >(); 284 audits.put(rent, ex); 285 if(ex instanceof UnknownHostException ){ 287 String errorMess = NbBundle.getMessage(RetrieverEngine.class, "MSG_unknown_host_p1")+ex.getLocalizedMessage()+"\n"+NbBundle.getMessage(RetrieverEngine.class, "MSG_unknownhost_p2"); 288 outputError(errorMess); 289 if(showErrorPopup){ 290 NotifyDescriptor.Message ndm = new NotifyDescriptor.Message(errorMess, NotifyDescriptor.Message.ERROR_MESSAGE); 291 DialogDisplayer.getDefault().notify(ndm); 292 } 293 return; 294 } 295 if(ex instanceof URISyntaxException ){ 296 String errorMess = ex.getLocalizedMessage(); 297 outputError(errorMess); 298 if(showErrorPopup){ 299 NotifyDescriptor.Message ndm = new NotifyDescriptor.Message(errorMess, NotifyDescriptor.Message.ERROR_MESSAGE); 300 DialogDisplayer.getDefault().notify(ndm); 301 } 302 return; 303 } 304 if(ex instanceof FileNotFoundException ){ 305 String errorMess = NbBundle.getMessage(RetrieverEngine.class, "MSG_unknown_file", ex.getMessage()); 306 outputError(errorMess); 307 if(showErrorPopup){ 308 NotifyDescriptor.Message ndm = new NotifyDescriptor.Message(errorMess, NotifyDescriptor.Message.ERROR_MESSAGE); 309 DialogDisplayer.getDefault().notify(ndm); 310 } 311 return; 312 } 313 314 if(ex instanceof IOException ){ 315 String exStr = NbBundle.getMessage(RetrieverEngine.class, IConstants.EXCEPTION_CYCLIC_REFERENCE_INDICATOR); 316 if(ex.getMessage().startsWith(exStr)){ 317 outputMessage(ex.getMessage()+":\n\t "+ NbBundle.getMessage(RetrieverEngine.class, 318 "MSG_retrieving_location_found_in",rent.getCurrentAddress(), 319 rent.getBaseAddress())); 320 return; 321 } 322 String errorMess = NbBundle.getMessage(RetrieverEngine.class, "MSG_general_io_error", ex.getMessage()); 323 if(showErrorPopup){ 324 NotifyDescriptor.Message ndm = new NotifyDescriptor.Message(errorMess, NotifyDescriptor.Message.ERROR_MESSAGE); 325 DialogDisplayer.getDefault().notify(ndm); 326 } 327 outputError(errorMess); 328 return; 329 } 330 331 outputError(ex.getMessage()); 332 return; 333 334 } 335 336 String opTabTitle = NbBundle.getMessage(RetrieverEngine.class, 337 "TITLE_retriever_output_tab_title"); 339 InputOutput iop = null; 340 private InputOutput getOPWindow(){ 341 if(iop == null){ 342 iop = IOProvider.getDefault().getIO(opTabTitle, false); 343 iop.setErrSeparated(true); 344 iop.setFocusTaken(false); 345 350 ioOut = iop.getOut(); 351 DateFormat dtf = DateFormat.getDateTimeInstance(); 352 ioOut.print("\n\n"+dtf.format(new Date (System.currentTimeMillis()))+" : "); 353 } 354 return iop; 355 } 356 357 private void closeOPOuts(){ 358 getErrOut().close(); 359 getOPOut().close(); 360 } 361 362 OutputWriter ioOut; 363 private OutputWriter getOPOut(){ 364 if(ioOut == null){ 365 ioOut = getOPWindow().getOut(); 366 } 367 return ioOut; 368 } 369 370 OutputWriter ioError; 371 private OutputWriter getErrOut(){ 372 if(ioError == null){ 373 ioError = getOPWindow().getErr(); 374 } 375 return ioError; 376 } 377 378 private void outputError(String str){ 379 OutputWriter err = getErrOut(); 380 err.println(NbBundle.getMessage(RetrieverEngine.class, "MSG_Error_str", 381 str)); err.flush(); 383 } 384 385 private void outputMessage(String str){ 386 OutputWriter err = getOPOut(); 387 err.println(str); err.flush(); 389 } 390 391 private void updateDownloadingInfo(RetrieveEntry rent) { 392 OutputWriter opt = getOPOut(); 393 if(rent.getBaseAddress() != null){ 394 opt.println( 395 NbBundle.getMessage(RetrieverEngine.class, 396 "MSG_retrieving_location_found_in",rent.getCurrentAddress(), 397 rent.getBaseAddress())); }else{ 399 opt.println( 400 NbBundle.getMessage(RetrieverEngine.class, 401 "MSG_retrieving_location",rent.getCurrentAddress())); } 403 opt.flush(); 404 } 405 List <RetrieveEntry> retrievedList = new ArrayList <RetrieveEntry>(); 406 private void updateDownloadedInfo(RetrieveEntry rent) { 407 retrievedList.add(rent); 408 OutputWriter opt = getOPOut(); 409 String str = " "+rent.getEffectiveAddress(); 410 opt.println( 411 NbBundle.getMessage(RetrieverEngine.class, 412 "MSG_retrieved_saved_at",str, rent.getSaveFile())); opt.flush(); 414 } 415 416 public File getSeedFileLocation(){ 417 if(retrievedList.size() > 0){ 418 RetrieveEntry rent = retrievedList.get(0); 419 return rent.getSaveFile(); 420 } 421 return null; 422 } 423 424 private void createCatalogIfRequired(RetrieveEntry rent) { 425 URI curURI = null; 426 String addr = rent.getEffectiveAddress(); 427 try { 428 String tempStr = URLResourceRetriever.resolveURL(rent.getBaseAddress(), rent.getCurrentAddress()); 431 if(! (new URI (tempStr).equals(new URI (addr))) ){ 432 addr = tempStr; 433 } 434 } catch (URISyntaxException ex) { 435 } 437 if(isSave2SingleFolder()){ 438 if( !rent.getCurrentAddress().equals(rent.getEffectiveAddress()) ) 439 addr = rent.getCurrentAddress(); 440 } 441 try { 442 curURI = new URI (addr); 443 } catch (URISyntaxException ex) { 444 return; 446 } 447 FileObject fobj = null; 448 try{ 449 fobj = FileUtil.toFileObject(FileUtil.normalizeFile(rent.getSaveFile())); 450 }catch(Exception e){ 451 return; 452 } 453 if(fobj == null) 454 return; 455 CatalogWriteModel dr = null; 456 try { 457 if(this.catalogFileObject == null) 458 dr = CatalogWriteModelFactory.getInstance() 459 .getCatalogWriteModelForProject(fobj); 460 else 461 dr = CatalogWriteModelFactory.getInstance() 462 .getCatalogWriteModelForCatalogFile(this.catalogFileObject); 463 } catch (CatalogModelException ex) { 464 return; 466 } 467 try { 469 dr.addURI(curURI, fobj); 470 } catch (Exception ex) { 471 ex = new Exception ("Exception while writing in to catalog.", ex); 473 handleException(rent, ex); 474 return; 475 } 476 } 477 478 boolean fileOverwrite = false; 479 480 public void setFileOverwrite(boolean fileOverwrite){ 481 this.fileOverwrite = fileOverwrite; 482 } 483 484 public boolean getFileOverwrite() { 485 return fileOverwrite; 486 } 487 488 Map <RetrieveEntry, Exception > audits; 489 public Map <RetrieveEntry, Exception > getRetrievedResourceExceptionMap() { 490 return audits; 491 } 492 493 494 FileObject catalogFileObject = null; 495 public void setCatalogFile(FileObject catalogFileObject) { 496 this.catalogFileObject = catalogFileObject; 497 } 498 499 500 private boolean save2SingleFolder = false; 501 public void setSave2SingleFolder(boolean save2SingleFolder) { 502 this.save2SingleFolder = save2SingleFolder; 503 } 504 505 public boolean isSave2SingleFolder() { 506 return save2SingleFolder; 507 } 508 } 509 | Popular Tags |