/***************************************************************************** * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. *****************************************************************************/ package org.eclipse.buckminster.core.cspec.model; import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.buckminster.core.KeyConstants; import org.eclipse.buckminster.core.actor.IGlobalContext; import org.eclipse.buckminster.core.common.model.Format; import org.eclipse.buckminster.core.cspec.IComponentIdentifier; import org.eclipse.buckminster.core.cspec.IGenerator; import org.eclipse.buckminster.core.cspec.PathGroup; import org.eclipse.buckminster.core.metadata.model.BOMNode; import org.eclipse.buckminster.core.metadata.model.Resolution; import org.eclipse.buckminster.core.query.builder.ComponentQueryBuilder; import org.eclipse.buckminster.core.reader.IReaderType; import org.eclipse.buckminster.core.resolver.ResolutionContext; import org.eclipse.buckminster.core.rmap.model.Locator; import org.eclipse.buckminster.core.rmap.model.Provider; import org.eclipse.buckminster.core.rmap.model.ResourceMap; import org.eclipse.buckminster.core.rmap.model.SearchPath; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.URLUtils; import org.eclipse.buckminster.sax.Utils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.equinox.p2.metadata.Version; import org.xml.sax.helpers.AttributesImpl; /** * @author Thomas Hallgren */ public class Generator extends NamedElement implements IGenerator { public static final String ATTR_ATTRIBUTE = "attribute"; //$NON-NLS-1$ public static final String ATTR_COMPONENT = "component"; //$NON-NLS-1$ public static final String ATTR_GENERATES = "generates"; //$NON-NLS-1$ public static final String ATTR_GENERATES_TYPE = "generatesType"; //$NON-NLS-1$ public static final String ATTR_GENERATES_VERSION = "generatesVersion"; //$NON-NLS-1$ public static final String TAG = "generator"; //$NON-NLS-1$ private final CSpec cspec; private final String attribute; private final String component; private final String generatesType; private final Version generatesVersion; public Generator(CSpec cspec, String component, String attribute, ComponentIdentifier generates) { super(generates); this.cspec = cspec; this.component = component; this.attribute = attribute; this.generatesType = generates.getComponentTypeID(); this.generatesVersion = generates.getVersion(); } @Override public String getAttribute() { return attribute; } @Override public String getComponent() { return component; } public CSpec getCSpec() { return cspec; } @Override public String getDefaultTag() { return TAG; } @Override public IComponentIdentifier getGeneratedIdentifier() { return new ComponentIdentifier(getName(), generatesType, generatesVersion); } public String getGenerates() { return getName(); } @Override public String getNameAttributeName() { return ATTR_GENERATES; } public void registerGeneratedResolution(PathGroup[] result, IGlobalContext ctx, IProgressMonitor monitor) throws CoreException { // Register the resolution from this generator if (result.length != 1) return; PathGroup pg = result[0]; HashMap<String, Long> fileNames = new HashMap<String, Long>(); pg.appendRelativeFiles(fileNames); if (fileNames.isEmpty()) return; Set<String> paths = fileNames.keySet(); String readerType = IReaderType.LOCAL; Format uri; boolean isFile = false; IPath componentLocation; if (paths.size() == 1) { IPath path = Path.fromOSString(paths.iterator().next()); String suffix = path.getFileExtension(); if ("zip".equals(suffix) || "jar".equals(suffix)) //$NON-NLS-1$ //$NON-NLS-2$ { readerType = IReaderType.URL_ZIPPED; isFile = true; } componentLocation = pg.getBase().append(path); } else componentLocation = pg.getBase(); try { uri = new Format(URLUtils.normalizeToURL(componentLocation.toOSString()).toString()); } catch (MalformedURLException e) { throw BuckminsterException.wrap(e); } IComponentIdentifier ci = getGeneratedIdentifier(); String cType = ci.getComponentTypeID(); ResourceMap rmap = new ResourceMap(null); SearchPath searchPath = new SearchPath(rmap, "default"); //$NON-NLS-1$ Map<String, String> props = new HashMap<String, String>(2); props.put(KeyConstants.IS_MUTABLE, "false"); //$NON-NLS-1$ props.put(KeyConstants.IS_SOURCE, "false"); //$NON-NLS-1$ Provider provider = new Provider(searchPath, readerType, new String[] { cType }, null, uri, null, null, null, props, null, null); searchPath.addProvider(provider); rmap.addSearchPath(searchPath); rmap.addMatcher(new Locator(rmap, null, "default")); //$NON-NLS-1$ ComponentQueryBuilder query = new ComponentQueryBuilder(); query.setRootRequest(new ComponentRequest(ci.getName(), ci.getComponentTypeID(), null)); ResolutionContext rctx = new ResolutionContext(query.createComponentQuery()); BOMNode node = rmap.resolve(rctx.getRootNodeQuery(), monitor); Resolution res = node.getResolution(); if (res != null) { if (isFile) componentLocation = componentLocation.removeLastSegments(1); ctx.addGeneratedResolution(res, componentLocation); } } @Override protected void addAttributes(AttributesImpl attrs) { super.addAttributes(attrs); Utils.addAttribute(attrs, ATTR_ATTRIBUTE, attribute); if (component != null) Utils.addAttribute(attrs, ATTR_COMPONENT, component); Utils.addAttribute(attrs, ATTR_GENERATES, getName()); if (generatesType != null) Utils.addAttribute(attrs, ATTR_GENERATES_TYPE, generatesType); if (generatesVersion != null) Utils.addAttribute(attrs, ATTR_GENERATES_VERSION, generatesVersion.toString()); } }