/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.update.internal.mirror; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.update.core.ContentReference; import org.eclipse.update.core.ICategory; import org.eclipse.update.core.IFeature; import org.eclipse.update.core.IFeatureContentProvider; import org.eclipse.update.core.IFeatureReference; import org.eclipse.update.core.INonPluginEntry; import org.eclipse.update.core.IPluginEntry; import org.eclipse.update.core.ISite; import org.eclipse.update.core.ISiteFeatureReference; import org.eclipse.update.core.IURLEntry; import org.eclipse.update.core.IVerificationListener; import org.eclipse.update.core.Site; import org.eclipse.update.core.SiteFeatureReferenceModel; import org.eclipse.update.core.Utilities; import org.eclipse.update.core.VersionedIdentifier; import org.eclipse.update.core.model.CategoryModel; import org.eclipse.update.core.model.SiteModelFactory; import org.eclipse.update.core.model.URLEntryModel; import org.eclipse.update.internal.core.CoreExceptionWithRootCause; import org.eclipse.update.internal.core.FatalIOException; import org.eclipse.update.internal.core.FeaturePackagedContentProvider; import org.eclipse.update.internal.core.ISiteContentConsumer; import org.eclipse.update.internal.core.UpdateCore; import org.eclipse.update.internal.core.UpdateManagerUtils; import org.eclipse.update.standalone.StandaloneUpdateApplication; /** * Local mirror site. Read/Write */ public class MirrorSite extends Site { private final static String INDENT = " "; //$NON-NLS-1$ private SiteModelFactory factory; /** * plugin entries */ private Collection downloadedPluginEntries = new ArrayList(); private Collection downloadedFeatureReferenceModels = new ArrayList(); private boolean ignoreNonPresentPlugins; public MirrorSite(SiteModelFactory factory) { this.factory = factory; } /** * Mirrors the specified features and listed optional features on this site. * @see ISite#install(IFeature, IVerificationListener, IProgressMonitor) * @param mirrorSiteUrl external URL of the mirror site or null; * if parameter is provided policy fragment will be generated * @exception CoreException */ public void mirrorAndExpose( ISite remoteSite, ISiteFeatureReference[] sourceFeatureRefs, IFeatureReference[] optionalfeatures, String mirrorSiteUrl) throws CoreException { mirrorAndExposeFeatures( remoteSite, sourceFeatureRefs, optionalfeatures); System.out.println( "Installing features finished. Updating categories ..."); //$NON-NLS-1$ updateCategories(remoteSite); System.out.println( "Updating categories finished. Updating site description ..."); //$NON-NLS-1$ updateDescription(remoteSite); System.out.println( "Updating site description finished. Saving site.xml ..."); //$NON-NLS-1$ save(); if (mirrorSiteUrl != null) { generateUpdatePolicy(mirrorSiteUrl); } } private void mirrorAndExposeFeatures( ISite remoteSite, ISiteFeatureReference[] sourceFeatureRefs, IFeatureReference[] optionalfeatures) throws CoreException { // Features that failed will be retried once again Collection failedFeatures = new ArrayList(); for (int i = 0; i < sourceFeatureRefs.length; i++) { try { IFeature sourceFeature = sourceFeatureRefs[i].getFeature(new NullProgressMonitor()); SiteFeatureReferenceModel featureRef = mirrorFeature( remoteSite, sourceFeature, optionalfeatures, 1); // Set categories of the new feature ICategory remoteCategories[] = sourceFeatureRefs[i].getCategories(); for (int j = 0; j < remoteCategories.length; j++) { featureRef.addCategoryName(remoteCategories[j].getName()); } addFeatureReferenceModel(remoteSite, featureRef); } catch (CoreException ce) { failedFeatures.add(sourceFeatureRefs[i]); } } // do we need to retry? if (failedFeatures.size() > 0) { sourceFeatureRefs = (ISiteFeatureReference[]) failedFeatures.toArray( new ISiteFeatureReference[failedFeatures.size()]); } else { return; } for (int i = 0; i < sourceFeatureRefs.length; i++) { IFeature sourceFeature = sourceFeatureRefs[i].getFeature(new NullProgressMonitor()); SiteFeatureReferenceModel featureRef = mirrorFeature(remoteSite, sourceFeature, optionalfeatures, 1); // Set categories of the new feature ICategory remoteCategories[] = sourceFeatureRefs[i].getCategories(); for (int j = 0; j < remoteCategories.length; j++) { featureRef.addCategoryName(remoteCategories[j].getName()); } addFeatureReferenceModel(remoteSite, featureRef); } } /** * Install the specified feature and listed optional features on this site. * @see ISite#install(IFeature, IVerificationListener, IProgressMonitor) * @exception CoreException */ private SiteFeatureReferenceModel mirrorFeature( ISite remoteSite, IFeature sourceFeature, IFeatureReference[] optionalfeatures, int indent) throws CoreException { String tab = ""; //$NON-NLS-1$ for (int i = 0; i < indent; i++) tab += " "; //$NON-NLS-1$ System.out.println( tab + "Mirroring feature " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ SiteFeatureReferenceModel existingFeatures[] = getDownloadedFeatureReferenceModels(); for (int e = 0; e < existingFeatures.length; e++) { if (existingFeatures[e] .getVersionedIdentifier() .equals(sourceFeature.getVersionedIdentifier())) { System.out.println( tab + "Feature " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " already exists. Skipping downloading."); //$NON-NLS-1$ return existingFeatures[e]; } } final IFeatureContentProvider provider = sourceFeature.getFeatureContentProvider(); // TODO: passing command options could be made more general in future, so this // cast is not needed. if (provider instanceof FeaturePackagedContentProvider) { ((FeaturePackagedContentProvider) provider).setContinueOnError(ignoreNonPresentPlugins); } System.out.println( tab + "Getting plugin entries for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ final IPluginEntry[] sourceFeaturePluginEntries = sourceFeature.getRawPluginEntries(); // determine list of plugins to install // find the intersection between the plugin entries already contained // on the target site, and plugin entries packaged in source feature IPluginEntry[] pluginsToInstall = UpdateManagerUtils.diff( sourceFeaturePluginEntries, getDownloadedPluginEntries()); System.out.println( tab + "Getting non plugin entries for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ final INonPluginEntry[] nonPluginsToInstall = sourceFeature.getRawNonPluginEntries(); System.out.println( tab + "Getting included features for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ IFeatureReference[] children = sourceFeature.getRawIncludedFeatureReferences(); if (optionalfeatures != null) { children = UpdateManagerUtils.optionalChildrenToInstall( children, optionalfeatures); } System.out.println( tab + "Downloading feature archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // download feature archives provider.getFeatureEntryArchiveReferences(null); System.out.println( tab + "Downloading plug-in archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // download plugin archives for (int i = 0; i < pluginsToInstall.length; i++) { try { provider.getPluginEntryArchiveReferences(pluginsToInstall[i], null); } catch (CoreException ce) { if ( ignoreNonPresentPlugins && (ce instanceof CoreExceptionWithRootCause) && (((CoreExceptionWithRootCause)ce).getRootException() != null) && (((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) { System.out.println("Could not mirror plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site"); //$NON-NLS-1$//$NON-NLS-2$ } else { throw ce; } } } System.out.println( tab + "Downloading non plug-in archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // download non-plugin archives for (int i = 0; i < nonPluginsToInstall.length; i++) { provider.getNonPluginEntryArchiveReferences( nonPluginsToInstall[i], null); } System.out.println( tab + "Installing child features for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // install child features first for (int i = 0; i < children.length; i++) { IFeature childFeature = children[i].getFeature(null); mirrorFeature( remoteSite, childFeature, optionalfeatures, indent + 1); } System.out.println( tab + "Storing plug-in archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // store plugins' archives for (int i = 0; i < pluginsToInstall.length; i++) { try { ContentReference[] references = provider.getPluginEntryArchiveReferences( pluginsToInstall[i], null); storePluginArchive(references[0]); addDownloadedPluginEntry(pluginsToInstall[i]); } catch (CoreException ce) { if ( ignoreNonPresentPlugins && (ce instanceof CoreExceptionWithRootCause) && (((CoreExceptionWithRootCause)ce).getRootException() != null) && (((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) { System.out.println("Could not write plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site"); //$NON-NLS-1$ //$NON-NLS-2$ } else { //System.out.println("ignoreNonPresentPlugins:"+ignoreNonPresentPlugins); //$NON-NLS-1$ throw ce; } } } System.out.println( tab + "Storing non plug-in archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // store non plugins' archives for (int i = 0; i < nonPluginsToInstall.length; i++) { ContentReference[] references = provider.getNonPluginEntryArchiveReferences( nonPluginsToInstall[i], null); for (int r = 0; r < references.length; r++) { storeNonPluginArchive( sourceFeature.getVersionedIdentifier(), references[r]); } } System.out.println( tab + "Storing feature archives for " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " ..."); //$NON-NLS-1$ // store feature archive ContentReference[] references = provider.getFeatureEntryArchiveReferences(null); storeFeatureArchive(references[0]); System.out.println( tab + "Adding feature " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " to model ..."); //$NON-NLS-1$ // add feature model to site model SiteFeatureReferenceModel featureRef = factory.createFeatureReferenceModel(); featureRef.setSiteModel(this); //featureRef.setURLString(featureURL.toExternalForm()); featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE); featureRef.setFeatureIdentifier( sourceFeature.getVersionedIdentifier().getIdentifier()); featureRef.setFeatureVersion( sourceFeature.getVersionedIdentifier().getVersion().toString()); addDownloadedFeatureReferenceModel(featureRef); System.out.println( tab + "Mirroring feature " //$NON-NLS-1$ + sourceFeature.getVersionedIdentifier() + " finished."); //$NON-NLS-1$ return featureRef; } /** * Adds a feature reference model to this site, * and exposes in site.xml if remote site exposes given feature. */ public void addFeatureReferenceModel( ISite remoteSite, SiteFeatureReferenceModel featureReference) { // check if remote site exposes this feature ISiteFeatureReference remoteFeatures[] = remoteSite.getRawFeatureReferences(); for (int i = 0; i < remoteFeatures.length; i++) { ISiteFeatureReference remoteFeatureRef = remoteFeatures[i]; try { if (remoteFeatureRef .getVersionedIdentifier() .equals(featureReference.getVersionedIdentifier())) { addFeatureReferenceModel(featureReference); } } catch (CoreException ce) { StandaloneUpdateApplication.exceptionLogged(); UpdateCore.log(ce); } } save(); System.out.println( "Feature " //$NON-NLS-1$ + featureReference.getVersionedIdentifier() + " added to site.xml."); //$NON-NLS-1$ } /** * Adds feature model to site model, removing old feature */ public void addFeatureReferenceModel(SiteFeatureReferenceModel featureReference) { SiteFeatureReferenceModel[] existingModels = getFeatureReferenceModels(); for (int j = 0; j < existingModels.length; j++) { if (existingModels[j] .getVersionedIdentifier() .equals(featureReference.getVersionedIdentifier())) { super.removeFeatureReferenceModel(existingModels[j]); } } super.addFeatureReferenceModel(featureReference); } /** * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor) */ private void storeFeatureArchive(ContentReference contentReference) throws CoreException { InputStream inStream = null; String featurePath = null; try { URL newURL = new URL( this.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + contentReference.getIdentifier() + ".jar"); //$NON-NLS-1$ featurePath = newURL.getFile(); inStream = contentReference.getInputStream(); UpdateManagerUtils.copyToLocal(inStream, featurePath, null); } catch (IOException e) { throw Utilities.newCoreException( "Error occurred while creating "+ featurePath+" file.", //$NON-NLS-1$ //$NON-NLS-2$ e); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { } } } } /** * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor) */ private void storePluginArchive(ContentReference contentReference) throws CoreException { InputStream inStream = null; String pluginPath = null; try { URL newURL = new URL(getURL(), contentReference.getIdentifier()); pluginPath = newURL.getFile(); inStream = contentReference.getInputStream(); // added null check here, since contentReference can, in theory, return null for input stream. if (inStream != null) { UpdateManagerUtils.copyToLocal(inStream, pluginPath, null); } } catch (IOException e) { throw Utilities.newCoreException( "Error occurred while creating "+ pluginPath+" file.", //$NON-NLS-1$ //$NON-NLS-2$ e); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { } } } } private void storeNonPluginArchive( VersionedIdentifier featureVersionedIdentifier, ContentReference contentReference) throws CoreException { InputStream inStream = null; File nonPluginArchivePath = null; try { URL newDirURL = new URL( getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "/" //$NON-NLS-1$ + featureVersionedIdentifier); File dir = new File(newDirURL.getFile()); dir.mkdirs(); inStream = contentReference.getInputStream(); nonPluginArchivePath = new File(dir, contentReference.getIdentifier()); UpdateManagerUtils.copyToLocal( inStream, nonPluginArchivePath.getAbsolutePath(), null); } catch (IOException e) { throw Utilities.newCoreException( "Error occurred while creating "+ nonPluginArchivePath.getAbsolutePath()+" file." //$NON-NLS-1$ //$NON-NLS-2$ ,e); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { } } } } private void save() { FileOutputStream fos = null; try { URL siteURL = new URL(this.getURL(), "site.xml"); //$NON-NLS-1$ fos = new FileOutputStream(new File(siteURL.getFile())); OutputStreamWriter outWriter = new OutputStreamWriter(fos, "UTF-8"); //$NON-NLS-1$ PrintWriter writer = new PrintWriter(outWriter); save(writer); writer.flush(); } catch (IOException ioe) { StandaloneUpdateApplication.exceptionLogged(); UpdateCore.log( Utilities.newCoreException( "Site XML could not be saved.", //$NON-NLS-1$ ioe)); } finally { if (fos != null) { try { fos.close(); } catch (IOException ioe2) { } } } } private void save(PrintWriter writer) { writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$ //writer.println("<!DOCTYPE site SYSTEM \"dtd/site.dtd\">"); writeSite("", writer); //$NON-NLS-1$ } private void writeSite(String indent, PrintWriter writer) { writer.print(indent + "<site"); //$NON-NLS-1$ String indent2 = indent + INDENT; // default type //writeIfDefined(indenta, writer, "type", getType()); // stored relative to site.xml //writeIfDefined(indenta, writer, "url", getURL()); writer.println(">"); //$NON-NLS-1$ URLEntryModel description = getDescriptionModel(); if (description != null) { writer.println(); writeDescription(indent2, writer, description); writer.println(); } writeFeatures(indent2, writer); writeCategories(indent2, writer); writer.println(indent + "</site>"); //$NON-NLS-1$ } private void writeFeatures(String indent, PrintWriter writer) { SiteFeatureReferenceModel[] featureReferenceModels = getFeatureReferenceModels(); for (int i = 0; i < featureReferenceModels.length; i++) { writer.print(indent); writer.print("<feature"); //$NON-NLS-1$ writer.print( " url=\"features/" //$NON-NLS-1$ + featureReferenceModels[i].getFeatureIdentifier() + "_" //$NON-NLS-1$ + featureReferenceModels[i].getFeatureVersion() + ".jar\""); //$NON-NLS-1$ writer.print( " id=\"" //$NON-NLS-1$ + featureReferenceModels[i].getFeatureIdentifier() + "\""); //$NON-NLS-1$ writer.print( " version=\"" //$NON-NLS-1$ + featureReferenceModels[i].getFeatureVersion() + "\""); //$NON-NLS-1$ writer.println(">"); //$NON-NLS-1$ String[] categoryNames = featureReferenceModels[i].getCategoryNames(); for (int cn = 0; cn < categoryNames.length; cn++) { writer.print(indent + INDENT); writer.println( "<category name=\"" + categoryNames[cn] + "\" />"); //$NON-NLS-1$ //$NON-NLS-2$ } writer.print(indent); writer.println("</feature>"); //$NON-NLS-1$ writer.println(); } } private void writeCategories(String indent, PrintWriter writer) { CategoryModel[] categoryModels = getCategoryModels(); if (categoryModels.length <= 0) { return; } for (int i = 0; i < categoryModels.length; i++) { writer.print(indent); writer.print("<category-def"); //$NON-NLS-1$ writer.print( " name=\"" //$NON-NLS-1$ + categoryModels[i].getName() + "\" label=\"" //$NON-NLS-1$ + categoryModels[i].getLabel() + "\""); //$NON-NLS-1$ writer.println(">"); //$NON-NLS-1$ if (categoryModels[i].getDescriptionModel() != null) { writeDescription( indent + INDENT, writer, categoryModels[i].getDescriptionModel()); } writer.print(indent); writer.println("</category-def>"); //$NON-NLS-1$ writer.println(); } } private void writeDescription( String indent, PrintWriter writer, URLEntryModel urlEntryModel) { String url = urlEntryModel.getURLString(); String text = urlEntryModel.getAnnotationNonLocalized(); writer.print(indent); writer.print("<description"); //$NON-NLS-1$ if (url != null) writer.print(" url=\"" + url + "\""); //$NON-NLS-1$ //$NON-NLS-2$ if (text == null || text.length() <= 0) { writer.println(" />"); //$NON-NLS-1$ } else { writer.println(">"); //$NON-NLS-1$ if (text != null) { writer.println( indent + INDENT + UpdateManagerUtils.xmlSafe(text)); } writer.println(indent + "</description>"); //$NON-NLS-1$ } } /** * Adds a plugin entry * Either from parsing the file system or * installing a feature * * We cannot figure out the list of plugins by reading the Site.xml as * the archives tag are optionals */ public void addDownloadedPluginEntry(IPluginEntry pluginEntry) { downloadedPluginEntries.add(pluginEntry); } private IPluginEntry[] getDownloadedPluginEntries() { return (IPluginEntry[]) downloadedPluginEntries.toArray( new IPluginEntry[downloadedPluginEntries.size()]); } /** * Adds a plugin entry * Either from parsing the file system or * installing a feature * * We cannot figure out the list of plugins by reading the Site.xml as * the archives tag are optionals */ public void addDownloadedFeatureReferenceModel(SiteFeatureReferenceModel featureModel) { downloadedFeatureReferenceModels.add(featureModel); } private SiteFeatureReferenceModel[] getDownloadedFeatureReferenceModels() { return ( SiteFeatureReferenceModel[]) downloadedFeatureReferenceModels .toArray( new SiteFeatureReferenceModel[downloadedFeatureReferenceModels .size()]); } /** * Checks if mirror site contains a feature with given ID and version * @param featureRefModel * @return true if such feature exists */ /*private boolean contains(SiteFeatureReferenceModel featureRefModel) { ISiteFeatureReference featureRefs[] = getRawFeatureReferences(); for (int i = 0; i < featureRefs.length; i++) { try { if (featureRefs[i] .getVersionedIdentifier() .equals(featureRefModel.getVersionedIdentifier())) { return true; } } catch (CoreException ce) { ce.printStackTrace(); } } return false; }*/ /** * Updates description of this site * from description of the remote site. */ private void updateDescription(ISite remoteSite) { IURLEntry urlEntry = remoteSite.getDescription(); if (urlEntry != null) { URLEntryModel newUrlEntryModel = new URLEntryModel(); URL url = urlEntry.getURL(); newUrlEntryModel.setAnnotation(urlEntry.getAnnotation()); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=136249 // URL is not required, so might be null // The null case is (already) handled correctly in // writeDescription if (url != null) { newUrlEntryModel.setURLString(url.toExternalForm()); } this.setDescriptionModel(newUrlEntryModel); } } /** * Updates all categories used by features on this site * from categories defined on remote site. * Categories not defined on remote site are unchanged. */ private void updateCategories(ISite remoteSite) { // collect name of categories used on this site Set usedCategoryNames = new HashSet(); SiteFeatureReferenceModel featureRefModels[] = getFeatureReferenceModels(); for (int f = 0; f < featureRefModels.length; f++) { String[] featureCategoryNames = featureRefModels[f].getCategoryNames(); for (int c = 0; c < featureCategoryNames.length; c++) { usedCategoryNames.add(featureCategoryNames[c]); } } Collection newCategoryModels = new ArrayList(); for (Iterator it = usedCategoryNames.iterator(); it.hasNext();) { String name = (String) it.next(); ICategory remoteCategory = remoteSite.getCategory(name); if (remoteCategory == null) { // remote site does not define this category CategoryModel oldCategory = null; try { oldCategory = (CategoryModel) getCategory(name); } catch (NullPointerException npe) { // cannot reproduce npe anymore } if (oldCategory != null) { newCategoryModels.add(oldCategory); } } else { newCategoryModels.add(remoteCategory); } } setCategoryModels( (CategoryModel[]) newCategoryModels.toArray( new CategoryModel[newCategoryModels.size()])); } private void generateUpdatePolicy(String url) { FileOutputStream fos = null; try { URL siteURL = new URL(this.getURL(), "policy.xml"); //$NON-NLS-1$ fos = new FileOutputStream(new File(siteURL.getFile())); OutputStreamWriter outWriter = new OutputStreamWriter(fos, "UTF-8"); //$NON-NLS-1$ PrintWriter writer = new PrintWriter(outWriter); writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$ writer.println("<update-policy>"); //$NON-NLS-1$ writer.println( "<!-- You can paste the following fragment, containing url-map elements, into another policy file. -->"); //$NON-NLS-1$ writeUrlMaps(writer, url); writer.println("<!-- End of fragment with url-map elements. -->"); //$NON-NLS-1$ writer.println("</update-policy>"); //$NON-NLS-1$ writer.flush(); } catch (IOException ioe) { StandaloneUpdateApplication.exceptionLogged(); UpdateCore.log( Utilities.newCoreException( "policy.xml could not be saved", //$NON-NLS-1$ ioe)); } finally { if (fos != null) { try { fos.close(); } catch (IOException ioe2) { } } } } private void writeUrlMaps(PrintWriter writer, String url) { SiteFeatureReferenceModel[] featureReferenceModels = getFeatureReferenceModels(); for (int i = 0; i < featureReferenceModels.length; i++) { writer.print("\t"); //$NON-NLS-1$ writer.print("<url-map"); //$NON-NLS-1$ writer.print( " pattern=\"" //$NON-NLS-1$ + featureReferenceModels[i].getFeatureIdentifier() + "\""); //$NON-NLS-1$ writer.print(" url=\"" + url + "\""); //$NON-NLS-1$ //$NON-NLS-2$ writer.println(" />"); //$NON-NLS-1$ } } public void setIgnoreNonPresentPlugins(boolean ignoreNonPresentPlugins) { this.ignoreNonPresentPlugins = ignoreNonPresentPlugins; } }