blob: b544f69460ff8b0571119c781c2c7687fba7fdd9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.tools;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryManager;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.internal.provisional.p2.metadata.RequiredCapability;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager;
import org.eclipse.equinox.internal.provisional.p2.query.Collector;
public class MetadataCompareApplication implements IApplication {
private MetadataRepositoryManager repoManager = new MetadataRepositoryManager();
private IMetadataRepository sourceRepo = null;
private IMetadataRepository targetRepo = null;
private static Comparator iuIdComparator = new Comparator() {
public int compare(Object source, Object target) {
IInstallableUnit sourceIU = (IInstallableUnit) source;
IInstallableUnit targetIU = (IInstallableUnit) target;
int id = sourceIU.getId().compareTo(targetIU.getId());
if (id != 0)
return id;
return sourceIU.getVersion().compareTo(targetIU.getVersion());
}
};
private URL sourceLocation;
private URL targetLocation;
private boolean compare = false;
private boolean list = false;
public Object start(IApplicationContext context) throws Exception {
initializeFromArguments((String[]) context.getArguments().get("application.args")); //$NON-NLS-1$
initRepositories();
if (compare) {
compareMetadataRepositories();
} else if (list) {
list(sourceLocation);
list(targetLocation);
}
return IApplication.EXIT_OK;
}
private void list(URL location) throws ProvisionException {
if (location == null)
return;
IMetadataRepository locationRepo = repoManager.getRepository(location);
if (locationRepo == null)
return;
Collector sourceRoots = locationRepo.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor());
IInstallableUnit[] sourceIUs = (IInstallableUnit[]) sourceRoots.toArray(IInstallableUnit.class);
sourceIUs = sort(sourceIUs, true);
for (int i = 0; i < sourceIUs.length; i++) {
System.out.print(sourceIUs[i]);
System.out.println(sourceIUs[i].isFragment() ? " (fragment)" : ""); //$NON-NLS-1$ //$NON-NLS-2$
}
System.out.println("Total: " + sourceIUs.length); //$NON-NLS-1$
}
private void compareMetadataRepositories() throws ProvisionException {
System.out.println("\n" + sourceLocation.toExternalForm() + " -> " + targetLocation.toExternalForm()); //$NON-NLS-1$ //$NON-NLS-2$
compare(sourceRepo, targetRepo);
}
private void initRepositories() throws ProvisionException {
if (targetLocation == null || sourceLocation == null)
throw new IllegalStateException("Must specify a source and target"); //$NON-NLS-1$
sourceRepo = repoManager.loadRepository(sourceLocation, null);
targetRepo = initializeTarget();
}
private IMetadataRepository initializeTarget() throws ProvisionException {
try {
IMetadataRepository repository = repoManager.loadRepository(targetLocation, null);
if (!repository.isModifiable())
throw new IllegalArgumentException("Metadata repository not modifiable: " + targetLocation); //$NON-NLS-1$
return repository;
} catch (ProvisionException e) {
//fall through and create repo
}
String repositoryName = targetLocation + " - metadata"; //$NON-NLS-1$
return repoManager.createRepository(targetLocation, repositoryName, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null);
}
private void compare(IMetadataRepository sourceRepo, IMetadataRepository targetRepo) {
Collector sourceRoots = sourceRepo.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor());
Collector targetRoots = targetRepo.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor());
IInstallableUnit[] sourceIUs = (IInstallableUnit[]) sourceRoots.toArray(IInstallableUnit.class);
sourceIUs = sort(sourceIUs, true);
IInstallableUnit[] targetIUs = (IInstallableUnit[]) targetRoots.toArray(IInstallableUnit.class);
targetIUs = sort(targetIUs, true);
int targetIndex = 0;
for (int i = 0; i < sourceIUs.length; i++)
targetIndex = compareUsingTargets(sourceIUs[i], targetIUs, targetIndex);
}
private int compareUsingTargets(IInstallableUnit sourceIU, IInstallableUnit[] targetIUs, int targetIndex) {
while (targetIndex < targetIUs.length) {
int difference = iuIdComparator.compare(sourceIU, targetIUs[targetIndex]);
if (difference < 0) {
System.out.println(sourceIU + " is not found in target repository"); //$NON-NLS-1$
return targetIndex;
} else if (difference == 0) {
String comparison = compare(sourceIU, targetIUs[targetIndex]);
if (comparison.length() > 0)
System.out.println(sourceIU + comparison);
return targetIndex + 1;
} else {
System.out.println(targetIUs[targetIndex++] + " is not found in source repository"); //$NON-NLS-1$
}
}
System.out.println(sourceIU + " is not found in target repository"); //$NON-NLS-1$
return targetIndex;
}
private boolean compare(Object a, Object b) {
if (a == null)
return b == null;
return a.equals(b);
}
private boolean compare(Object[] a, Object b[]) {
if (a == null)
return b == null;
return Arrays.equals(a, b);
}
private String compare(IInstallableUnit iu, IInstallableUnit next) {
if (next == null)
return " iu artifactLocators providedCapabilities requiredCapabilities touchpointType"; //$NON-NLS-1$
String result = ""; //$NON-NLS-1$
if (!iu.equals(next))
result += " iu"; //$NON-NLS-1$
// if (!compare(iu.getApplicabilityFilter(), next.getApplicabilityFilter()))
// result += " applicabilityFilter";
if (!compare(iu.getArtifacts(), next.getArtifacts()))
result += " artifactLocators"; //$NON-NLS-1$
if (!compare(iu.getProvidedCapabilities(), next.getProvidedCapabilities()))
result += " providedCapabilities"; //$NON-NLS-1$
if (!compareRequires(iu.getRequiredCapabilities(), next.getRequiredCapabilities()))
result += " requiredCapabilities"; //$NON-NLS-1$
if (!compare(iu.getTouchpointType(), next.getTouchpointType()))
result += " touchpointType"; //$NON-NLS-1$
if (iu.isFragment()) {
// if (((InstallableUnitFragment) iu).getHost() == null || ((InstallableUnitFragment) iu).getVersion() == null)
// return result;
// if (!((InstallableUnitFragment) iu).getHost().equals(((InstallableUnitFragment) next).getHost()))
// result += " hostid";
// if (!((InstallableUnitFragment) iu).getVersion().equals(((InstallableUnitFragment) next).getVersion()))
// result += " hostversionRange";
}
return result;
}
private boolean compareRequires(RequiredCapability[] a, RequiredCapability[] b) {
if (a == null)
return b == null;
if (a.length != b.length)
return false;
if (a == b)
return true;
for (int i = 0; i < a.length; i++)
if (findCapability(a[i], b) == null)
return false;
return true;
}
private RequiredCapability findCapability(RequiredCapability target, RequiredCapability[] b) {
for (int i = 0; i < b.length; i++) {
RequiredCapability capability = b[i];
if (target.equals(capability))
return capability;
}
return null;
}
private IInstallableUnit[] sort(IInstallableUnit[] ius, boolean clone) {
IInstallableUnit[] result = ius;
if (clone) {
result = new InstallableUnit[ius.length];
System.arraycopy(ius, 0, result, 0, ius.length);
}
Arrays.sort(result, iuIdComparator);
return result;
}
public void initializeFromArguments(String[] args) throws Exception {
if (args == null)
return;
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("-compare")) //$NON-NLS-1$
compare = true;
if (args[i].equalsIgnoreCase("-list")) //$NON-NLS-1$
list = true;
// check for args with parameters. If we are at the last argument or
// if the next one
// has a '-' as the first character, then we can't have an arg with
// a parm so continue.
if (i == args.length - 1 || args[i + 1].startsWith("-")) //$NON-NLS-1$
continue;
String arg = args[++i];
if (args[i - 1].equalsIgnoreCase("-source")) //$NON-NLS-1$
sourceLocation = new URL(arg);
if (args[i - 1].equalsIgnoreCase("-target")) //$NON-NLS-1$
targetLocation = new URL(arg);
}
}
public void stop() {
//do nothing
}
}