Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Niefer2010-02-10 16:19:38 +0000
committerAndrew Niefer2010-02-10 16:19:38 +0000
commit55d6e02ac89fe04a18ffc3ce62fa8bb0d7614345 (patch)
treef567bc6c17bbc28e9288b10b10179709fdb537f7 /bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal
parent47630b5366febb13438fb4a097a7dd4f39db3849 (diff)
downloadrt.equinox.p2-55d6e02ac89fe04a18ffc3ce62fa8bb0d7614345.tar.gz
rt.equinox.p2-55d6e02ac89fe04a18ffc3ce62fa8bb0d7614345.tar.xz
rt.equinox.p2-55d6e02ac89fe04a18ffc3ce62fa8bb0d7614345.zip
bug 302288 - feature comparison, *.mappings
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal')
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/JarComparator.java147
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/Messages.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/messages.properties21
3 files changed, 143 insertions, 45 deletions
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/JarComparator.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/JarComparator.java
index 7d2b7de43..8ee9b8e28 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/JarComparator.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/JarComparator.java
@@ -10,10 +10,6 @@
*******************************************************************************/
package org.eclipse.equinox.p2.internal.repository.comparator;
-import org.eclipse.equinox.p2.internal.repository.comparator.java.*;
-
-import org.eclipse.equinox.p2.repository.tools.comparator.IArtifactComparator;
-
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
@@ -21,8 +17,13 @@ import java.util.jar.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.publisher.eclipse.FeatureParser;
+import org.eclipse.equinox.p2.internal.repository.comparator.java.*;
+import org.eclipse.equinox.p2.publisher.eclipse.Feature;
+import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
+import org.eclipse.equinox.p2.repository.tools.comparator.IArtifactComparator;
import org.eclipse.osgi.util.NLS;
public class JarComparator implements IArtifactComparator {
@@ -31,11 +32,13 @@ public class JarComparator implements IArtifactComparator {
private static final String CLASS_EXTENSION = ".class"; //$NON-NLS-1$
private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
private static final String PROPERTIES_EXTENSION = ".properties"; //$NON-NLS-1$
+ private static final String MAPPINGS_EXTENSION = ".mappings"; //$NON-NLS-1$
private static final String PLUGIN_ID = "org.eclipse.equinox.p2.repository.tools"; //$NON-NLS-1$
private static final String DESTINATION_ARTIFACT_PREFIX = "destinationartifact"; //$NON-NLS-1$
private static final String SUFFIX_JAR = ".jar"; //$NON-NLS-1$
private static final String SOURCE_ARTIFACT_PREFIX = "sourceartifact"; //$NON-NLS-1$
private static final String OSGI_BUNDLE_CLASSIFIER = "osgi.bundle"; //$NON-NLS-1$
+ private static final String FEATURE_CLASSIFIER = "org.eclipse.update.feature"; //$NON-NLS-1$
private static final String META_INF = "meta-inf/"; //$NON-NLS-1$
private static final String DSA_EXT = ".dsa"; //$NON-NLS-1$
@@ -50,12 +53,9 @@ public class JarComparator implements IArtifactComparator {
destinationLocation = URIUtil.toUnencodedString(destinationDescriptor.getRepository().getLocation());
descriptorString = sourceDescriptor.toString();
- String classifier = sourceDescriptor.getArtifactKey().getClassifier();
- if (!OSGI_BUNDLE_CLASSIFIER.equals(classifier)) {
- return Status.OK_STATUS;
- }
- classifier = destinationDescriptor.getArtifactKey().getClassifier();
- if (!OSGI_BUNDLE_CLASSIFIER.equals(classifier)) {
+ String classifier1 = sourceDescriptor.getArtifactKey().getClassifier();
+ String classifier2 = destinationDescriptor.getArtifactKey().getClassifier();
+ if (!classifier1.equals(classifier2) || (!OSGI_BUNDLE_CLASSIFIER.equals(classifier1) && !FEATURE_CLASSIFIER.equals(classifier1))) {
return Status.OK_STATUS;
}
@@ -64,7 +64,10 @@ public class JarComparator implements IArtifactComparator {
try {
firstTempFile = getLocalJarFile(source, sourceDescriptor, SOURCE_ARTIFACT_PREFIX);
secondTempFile = getLocalJarFile(destination, destinationDescriptor, DESTINATION_ARTIFACT_PREFIX);
- return compare(firstTempFile, secondTempFile);
+ if (classifier1.equals(OSGI_BUNDLE_CLASSIFIER))
+ return compare(firstTempFile, secondTempFile);
+ else if (classifier1.equals(FEATURE_CLASSIFIER))
+ return compareFeatures(firstTempFile, secondTempFile);
} catch (CoreException e) {
return e.getStatus();
} finally {
@@ -73,6 +76,47 @@ public class JarComparator implements IArtifactComparator {
if (secondTempFile != null)
secondTempFile.delete();
}
+ return Status.OK_STATUS;
+ }
+
+ public IStatus compareFeatures(File sourceFile, File destinationFile) {
+ FeatureParser parser = new FeatureParser();
+ Feature feature1 = parser.parse(sourceFile);
+ Feature feature2 = parser.parse(destinationFile);
+
+ MultiStatus parent = new MultiStatus(PLUGIN_ID, 0, NLS.bind(Messages.differentEntry, new String[] {descriptorString, sourceLocation, destinationLocation}), null);
+
+ if (!feature1.getId().equals(feature2.getId()))
+ parent.add(newErrorStatus(NLS.bind(Messages.featureIdsDontMatch, feature1.getId(), feature2.getId())));
+ if (!feature1.getVersion().equals(feature2.getVersion()))
+ parent.add(newErrorStatus(NLS.bind(Messages.featureVersionsDontMatch, feature1.getVersion(), feature2.getVersion())));
+
+ Map<FeatureEntry, FeatureEntry> entryMap = new HashMap<FeatureEntry, FeatureEntry>();
+ FeatureEntry[] entries = feature1.getEntries();
+ for (int i = 0; i < entries.length; i++)
+ entryMap.put(entries[i], entries[i]);
+
+ entries = feature2.getEntries();
+ if (entries.length != entryMap.size())
+ parent.add(newErrorStatus(Messages.featureSize));
+
+ for (int i = 0; i < entries.length; i++) {
+ FeatureEntry firstEntry = entryMap.get(entries[i]);
+ if (firstEntry == null)
+ parent.add(newErrorStatus(NLS.bind(Messages.featureEntry, entries[i])));
+ else {
+ if (firstEntry.isOptional() != entries[i].isOptional())
+ parent.add(newErrorStatus(NLS.bind(Messages.featureEntryOptional, entries[i])));
+ if (firstEntry.isUnpack() != entries[i].isUnpack())
+ parent.add(newErrorStatus(NLS.bind(Messages.featureEntryUnpack, entries[i])));
+ if (firstEntry.isRequires() && firstEntry.getMatch() != null && !firstEntry.getMatch().equals(entries[i].getMatch()))
+ parent.add(newErrorStatus(NLS.bind(Messages.featureEntryMatch, entries[i])));
+ if (firstEntry.getFilter() != null && !firstEntry.getFilter().equals(entries[i].getFilter()))
+ parent.add(newErrorStatus(NLS.bind(Messages.featureEntryFilter, entries[i])));
+ }
+ }
+
+ return parent.getChildren().length == 0 ? Status.OK_STATUS : parent;
}
public IStatus compare(File sourceFile, File destinationFile) {
@@ -83,13 +127,17 @@ public class JarComparator implements IArtifactComparator {
secondFile = new ZipFile(destinationFile);
final int firstFileSize = firstFile.size();
final int secondFileSize = secondFile.size();
+ MultiStatus parent = new MultiStatus(PLUGIN_ID, 0, NLS.bind(Messages.differentEntry, new String[] {descriptorString, sourceLocation, destinationLocation}), null);
+
if (firstFileSize != secondFileSize) {
- return newErrorStatus(NLS.bind(Messages.differentNumberOfEntries, new String[] {descriptorString, sourceLocation, Integer.toString(firstFileSize), destinationLocation, Integer.toString(secondFileSize)}));
+ parent.add(newErrorStatus(NLS.bind(Messages.differentNumberOfEntries, new String[] {descriptorString, sourceLocation, Integer.toString(firstFileSize), destinationLocation, Integer.toString(secondFileSize)})));
+ return parent;
}
for (Enumeration<? extends ZipEntry> enumeration = firstFile.entries(); enumeration.hasMoreElements();) {
ZipEntry entry = enumeration.nextElement();
String entryName = entry.getName();
final ZipEntry entry2 = secondFile.getEntry(entryName);
+ IStatus result = null;
if (!entry.isDirectory() && entry2 != null) {
String lowerCase = entryName.toLowerCase();
if (isSigningEntry(lowerCase)) {
@@ -101,35 +149,40 @@ public class JarComparator implements IArtifactComparator {
try {
firstStream = new BufferedInputStream(firstFile.getInputStream(entry));
secondStream = new BufferedInputStream(secondFile.getInputStream(entry2));
- boolean result = false;
if (lowerCase.endsWith(CLASS_EXTENSION)) {
try {
- result = compareClasses(firstStream, entry.getSize(), secondStream, entry2.getSize());
+ result = compareClasses(entryName, firstStream, entry.getSize(), secondStream, entry2.getSize());
} catch (ClassFormatException e) {
- return newErrorStatus(NLS.bind(Messages.differentEntry, new String[] {entryName, descriptorString, sourceLocation}), e);
+ result = newErrorStatus(NLS.bind(Messages.differentEntry, new String[] {entryName, descriptorString, sourceLocation}), e);
}
} else if (lowerCase.endsWith(JAR_EXTENSION)) {
result = compareNestedJars(firstStream, entry.getSize(), secondStream, entry2.getSize(), entryName);
- } else if (lowerCase.endsWith(PROPERTIES_EXTENSION)) {
- result = compareProperties(firstStream, secondStream);
+ } else if (lowerCase.endsWith(PROPERTIES_EXTENSION) || lowerCase.endsWith(MAPPINGS_EXTENSION)) {
+ result = compareProperties(entryName, firstStream, secondStream);
} else if (entryName.equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
result = compareManifest(firstStream, secondStream); //MANIFEST.MF file
} else {
- result = compareBytes(firstStream, entry.getSize(), secondStream, entry2.getSize());
+ long size1 = entry.getSize();
+ long size2 = entry2.getSize();
+ if (size1 != size2)
+ result = newErrorStatus(NLS.bind(Messages.binaryDifferentLength, new String[] {entryName, String.valueOf(Math.abs(size1 - size2))}));
+ else
+ result = compareBytes(entryName, firstStream, entry.getSize(), secondStream, entry2.getSize());
}
- if (!result)
- return newErrorStatus(NLS.bind(Messages.differentEntry, new String[] {entryName, descriptorString, sourceLocation}));
} finally {
Utility.close(firstStream);
Utility.close(secondStream);
}
} else if (!entry.isDirectory()) {
// missing entry, entry2 == null
- return newErrorStatus(NLS.bind(Messages.missingEntry, new String[] {entryName, descriptorString, sourceLocation}));
+ result = newErrorStatus(NLS.bind(Messages.missingEntry, new String[] {entryName, descriptorString, sourceLocation}));
+ }
+
+ if (result != null && !result.isOK()) {
+ parent.add(result);
+ return parent;
}
}
- } catch (CoreException e) {
- return e.getStatus();
} catch (IOException e) {
// missing entry
return newErrorStatus(NLS.bind(Messages.ioexception, new String[] {sourceFile.getAbsolutePath(), destinationFile.getAbsolutePath()}), e);
@@ -140,78 +193,84 @@ public class JarComparator implements IArtifactComparator {
return Status.OK_STATUS;
}
- private boolean compareManifest(InputStream firstStream, InputStream secondStream) throws IOException {
+ private IStatus compareManifest(InputStream firstStream, InputStream secondStream) throws IOException {
Manifest manifest = new Manifest(firstStream);
Manifest manifest2 = new Manifest(secondStream);
if (manifest == null || manifest2 == null)
- return true;
+ return Status.OK_STATUS;
Attributes attributes = manifest.getMainAttributes();
Attributes attributes2 = manifest2.getMainAttributes();
if (attributes.size() != attributes2.size())
- return false;
+ return newErrorStatus(NLS.bind(Messages.manifestDifferentSize, String.valueOf(Math.abs(attributes.size() - attributes2.size()))));
for (Entry<Object, Object> entry : attributes.entrySet()) {
Object value2 = attributes2.get(entry.getKey());
if (value2 == null) {
- return false;
+ return newErrorStatus(NLS.bind(Messages.manifestMissingEntry, entry.getKey()));
}
if (!value2.equals(entry.getValue())) {
- return false;
+ return newErrorStatus(NLS.bind(Messages.manifestDifferentValue, entry.getKey()));
}
}
- return true;
+ return Status.OK_STATUS;
}
- private boolean compareClasses(InputStream stream1, long size1, InputStream stream2, long size2) throws ClassFormatException, IOException {
+ private IStatus compareClasses(String entryName, InputStream stream1, long size1, InputStream stream2, long size2) throws ClassFormatException, IOException {
Disassembler disassembler = new Disassembler();
byte[] firstEntryClassFileBytes = Utility.getInputStreamAsByteArray(stream1, (int) size1);
byte[] secondEntryClassFileBytes = Utility.getInputStreamAsByteArray(stream2, (int) size2);
String contentsFile1 = disassembler.disassemble(firstEntryClassFileBytes, LINE_SEPARATOR, Disassembler.DETAILED | Disassembler.COMPACT);
String contentsFile2 = disassembler.disassemble(secondEntryClassFileBytes, LINE_SEPARATOR, Disassembler.DETAILED | Disassembler.COMPACT);
- return contentsFile1.equals(contentsFile2);
+ if (!contentsFile1.equals(contentsFile2))
+ return newErrorStatus(NLS.bind(Messages.classesDifferent, entryName));
+ return Status.OK_STATUS;
}
- private boolean compareNestedJars(InputStream stream1, long size1, InputStream stream2, long size2, String entry) throws CoreException, IOException {
+ private IStatus compareNestedJars(InputStream stream1, long size1, InputStream stream2, long size2, String entry) throws IOException {
File firstTempFile = getLocalJarFile(stream1, entry, size1);
File secondTempFile = getLocalJarFile(stream2, entry, size2);
try {
- IStatus status = compare(firstTempFile, secondTempFile);
- if (!status.isOK())
- throw new CoreException(status);
+ return compare(firstTempFile, secondTempFile);
} finally {
if (firstTempFile != null)
firstTempFile.delete();
if (secondTempFile != null)
secondTempFile.delete();
}
- return true;
}
- private boolean compareProperties(InputStream stream1, InputStream stream2) {
+ private IStatus compareProperties(String entryName, InputStream stream1, InputStream stream2) {
Properties props1 = loadProperties(stream1);
Properties props2 = loadProperties(stream2);
if (props1.size() != props2.size())
- return false;
+ return newErrorStatus(NLS.bind(Messages.propertiesSizesDifferent, entryName, String.valueOf(Math.abs(props1.size() - props2.size()))));
props1.keys();
for (Iterator<Object> iterator = props1.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
if (!props2.containsKey(key))
- return false;
- if (!props1.getProperty(key).equals(props2.getProperty(key)))
- return false;
+ return newErrorStatus(NLS.bind(Messages.missingProperty, key, entryName));
+ String prop1 = props1.getProperty(key);
+ String prop2 = props2.getProperty(key);
+ if (!prop1.equals(prop2)) {
+ if (prop1.length() < 10 && prop2.length() < 10)
+ return newErrorStatus(NLS.bind(Messages.differentPropertyValueFull, new String[] {entryName, key, prop1, prop2}));
+ return newErrorStatus(NLS.bind(Messages.differentPropertyValueFull, entryName, key));
+ }
}
- return true;
+ return Status.OK_STATUS;
}
- private boolean compareBytes(InputStream firstStream, long size1, InputStream secondStream, long size2) throws IOException {
+ private IStatus compareBytes(String entryName, InputStream firstStream, long size1, InputStream secondStream, long size2) throws IOException {
byte[] firstBytes = Utility.getInputStreamAsByteArray(firstStream, (int) size1);
byte[] secondBytes = Utility.getInputStreamAsByteArray(secondStream, (int) size2);
- return Arrays.equals(firstBytes, secondBytes);
+ if (!Arrays.equals(firstBytes, secondBytes))
+ return newErrorStatus(NLS.bind(Messages.binaryFilesDifferent, entryName));
+ return Status.OK_STATUS;
}
private Properties loadProperties(InputStream input) {
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/Messages.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/Messages.java
index 7a69bbb73..198df63bb 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/Messages.java
@@ -15,9 +15,29 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.equinox.p2.internal.repository.comparator.java.messages"; //$NON-NLS-1$
public static String differentNumberOfEntries;
+ public static String binaryDifferentLength;
+ public static String classesDifferent;
+ public static String propertiesSizesDifferent;
+ public static String differentPropertyValueShort;
+ public static String differentPropertyValueFull;
+ public static String missingProperty;
+ public static String manifestDifferentSize;
+ public static String manifestMissingEntry;
+ public static String manifestDifferentValue;
+ public static String binaryFilesDifferent;
public static String differentEntry;
public static String missingEntry;
public static String ioexception;
+
+ public static String featureSize;
+ public static String featureIdsDontMatch;
+ public static String featureVersionsDontMatch;
+ public static String featureEntry;
+ public static String featureEntryOptional;
+ public static String featureEntryUnpack;
+ public static String featureEntryMatch;
+ public static String featureEntryFilter;
+
public static String disassembler_opentypedeclaration;
public static String disassembler_closetypedeclaration;
public static String disassembler_endofmethodheader;
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/messages.properties b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/messages.properties
index e8c395639..a835f6ed1 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/comparator/java/messages.properties
@@ -9,9 +9,28 @@
# IBM Corporation - initial API and implementation
###############################################################################
differentNumberOfEntries=Difference in [{0}]: {1} contains {2} files and {3} contains {4} files
-differentEntry=Difference found for {0} within [{1}] from {2}
+differentEntry=Difference found for {0} between {1} and {2}
missingEntry=Missing {0} within [{1}] from {2}
ioexception=IOException comparing {0} and {1}
+binaryDifferentLength= Binary file {0}: sizes differ by {1} bytes.
+classesDifferent= The class {0} is different.
+propertiesSizesDifferent=The properties file {0} has a different number ({0}) of properties.
+differentPropertyValueShort=In {0}, the property \"{1}\" has different values.
+differentPropertyValueFull= In {0}, the property \"{1}\" has different values: \"{2}\" and \"{3}\".
+missingProperty= The property \"{0}\" is not present in both properties files ({2}).
+manifestDifferentSize=The Manifest file sizes differ by {0} elements.
+manifestMissingEntry= The header \"{0}\" is not present in both Manifest files.
+manifestDifferentValue=The manifest header \"{0}\" has different values.
+binaryFilesDifferent=Binary file \"{0}\" is different.
+
+featureSize=The feature has a different number of entries/
+featureIdsDontMatch=Feature ids are not equal: \"{0}\" and \"{1}\"
+featureVersionsDontMatch=Feature versions are not equal: \"{0}\" and \"{1}\"
+featureEntry=The entry \"{0}\" is not present in both features.
+featureEntryOptional=The entry \"{0}\" is not optional in both features.
+featureEntryUnpack=The entry \"{0}\" has different unpack attribute values.
+featureEntryMatch=The entry \"{0}\" has different match rules.
+featureEntryFilter=The entry \"{0}\" has different filters.
### Disassembler messages

Back to the top