Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2008, 2010 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 Sonatype, Inc. - transport split /
 
 package org.eclipse.equinox.internal.p2.updatesite;
 
 import java.io.*;
 import java.net.*;
 import java.util.Map;
 import  org.eclipse.equinox.internal.p2.publisher.eclipse.FeatureParser;
 import  org.eclipse.equinox.p2.publisher.eclipse.*;

Since:
1.0
 
 public class UpdateSite {
 
 	private static final String VERSION_SEPARATOR = "_"//$NON-NLS-1$
 	private static final String JAR_EXTENSION = ".jar"//$NON-NLS-1$
 	private static final String FEATURE_DIR = "features/"//$NON-NLS-1$
 	private static final String PLUGIN_DIR = "plugins/"//$NON-NLS-1$
 	private static final String FEATURE_TEMP_FILE = "feature"//$NON-NLS-1$
 	private static final String SITE_FILE = "site.xml"//$NON-NLS-1$
 	private static final String PROTOCOL_FILE = "file"//$NON-NLS-1$
 	private static final int RETRY_COUNT = 2;
 	private static final String DOT_XML = ".xml"//$NON-NLS-1$
 	private static final String SITE = "site"//$NON-NLS-1$
 	private String checksum;
 	private URI location;
 	private URI rootLocation;
 	private SiteModel site;
 
 	/*
 	 * Some variables for caching.
 	 */
 	// map of String (URI.toString()) to UpdateSite
 	// map of String (URI.toString()) to UpdateSite (for category xmls)
 	// map of String (featureID_featureVersion) to Feature
 	private Map<String, Feature> featureCache = new HashMap<String, Feature>();
 	private Transport transport;
 
 	/*
 	 * Return a URI based on the given URI, which points to a site.xml file.
 	 */
 	private static URI getSiteURI(URI baseLocation) {
 		String segment = URIUtil.lastSegment(baseLocation);
 			return baseLocation;
 		return URIUtil.append(baseLocation);
 	}

Be lenient about accepting any location with *site*.xml at the end.
 
 	private static boolean constainsUpdateSiteFileName(String segment) {
 		return segment != null && segment.endsWith() && segment.indexOf() != -1;
 	}

Loads and returns a category file

Parameters:
location
monitor
Returns:
A CategoryFile
Throws:
ProvisionException
 
 	public static synchronized UpdateSite loadCategoryFile(URI locationTransport transportIProgressMonitor monitorthrows ProvisionException {
 		if (location == null)
 			return null;
 		UpdateSite result = null;
 		if (!.equals(location.getScheme()) && .containsKey(location.toString())) {
 			result = .get(location.toString()).get();
 			if (result != null)
 				return result;
 			//else soft reference has been cleared, take it out of the cache
 		}
 
 		InputStream input = null;
 		File siteFile = loadActualSiteFile(locationlocationtransportmonitor);
 		try {
 			CategoryParser siteParser = new CategoryParser(location);
			Checksum checksum = new CRC32();
			input = new CheckedInputStream(new BufferedInputStream(new FileInputStream(siteFile)), checksum);
			SiteModel siteModel = siteParser.parse(input);
			String checksumString = Long.toString(checksum.getValue());
			result = new UpdateSite(siteModellocationtransportchecksumString);
			if (!.equals(location.getScheme()))
				.put(location.toString(), new SoftReference<UpdateSite>(result));
			return result;
catch (SAXException e) {
			String msg = NLS.bind(.location);
catch (IOException e) {
			String msg = NLS.bind(.location);
finally {
			try {
				if (input != null)
					input.close();
catch (IOException e) {
				// ignore
			}
			if (!.equals(location.getScheme()))
				siteFile.delete();
		}
	}
	/*
	 * Load and return an update site object from the given location.
	 */
	public static synchronized UpdateSite load(URI locationTransport transportIProgressMonitor monitorthrows ProvisionException {
		if (location == null)
			return null;
		UpdateSite result = null;
		//only caching remote sites
		if (!.equals(location.getScheme()) && .containsKey(location.toString())) {
			result = .get(location.toString()).get();
			if (result != null)
				return result;
			//else soft reference has been cleared, take it out of the cache
		}
		InputStream input = null;
		File siteFile = loadActualSiteFile(locationgetSiteURI(location), transportmonitor);
		try {
			DefaultSiteParser siteParser = new DefaultSiteParser(location);
			Checksum checksum = new CRC32();
			input = new CheckedInputStream(new BufferedInputStream(new FileInputStream(siteFile)), checksum);
			SiteModel siteModel = siteParser.parse(input);
			String checksumString = Long.toString(checksum.getValue());
			result = new UpdateSite(siteModelgetSiteURI(location), transportchecksumString);
			if (!.equals(location.getScheme()))
				.put(location.toString(), new SoftReference<UpdateSite>(result));
			return result;
catch (SAXException e) {
			String msg = NLS.bind(.location);
catch (IOException e) {
			String msg = NLS.bind(.location);
finally {
			try {
				if (input != null)
					input.close();
catch (IOException e) {
				// ignore
			}
			if (!.equals(location.getScheme()))
				siteFile.delete();
		}
	}

Returns a local file containing the contents of the update site at the given location.
	private static File loadActualSiteFile(URI locationURI actualLocationTransport transportIProgressMonitor monitorthrows ProvisionException {
		SubMonitor submonitor = SubMonitor.convert(monitor, 1000);
		try {
			File siteFile = null;
			IStatus transferResult = null;
			boolean deleteSiteFile = false;
			try {
				if (.equals(actualLocation.getScheme())) {
					siteFile = URIUtil.toFile(actualLocation);
					if (siteFile.exists())
						transferResult = .;
					else {
						String msg = NLS.bind(.location);
					}
else {
					// creating a temp file. In the event of an error we want to delete it.
					deleteSiteFile = true;
					OutputStream destination = null;
					try {
						siteFile = File.createTempFile("site"".xml"); //$NON-NLS-1$//$NON-NLS-2$
						destination = new BufferedOutputStream(new FileOutputStream(siteFile));
catch (IOException e) {
						throw new ProvisionException(new Status(..."Can not create tempfile for site.xml"e)); //$NON-NLS-1$
					}
					try {
						transferResult = transport.download(actualLocationdestinationsubmonitor.newChild(999));
finally {
						try {
							destination.close();
catch (IOException e) {
							throw new ProvisionException(new Status(..."Failing to close tempfile for site.xml"e)); //$NON-NLS-1$
						}
					}
				}
				if (monitor.isCanceled())
				if (transferResult.isOK()) {
					// successful. If the siteFile is the download of a remote site.xml it will get cleaned up later
					deleteSiteFile = false;
					return siteFile;
				}
				// The transferStatus from download has a well formatted message that should
				// be used as it contains useful feedback to the user.
				// The only thing needed is to translate the error code ARTIFACT_NOT_FOUND to
				// REPOSITORY_NOT_FOUND as the download does not know what the file represents.
				//
				IStatus ms = null;
				if (transferResult.getException() instanceof FileNotFoundException)
					ms = new MultiStatus(.//
							// (code == ProvisionException.ARTIFACT_NOT_FOUND || code == ProvisionException.REPOSITORY_NOT_FOUND ? ProvisionException.REPOSITORY_NOT_FOUND : ProvisionException.REPOSITORY_FAILED_READ), //
							new IStatus[] {transferResult}, //
							NLS.bind(.location), null);
				else
					ms = transferResult;
				throw new ProvisionException(ms);
finally {
				if (deleteSiteFile && siteFile != null)
					siteFile.delete();
			}
finally {
			if (monitor != null)
				monitor.done();
		}
	}
	/*
	 * Parse the feature.xml specified by the given input stream and return the feature object.
	 * In case of failure, the failure is logged and null is returned
	 */
	private Feature parseFeature(FeatureParser featureParserURI featureURIIProgressMonitor monitor) {
		File featureFile = null;
		if (.equals(featureURI.getScheme())) {
			featureFile = URIUtil.toFile(featureURI);
			return featureParser.parse(featureFile);
		}
		try {
			IStatus transferResult = null;
			//try the download twice in case of transient network problems
			for (int i = 0; i < i++) {
				if (monitor.isCanceled())
				OutputStream destination = new BufferedOutputStream(new FileOutputStream(featureFile));
				try {
					transferResult = .download(featureURIdestinationmonitor);
finally {
					try {
						destination.close();
catch (IOException e) {
						LogHelper.log(new Status(.., NLS.bind(.featureURI), e));
						return null;
					}
				}
				if (transferResult.isOK())
					break;
			}
			if (monitor.isCanceled())
			if (!transferResult.isOK()) {
				LogHelper.log(new ProvisionException(transferResult));
				return null;
			}
			return featureParser.parse(featureFile);
catch (IOException e) {
			LogHelper.log(new Status(.., NLS.bind(.featureURI), e));
finally {
			if (featureFile != null)
				featureFile.delete();
		}
		return null;
	}
	/*
	 * Constructor for the class.
	 */
	private UpdateSite(SiteModel siteURI locationTransport transportString checksum) {
		super();
		this. = site;
		this. = location;
		this. = checksum;
		this. = transport;
	}
	private URI getRootLocation() {
		String locationString = .toString();
		int slashIndex = locationString.lastIndexOf('/');
		if (slashIndex == -1 || slashIndex == (locationString.length() - 1))
			return ;
		return URI.create(locationString.substring(0, slashIndex + 1));
	}
	/*
	 * Iterate over the archive entries in this site and return the matching URI string for
	 * the given identifier, if there is one.
	 */
	private URI getArchiveURI(URI baseString identifier) {
		URLEntry[] archives = .getArchives();
		for (int i = 0; archives != null && i < archives.length; i++) {
			URLEntry entry = archives[i];
			if (identifier.equals(entry.getAnnotation()))
				return internalGetURI(baseentry.getURL());
		}
		return null;
	}
	/*
	 * Return the checksum for this site.
	 */
	public String getChecksum() {
		return ;
	}
	/*
	 * Return a URI which represents the location of the given feature.
	 */
	public URI getSiteFeatureURI(SiteFeature siteFeature) {
		URL url = siteFeature.getURL();
		try {
			if (url != null)
				return URIUtil.toURI(url);
catch (URISyntaxException e) {
			//fall through and resolve the URI ourselves
		}
		URI base = getBaseURI();
		String featureURIString = siteFeature.getURLString();
		return internalGetURI(basefeatureURIString);
	}
	/*
	 * Return a URI which represents the location of the given feature.
	 */
	public URI getFeatureURI(String idString version) {
		SiteFeature[] entries = .getFeatures();
		for (int i = 0; i < entries.lengthi++) {
			if (id.equals(entries[i].getFeatureIdentifier()) && version.equals(entries[i].getFeatureVersion())) {
				return getSiteFeatureURI(entries[i]);
			}
		}
		URI base = getBaseURI();
		URI url = getArchiveURI(base + id +  + version + );
		if (url != null)
			return url;
		return URIUtil.append(base + id +  + version + );
	}
	/*
	 * Return the location of this site.
	 */
	public URI getLocation() {
		return ;
	}
	public String getMirrorsURI() {
		//copy mirror information from update site to p2 repositories
		String mirrors = .getMirrorsURI();
		if (mirrors == null)
			return null;
		//remove site.xml file reference
		int index = mirrors.indexOf("site.xml"); //$NON-NLS-1$
		if (index != -1)
			mirrors = mirrors.substring(0, index) + mirrors.substring(index + "site.xml".length()); //$NON-NLS-1$
		return mirrors;
	}
	/*
	 * Return a URI which represents the location of the given plug-in.
	 */
	public URI getPluginURI(FeatureEntry plugin) {
		URI base = getBaseURI();
		String path =  + plugin.getId() +  + plugin.getVersion() + ;
		URI url = getArchiveURI(basepath);
		if (url != null)
			return url;
		return URIUtil.append(basepath);
	}
	private URI getBaseURI() {
		URI base = null;
		String siteURIString = .getLocationURIString();
		if (siteURIString != null) {
			if (!siteURIString.endsWith("/")) //$NON-NLS-1$
				siteURIString += "/"//$NON-NLS-1$
			base = internalGetURI(siteURIString);
		}
		if (base == null)
			base = ;
		return base;
	}
	/*
	 * Return the site model.
	 */
	public SiteModel getSite() {
		return ;
	}
	/*
	 * The trailing parameter can be either null, relative or absolute. If it is null,
	 * then return null. If it is absolute, then create a new url and return it. If it is
	 * relative, then make it relative to the given base url.
	 */
	private URI internalGetURI(URI baseString trailing) {
		if (trailing == null)
			return null;
		return URIUtil.makeAbsolute(URI.create(trailing), base);
	}
	/*
	 * Load and return the features references in this update site.
	 */
	public synchronized Feature[] loadFeatures(IProgressMonitor monitorthrows ProvisionException {
		if (!.isEmpty())
			return .values().toArray(new Feature[.size()]);
		Feature[] result = loadFeaturesFromDigest(monitor);
		return result == null ? loadFeaturesFromSite(monitor) : result;
	}
	/*
	 * Try and load the feature information from the update site's
	 * digest file, if it exists.
	 */
	private Feature[] loadFeaturesFromDigest(IProgressMonitor monitor) {
		File digestFile = null;
		boolean local = false;
		try {
			URI digestURI = getDigestURI();
			if (.equals(digestURI.getScheme())) {
				digestFile = URIUtil.toFile(digestURI);
				if (!digestFile.exists())
					return null;
				local = true;
else {
				digestFile = File.createTempFile("digest"".zip"); //$NON-NLS-1$ //$NON-NLS-2$
				BufferedOutputStream destination = new BufferedOutputStream(new FileOutputStream(digestFile));
				IStatus result = null;
				try {
					result = .download(digestURIdestinationmonitor);
finally {
					try {
						destination.close();
catch (IOException e) {
						return null;
					}
				}
				if (result.getSeverity() == . || monitor.isCanceled())
				if (!result.isOK())
					return null;
			}
			Feature[] features = new DigestParser().parse(digestFiledigestURI);
			if (features == null)
				return null;
			Map<String, Feature> tmpFeatureCache = new HashMap<String, Feature>(features.length);
			for (int i = 0; i < features.length; i++) {
				String key = features[i].getId() +  + features[i].getVersion();
				tmpFeatureCache.put(keyfeatures[i]);
			}
			 = tmpFeatureCache;
			return features;
catch (FileNotFoundException fnfe) {
			// we do not track FNF exceptions as we will fall back to the 
			// standard feature parsing from the site itself, see bug 225587.
catch (IOException e) {
finally {
			if (!local && digestFile != null)
				digestFile.delete();
		}
		return null;
	}
	private URI getDigestURI() {
		URI digestBase = null;
		String digestURIString = .getDigestURIString();
		if (digestURIString != null) {
			if (!digestURIString.endsWith("/")) //$NON-NLS-1$
				digestURIString += "/"//$NON-NLS-1$
			digestBase = internalGetURI(digestURIString);
		}
		if (digestBase == null)
			digestBase = ;
		return URIUtil.append(digestBase"digest.zip"); //$NON-NLS-1$
	}
	/*
	 * Load and return the features that are referenced by this update site. Note this
	 * requires downloading and parsing the feature manifest locally.
	 */
	private Feature[] loadFeaturesFromSite(IProgressMonitor monitorthrows ProvisionException {
		SiteFeature[] siteFeatures = .getFeatures();
		FeatureParser featureParser = new FeatureParser();
		Map<String, Feature> tmpFeatureCache = new HashMap<String, Feature>(siteFeatures.length);
		for (int i = 0; i < siteFeatures.lengthi++) {
			if (monitor.isCanceled()) {
			}
			SiteFeature siteFeature = siteFeatures[i];
			String key = null;
			if (siteFeature.getFeatureIdentifier() != null && siteFeature.getFeatureVersion() != null) {
				key = siteFeature.getFeatureIdentifier() +  + siteFeature.getFeatureVersion();
				if (tmpFeatureCache.containsKey(key))
					continue;
			}
			URI featureURI = getSiteFeatureURI(siteFeature);
			Feature feature = parseFeature(featureParserfeatureURInew NullProgressMonitor());
			if (feature == null) {
				LogHelper.log(new Status(.., NLS.bind(.featureURI)));
else {
				if (key == null) {
					siteFeature.setFeatureIdentifier(feature.getId());
					siteFeature.setFeatureVersion(feature.getVersion());
					key = siteFeature.getFeatureIdentifier() +  + siteFeature.getFeatureVersion();
				}
				tmpFeatureCache.put(keyfeature);
				loadIncludedFeatures(featurefeatureParsertmpFeatureCachemonitor);
			}
		}
		 = tmpFeatureCache;
		return .values().toArray(new Feature[.size()]);
	}
	/*
	 * Load the features that are included by the given feature.
	 */
	private void loadIncludedFeatures(Feature feature, FeatureParser featureParserMap<String, Feature> featuresIProgressMonitor monitorthrows ProvisionException {
		FeatureEntry[] featureEntries = feature.getEntries();
		for (int i = 0; i < featureEntries.length; i++) {
			if (monitor.isCanceled())
			FeatureEntry entry = featureEntries[i];
			if (entry.isRequires() || entry.isPlugin())
				continue;
			String key = entry.getId() +  + entry.getVersion();
			if (features.containsKey(key))
				continue;
			URI includedFeatureURI = getFeatureURI(entry.getId(), entry.getVersion());
			Feature includedFeature = parseFeature(featureParserincludedFeatureURImonitor);
			if (includedFeature == null) {
				LogHelper.log(new Status(.., NLS.bind(.includedFeatureURI)));
else {
				features.put(keyincludedFeature);
				loadIncludedFeatures(includedFeaturefeatureParserfeaturesmonitor);
			}
		}
	}
New to GrepCode? Check out our FAQ X