/***************************************************************************** * 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.cspecext.model; import java.util.Collection; import java.util.Map; import java.util.Set; import org.eclipse.buckminster.core.common.model.Documentation; import org.eclipse.buckminster.core.cspec.IAction; import org.eclipse.buckminster.core.cspec.IActionArtifact; import org.eclipse.buckminster.core.cspec.IArtifact; import org.eclipse.buckminster.core.cspec.IAttribute; import org.eclipse.buckminster.core.cspec.ICSpecData; import org.eclipse.buckminster.core.cspec.IComponentRequest; import org.eclipse.buckminster.core.cspec.IGenerator; import org.eclipse.buckminster.core.cspec.builder.AttributeBuilder; import org.eclipse.buckminster.core.cspec.builder.CSpecBuilder; import org.eclipse.buckminster.core.cspec.builder.GeneratorBuilder; import org.eclipse.buckminster.core.cspec.builder.TopLevelAttributeBuilder; import org.eclipse.buckminster.core.cspec.model.ComponentRequest; import org.eclipse.buckminster.core.cspec.model.TopLevelAttribute; import org.eclipse.buckminster.sax.Utils; import org.eclipse.core.runtime.CoreException; import org.eclipse.equinox.p2.metadata.Version; /** * @author Thomas Hallgren */ public class CSpecExtension { public static final String TAG = "cspecExtension"; //$NON-NLS-1$ public static final String ELEM_ALTER_ACTIONS = "alterActions"; //$NON-NLS-1$ public static final String ELEM_ALTER_ARTIFACTS = "alterArtifacts"; //$NON-NLS-1$ public static final String ELEM_ALTER_DEPENDENCIES = "alterDependencies"; //$NON-NLS-1$ public static final String ELEM_ALTER_GROUPS = "alterGroups"; //$NON-NLS-1$ public static <T> T overrideCheckNull(T a, T b) { if (a == null) return b; if (b == null) return a; if (b.toString().equalsIgnoreCase("null")) //$NON-NLS-1$ return null; return b; } private final ICSpecData base; private final Set<String> removedDependencies; private final Set<String> removedAttributes; private final Map<String, String> renamedAttributes; private final Map<String, AlterAttribute<? extends TopLevelAttribute>> alteredAttributes; private final Map<String, AlterDependency> alteredDependencies; public CSpecExtension(ICSpecData base, Set<String> removedDependencies, Map<String, AlterDependency> alteredDependencies, Set<String> removedAttributes, Map<String, String> renamedAttributes, Map<String, AlterAttribute<? extends TopLevelAttribute>> alteredAttributes) { this.base = base; this.removedDependencies = Utils.createUnmodifiableSet(removedDependencies); this.removedAttributes = Utils.createUnmodifiableSet(removedAttributes); this.renamedAttributes = Utils.createUnmodifiableMap(renamedAttributes); this.alteredAttributes = Utils.createUnmodifiableMap(alteredAttributes); this.alteredDependencies = Utils.createUnmodifiableMap(alteredDependencies); } public void alterCSpec(CSpecBuilder cspecBuilder) throws CoreException { for (String removedDep : removedDependencies) { cspecBuilder.getRequiredDependency(new ComponentRequest(removedDep, null, null)); cspecBuilder.removeDependency(removedDep); } for (AlterDependency alterDep : alteredDependencies.values()) alterDep.alterDependency(cspecBuilder.getRequiredDependency(alterDep)); Collection<? extends IComponentRequest> addedDeps = base.getDependencies(); for (IComponentRequest addedDep : addedDeps) cspecBuilder.addDependency(addedDep); for (IGenerator addedGenerator : base.getGeneratorList()) { GeneratorBuilder bld = cspecBuilder.createGeneratorBuilder(); bld.initFrom(addedGenerator); cspecBuilder.addGenerator(bld); } for (String removedAttr : removedAttributes) { cspecBuilder.getRequiredAttribute(removedAttr); cspecBuilder.removeAttribute(removedAttr); } for (Map.Entry<String, String> renamedAttribute : renamedAttributes.entrySet()) { String oldName = renamedAttribute.getKey(); AttributeBuilder bld = cspecBuilder.getRequiredAttribute(oldName); bld.setName(renamedAttribute.getValue()); cspecBuilder.removeAttribute(oldName); cspecBuilder.addAttribute(bld); } for (AlterAttribute<?> alterAttr : alteredAttributes.values()) alterAttr.alterAttribute((TopLevelAttributeBuilder) cspecBuilder.getRequiredAttribute(alterAttr.getName())); Map<String, ? extends IAttribute> addedAttrs = base.getAttributes(); for (IAttribute addedAttr : addedAttrs.values()) { AttributeBuilder attrBld; if (addedAttr instanceof IActionArtifact) attrBld = cspecBuilder.createActionArtifactBuilder(); else if (addedAttr instanceof IAction) attrBld = cspecBuilder.createActionBuilder(); else if (addedAttr instanceof IArtifact) attrBld = cspecBuilder.createArtifactBuilder(); else attrBld = cspecBuilder.createGroupBuilder(); attrBld.initFrom(addedAttr); cspecBuilder.addAttribute(attrBld); } // On the top element, we never override a value with NULL unless it is // explicitly set to the string "null" // cspecBuilder.setComponentTypeID(overrideCheckNull(cspecBuilder.getComponentTypeID(), base.getComponentTypeID())); cspecBuilder.setVersion(overrideCheckNull(cspecBuilder.getVersion(), base.getVersion())); Documentation origDoc = cspecBuilder.getDocumentation(); Documentation baseDoc = base.getDocumentation(); cspecBuilder.setDocumentation(origDoc == null ? baseDoc : origDoc.merge(baseDoc)); } /** * Returns the CSPEC base that contains the top element attribute overrides * and all pure additions * * @return A Cspec that acts as the base for the extension */ public void alterTopElement(CSpecBuilder bld) throws CoreException { Version extVersion = base.getVersion(); if (extVersion != null) bld.setVersion(extVersion); String ctype = base.getComponentTypeID(); if (ctype != null) bld.setComponentTypeID(ctype); } }