1 11 package org.eclipse.update.internal.mirror; 12 13 import java.io.File ; 14 import java.io.FileOutputStream ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.io.OutputStreamWriter ; 18 import java.io.PrintWriter ; 19 import java.net.URL ; 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.Set ; 25 26 import org.eclipse.core.runtime.CoreException; 27 import org.eclipse.core.runtime.IProgressMonitor; 28 import org.eclipse.core.runtime.NullProgressMonitor; 29 import org.eclipse.update.core.ContentReference; 30 import org.eclipse.update.core.ICategory; 31 import org.eclipse.update.core.IFeature; 32 import org.eclipse.update.core.IFeatureContentProvider; 33 import org.eclipse.update.core.IFeatureReference; 34 import org.eclipse.update.core.INonPluginEntry; 35 import org.eclipse.update.core.IPluginEntry; 36 import org.eclipse.update.core.ISite; 37 import org.eclipse.update.core.ISiteFeatureReference; 38 import org.eclipse.update.core.IURLEntry; 39 import org.eclipse.update.core.IVerificationListener; 40 import org.eclipse.update.core.Site; 41 import org.eclipse.update.core.SiteFeatureReferenceModel; 42 import org.eclipse.update.core.Utilities; 43 import org.eclipse.update.core.VersionedIdentifier; 44 import org.eclipse.update.core.model.CategoryModel; 45 import org.eclipse.update.core.model.SiteModelFactory; 46 import org.eclipse.update.core.model.URLEntryModel; 47 import org.eclipse.update.internal.core.CoreExceptionWithRootCause; 48 import org.eclipse.update.internal.core.FatalIOException; 49 import org.eclipse.update.internal.core.FeaturePackagedContentProvider; 50 import org.eclipse.update.internal.core.ISiteContentConsumer; 51 import org.eclipse.update.internal.core.UpdateCore; 52 import org.eclipse.update.internal.core.UpdateManagerUtils; 53 import org.eclipse.update.standalone.StandaloneUpdateApplication; 54 55 58 public class MirrorSite extends Site { 59 private final static String INDENT = " "; private SiteModelFactory factory; 61 64 private Collection downloadedPluginEntries = new ArrayList (); 65 private Collection downloadedFeatureReferenceModels = new ArrayList (); 66 private boolean ignoreNonPresentPlugins; 67 public MirrorSite(SiteModelFactory factory) { 68 this.factory = factory; 69 } 70 71 78 public void mirrorAndExpose( 79 ISite remoteSite, 80 ISiteFeatureReference[] sourceFeatureRefs, 81 IFeatureReference[] optionalfeatures, 82 String mirrorSiteUrl) 83 throws CoreException { 84 85 mirrorAndExposeFeatures( 86 remoteSite, 87 sourceFeatureRefs, 88 optionalfeatures); 89 90 System.out.println( 91 "Installing features finished. Updating categories ..."); updateCategories(remoteSite); 93 System.out.println( 94 "Updating categories finished. Updating site description ..."); updateDescription(remoteSite); 96 System.out.println( 97 "Updating site description finished. Saving site.xml ..."); save(); 99 if (mirrorSiteUrl != null) { 100 generateUpdatePolicy(mirrorSiteUrl); 101 } 102 } 103 private void mirrorAndExposeFeatures( 104 ISite remoteSite, 105 ISiteFeatureReference[] sourceFeatureRefs, 106 IFeatureReference[] optionalfeatures) 107 throws CoreException { 108 109 Collection failedFeatures = new ArrayList (); 111 for (int i = 0; i < sourceFeatureRefs.length; i++) { 112 try { 113 IFeature sourceFeature = 114 sourceFeatureRefs[i].getFeature(new NullProgressMonitor()); 115 SiteFeatureReferenceModel featureRef = 116 mirrorFeature( 117 remoteSite, 118 sourceFeature, 119 optionalfeatures, 120 1); 121 ICategory remoteCategories[] = 123 sourceFeatureRefs[i].getCategories(); 124 for (int j = 0; j < remoteCategories.length; j++) { 125 featureRef.addCategoryName(remoteCategories[j].getName()); 126 } 127 128 addFeatureReferenceModel(remoteSite, featureRef); 129 } catch (CoreException ce) { 130 failedFeatures.add(sourceFeatureRefs[i]); 131 } 132 } 133 134 if (failedFeatures.size() > 0) { 136 sourceFeatureRefs = 137 (ISiteFeatureReference[]) failedFeatures.toArray( 138 new ISiteFeatureReference[failedFeatures.size()]); 139 } else { 140 return; 141 } 142 143 for (int i = 0; i < sourceFeatureRefs.length; i++) { 144 IFeature sourceFeature = 145 sourceFeatureRefs[i].getFeature(new NullProgressMonitor()); 146 SiteFeatureReferenceModel featureRef = 147 mirrorFeature(remoteSite, sourceFeature, optionalfeatures, 1); 148 ICategory remoteCategories[] = sourceFeatureRefs[i].getCategories(); 150 for (int j = 0; j < remoteCategories.length; j++) { 151 featureRef.addCategoryName(remoteCategories[j].getName()); 152 } 153 154 addFeatureReferenceModel(remoteSite, featureRef); 155 } 156 } 157 158 163 private SiteFeatureReferenceModel mirrorFeature( 164 ISite remoteSite, 165 IFeature sourceFeature, 166 IFeatureReference[] optionalfeatures, 167 int indent) 168 throws CoreException { 169 String tab = ""; for (int i = 0; i < indent; i++) 171 tab += " "; System.out.println( 173 tab 174 + "Mirroring feature " + sourceFeature.getVersionedIdentifier() 176 + " ..."); SiteFeatureReferenceModel existingFeatures[] = 178 getDownloadedFeatureReferenceModels(); 179 for (int e = 0; e < existingFeatures.length; e++) { 180 if (existingFeatures[e] 181 .getVersionedIdentifier() 182 .equals(sourceFeature.getVersionedIdentifier())) { 183 System.out.println( 184 tab 185 + "Feature " + sourceFeature.getVersionedIdentifier() 187 + " already exists. Skipping downloading."); return existingFeatures[e]; 189 } 190 } 191 192 final IFeatureContentProvider provider = 193 sourceFeature.getFeatureContentProvider(); 194 195 if (provider instanceof FeaturePackagedContentProvider) { 198 ((FeaturePackagedContentProvider) provider).setContinueOnError(ignoreNonPresentPlugins); 199 } 200 201 System.out.println( 202 tab 203 + "Getting plugin entries for " + sourceFeature.getVersionedIdentifier() 205 + " ..."); final IPluginEntry[] sourceFeaturePluginEntries = 207 sourceFeature.getRawPluginEntries(); 208 209 213 IPluginEntry[] pluginsToInstall = 214 UpdateManagerUtils.diff( 215 sourceFeaturePluginEntries, 216 getDownloadedPluginEntries()); 217 218 System.out.println( 219 tab 220 + "Getting non plugin entries for " + sourceFeature.getVersionedIdentifier() 222 + " ..."); final INonPluginEntry[] nonPluginsToInstall = 224 sourceFeature.getRawNonPluginEntries(); 225 226 System.out.println( 227 tab 228 + "Getting included features for " + sourceFeature.getVersionedIdentifier() 230 + " ..."); IFeatureReference[] children = 232 sourceFeature.getRawIncludedFeatureReferences(); 233 if (optionalfeatures != null) { 234 children = 235 UpdateManagerUtils.optionalChildrenToInstall( 236 children, 237 optionalfeatures); 238 } 239 240 System.out.println( 241 tab 242 + "Downloading feature archives for " + sourceFeature.getVersionedIdentifier() 244 + " ..."); provider.getFeatureEntryArchiveReferences(null); 247 248 System.out.println( 249 tab 250 + "Downloading plug-in archives for " + sourceFeature.getVersionedIdentifier() 252 + " ..."); for (int i = 0; i < pluginsToInstall.length; i++) { 255 try { 256 provider.getPluginEntryArchiveReferences(pluginsToInstall[i], null); 257 } catch (CoreException ce) { 258 if ( ignoreNonPresentPlugins && 259 (ce instanceof CoreExceptionWithRootCause) && 260 (((CoreExceptionWithRootCause)ce).getRootException() != null) && 261 (((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) { 262 System.out.println("Could not mirror plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site"); } else { 264 throw ce; 265 } 266 } 267 } 268 269 System.out.println( 270 tab 271 + "Downloading non plug-in archives for " + sourceFeature.getVersionedIdentifier() 273 + " ..."); for (int i = 0; i < nonPluginsToInstall.length; i++) { 276 provider.getNonPluginEntryArchiveReferences( 277 nonPluginsToInstall[i], 278 null); 279 } 280 281 System.out.println( 282 tab 283 + "Installing child features for " + sourceFeature.getVersionedIdentifier() 285 + " ..."); for (int i = 0; i < children.length; i++) { 288 IFeature childFeature = children[i].getFeature(null); 289 mirrorFeature( 290 remoteSite, 291 childFeature, 292 optionalfeatures, 293 indent + 1); 294 } 295 296 System.out.println( 297 tab 298 + "Storing plug-in archives for " + sourceFeature.getVersionedIdentifier() 300 + " ..."); for (int i = 0; i < pluginsToInstall.length; i++) { 303 try { 304 ContentReference[] references = provider.getPluginEntryArchiveReferences( pluginsToInstall[i], null); 305 storePluginArchive(references[0]); 306 addDownloadedPluginEntry(pluginsToInstall[i]); 307 } catch (CoreException ce) { 308 if ( ignoreNonPresentPlugins && 309 (ce instanceof CoreExceptionWithRootCause) && 310 (((CoreExceptionWithRootCause)ce).getRootException() != null) && 311 (((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) { 312 System.out.println("Could not write plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site"); } else { 314 throw ce; 316 } 317 } 318 } 319 320 System.out.println( 321 tab 322 + "Storing non plug-in archives for " + sourceFeature.getVersionedIdentifier() 324 + " ..."); for (int i = 0; i < nonPluginsToInstall.length; i++) { 327 ContentReference[] references = 328 provider.getNonPluginEntryArchiveReferences( 329 nonPluginsToInstall[i], 330 null); 331 for (int r = 0; r < references.length; r++) { 332 storeNonPluginArchive( 333 sourceFeature.getVersionedIdentifier(), 334 references[r]); 335 } 336 } 337 338 System.out.println( 339 tab 340 + "Storing feature archives for " + sourceFeature.getVersionedIdentifier() 342 + " ..."); ContentReference[] references = 345 provider.getFeatureEntryArchiveReferences(null); 346 storeFeatureArchive(references[0]); 347 348 System.out.println( 349 tab 350 + "Adding feature " + sourceFeature.getVersionedIdentifier() 352 + " to model ..."); 354 SiteFeatureReferenceModel featureRef = 356 factory.createFeatureReferenceModel(); 357 featureRef.setSiteModel(this); 358 featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE); 360 featureRef.setFeatureIdentifier( 361 sourceFeature.getVersionedIdentifier().getIdentifier()); 362 featureRef.setFeatureVersion( 363 sourceFeature.getVersionedIdentifier().getVersion().toString()); 364 addDownloadedFeatureReferenceModel(featureRef); 365 366 System.out.println( 367 tab 368 + "Mirroring feature " + sourceFeature.getVersionedIdentifier() 370 + " finished."); return featureRef; 372 373 } 374 378 public void addFeatureReferenceModel( 379 ISite remoteSite, 380 SiteFeatureReferenceModel featureReference) { 381 ISiteFeatureReference remoteFeatures[] = 383 remoteSite.getRawFeatureReferences(); 384 for (int i = 0; i < remoteFeatures.length; i++) { 385 ISiteFeatureReference remoteFeatureRef = remoteFeatures[i]; 386 try { 387 if (remoteFeatureRef 388 .getVersionedIdentifier() 389 .equals(featureReference.getVersionedIdentifier())) { 390 addFeatureReferenceModel(featureReference); 391 } 392 } catch (CoreException ce) { 393 StandaloneUpdateApplication.exceptionLogged(); 394 UpdateCore.log(ce); 395 } 396 } 397 save(); 398 System.out.println( 399 "Feature " + featureReference.getVersionedIdentifier() 401 + " added to site.xml."); } 403 406 public void addFeatureReferenceModel(SiteFeatureReferenceModel featureReference) { 407 SiteFeatureReferenceModel[] existingModels = 408 getFeatureReferenceModels(); 409 for (int j = 0; j < existingModels.length; j++) { 410 if (existingModels[j] 411 .getVersionedIdentifier() 412 .equals(featureReference.getVersionedIdentifier())) { 413 super.removeFeatureReferenceModel(existingModels[j]); 414 } 415 } 416 super.addFeatureReferenceModel(featureReference); 417 } 418 419 422 private void storeFeatureArchive(ContentReference contentReference) 423 throws CoreException { 424 InputStream inStream = null; 425 String featurePath = null; 426 427 try { 428 URL newURL = 429 new URL ( 430 this.getURL(), 431 Site.DEFAULT_INSTALLED_FEATURE_PATH 432 + contentReference.getIdentifier() 433 + ".jar"); featurePath = newURL.getFile(); 435 inStream = contentReference.getInputStream(); 436 UpdateManagerUtils.copyToLocal(inStream, featurePath, null); 437 } catch (IOException e) { 438 throw Utilities.newCoreException( 439 "Error occurred while creating "+ featurePath+" file.", e); 441 } finally { 442 if (inStream != null) { 443 try { 444 inStream.close(); 445 } catch (IOException e) { 446 } 447 } 448 } 449 450 } 451 454 private void storePluginArchive(ContentReference contentReference) 455 throws CoreException { 456 457 InputStream inStream = null; 458 String pluginPath = null; 459 try { 460 URL newURL = new URL (getURL(), contentReference.getIdentifier()); 461 pluginPath = newURL.getFile(); 462 inStream = contentReference.getInputStream(); 463 if (inStream != null) { 465 UpdateManagerUtils.copyToLocal(inStream, pluginPath, null); 466 } 467 } catch (IOException e) { 468 throw Utilities.newCoreException( 469 "Error occurred while creating "+ pluginPath+" file.", e); 471 } finally { 472 if (inStream != null) { 473 try { 474 inStream.close(); 475 } catch (IOException e) { 476 } 477 } 478 } 479 } 480 481 private void storeNonPluginArchive( 482 VersionedIdentifier featureVersionedIdentifier, 483 ContentReference contentReference) 484 throws CoreException { 485 486 InputStream inStream = null; 487 File nonPluginArchivePath = null; 488 try { 489 URL newDirURL = 490 new URL ( 491 getURL(), 492 Site.DEFAULT_INSTALLED_FEATURE_PATH 493 + "/" + featureVersionedIdentifier); 495 File dir = new File (newDirURL.getFile()); 496 dir.mkdirs(); 497 inStream = contentReference.getInputStream(); 498 nonPluginArchivePath = 499 new File (dir, contentReference.getIdentifier()); 500 UpdateManagerUtils.copyToLocal( 501 inStream, 502 nonPluginArchivePath.getAbsolutePath(), 503 null); 504 } catch (IOException e) { 505 throw Utilities.newCoreException( 506 "Error occurred while creating "+ nonPluginArchivePath.getAbsolutePath()+" file." ,e); 508 } finally { 509 if (inStream != null) { 510 try { 511 inStream.close(); 512 } catch (IOException e) { 513 } 514 } 515 } 516 } 517 518 private void save() { 519 FileOutputStream fos = null; 520 try { 521 URL siteURL = new URL (this.getURL(), "site.xml"); fos = new FileOutputStream (new File (siteURL.getFile())); 523 OutputStreamWriter outWriter = new OutputStreamWriter (fos, "UTF-8"); PrintWriter writer = new PrintWriter (outWriter); 525 save(writer); 526 writer.flush(); 527 } catch (IOException ioe) { 528 StandaloneUpdateApplication.exceptionLogged(); 529 UpdateCore.log( 530 Utilities.newCoreException( 531 "Site XML could not be saved.", ioe)); 533 } finally { 534 if (fos != null) { 535 try { 536 fos.close(); 537 } catch (IOException ioe2) { 538 } 539 } 540 } 541 } 542 private void save(PrintWriter writer) { 543 writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writeSite("", writer); } 547 548 private void writeSite(String indent, PrintWriter writer) { 549 writer.print(indent + "<site"); String indent2 = indent + INDENT; 551 writer.println(">"); URLEntryModel description = getDescriptionModel(); 557 if (description != null) { 558 writer.println(); 559 writeDescription(indent2, writer, description); 560 writer.println(); 561 } 562 writeFeatures(indent2, writer); 563 writeCategories(indent2, writer); 564 writer.println(indent + "</site>"); } 566 private void writeFeatures(String indent, PrintWriter writer) { 567 SiteFeatureReferenceModel[] featureReferenceModels = 568 getFeatureReferenceModels(); 569 for (int i = 0; i < featureReferenceModels.length; i++) { 570 writer.print(indent); 571 writer.print("<feature"); writer.print( 573 " url=\"features/" + featureReferenceModels[i].getFeatureIdentifier() 575 + "_" + featureReferenceModels[i].getFeatureVersion() 577 + ".jar\""); writer.print( 579 " id=\"" + featureReferenceModels[i].getFeatureIdentifier() 581 + "\""); writer.print( 583 " version=\"" + featureReferenceModels[i].getFeatureVersion() 585 + "\""); writer.println(">"); 588 String [] categoryNames = 589 featureReferenceModels[i].getCategoryNames(); 590 for (int cn = 0; cn < categoryNames.length; cn++) { 591 writer.print(indent + INDENT); 592 writer.println( 593 "<category name=\"" + categoryNames[cn] + "\" />"); 595 } 596 597 writer.print(indent); 598 writer.println("</feature>"); writer.println(); 600 } 601 } 602 private void writeCategories(String indent, PrintWriter writer) { 603 CategoryModel[] categoryModels = getCategoryModels(); 604 if (categoryModels.length <= 0) { 605 return; 606 } 607 for (int i = 0; i < categoryModels.length; i++) { 608 writer.print(indent); 609 writer.print("<category-def"); writer.print( 611 " name=\"" + categoryModels[i].getName() 613 + "\" label=\"" + categoryModels[i].getLabel() 615 + "\""); writer.println(">"); if (categoryModels[i].getDescriptionModel() != null) { 618 writeDescription( 619 indent + INDENT, 620 writer, 621 categoryModels[i].getDescriptionModel()); 622 } 623 writer.print(indent); 624 writer.println("</category-def>"); writer.println(); 626 } 627 } 628 private void writeDescription( 629 String indent, 630 PrintWriter writer, 631 URLEntryModel urlEntryModel) { 632 String url = urlEntryModel.getURLString(); 633 String text = urlEntryModel.getAnnotationNonLocalized(); 634 if (url == null && text == null && text.length() <= 0) { 635 return; 636 } 637 writer.print(indent); 638 writer.print("<description"); if (url != null) 640 writer.print(" url=\"" + url + "\""); if (text == null || text.length() <= 0) { 642 writer.println(" />"); } else { 644 writer.println(">"); if (text != null) { 646 writer.println( 647 indent + INDENT + UpdateManagerUtils.Writer.xmlSafe(text)); 648 } 649 writer.println(indent + "</description>"); } 651 } 652 660 public void addDownloadedPluginEntry(IPluginEntry pluginEntry) { 661 downloadedPluginEntries.add(pluginEntry); 662 } 663 664 private IPluginEntry[] getDownloadedPluginEntries() { 665 return (IPluginEntry[]) downloadedPluginEntries.toArray( 666 new IPluginEntry[downloadedPluginEntries.size()]); 667 } 668 676 public void addDownloadedFeatureReferenceModel(SiteFeatureReferenceModel featureModel) { 677 downloadedFeatureReferenceModels.add(featureModel); 678 } 679 680 private SiteFeatureReferenceModel[] getDownloadedFeatureReferenceModels() { 681 return ( 682 SiteFeatureReferenceModel[]) downloadedFeatureReferenceModels 683 .toArray( 684 new SiteFeatureReferenceModel[downloadedFeatureReferenceModels 685 .size()]); 686 } 687 692 707 708 712 private void updateDescription(ISite remoteSite) { 713 IURLEntry urlEntry = remoteSite.getDescription(); 714 if (urlEntry != null) { 715 URLEntryModel newUrlEntryModel = new URLEntryModel(); 716 URL url = urlEntry.getURL(); 717 newUrlEntryModel.setAnnotation(urlEntry.getAnnotation()); 718 if (url != null) { 723 newUrlEntryModel.setURLString(url.toExternalForm()); 724 } 725 this.setDescriptionModel(newUrlEntryModel); 726 } 727 } 728 733 private void updateCategories(ISite remoteSite) { 734 Set usedCategoryNames = new HashSet (); 736 SiteFeatureReferenceModel featureRefModels[] = 737 getFeatureReferenceModels(); 738 for (int f = 0; f < featureRefModels.length; f++) { 739 String [] featureCategoryNames = 740 featureRefModels[f].getCategoryNames(); 741 742 for (int c = 0; c < featureCategoryNames.length; c++) { 743 usedCategoryNames.add(featureCategoryNames[c]); 744 } 745 } 746 747 Collection newCategoryModels = new ArrayList (); 748 for (Iterator it = usedCategoryNames.iterator(); it.hasNext();) { 749 String name = (String ) it.next(); 750 ICategory remoteCategory = remoteSite.getCategory(name); 751 if (remoteCategory == null) { 752 CategoryModel oldCategory = null; 754 try { 755 oldCategory = (CategoryModel) getCategory(name); 756 } catch (NullPointerException npe) { 757 } 759 if (oldCategory != null) { 760 newCategoryModels.add(oldCategory); 761 } 762 } else { 763 newCategoryModels.add(remoteCategory); 764 } 765 766 } 767 setCategoryModels( 768 (CategoryModel[]) newCategoryModels.toArray( 769 new CategoryModel[newCategoryModels.size()])); 770 771 } 772 private void generateUpdatePolicy(String url) { 773 FileOutputStream fos = null; 774 try { 775 URL siteURL = new URL (this.getURL(), "policy.xml"); fos = new FileOutputStream (new File (siteURL.getFile())); 777 OutputStreamWriter outWriter = new OutputStreamWriter (fos, "UTF-8"); PrintWriter writer = new PrintWriter (outWriter); 779 780 writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writer.println("<update-policy>"); 783 writer.println( 784 "<!-- You can paste the following fragment, containing url-map elements, into another policy file. -->"); writeUrlMaps(writer, url); 786 writer.println("<!-- End of fragment with url-map elements. -->"); 788 writer.println("</update-policy>"); 790 writer.flush(); 791 } catch (IOException ioe) { 792 StandaloneUpdateApplication.exceptionLogged(); 793 UpdateCore.log( 794 Utilities.newCoreException( 795 "policy.xml could not be saved", ioe)); 797 } finally { 798 if (fos != null) { 799 try { 800 fos.close(); 801 } catch (IOException ioe2) { 802 } 803 } 804 } 805 } 806 private void writeUrlMaps(PrintWriter writer, String url) { 807 SiteFeatureReferenceModel[] featureReferenceModels = 808 getFeatureReferenceModels(); 809 for (int i = 0; i < featureReferenceModels.length; i++) { 810 writer.print("\t"); writer.print("<url-map"); writer.print( 813 " pattern=\"" + featureReferenceModels[i].getFeatureIdentifier() 815 + "\""); writer.print(" url=\"" + url + "\""); writer.println(" />"); } 819 } 820 821 public void setIgnoreNonPresentPlugins(boolean ignoreNonPresentPlugins) { 822 this.ignoreNonPresentPlugins = ignoreNonPresentPlugins; 823 824 } 825 } 826 | Popular Tags |