/******************************************************************************* * Copyright (c) 2004, 2006 * Thomas Hallgren, Kenneth Olwing, Mitch Sonies * Pontus Rydin, Nils Unden, Peer Torngren * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed above, as Initial Contributors under such license. * The text of such license is available at www.eclipse.org. *******************************************************************************/ package org.eclipse.buckminster.pde.internal; import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.eclipse.buckminster.core.cspec.model.ComponentRequest; import org.eclipse.buckminster.core.ctype.IComponentType; import org.eclipse.buckminster.core.resolver.NodeQuery; import org.eclipse.buckminster.pde.Messages; import org.eclipse.buckminster.pde.internal.imports.PluginImportOperation; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.URLUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.internal.core.ifeature.IFeatureModel; @SuppressWarnings("restriction") final class EclipseImportBase { static class Key { private final String repositoryURI; private final ComponentRequest request; Key(String repositoryURI, ComponentRequest request) { this.repositoryURI = repositoryURI; this.request = request; } @Override public boolean equals(Object o) { return this == o || (o instanceof Key) && repositoryURI.equals(((Key) o).repositoryURI) && request.equals(((Key) o).request); } public String getRepositoryURI() { return repositoryURI; } public ComponentRequest getRequest() { return request; } @Override public int hashCode() { return repositoryURI.hashCode() * 37 + request.hashCode(); } } /** * Parameter in the resource URI that determines the search order when * resolving the component. Valid values are "binary" and * "linked" or "source". Default is "binary" */ static final String PARAM_IMPORT_TYPE = "importType"; //$NON-NLS-1$ static final String IMPORT_TYPE_BINARY = "binary"; //$NON-NLS-1$ static final String IMPORT_TYPE_LINKED = "linked"; //$NON-NLS-1$ static final String IMPORT_TYPE_SOURCE = "source"; //$NON-NLS-1$ private final int type; private final boolean platform; private final boolean feature; private final Key key; private final String query; private final File location; private final URL remoteLocation; private boolean unpack = false; private static final UUID CACHE_IMPORT_BASE_CACHE = UUID.randomUUID(); public static EclipseImportBase obtain(NodeQuery query, String repositoryURI) throws CoreException { Key key = new Key(repositoryURI, query.getComponentRequest()); Map<Key, EclipseImportBase> cache = getImportBaseCacheCache(query.getContext().getUserCache()); synchronized (cache) { EclipseImportBase importBase = cache.get(key); if (importBase == null) { importBase = new EclipseImportBase(key); cache.put(key, importBase); } return importBase; } } @SuppressWarnings("unchecked") static Map<Key, EclipseImportBase> getImportBaseCacheCache(Map<UUID, Object> ctxUserCache) { synchronized (ctxUserCache) { Map<Key, EclipseImportBase> listCache = (Map<Key, EclipseImportBase>) ctxUserCache.get(CACHE_IMPORT_BASE_CACHE); if (listCache == null) { listCache = Collections.synchronizedMap(new HashMap<Key, EclipseImportBase>()); ctxUserCache.put(CACHE_IMPORT_BASE_CACHE, listCache); } return listCache; } } private EclipseImportBase(Key key) throws CoreException { URI uri; try { uri = new URI(key.getRepositoryURI()); } catch (URISyntaxException e) { throw BuckminsterException.fromMessage(e.getMessage()); } String scheme = uri.getScheme(); String path = uri.getPath(); URL remoteLoc = null; File loc = null; boolean platf = false; if (scheme == null) { if (path == null || path.length() == 0) platf = true; else loc = new File(path); } else if ("file".equalsIgnoreCase(scheme)) //$NON-NLS-1$ loc = new File(path); else { try { if (!(path.endsWith("/") || path.endsWith(".map") || path.endsWith(".xml") || path.endsWith(".jar"))) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ path += '/'; remoteLoc = new URL(scheme, uri.getHost(), uri.getPort(), path); } catch (MalformedURLException e) { throw BuckminsterException.fromMessage(e.getMessage()); } } this.location = loc; this.remoteLocation = remoteLoc; this.platform = platf; this.query = uri.getQuery(); this.key = key; this.feature = IComponentType.ECLIPSE_FEATURE.equals(key.getRequest().getComponentTypeID()); Map<String, String> params = URLUtils.queryAsParameters(uri.getQuery()); String importType = params.get(PARAM_IMPORT_TYPE); if (importType == null) type = PluginImportOperation.IMPORT_UNKNOWN; else if (IMPORT_TYPE_BINARY.equalsIgnoreCase(importType)) type = PluginImportOperation.IMPORT_BINARY; else if (IMPORT_TYPE_LINKED.equalsIgnoreCase(importType)) type = PluginImportOperation.IMPORT_BINARY_WITH_LINKS; else if (IMPORT_TYPE_SOURCE.equalsIgnoreCase(importType)) type = PluginImportOperation.IMPORT_WITH_SOURCE; else throw BuckminsterException.fromMessage(NLS.bind(Messages.invalid_import_type_0, importType)); } @Override public boolean equals(Object o) { return o == this || (o instanceof EclipseImportBase && ((EclipseImportBase) o).key.equals(key)); } @Override public int hashCode() { return key.hashCode(); } String getComponentName() { return key.getRequest().getName(); } List<IFeatureModel> getFeatureModels(EclipseImportReaderType readerType, IProgressMonitor monitor) throws CoreException { return readerType.getFeatureModels(getLocation(), getComponentName(), monitor); } Key getKey() { return key; } final File getLocation() throws CoreException { if (location == null && !platform) throw BuckminsterException.fromMessage(Messages.site_is_not_local); return location; } List<IPluginModelBase> getPluginModels(EclipseImportReaderType readerType, IProgressMonitor monitor) throws CoreException { return readerType.getPluginModels(getLocation(), getComponentName(), monitor); } String getQuery() { return query; } final URL getRemoteLocation() throws CoreException { if (remoteLocation == null) { try { return location.toURI().toURL(); } catch (MalformedURLException e) { throw BuckminsterException.wrap(e); } } return remoteLocation; } int getType() { return type; } boolean isFeature() { return feature; } boolean isLocal() { return remoteLocation == null; } /** * Should this bundle be unpacked (set in the enclosing feature.xml) * * @return true if supposed to be unpacked */ boolean isUnpack() { return unpack; } /** * Should this bundle be unpacked (set in the enclosing feature.xml) * * @param unpack */ void setUnpack(boolean unpack) { this.unpack = unpack; } }