Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSusan McCourt2014-06-06 13:46:24 -0400
committerPascal Rapicault2014-06-27 23:26:42 -0400
commit9ea8e4cc9aa6ec8ff70a4e0a811401f5c941ad68 (patch)
treeb69d499e8504c5ed1c058c5b92038eaab2431297 /bundles/org.eclipse.equinox.p2.updatesite
parent775d3353cbbd08cb5605f993b32081438f5674b3 (diff)
downloadrt.equinox.p2-9ea8e4cc9aa6ec8ff70a4e0a811401f5c941ad68.tar.gz
rt.equinox.p2-9ea8e4cc9aa6ec8ff70a4e0a811401f5c941ad68.tar.xz
rt.equinox.p2-9ea8e4cc9aa6ec8ff70a4e0a811401f5c941ad68.zip
Bug 436872 - [category] Specify download stats URL and type of artifacts
to monitor in category.xml Adds an argument to MirroringApplication to mirror artifact repository properties. This is needed in order to properly export the p2.statsURI property generated in the publisher. Change-Id: I0947d6320f24ef09e67f650b765bbe3908dd382e Signed-off-by: Pascal Rapicault <pascal@rapicorp.com>
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.updatesite')
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/CategoryParser.java99
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteModel.java65
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java65
4 files changed, 228 insertions, 2 deletions
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
index a07ca0c58..6aea12f30 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
@@ -18,6 +18,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.app;version="1.1.0",
org.eclipse.equinox.internal.p2.artifact.repository.simple,
org.eclipse.equinox.internal.p2.core.helpers,
+ org.eclipse.equinox.internal.p2.metadata,
org.eclipse.equinox.internal.p2.publisher.eclipse,
org.eclipse.equinox.internal.p2.repository,
org.eclipse.equinox.p2.core;version="[2.0.0,3.0.0)",
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/CategoryParser.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/CategoryParser.java
index ece98b7db..e8a94ecb0 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/CategoryParser.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/CategoryParser.java
@@ -47,6 +47,7 @@ public class CategoryParser extends DefaultHandler {
private static final String EXPRESSION = "expression"; //$NON-NLS-1$
private static final String PARAM = "param"; //$NON-NLS-1$
private static final String REPOSITORY_REF = "repository-reference"; //$NON-NLS-1$
+ private static final String STATS_URI = "stats"; //$NON-NLS-1$
private static final int STATE_ARCHIVE = 3;
private static final int STATE_CATEGORY = 4;
@@ -63,6 +64,7 @@ public class CategoryParser extends DefaultHandler {
private static final int STATE_QUERY = 11;
private static final int STATE_SITE = 1;
private static final int STATE_REPOSITORY_REF = 13;
+ private static final int STATE_STATS = 14;
private boolean DESCRIPTION_SITE_ALREADY_SEEN = false;
// Current object stack (used to hold the current object we are
@@ -245,6 +247,11 @@ public class CategoryParser extends DefaultHandler {
// do not pop object as we did not push the reference
break;
+ case STATE_STATS :
+ stateStack.pop();
+ // do not pop object stack because we didn't push anything
+ break;
+
case STATE_DESCRIPTION_SITE :
stateStack.pop();
text = ""; //$NON-NLS-1$
@@ -392,6 +399,9 @@ public class CategoryParser extends DefaultHandler {
case STATE_REPOSITORY_REF :
return "Repository Reference"; //$NON-NLS-1$
+ case STATE_STATS :
+ return "Stats Repository"; //$NON-NLS-1$
+
default :
return Messages.DefaultSiteParser_UnknownState;
}
@@ -472,6 +482,20 @@ public class CategoryParser extends DefaultHandler {
} else if (elementName.equals(REPOSITORY_REF)) {
stateStack.push(new Integer(STATE_REPOSITORY_REF));
processRepositoryReference(attributes);
+ } else if (elementName.equals(STATS_URI)) {
+ stateStack.push(new Integer(STATE_STATS));
+ processStatsInfo(attributes);
+ } else
+ internalErrorUnknownTag(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] {elementName, getState(currentState())})));
+ }
+
+ private void handleStatsState(String elementName, Attributes attributes) {
+ if (elementName.equals(FEATURE)) {
+ stateStack.push(STATE_FEATURE);
+ processStatsFeature(attributes);
+ } else if (elementName.equals(BUNDLE)) {
+ stateStack.push(STATE_BUNDLE);
+ processStatsBundle(attributes);
} else
internalErrorUnknownTag(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] {elementName, getState(currentState())})));
}
@@ -648,12 +672,83 @@ public class CategoryParser extends DefaultHandler {
} catch (URISyntaxException e) {
// UI should have already caught this
}
+ }
+
+ /*
+ * process stats top level element
+ */
+ private void processStatsInfo(Attributes attributes) {
+ String location = attributes.getValue("location"); //$NON-NLS-1$
+ try {
+ // One final validation but UI should have already done this.
+ URIUtil.fromString(location);
+ SiteModel site = (SiteModel) objectStack.peek();
+ site.setStatsURIString(location);
+ } catch (URISyntaxException e) {
+ // Ignore if not valid.
+ }
if (Tracing.DEBUG_GENERATOR_PARSING)
debug("End processing Repository Reference: location:" + location); //$NON-NLS-1$
}
/*
+ * process stats feature artifact
+ */
+ private void processStatsFeature(Attributes attributes) {
+ SiteFeature feature = new SiteFeature();
+
+ // identifier and version
+ String id = attributes.getValue("id"); //$NON-NLS-1$
+ String ver = attributes.getValue("version"); //$NON-NLS-1$
+
+ boolean noId = (id == null || id.trim().equals("")); //$NON-NLS-1$
+
+ // We need to have id and version, or the url, or both.
+ if (noId)
+ internalError(NLS.bind(Messages.DefaultSiteParser_Missing, (new String[] {"url", getState(currentState())}))); //$NON-NLS-1$
+
+ feature.setFeatureIdentifier(id);
+ feature.setFeatureVersion(ver);
+
+ SiteModel site = (SiteModel) objectStack.peek();
+ site.addStatsFeature(feature);
+ objectStack.push(feature);
+ feature.setSiteModel(site);
+
+ if (Tracing.DEBUG_GENERATOR_PARSING)
+ debug("End Processing Stats Feature Tag: id:" + id + " version:" + ver); //$NON-NLS-1$ //$NON-NLS-2$ }
+ }
+
+ /*
+ * process stats bundle artifact info
+ */
+ private void processStatsBundle(Attributes attributes) {
+ SiteBundle bundle = new SiteBundle();
+
+ // identifier and version
+ String id = attributes.getValue("id"); //$NON-NLS-1$
+ String ver = attributes.getValue("version"); //$NON-NLS-1$
+
+ boolean noId = (id == null || id.trim().equals("")); //$NON-NLS-1$
+
+ // We need to have id and version, or the url, or both.
+ if (noId)
+ internalError(NLS.bind(Messages.DefaultSiteParser_Missing, (new String[] {"url", getState(currentState())}))); //$NON-NLS-1$
+
+ bundle.setBundleIdentifier(id);
+ bundle.setBundleVersion(ver);
+
+ SiteModel site = (SiteModel) objectStack.peek();
+ site.addStatsBundle(bundle);
+ objectStack.push(bundle);
+ bundle.setSiteModel(site);
+
+ if (Tracing.DEBUG_GENERATOR_PARSING)
+ debug("End Processing Stats Bundle Tag: id:" + id + " version:" + ver); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
* process feature info
*/
private void processFeature(Attributes attributes) {
@@ -857,6 +952,10 @@ public class CategoryParser extends DefaultHandler {
handleSiteState(localName, attributes);
break;
+ case STATE_STATS :
+ handleStatsState(localName, attributes);
+ break;
+
default :
internalErrorUnknownTag(NLS.bind(Messages.DefaultSiteParser_UnknownStartState, (new String[] {getState(currentState())})));
break;
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteModel.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteModel.java
index d2c1c2cbf..087659606 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteModel.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteModel.java
@@ -38,6 +38,7 @@ public class SiteModel {
private URI locationURI;
private String locationURIString;
private String mirrorsURIString;
+ private String statsURIString;
private boolean supportsPack200;
private String type;
private URLEntry[] associateSites;
@@ -45,6 +46,8 @@ public class SiteModel {
private List<String> messageKeys;
private Map<Locale, Map<String, String>> localizations;
private List<RepositoryReference> repositoryReferences;
+ private List<SiteFeature> statsFeatures;
+ private List<SiteBundle> statsBundles;
/**
* Creates an uninitialized site model object.
@@ -107,6 +110,28 @@ public class SiteModel {
}
/**
+ * Adds a feature reference model to site stats artifacts.
+ *
+ * @param featureReference feature reference model
+ */
+ public void addStatsFeature(SiteFeature featureReference) {
+ if (this.statsFeatures == null)
+ this.statsFeatures = new ArrayList<SiteFeature>();
+ this.statsFeatures.add(featureReference);
+ }
+
+ /**
+ * Adds a bundle reference model to site stats artifacts
+ *
+ * @param bundleReference bundle reference model
+ */
+ public void addStatsBundle(SiteBundle bundleReference) {
+ if (this.statsBundles == null)
+ this.statsBundles = new ArrayList<SiteBundle>();
+ this.statsBundles.add(bundleReference);
+ }
+
+ /**
* Adds a iu model to site.
*
* @param iu iu model
@@ -199,6 +224,28 @@ public class SiteModel {
}
/**
+ * Returns an array of feature reference models for stats on this site.
+ *
+ * @return an array of feature reference models, or an empty array.
+ */
+ public SiteFeature[] getStatsFeatures() {
+ if (statsFeatures == null || statsFeatures.size() == 0)
+ return new SiteFeature[0];
+ return statsFeatures.toArray(new SiteFeature[0]);
+ }
+
+ /**
+ * Returns an array of bundle reference models for stats on this site.
+ *
+ * @return an array of bundle reference models, or an empty array.
+ */
+ public SiteBundle[] getStatsBundles() {
+ if (statsBundles == null || statsBundles.size() == 0)
+ return new SiteBundle[0];
+ return statsBundles.toArray(new SiteBundle[0]);
+ }
+
+ /**
* Returns an array of IU models on this site.
*
* @return an array of IU models, or an empty array.
@@ -221,6 +268,15 @@ public class SiteModel {
}
/**
+ * Returns the URI of the stats repository that tracks downloads.
+ *
+ * @return a String representation of the stats URI.
+ */
+ public String getStatsURI() {
+ return statsURIString;
+ }
+
+ /**
* Gets the localizations for the site as a map from locale
* to the set of translated properties for that locale.
*
@@ -379,4 +435,13 @@ public class SiteModel {
return digestURIString;
}
+ /**
+ * Sets the URI of the stats repository used to track downloads.
+ *
+ * @param statsURI a String describing the stats URI
+ */
+ public void setStatsURIString(String statsURI) {
+ this.statsURIString = statsURI;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
index df31e3062..965110269 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/SiteXMLAction.java
@@ -26,10 +26,12 @@ import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescriptio
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.publisher.*;
-import org.eclipse.equinox.p2.publisher.eclipse.URLEntry;
+import org.eclipse.equinox.p2.publisher.eclipse.*;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.IRepositoryReference;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
import org.eclipse.equinox.p2.repository.spi.RepositoryReference;
import org.eclipse.equinox.spi.p2.publisher.LocalizationHelper;
import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
@@ -40,6 +42,8 @@ import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
*/
public class SiteXMLAction extends AbstractPublisherAction {
static final private String QUALIFIER = "qualifier"; //$NON-NLS-1$
+ static final private String P_STATS_URI = "p2.statsURI"; //$NON-NLS-1$
+ static final private String P_STATS_MARKER = "download.stats"; //$NON-NLS-1$
private static final VersionSuffixGenerator versionSuffixGenerator = new VersionSuffixGenerator();
protected UpdateSite updateSite;
private SiteCategory defaultCategory;
@@ -99,7 +103,57 @@ public class SiteXMLAction extends AbstractPublisherAction {
}
initialize();
initializeRepoFromSite(publisherInfo);
- return generateCategories(publisherInfo, results, monitor);
+ IStatus markingStats = markStatsArtifacts(publisherInfo, results, monitor);
+ if (markingStats.isOK()) {
+ return generateCategories(publisherInfo, results, monitor);
+ }
+ return markingStats;
+ }
+
+ private IStatus markStatsArtifacts(IPublisherInfo publisherInfo, IPublisherResult results, IProgressMonitor monitor) {
+ SiteModel site = updateSite.getSite();
+ // process all features listed and mark artifacts
+ SiteFeature[] features = site.getStatsFeatures();
+ if (features != null) {
+ for (SiteFeature feature : features) {
+ if (monitor.isCanceled())
+ return Status.CANCEL_STATUS;
+ Collection<IInstallableUnit> ius = getFeatureIU(feature, publisherInfo, results);
+ if (ius != null) {
+ for (IInstallableUnit iu : ius) {
+ IArtifactKey key = FeaturesAction.createFeatureArtifactKey(feature.getFeatureIdentifier(), iu.getVersion().toString());
+ IArtifactDescriptor[] descriptors = publisherInfo.getArtifactRepository().getArtifactDescriptors(key);
+ if (descriptors.length > 0 && descriptors[0] instanceof ArtifactDescriptor) {
+ HashMap<String, String> map = new HashMap<String, String>();
+ map.put(P_STATS_MARKER, feature.getFeatureIdentifier());
+ ((ArtifactDescriptor) descriptors[0]).addProperties(map);
+ }
+ }
+ }
+ }
+ }
+ SiteBundle[] bundles = site.getStatsBundles();
+ if (bundles != null) {
+ for (SiteBundle bundle : bundles) {
+ if (monitor.isCanceled())
+ return Status.CANCEL_STATUS;
+ Collection<IInstallableUnit> ius = getBundleIU(bundle, publisherInfo, results);
+ if (ius != null) {
+ for (IInstallableUnit iu : ius) {
+ IArtifactKey key = BundlesAction.createBundleArtifactKey(iu.getId(), iu.getVersion().toString());
+ IArtifactDescriptor[] descriptors = publisherInfo.getArtifactRepository().getArtifactDescriptors(key);
+ if (descriptors.length > 0 && descriptors[0] instanceof ArtifactDescriptor) {
+ HashMap<String, String> map = new HashMap<String, String>();
+ map.put(P_STATS_MARKER, iu.getId());
+ ((ArtifactDescriptor) descriptors[0]).addProperties(map);
+ }
+ }
+ }
+ }
+ }
+ // Process all ius that should be marked for download stat tracking
+ return Status.OK_STATUS;
+
}
private IStatus generateCategories(IPublisherInfo publisherInfo, IPublisherResult results, IProgressMonitor monitor) {
@@ -408,6 +462,13 @@ public class SiteXMLAction extends AbstractPublisherAction {
publisherInfo.getMetadataRepository().addReferences(toAdd);
}
+ // publish download stats URL from category file
+ String statsURI = site.getStatsURI();
+ if (statsURI != null && statsURI.length() > 0) {
+ if (publisherInfo.getArtifactRepository() != null)
+ publisherInfo.getArtifactRepository().setProperty(P_STATS_URI, statsURI);
+ }
+
File siteFile = URIUtil.toFile(updateSite.getLocation());
if (siteFile != null && siteFile.exists()) {
File siteParent = siteFile.getParentFile();

Back to the top