Skip to main content
summaryrefslogtreecommitdiffstats
blob: fbd0cb0bf08eb938be5eb140029acdf82e0b056b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*******************************************************************************
 * Copyright (c) 2009, 2017 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
 *     Sonatype Inc - ongoing development
 *******************************************************************************/

package org.eclipse.equinox.p2.internal.repository.tools;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.repository.helpers.ChecksumProducer;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.IRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.*;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.spi.ProcessingStepDescriptor;
import org.eclipse.osgi.util.NLS;

public class RecreateRepositoryApplication extends AbstractApplication {
	static final private String PUBLISH_PACK_FILES_AS_SIBLINGS = "publishPackFilesAsSiblings"; //$NON-NLS-1$
	private RepositoryDescriptor descriptor;
	private String repoName = null;
	boolean removeArtifactRepo = true;
	private Map<String, String> repoProperties = null;
	private Map<IArtifactKey, IArtifactDescriptor[]> repoMap = null;

	public IStatus run(IProgressMonitor monitor) throws ProvisionException {
		try {
			IArtifactRepository repository = initialize(monitor);
			removeRepository(repository, monitor);
			recreateRepository(monitor);
		} finally {
			if (removeArtifactRepo) {
				IArtifactRepositoryManager repositoryManager = getArtifactRepositoryManager();
				repositoryManager.removeRepository(descriptor.getRepoLocation());
			}
		}

		return Status.OK_STATUS;
	}

	public void setArtifactRepository(RepositoryDescriptor descriptor) {
		this.descriptor = descriptor;
	}

	private IArtifactRepository initialize(IProgressMonitor monitor) throws ProvisionException {
		IArtifactRepositoryManager repositoryManager = getArtifactRepositoryManager();
		removeArtifactRepo = !repositoryManager.contains(descriptor.getRepoLocation());

		IArtifactRepository repository = repositoryManager.loadRepository(descriptor.getRepoLocation(), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, monitor);

		if (repository == null || !repository.isModifiable())
			throw new ProvisionException(NLS.bind(Messages.exception_destinationNotModifiable, repository.getLocation()));
		if (!(repository instanceof IFileArtifactRepository))
			throw new ProvisionException(NLS.bind(Messages.exception_notLocalFileRepo, repository.getLocation()));

		repoName = repository.getName();
		repoProperties = repository.getProperties();

		repoMap = new HashMap<IArtifactKey, IArtifactDescriptor[]>();
		IQueryResult<IArtifactKey> keys = repository.query(ArtifactKeyQuery.ALL_KEYS, null);
		for (Iterator<IArtifactKey> iterator = keys.iterator(); iterator.hasNext();) {
			IArtifactKey key = iterator.next();
			IArtifactDescriptor[] descriptors = repository.getArtifactDescriptors(key);
			repoMap.put(key, descriptors);
		}

		return repository;
	}

	private void removeRepository(IArtifactRepository repository, IProgressMonitor monitor) throws ProvisionException {
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
		manager.removeRepository(repository.getLocation());

		boolean compressed = Boolean.parseBoolean(repoProperties.get(IRepository.PROP_COMPRESSED));
		URI realLocation = SimpleArtifactRepository.getActualLocation(repository.getLocation(), compressed);
		File realFile = URIUtil.toFile(realLocation);
		if (!realFile.exists() || !realFile.delete())
			throw new ProvisionException(NLS.bind(Messages.exception_unableToRemoveRepo, realFile.toString()));
	}

	private void recreateRepository(IProgressMonitor monitor) throws ProvisionException {
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();

		//add pack200 mappings, the existing repoProperties is not modifiable 
		Map<String, String> newProperties = new HashMap<String, String>(repoProperties);
		newProperties.put(PUBLISH_PACK_FILES_AS_SIBLINGS, "true"); //$NON-NLS-1$
		IArtifactRepository repository = manager.createRepository(descriptor.getRepoLocation(), repoName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, newProperties);
		if (!(repository instanceof IFileArtifactRepository))
			throw new ProvisionException(NLS.bind(Messages.exception_notLocalFileRepo, repository.getLocation()));

		IFileArtifactRepository simple = (IFileArtifactRepository) repository;
		for (IArtifactKey key : repoMap.keySet()) {
			IArtifactDescriptor[] descriptors = repoMap.get(key);

			String unpackedSize = null;
			File packFile = null;
			Set<File> files = new HashSet<File>();
			for (IArtifactDescriptor descriptor : descriptors) {
				File artifactFile = simple.getArtifactFile(descriptor);
				files.add(artifactFile);

				String size = Long.toString(artifactFile.length());

				ArtifactDescriptor newDescriptor = new ArtifactDescriptor(descriptor);
				newDescriptor.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, size);
				newDescriptor.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, size);

				try {
					String md5 = ChecksumProducer.computeMD5(artifactFile);
					if (md5 != null)
						newDescriptor.setProperty(IArtifactDescriptor.DOWNLOAD_MD5, md5);
				} catch (IOException e) {
					// don't care if failed to compute checksum
					// TODO provide message?
					LogHelper.log(new Status(IStatus.WARNING, Activator.ID, "", e));
				}

				File temp = new File(artifactFile.getParentFile(), artifactFile.getName() + ".pack.gz"); //$NON-NLS-1$
				if (temp.exists()) {
					packFile = temp;
					unpackedSize = size;
				}

				repository.addDescriptor(newDescriptor, null);
			}
			if (packFile != null && !files.contains(packFile) && packFile.length() > 0) {
				ArtifactDescriptor packDescriptor = createPack200ArtifactDescriptor(key, packFile, unpackedSize);
				repository.addDescriptor(packDescriptor, null);
			}
		}
	}

	private ArtifactDescriptor createPack200ArtifactDescriptor(IArtifactKey key, File packFile, String installSize) {

		if (packFile != null && packFile.exists()) {
			ArtifactDescriptor result = new ArtifactDescriptor(key);
			result.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, installSize);
			result.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(packFile.length()));
			IProcessingStepDescriptor[] steps = new IProcessingStepDescriptor[] {new ProcessingStepDescriptor("org.eclipse.equinox.p2.processing.Pack200Unpacker", null, true)}; //$NON-NLS-1$
			result.setProcessingSteps(steps);
			result.setProperty(IArtifactDescriptor.FORMAT, IArtifactDescriptor.FORMAT_PACKED);
			return result;
		}
		return null;
	}
}

Back to the top