/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.internal.mirror;

import java.io.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.standalone.*;

/**
 * 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();
	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();
		System.out.println(
			tab
				+ "Getting plugin entries for " //$NON-NLS-1$
				+ sourceFeature.getVersionedIdentifier()
				+ " ..."); //$NON-NLS-1$
		final IPluginEntry[] sourceFeaturePluginEntries =
			sourceFeature.getPluginEntries();

		// 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++) {
			provider.getPluginEntryArchiveReferences(pluginsToInstall[i], null);
		}

		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++) {
			ContentReference[] references =
				provider.getPluginEntryArchiveReferences(
					pluginsToInstall[i],
					null);
			storePluginArchive(references[0]);
			addDownloadedPluginEntry(pluginsToInstall[i]);
		}

		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();
			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$
			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();
		if (url == null && text == null && text.length() <= 0) {
			return;
		}
		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.Writer.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());
			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$
		}
	}
}
