001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.build;
011:
012: import java.io.File;
013: import java.util.regex.Pattern;
014:
015: import org.eclipse.core.resources.IContainer;
016: import org.eclipse.core.resources.IFolder;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IProgressMonitor;
020: import org.eclipse.core.runtime.IStatus;
021: import org.eclipse.core.runtime.Path;
022: import org.eclipse.core.runtime.jobs.MultiRule;
023: import org.eclipse.pde.internal.core.PDECore;
024: import org.eclipse.pde.internal.core.exports.FeatureExportInfo;
025: import org.eclipse.pde.internal.core.exports.FeatureExportOperation;
026: import org.eclipse.pde.internal.core.exports.SiteBuildOperation;
027: import org.eclipse.pde.internal.core.ifeature.IFeature;
028: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
029: import org.eclipse.pde.internal.core.isite.ISiteFeature;
030: import org.eclipse.pde.internal.core.isite.ISiteModel;
031: import org.eclipse.pde.internal.core.site.WorkspaceSiteModel;
032: import org.eclipse.pde.internal.core.util.PatternConstructor;
033: import org.eclipse.pde.internal.ui.PDEPlugin;
034: import org.eclipse.pde.internal.ui.PDEUIMessages;
035: import org.osgi.framework.Version;
036:
037: public class BuildSiteJob extends FeatureExportJob {
038:
039: private static FeatureExportInfo getInfo(IFeatureModel[] models,
040: ISiteModel siteModel) {
041: FeatureExportInfo info = new FeatureExportInfo();
042: info.useJarFormat = true;
043: info.toDirectory = true;
044: info.destinationDirectory = siteModel.getUnderlyingResource()
045: .getParent().getLocation().toOSString();
046: info.items = models;
047: return info;
048: }
049:
050: private long fBuildTime;
051:
052: private IFeatureModel[] fFeatureModels;
053: private ISiteModel fSiteModel;
054: private IContainer fSiteContainer;
055:
056: public BuildSiteJob(IFeatureModel[] features, ISiteModel site) {
057: super (getInfo(features, site), PDEUIMessages.BuildSiteJob_name);
058: fFeatureModels = features;
059: fSiteModel = site;
060: fSiteContainer = site.getUnderlyingResource().getParent();
061: setRule(MultiRule.combine(fSiteContainer.getProject(),
062: getRule()));
063: }
064:
065: protected IStatus run(IProgressMonitor monitor) {
066: fBuildTime = System.currentTimeMillis();
067: IStatus status = super .run(monitor);
068: try {
069: fSiteContainer.refreshLocal(IResource.DEPTH_INFINITE,
070: monitor);
071: updateSiteFeatureVersions();
072: } catch (CoreException ce) {
073: PDECore.logException(ce);
074: }
075: return status;
076: }
077:
078: protected FeatureExportOperation createOperation() {
079: return new SiteBuildOperation(fInfo);
080: }
081:
082: private void updateSiteFeatureVersions() {
083: try {
084: for (int i = 0; i < fFeatureModels.length; i++) {
085: IFeature feature = fFeatureModels[i].getFeature();
086: Version pvi = Version
087: .parseVersion(feature.getVersion());
088:
089: if ("qualifier".equals(pvi.getQualifier())) { //$NON-NLS-1$
090: String newVersion = findBuiltVersion(feature
091: .getId(), pvi.getMajor(), pvi.getMinor(),
092: pvi.getMicro());
093: if (newVersion == null) {
094: continue;
095: }
096: ISiteFeature reVersionCandidate = findSiteFeature(
097: feature, pvi);
098: if (reVersionCandidate != null) {
099: reVersionCandidate.setVersion(newVersion);
100: reVersionCandidate
101: .setURL("features/" + feature.getId() + "_" //$NON-NLS-1$ //$NON-NLS-2$
102: + newVersion + ".jar"); //$NON-NLS-1$
103: }
104: }
105: }
106: ((WorkspaceSiteModel) fSiteModel).save();
107: } catch (CoreException ce) {
108: PDEPlugin.logException(ce);
109: }
110: }
111:
112: private ISiteFeature findSiteFeature(IFeature feature, Version pvi) {
113: ISiteFeature reversionCandidate = null;
114: // first see if version with qualifier being qualifier is present among
115: // site features
116: ISiteFeature[] siteFeatures = fSiteModel.getSite()
117: .getFeatures();
118: for (int s = 0; s < siteFeatures.length; s++) {
119: if (siteFeatures[s].getId().equals(feature.getId())
120: && siteFeatures[s].getVersion().equals(
121: feature.getVersion())) {
122: return siteFeatures[s];
123: }
124: }
125: String highestQualifier = null;
126: // then find feature with the highest qualifier
127: for (int s = 0; s < siteFeatures.length; s++) {
128: if (siteFeatures[s].getId().equals(feature.getId())) {
129: Version candidatePvi = Version
130: .parseVersion(siteFeatures[s].getVersion());
131: if (pvi.getMajor() == candidatePvi.getMajor()
132: && pvi.getMinor() == candidatePvi.getMinor()
133: && pvi.getMicro() == candidatePvi.getMicro()) {
134: if (reversionCandidate == null
135: || candidatePvi.getQualifier().compareTo(
136: highestQualifier) > 0) {
137: reversionCandidate = siteFeatures[s];
138: highestQualifier = candidatePvi.getQualifier();
139: }
140: }
141: }
142: }
143: return reversionCandidate;
144: }
145:
146: /**
147: * Finds the highest version from feature jars. ID and version components
148: * are constant. Qualifier varies
149: *
150: * @param builtJars
151: * candidate jars in format id_version.jar
152: * @param id
153: * @param major
154: * @param minor
155: * @param service
156: * @return
157: */
158: private String findBuiltVersion(String id, int major, int minor,
159: int service) {
160: IFolder featuresFolder = fSiteContainer.getFolder(new Path(
161: "features")); //$NON-NLS-1$
162: if (!featuresFolder.exists()) {
163: return null;
164: }
165: IResource[] featureJars = null;
166: try {
167: featureJars = featuresFolder.members();
168: } catch (CoreException ce) {
169: return null;
170: }
171: Pattern pattern = PatternConstructor.createPattern(id + "_" //$NON-NLS-1$
172: + major + "." //$NON-NLS-1$
173: + minor + "." //$NON-NLS-1$
174: + service + "*.jar", true); //$NON-NLS-1$
175: // finding the newest feature archive
176: String newestName = null;
177: long newestTime = 0;
178: for (int i = 0; i < featureJars.length; i++) {
179: File file = new File(featureJars[i].getLocation()
180: .toOSString());
181: long jarTime = file.lastModified();
182: String jarName = featureJars[i].getName();
183:
184: if (jarTime < fBuildTime) {
185: continue;
186: }
187: if (jarTime <= newestTime) {
188: continue;
189: }
190: if (pattern.matcher(jarName).matches()) {
191: newestName = featureJars[i].getName();
192: newestTime = jarTime;
193: }
194: }
195: if (newestName == null) {
196: return null;
197: }
198:
199: return newestName.substring(id.length() + 1, newestName
200: .length() - 4);
201: }
202:
203: /*
204: * (non-Javadoc)
205: *
206: * @see org.eclipse.pde.internal.ui.wizards.exports.FeatureExportJob#getLogFoundMessage()
207: */
208: protected String getLogFoundMessage() {
209: return PDEUIMessages.BuildSiteJob_message;
210: }
211: }
|