blob: 5330429008605db536640ee447426794aa69c8b0 [file] [log] [blame]
package org.eclipse.equinox.p2.directorywatcher;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.equinox.p2.artifact.repository.*;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.generator.BundleDescriptionFactory;
import org.eclipse.equinox.p2.metadata.generator.MetadataGeneratorHelper;
import org.eclipse.equinox.p2.metadata.repository.IMetadataRepository;
import org.eclipse.equinox.p2.metadata.repository.IMetadataRepositoryManager;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class RepositoryListener implements IDirectoryChangeListener {
IMetadataRepository metadataRepository;
IArtifactRepository artifactRepository;
BundleDescriptionFactory bundleDescriptionFactory;
Map currentFiles = new HashMap();
public RepositoryListener(BundleContext context, File bundleDirectory) {
String stateDirName = "listener_" + bundleDirectory.getAbsolutePath().hashCode();
File stateDir = context.getDataFile(stateDirName);
stateDir.mkdirs();
URL stateDirURL;
try {
stateDirURL = stateDir.toURL();
} catch (MalformedURLException e) {
throw new IllegalStateException(e.getMessage());
}
initializeMetadataRepository(context, stateDirURL);
initializeArtifactRepository(context, stateDirURL);
initializeBundleDescriptionFactory(context);
}
private void initializeBundleDescriptionFactory(BundleContext context) {
ServiceReference reference = context.getServiceReference(PlatformAdmin.class.getName());
if (reference == null)
throw new IllegalStateException("PlatformAdmin not registered.");
PlatformAdmin platformAdmin = (PlatformAdmin) context.getService(reference);
if (platformAdmin == null)
throw new IllegalStateException("PlatformAdmin not registered.");
try {
StateObjectFactory stateObjectFactory = platformAdmin.getFactory();
bundleDescriptionFactory = new BundleDescriptionFactory(stateObjectFactory, null);
} finally {
context.ungetService(reference);
}
}
private void initializeArtifactRepository(BundleContext context, URL stateDirURL) {
ServiceReference reference = context.getServiceReference(IArtifactRepositoryManager.class.getName());
if (reference == null)
throw new IllegalStateException("ArtifactRepositoryManager not registered.");
IArtifactRepositoryManager manager = (IArtifactRepositoryManager) context.getService(reference);
if (manager == null)
throw new IllegalStateException("ArtifactRepositoryManager not registered.");
try {
artifactRepository = manager.getRepository(stateDirURL);
if (artifactRepository == null)
artifactRepository = manager.createRepository(stateDirURL, "artifact listener", "org.eclipse.equinox.p2.artifact.repository.simpleRepository");
} finally {
context.ungetService(reference);
}
if (artifactRepository == null)
throw new IllegalStateException("Couldn't create listener artifact repository for: " + stateDirURL);
}
private void initializeMetadataRepository(BundleContext context, URL stateDirURL) {
ServiceReference reference = context.getServiceReference(IMetadataRepositoryManager.class.getName());
if (reference == null)
throw new IllegalStateException("MetadataRepositoryManager not registered.");
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) context.getService(reference);
if (manager == null)
throw new IllegalStateException("MetadataRepositoryManager not registered.");
try {
metadataRepository = manager.getRepository(stateDirURL);
if (metadataRepository == null)
metadataRepository = manager.createRepository(stateDirURL, "metadata listener", "org.eclipse.equinox.p2.metadata.repository.simpleRepository");
} finally {
context.ungetService(reference);
}
if (metadataRepository == null)
throw new IllegalStateException("Couldn't create listener metadata repository for: " + stateDirURL);
}
public boolean added(File file) {
currentFiles.put(file, new Long(file.lastModified()));
return true;
}
public boolean changed(File file) {
currentFiles.put(file, new Long(file.lastModified()));
return true;
}
public boolean removed(File file) {
currentFiles.remove(file);
return true;
}
public String[] getExtensions() {
return new String[] {".jar"};
}
public Long getSeenFile(File file) {
return (Long) currentFiles.get(file);
}
public void startPoll() {
}
public void stopPoll() {
synchronizeMetadataRepository();
synchronizeArtifactRepository();
}
private void synchronizeMetadataRepository() {
Map snapshot = new HashMap(currentFiles);
List toRemove = new ArrayList();
IInstallableUnit[] ius = metadataRepository.getInstallableUnits(null);
for (int i = 0; i < ius.length; i++) {
IInstallableUnit iu = ius[i];
File iuFile = new File(iu.getProperty("file.name"));
Long iuLastModified = new Long(iu.getProperty("file.lastModified"));
Long snapshotLastModified = (Long) snapshot.get(iuFile);
if (snapshotLastModified == null || !snapshotLastModified.equals(iuLastModified))
toRemove.add(iu);
else
snapshot.remove(iuFile);
}
IInstallableUnit[] iusToRemove = (IInstallableUnit[]) toRemove.toArray(new IInstallableUnit[toRemove.size()]);
metadataRepository.removeInstallableUnits(iusToRemove);
IInstallableUnit[] iusToAdd = generateIUs(snapshot.keySet());
metadataRepository.addInstallableUnits(iusToAdd);
}
private void synchronizeArtifactRepository() {
List snapshot = new ArrayList(Arrays.asList(artifactRepository.getArtifactKeys()));
IInstallableUnit[] ius = metadataRepository.getInstallableUnits(null);
for (int i = 0; i < ius.length; i++) {
IInstallableUnit iu = ius[i];
IArtifactKey[] artifacts = iu.getArtifacts();
if (artifacts == null || artifacts.length == 0)
continue;
IArtifactKey artifact = artifacts[0];
if (!snapshot.remove(artifact)) {
File iuFile = new File(iu.getProperty("file.name"));
IArtifactDescriptor descriptor = generateArtifactDescriptor(iuFile);
if (descriptor != null)
artifactRepository.addDescriptor(descriptor);
}
}
for (Iterator it = snapshot.iterator(); it.hasNext();) {
IArtifactKey key = (IArtifactKey) it.next();
artifactRepository.removeDescriptor(key);
}
}
private IArtifactDescriptor generateArtifactDescriptor(File bundle) {
BundleDescription bundleDescription = bundleDescriptionFactory.getBundleDescription(bundle);
IArtifactKey key = MetadataGeneratorHelper.createEclipseArtifactKey(bundleDescription.getSymbolicName(), bundleDescription.getVersion().toString());
return MetadataGeneratorHelper.createArtifactDescriptor(key, bundle, true, false);
}
private IInstallableUnit[] generateIUs(Collection files) {
List ius = new ArrayList();
int i = 0;
for (Iterator it = files.iterator(); it.hasNext(); i++) {
File bundle = (File) it.next();
IInstallableUnit iu = generateIU(bundle);
if (iu != null)
ius.add(iu);
}
return (IInstallableUnit[]) ius.toArray(new IInstallableUnit[ius.size()]);
}
private IInstallableUnit generateIU(File bundle) {
BundleDescription bundleDescription = bundleDescriptionFactory.getBundleDescription(bundle);
if (bundleDescription == null)
return null;
Properties props = new Properties();
props.setProperty("file.name", bundle.getAbsolutePath());
props.setProperty("file.lastModified", Long.toString(bundle.lastModified()));
IArtifactKey key = MetadataGeneratorHelper.createEclipseArtifactKey(bundleDescription.getSymbolicName(), bundleDescription.getVersion().toString());
IInstallableUnit iu = (IInstallableUnit) MetadataGeneratorHelper.createEclipseIU(bundleDescription, (Map) bundleDescription.getUserObject(), false, key, props);
return iu;
}
public IMetadataRepository getMetadataRepository() {
return metadataRepository;
}
public IArtifactRepository getArtifactRepository() {
return artifactRepository;
}
}