/*******************************************************************************
 * Copyright (c) 2000, 2004 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.FatalIOException;
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();
		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.getCause() != null) && (ce.getCause() 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.getCause() != null) && (ce.getCause() 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();
			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();
		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$
		}
	}

	public void setIgnoreNonPresentPlugins(boolean ignoreNonPresentPlugins) {
		this.ignoreNonPresentPlugins = ignoreNonPresentPlugins;
		
	}
}
