/*******************************************************************************
* 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.version;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import org.eclipse.buckminster.core.KeyConstants;
import org.eclipse.buckminster.core.actor.IActionContext;
import org.eclipse.buckminster.core.cspec.IComponentIdentifier;
import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier;
import org.eclipse.buckminster.core.metadata.MissingComponentException;
import org.eclipse.buckminster.core.metadata.WorkspaceInfo;
import org.eclipse.buckminster.core.reader.AbstractReaderType;
import org.eclipse.buckminster.core.reader.IReaderType;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.Version;
/**
* This class will generate qualifiers based on component revisions. The
* revision is obtained using the same @ IReaderType} that was used when the
* component was first materialized
*
* @author Thomas Hallgren
*/
public class RevisionQualifierGenerator extends AbstractQualifierGenerator {
public static String FORMAT_PROPERTY = "generator.lastRevision.format"; //$NON-NLS-1$
public static String DEFAULT_FORMAT = "r{0,number,##################}"; //$NON-NLS-1$
@Override
public Version generateQualifier(IActionContext context, ComponentIdentifier cid, List<ComponentIdentifier> dependencies) throws CoreException {
final Version currentVersion = cid.getVersion();
if (currentVersion == null)
return null;
try {
IPath location = WorkspaceInfo.getComponentLocation(cid);
IReaderType readerType = AbstractReaderType.getTypeForResource(WorkspaceInfo.getProject(cid));
if (readerType == null)
return currentVersion;
long revision = readerType.getLastRevision(location.toFile(), context.getCancellationMonitor());
if (revision == -1)
return currentVersion;
Map<String, ? extends Object> props = context.getProperties();
String format = (String) props.get(FORMAT_PROPERTY);
if (format == null)
format = DEFAULT_FORMAT;
boolean subBuildId = false;
MessageFormat mf = new MessageFormat(format);
for (IComponentIdentifier dependency : dependencies) {
Version depVer = dependency.getVersion();
if (depVer == null)
continue;
String qualifier = VersionHelper.getQualifier(depVer);
if (qualifier == null)
continue;
long depRev = 0;
try {
depRev = ((Number) (mf.parse(qualifier)[0])).longValue();
} catch (Exception e) {
// We might have encountered something that ends with a
// build id. Let's try parsing it
String tmp = qualifier;
int lastDash = tmp.lastIndexOf('-');
while (lastDash > 0) {
tmp = tmp.substring(0, lastDash);
try {
depRev = ((Number) (mf.parse(tmp)[0])).longValue();
subBuildId = true;
break;
} catch (Exception e2) {
// expected. Continue in case the build id itself
// contains dashes.
lastDash = tmp.lastIndexOf('-');
}
}
}
if (depRev > revision)
revision = depRev;
}
String buildId = (String) props.get("build.id"); //$NON-NLS-1$
String newQual = mf.format(new Object[] { new Long(revision) });
if (buildId != null && subBuildId)
// A dependency had a build id appended to the revision. This
// means we must have that too.
newQual = newQual + '-' + buildId;
newQual = VersionHelper.getQualifier(currentVersion).replace("qualifier", newQual); //$NON-NLS-1$
Version newVersion = VersionHelper.replaceQualifier(currentVersion, newQual);
if (buildId == null || subBuildId)
return newVersion;
// Check if a previous build contained a generated build id in which
// case we need to append that to the revision number
IInstallableUnit prevIU = obtainFromReferenceRepo(cid, null);
if (prevIU == null)
return newVersion;
String oldBuildId = prevIU.getProperty(KeyConstants.BUILD_ID);
if (oldBuildId == null || oldBuildId.equals(buildId))
return newVersion;
Version oldVer = prevIU.getVersion();
String oldQual = VersionHelper.getQualifier(oldVer);
if (oldQual.equals(newQual) || (oldQual.startsWith(newQual) && oldQual.charAt(newQual.length()) == '-')) {
// Exactly the same revision has been generated before
// Component contains a generated build id that differs
// from the current one. Append '-<buildId>'
newQual = newQual + '-' + buildId;
newQual = VersionHelper.getQualifier(currentVersion).replace("qualifier", newQual); //$NON-NLS-1$
newVersion = VersionHelper.replaceQualifier(currentVersion, newQual);
}
return newVersion;
} catch (MissingComponentException e) {
return currentVersion;
}
}
}