Lines 1-235
Link Here
|
1 |
/******************************************************************************* |
|
|
2 |
* Copyright (c) 2010 EclipseSource Inc. and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/epl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* EclipseSource Inc. - initial API and implementation |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.pde.internal.ui.wizards.exports; |
12 |
|
13 |
import java.net.URI; |
14 |
import java.util.*; |
15 |
import org.eclipse.core.filesystem.*; |
16 |
import org.eclipse.core.runtime.*; |
17 |
import org.eclipse.core.runtime.jobs.Job; |
18 |
import org.eclipse.equinox.p2.internal.repository.tools.Repo2Runnable; |
19 |
import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; |
20 |
import org.eclipse.equinox.p2.metadata.IInstallableUnit; |
21 |
import org.eclipse.equinox.p2.metadata.IProvidedCapability; |
22 |
import org.eclipse.equinox.p2.query.IQueryResult; |
23 |
import org.eclipse.pde.internal.core.feature.ExternalFeatureModel; |
24 |
import org.eclipse.pde.internal.core.ifeature.IFeatureModel; |
25 |
import org.eclipse.pde.internal.core.target.IUBundleContainer; |
26 |
import org.eclipse.pde.internal.core.target.P2TargetUtils; |
27 |
import org.eclipse.pde.internal.core.target.provisional.*; |
28 |
import org.eclipse.pde.internal.ui.PDEPlugin; |
29 |
import org.eclipse.pde.internal.ui.PDEUIMessages; |
30 |
|
31 |
/** |
32 |
* This job exports the bundles and features that make up your target. |
33 |
*/ |
34 |
public class ExportTargetJob extends Job { |
35 |
|
36 |
private URI fDestination; |
37 |
private boolean fclearDestinationDirectory = true; |
38 |
private IFileStore featureDir; |
39 |
private IFileStore pluginDir; |
40 |
private IFileSystem fileSystem; |
41 |
private Map filter; |
42 |
private ITargetDefinition fTarget; |
43 |
|
44 |
public ExportTargetJob(ITargetDefinition target, URI destination, boolean clearDestinationDirectory) { |
45 |
super("Export Current Target Definition Job"); //$NON-NLS-1$ |
46 |
fTarget = target; |
47 |
fDestination = destination; |
48 |
fclearDestinationDirectory = clearDestinationDirectory; |
49 |
} |
50 |
|
51 |
protected IStatus run(IProgressMonitor monitor) { |
52 |
try { |
53 |
constructFilter(fTarget); |
54 |
IBundleContainer[] containers = fTarget.getBundleContainers(); |
55 |
int totalWork = containers.length; |
56 |
monitor.beginTask(PDEUIMessages.ExportTargetDefinition_task, totalWork); |
57 |
|
58 |
monitor.subTask(PDEUIMessages.ExportTargetJob_ConfiguringDestination); |
59 |
setupDestination(monitor); |
60 |
|
61 |
monitor.subTask(PDEUIMessages.ExportTargetJob_ExportingTargetContents); |
62 |
for (int i = 0; i < containers.length; i++) { |
63 |
IBundleContainer container = containers[i]; |
64 |
container.resolve(fTarget, monitor); |
65 |
if (!(container instanceof IUBundleContainer)) |
66 |
exportContainer(container, fTarget, featureDir, pluginDir, fileSystem, monitor); |
67 |
} |
68 |
exportProfile(fTarget, fDestination, monitor); |
69 |
} catch (CoreException e) { |
70 |
return new Status(IStatus.ERROR, PDEPlugin.getPluginId(), "Failed to export the target", e); //$NON-NLS-1$ |
71 |
} finally { |
72 |
monitor.done(); |
73 |
} |
74 |
return Status.OK_STATUS; |
75 |
} |
76 |
|
77 |
private void constructFilter(ITargetDefinition target) { |
78 |
NameVersionDescriptor[] included = target.getIncluded(); |
79 |
if (included == null) |
80 |
return; |
81 |
filter = new HashMap(); |
82 |
for (int i = 0; i < included.length; i++) { |
83 |
NameVersionDescriptor inclusion = included[i]; |
84 |
NameVersionDescriptor[] versions = (NameVersionDescriptor[]) filter.get(inclusion.getId()); |
85 |
if (versions == null) |
86 |
filter.put(inclusion.getId(), new NameVersionDescriptor[] {inclusion}); |
87 |
else { |
88 |
NameVersionDescriptor[] versions2 = new NameVersionDescriptor[versions.length + 1]; |
89 |
System.arraycopy(versions, 0, versions2, 0, versions.length); |
90 |
versions2[versions.length] = inclusion; |
91 |
filter.put(inclusion.getId(), versions2); |
92 |
} |
93 |
} |
94 |
} |
95 |
|
96 |
private void setupDestination(IProgressMonitor monitor) throws CoreException { |
97 |
fileSystem = EFS.getLocalFileSystem(); |
98 |
if (!fileSystem.canWrite()) { |
99 |
throw new CoreException(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), "Destination directory not writable.")); //$NON-NLS-1$ |
100 |
} |
101 |
IFileStore destination = fileSystem.getStore(fDestination); |
102 |
featureDir = destination.getChild("features"); //$NON-NLS-1$ |
103 |
pluginDir = destination.getChild("plugins"); //$NON-NLS-1$ |
104 |
if (fclearDestinationDirectory) { |
105 |
monitor.subTask(PDEUIMessages.ExportTargetDeleteOldData); //Deleting old data... |
106 |
featureDir.delete(EFS.NONE, null); |
107 |
pluginDir.delete(EFS.NONE, null); |
108 |
} |
109 |
featureDir.mkdir(EFS.NONE, null); |
110 |
pluginDir.mkdir(EFS.NONE, null); |
111 |
} |
112 |
|
113 |
private boolean shouldExport(NameVersionDescriptor descriptor) { |
114 |
// currently PDE does not selectively include/exclude features |
115 |
if (filter == null || descriptor.getType().equals(NameVersionDescriptor.TYPE_FEATURE)) |
116 |
return true; |
117 |
NameVersionDescriptor[] versions = (NameVersionDescriptor[]) filter.get(descriptor.getId()); |
118 |
if (versions == null) |
119 |
return false; |
120 |
for (int i = 0; i < versions.length; i++) { |
121 |
String version = versions[i].getVersion(); |
122 |
if ((version == null || version.equals(descriptor.getVersion())) && descriptor.getType().equals(versions[i].getType())) |
123 |
return true; |
124 |
} |
125 |
return false; |
126 |
} |
127 |
|
128 |
private boolean shouldExport(IFeatureModel feature) { |
129 |
if (filter == null) |
130 |
return true; |
131 |
if (!feature.isEnabled() || !(feature instanceof ExternalFeatureModel)) |
132 |
return false; |
133 |
NameVersionDescriptor descriptor = new NameVersionDescriptor(feature.getFeature().getId(), feature.getFeature().getVersion(), NameVersionDescriptor.TYPE_FEATURE); |
134 |
return shouldExport(descriptor); |
135 |
} |
136 |
|
137 |
private boolean shouldExport(IResolvedBundle bundle) { |
138 |
if (filter == null) |
139 |
return true; |
140 |
NameVersionDescriptor descriptor = new NameVersionDescriptor(bundle.getBundleInfo().getSymbolicName(), bundle.getBundleInfo().getVersion(), NameVersionDescriptor.TYPE_PLUGIN); |
141 |
return shouldExport(descriptor); |
142 |
} |
143 |
|
144 |
private boolean shouldExport(IInstallableUnit iu) { |
145 |
if (filter == null) |
146 |
return true; |
147 |
NameVersionDescriptor descriptor = null; |
148 |
String feature = getCapability(iu, "org.eclipse.update.feature"); //$NON-NLS-1$ |
149 |
if (feature != null) { |
150 |
descriptor = new NameVersionDescriptor(feature, iu.getVersion().toString(), NameVersionDescriptor.TYPE_FEATURE); |
151 |
} else if (iu.getId().endsWith(".feature.group")) { //$NON-NLS-1$ |
152 |
descriptor = new NameVersionDescriptor(iu.getId(), iu.getVersion().toString(), NameVersionDescriptor.TYPE_FEATURE); |
153 |
} else if ("bundle".equalsIgnoreCase(getCapability(iu, "org.eclipse.equinox.p2.eclipse.type"))) { //$NON-NLS-1$ //$NON-NLS-2$ |
154 |
descriptor = new NameVersionDescriptor(iu.getId(), iu.getVersion().toString(), NameVersionDescriptor.TYPE_PLUGIN); |
155 |
} else if ("source".equalsIgnoreCase(getCapability(iu, "org.eclipse.equinox.p2.eclipse.type"))) { //$NON-NLS-1$ //$NON-NLS-2$ |
156 |
descriptor = new NameVersionDescriptor(iu.getId(), iu.getVersion().toString(), NameVersionDescriptor.TYPE_PLUGIN); |
157 |
} |
158 |
// default to true unless we know otherwise. This ensures that random metadata bits |
159 |
// are moved over to the target as they might be needed in a future provisioning operation. |
160 |
// We could move only unknown IUs that do NOT have artifacts... Have to think about that. |
161 |
return descriptor == null ? true : shouldExport(descriptor); |
162 |
} |
163 |
|
164 |
private String getCapability(IInstallableUnit iu, String namespace) { |
165 |
for (Iterator i = iu.getProvidedCapabilities().iterator(); i.hasNext();) { |
166 |
IProvidedCapability capability = (IProvidedCapability) i.next(); |
167 |
if (capability.getNamespace().equals(namespace)) |
168 |
return capability.getName(); |
169 |
} |
170 |
return null; |
171 |
} |
172 |
|
173 |
private void exportContainer(IBundleContainer container, ITargetDefinition target, IFileStore featureDir, IFileStore pluginDir, IFileSystem fileSystem, IProgressMonitor monitor) throws CoreException { |
174 |
IFeatureModel[] features = container.getFeatures(); |
175 |
if (features != null) { |
176 |
monitor.subTask(PDEUIMessages.ExportTargetExportFeatures); |
177 |
for (int i = 0; i < features.length; i++) { |
178 |
if (shouldExport(features[i])) |
179 |
copy(features[i].getInstallLocation(), featureDir, fileSystem, monitor); |
180 |
} |
181 |
} |
182 |
|
183 |
IResolvedBundle[] bundles = container.getBundles(); |
184 |
if (bundles != null) { |
185 |
monitor.subTask(PDEUIMessages.ExportTargetExportPlugins); |
186 |
for (int i = 0; i < bundles.length; i++) { |
187 |
if (shouldExport(bundles[i])) |
188 |
copy(bundles[i].getBundleInfo().getLocation().getPath(), pluginDir, fileSystem, monitor); |
189 |
} |
190 |
} |
191 |
} |
192 |
|
193 |
private IStatus copy(String src, IFileStore destinationParent, IFileSystem fileSystem, IProgressMonitor monitor) throws CoreException { |
194 |
Path srcPath = new Path(src); |
195 |
IFileStore source = fileSystem.getStore(srcPath); |
196 |
String elementName = srcPath.segment(srcPath.segmentCount() - 1); |
197 |
IFileStore destination = destinationParent.getChild(elementName); |
198 |
if (destination.fetchInfo().exists()) { |
199 |
monitor.worked(1); |
200 |
return Status.OK_STATUS; |
201 |
} |
202 |
if (source.fetchInfo().isDirectory()) { |
203 |
destination.mkdir(EFS.NONE, new NullProgressMonitor()); |
204 |
} |
205 |
source.copy(destination, EFS.OVERWRITE, new SubProgressMonitor(monitor, 1)); |
206 |
return Status.OK_STATUS; |
207 |
} |
208 |
|
209 |
private RepositoryDescriptor createRepoDescriptor(URI location, String name, String kind) { |
210 |
RepositoryDescriptor result = new RepositoryDescriptor(); |
211 |
result.setLocation(location); |
212 |
result.setKind(kind); |
213 |
result.setName(name); |
214 |
if (fclearDestinationDirectory) |
215 |
result.setAppend(false); |
216 |
return result; |
217 |
} |
218 |
|
219 |
private void exportProfile(ITargetDefinition target, URI destination, IProgressMonitor monitor) throws CoreException { |
220 |
Repo2Runnable exporter = new Repo2Runnable(); |
221 |
exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_METADATA)); |
222 |
exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_ARTIFACT)); |
223 |
exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool().getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT)); |
224 |
|
225 |
IQueryResult ius = P2TargetUtils.getIUs(target, monitor); |
226 |
ArrayList toExport = new ArrayList(); |
227 |
for (Iterator i = ius.iterator(); i.hasNext();) { |
228 |
IInstallableUnit iu = (IInstallableUnit) i.next(); |
229 |
if (shouldExport(iu)) |
230 |
toExport.add(iu); |
231 |
} |
232 |
exporter.setSourceIUs(toExport); |
233 |
exporter.run(monitor); |
234 |
} |
235 |
} |