| /******************************************************************************* |
| * 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 implementation and ideas |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.directorywatcher; |
| |
| import java.io.File; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.*; |
| import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; |
| import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; |
| import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; |
| import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepositoryManager; |
| import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; |
| import org.eclipse.equinox.internal.provisional.p2.directorywatcher.DirectoryChangeListener; |
| import org.eclipse.equinox.internal.provisional.p2.directorywatcher.DirectoryWatcher; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.generator.*; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; |
| |
| public class ProvisioningListener extends DirectoryChangeListener { |
| |
| // The mapping rules for in-place generation need to construct paths that are flat, |
| // with no nesting structure. |
| static final private String[][] INPLACE_MAPPING_RULES = { {"(& (classifier=org.eclipse.update.feature))", "${repoUrl}/features/${id}_${version}.jar"}, //$NON-NLS-1$//$NON-NLS-2$ |
| {"(& (classifier=osgi.bundle))", "${repoUrl}/${id}_${version}.jar"}, //$NON-NLS-1$//$NON-NLS-2$ |
| {"(& (classifier=binary))", "${repoUrl}/${id}_${version}"}}; //$NON-NLS-1$//$NON-NLS-2$ |
| |
| private Set toUninstall; |
| private Set toUpdate; |
| private Set toInstall; |
| private Set toGenerate; |
| private DirectoryWatcher watcher; |
| private Map seenFiles; |
| |
| public ProvisioningListener(DirectoryWatcher watcher) { |
| this.watcher = watcher; |
| seenFiles = new HashMap(); |
| } |
| |
| public boolean added(File file) { |
| toInstall.add(file); |
| if (file.getName().endsWith(".iu")) { |
| // add the IU and artifact entries in to the repo associated with the watched dir |
| // keep track of the JARs added so we can remove them from the list of JARs |
| // to be run through the metadata generator |
| } else if (file.getName().endsWith(".jar")) { |
| // queue up this JAR to be run through the metadata generator if needed |
| toGenerate.add(file); |
| } |
| seenFiles.put(file, new Long(file.lastModified())); |
| return true; |
| } |
| |
| public boolean changed(File file) { |
| toUpdate.add(file); |
| if (file.getName().endsWith(".iu")) { |
| // overwrite the IU and artifact entries in to the repo associated with the watched dir |
| // keep track of the JARs added so we can remove them from the list of JARs |
| // to be run through the metadata generator |
| } else if (file.getName().endsWith(".jar")) { |
| // queue up this JAR to be run through the metadata generator |
| toGenerate.add(file); |
| } |
| seenFiles.put(file, new Long(file.lastModified())); |
| return true; |
| } |
| |
| public boolean removed(File file) { |
| toUninstall.add(file); |
| if (file.getName().endsWith(".iu")) { |
| // remove the IU and artifact entries in to the repo associated with the watched dir |
| // keep track of the JARs added so we can remove them from the list of JARs |
| // to be run through the metadata generator |
| } else if (file.getName().endsWith(".jar")) { |
| // figure out which IU corresponds to this JAR and remove it |
| } |
| seenFiles.remove(file); |
| return true; |
| } |
| |
| public boolean isInterested(File file) { |
| return file.getName().endsWith(".iu") || file.getName().endsWith(".jar"); |
| } |
| |
| private void initialize() { |
| toUninstall = new HashSet(3); |
| toUpdate = new HashSet(3); |
| toInstall = new HashSet(3); |
| toGenerate = new HashSet(3); |
| } |
| |
| public void startPoll() { |
| initialize(); |
| } |
| |
| public void stopPoll() { |
| processIUs(); |
| generate(); |
| // 1) add/remove/update all the IUs and artifacts in the repo as required |
| // 2) generate all the IUs we need to generate. Here we have to sort out which |
| // JARs are just JARs and which are artifacts that have associated IUs. Anything with |
| // an IU already does not need to be generated |
| // reconcile the lists to ensure that the JAR |
| // 3) construct the set of operations needed and call the engine |
| // 4) kick something if needed |
| initialize(); |
| } |
| |
| private IGeneratorInfo getProvider(File[] locations, File destination) { |
| EclipseInstallGeneratorInfoProvider provider = new EclipseInstallGeneratorInfoProvider(); |
| provider.initialize(null, null, null, locations, null); |
| try { |
| initializeMetadataRepository(provider, destination.toURL()); |
| initializeArtifactRepository(provider, destination.toURL()); |
| } catch (MalformedURLException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| provider.setPublishArtifactRepository(true); |
| provider.setPublishArtifacts(false); |
| provider.setMappingRules(INPLACE_MAPPING_RULES); |
| return provider; |
| } |
| |
| private void processIUs() { |
| } |
| |
| private void generate() { |
| File directory = watcher.getDirectory(); |
| IGeneratorInfo info = getProvider(new File[] {directory}, directory); |
| new Generator(info).generate(); |
| } |
| |
| public Long getSeenFile(File file) { |
| return (Long) seenFiles.get(file); |
| } |
| |
| private void initializeArtifactRepository(EclipseInstallGeneratorInfoProvider provider, URL location) { |
| IArtifactRepositoryManager manager = (IArtifactRepositoryManager) ServiceHelper.getService(Activator.getContext(), IArtifactRepositoryManager.class.getName()); |
| try { |
| IArtifactRepository repository = manager.loadRepository(location, null); |
| if (repository.isModifiable()) { |
| provider.setArtifactRepository(repository); |
| if (!provider.append()) |
| repository.removeAll(); |
| return; |
| } |
| throw new IllegalArgumentException("Artifact repository not writeable: " + location); //$NON-NLS-1$ |
| } catch (ProvisionException e) { |
| //fall through and create a new repository |
| } |
| String repositoryName = location + " - artifacts"; //$NON-NLS-1$ |
| try { |
| IArtifactRepository result = manager.createRepository(location, repositoryName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY); |
| provider.setArtifactRepository(result); |
| } catch (ProvisionException e) { |
| LogHelper.log(e); |
| } |
| } |
| |
| private void initializeMetadataRepository(EclipseInstallGeneratorInfoProvider provider, URL location) { |
| IMetadataRepositoryManager manager = (IMetadataRepositoryManager) ServiceHelper.getService(Activator.getContext(), IMetadataRepositoryManager.class.getName()); |
| try { |
| IMetadataRepository repository = manager.loadRepository(location, null); |
| if (repository != null) { |
| if (repository.isModifiable()) { |
| provider.setMetadataRepository(repository); |
| if (!provider.append()) |
| repository.removeAll(); |
| return; |
| } |
| throw new IllegalArgumentException("Metadata repository not writeable: " + location); //$NON-NLS-1$ |
| } |
| } catch (ProvisionException e) { |
| //fall through and create a new repository |
| } |
| try { |
| String repositoryName = location + " - metadata"; //$NON-NLS-1$ |
| IMetadataRepository repository = manager.createRepository(location, repositoryName, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY); |
| provider.setMetadataRepository(repository); |
| } catch (ProvisionException e) { |
| LogHelper.log(e); |
| } |
| } |
| |
| } |