]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java
Generalize ArchiveWrapper and deprecates ImportBundlesZip
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / maven / Migration_01_03.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.repo.maven;
17
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.jar.Attributes.Name;
24 import java.util.jar.Manifest;
25
26 import javax.jcr.Binary;
27 import javax.jcr.Node;
28 import javax.jcr.NodeIterator;
29 import javax.jcr.Property;
30 import javax.jcr.Repository;
31 import javax.jcr.RepositoryException;
32 import javax.jcr.Session;
33 import javax.jcr.nodetype.NodeType;
34 import javax.jcr.query.QueryManager;
35 import javax.jcr.query.QueryResult;
36 import javax.jcr.query.qom.Ordering;
37 import javax.jcr.query.qom.QueryObjectModel;
38 import javax.jcr.query.qom.QueryObjectModelFactory;
39 import javax.jcr.query.qom.Selector;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.argeo.jcr.JcrUtils;
44 import org.argeo.slc.NameVersion;
45 import org.argeo.slc.SlcException;
46 import org.argeo.slc.jcr.SlcNames;
47 import org.argeo.slc.jcr.SlcTypes;
48 import org.argeo.slc.repo.ArtifactIndexer;
49 import org.argeo.slc.repo.JarFileIndexer;
50 import org.argeo.slc.repo.RepoUtils;
51 import org.argeo.slc.repo.osgi.OsgiProfile;
52 import org.osgi.framework.Constants;
53 import org.sonatype.aether.artifact.Artifact;
54 import org.sonatype.aether.util.artifact.DefaultArtifact;
55
56 /**
57 * Migrate the distribution from 1.2 to 1.4 by cleaning naming and dependencies.
58 * The dependency to the SpringSource Enterprise Bundle repository is removed as
59 * well as their naming conventions. All third party are move to org.argeo.tp
60 * group IDs. Maven dependency for Eclipse artifacts don't use version ranges
61 * anymore. Verison constraints on javax.* packages are removed (since they lead
62 * to "use package conflicts" when Eclipse and Spring Security are used
63 * together).
64 */
65 public class Migration_01_03 implements Runnable, SlcNames {
66 final String SPRING_SOURCE_PREFIX = "com.springsource";
67 private final static Log log = LogFactory.getLog(Migration_01_03.class);
68
69 private Repository repository;
70 private String sourceWorkspace;
71 private String targetWorkspace;
72
73 private List<String> excludedBundles = new ArrayList<String>();
74 private Map<String, String> symbolicNamesMapping = new HashMap<String, String>();
75
76 private Session origSession;
77 private Session targetSession;
78
79 private List<String> systemPackages = OsgiProfile.PROFILE_JAVA_SE_1_6
80 .getSystemPackages();
81
82 private String artifactBasePath = "/";
83
84 private ArtifactIndexer artifactIndexer = new ArtifactIndexer();
85 private JarFileIndexer jarFileIndexer = new JarFileIndexer();
86
87 public void init() throws RepositoryException {
88 origSession = JcrUtils.loginOrCreateWorkspace(repository,
89 sourceWorkspace);
90 targetSession = JcrUtils.loginOrCreateWorkspace(repository,
91 targetWorkspace);
92
93 // works only in OSGi!!
94 // systemPackages = Arrays.asList(System.getProperty(
95 // "org.osgi.framework.system.packages").split(","));
96 }
97
98 public void destroy() {
99 JcrUtils.logoutQuietly(origSession);
100 JcrUtils.logoutQuietly(targetSession);
101 }
102
103 public void run() {
104
105 try {
106 // clear target
107 NodeIterator nit = targetSession.getNode(artifactBasePath)
108 .getNodes();
109 while (nit.hasNext()) {
110 Node node = nit.nextNode();
111 if (node.isNodeType(NodeType.NT_FOLDER)
112 || node.isNodeType(NodeType.NT_UNSTRUCTURED)) {
113 node.remove();
114 node.getSession().save();
115 if (log.isDebugEnabled())
116 log.debug("Cleared " + node);
117 }
118 }
119
120 NodeIterator origArtifacts = listArtifactVersions(origSession);
121 // process
122 while (origArtifacts.hasNext()) {
123 Node origArtifactNode = origArtifacts.nextNode();
124 if (log.isTraceEnabled())
125 log.trace(origArtifactNode);
126
127 processOrigArtifactVersion(origArtifactNode);
128 }
129 } catch (Exception e) {
130 throw new SlcException("Cannot perform v1.3 migration from "
131 + sourceWorkspace + " to " + targetWorkspace, e);
132 } finally {
133 JcrUtils.discardQuietly(targetSession);
134 }
135 }
136
137 protected void processOrigArtifactVersion(Node origArtifactNode)
138 throws RepositoryException, IOException {
139 Artifact origArtifact = RepoUtils.asArtifact(origArtifactNode);
140
141 // skip eclipse artifacts
142 if ((origArtifact.getGroupId().startsWith("org.eclipse") && !(origArtifact
143 .getArtifactId().equals("org.eclipse.osgi")
144 || origArtifact.getArtifactId().equals(
145 "org.eclipse.osgi.source") || origArtifact
146 .getArtifactId().startsWith("org.eclipse.rwt.widgets.upload")))
147 || origArtifact.getArtifactId().startsWith("com.ibm.icu")) {
148 if (log.isDebugEnabled())
149 log.debug("Skip " + origArtifact);
150 return;
151 }
152
153 // skip SpringSource ActiveMQ
154 if (origArtifact.getArtifactId().startsWith(
155 "com.springsource.org.apache.activemq"))
156 return;
157
158 String origJarNodeName = MavenConventionsUtils
159 .artifactFileName(origArtifact);
160 if (!origArtifactNode.hasNode(origJarNodeName))
161 throw new SlcException("Cannot find jar node for "
162 + origArtifactNode);
163 Node origJarNode = origArtifactNode.getNode(origJarNodeName);
164
165 // read MANIFEST
166 Binary manifestBinary = origJarNode.getProperty(SLC_MANIFEST)
167 .getBinary();
168 Manifest origManifest = new Manifest(manifestBinary.getStream());
169 JcrUtils.closeQuietly(manifestBinary);
170
171 Boolean manifestModified = false;
172 Manifest targetManifest = new Manifest(origManifest);
173
174 // transform symbolic name
175 String origSymbolicName = origManifest.getMainAttributes().getValue(
176 Constants.BUNDLE_SYMBOLICNAME);
177 final String targetSymbolicName;
178 if (symbolicNamesMapping.containsKey(origSymbolicName)) {
179 targetSymbolicName = symbolicNamesMapping.get(origSymbolicName);
180 } else if (origSymbolicName.startsWith(SPRING_SOURCE_PREFIX)
181 && !origSymbolicName.equals(SPRING_SOURCE_PREFIX + ".json")) {
182 targetSymbolicName = origSymbolicName
183 .substring(SPRING_SOURCE_PREFIX.length() + 1);
184 } else {
185 targetSymbolicName = origSymbolicName;
186 }
187
188 if (!targetSymbolicName.equals(origSymbolicName)) {
189 targetManifest.getMainAttributes().putValue(
190 Constants.BUNDLE_SYMBOLICNAME, targetSymbolicName);
191 manifestModified = true;
192 if (log.isDebugEnabled())
193 log.debug(Constants.BUNDLE_SYMBOLICNAME + " to "
194 + targetSymbolicName + " \t\tfrom " + origSymbolicName);
195 }
196
197 // skip excluded bundles
198 if (excludedBundles.contains(targetSymbolicName))
199 return;
200
201 // check fragment host
202 if (origManifest.getMainAttributes().containsKey(
203 new Name(Constants.FRAGMENT_HOST))) {
204 String origFragmentHost = origManifest.getMainAttributes()
205 .getValue(Constants.FRAGMENT_HOST);
206 String targetFragmentHost;
207 if (symbolicNamesMapping.containsKey(origFragmentHost)) {
208 targetFragmentHost = symbolicNamesMapping.get(origFragmentHost);
209 } else if (origFragmentHost.startsWith(SPRING_SOURCE_PREFIX)
210 && !origFragmentHost.equals(SPRING_SOURCE_PREFIX + ".json")) {
211 targetFragmentHost = origFragmentHost
212 .substring(SPRING_SOURCE_PREFIX.length() + 1);
213 } else if (origFragmentHost
214 .equals("org.argeo.dep.jacob;bundle-version=\"[1.14.3,1.14.4)\"")) {
215 // this one for those who think I cannot be pragmatic - mbaudier
216 targetFragmentHost = "com.jacob;bundle-version=\"[1.14.3,1.14.4)\"";
217 } else {
218 targetFragmentHost = origFragmentHost;
219 }
220
221 if (!targetFragmentHost.equals(origFragmentHost)) {
222 targetManifest.getMainAttributes().putValue(
223 Constants.FRAGMENT_HOST, targetFragmentHost);
224 manifestModified = true;
225 if (log.isDebugEnabled())
226 log.debug(Constants.FRAGMENT_HOST + " to "
227 + targetFragmentHost + " from " + origFragmentHost);
228 }
229 }
230
231 // we assume there is no Require-Bundle in com.springsource.* bundles
232
233 // javax with versions
234 StringBuffer targetImportPackages = new StringBuffer("");
235 NodeIterator origImportPackages = origJarNode.getNodes(SLC_
236 + Constants.IMPORT_PACKAGE);
237 Boolean importPackagesModified = false;
238 while (origImportPackages.hasNext()) {
239 Node importPackage = origImportPackages.nextNode();
240 String pkg = importPackage.getProperty(SLC_NAME).getString();
241 targetImportPackages.append(pkg);
242 if (importPackage.hasProperty(SLC_VERSION)) {
243 String sourceVersion = importPackage.getProperty(SLC_VERSION)
244 .getString();
245 String targetVersion = sourceVersion;
246 if (systemPackages.contains(pkg)) {
247 if (!(sourceVersion.trim().equals("0") || sourceVersion
248 .trim().equals("0.0.0"))) {
249 targetVersion = null;
250 importPackagesModified = true;
251 if (log.isDebugEnabled())
252 log.debug(origSymbolicName
253 + ": Nullify version of " + pkg + " from "
254 + sourceVersion);
255 }
256 }
257 if (targetVersion != null)
258 targetImportPackages.append(";version=\"")
259 .append(targetVersion).append("\"");
260 }
261 if (importPackage.hasProperty(SLC_OPTIONAL)) {
262 Boolean optional = importPackage.getProperty(SLC_OPTIONAL)
263 .getBoolean();
264 if (optional)
265 targetImportPackages.append(";resolution:=\"optional\"");
266
267 }
268 if (origImportPackages.hasNext())
269 targetImportPackages.append(",");
270 }
271
272 if (importPackagesModified) {
273 targetManifest.getMainAttributes().putValue(
274 Constants.IMPORT_PACKAGE, targetImportPackages.toString());
275 manifestModified = true;
276 }
277
278 if (!manifestModified && log.isTraceEnabled()) {
279 log.trace("MANIFEST of " + origSymbolicName + " was not modified");
280 }
281
282 // target coordinates
283 final String targetGroupId;
284 if (origArtifact.getArtifactId().startsWith(
285 "org.eclipse.rwt.widgets.upload"))
286 targetGroupId = "org.argeo.tp.rap";
287 else if (origArtifact.getArtifactId().startsWith("org.polymap"))
288 targetGroupId = "org.argeo.tp.rap";
289 else if (origArtifact.getGroupId().startsWith("org.eclipse")
290 && !origArtifact.getArtifactId().equals("org.eclipse.osgi"))
291 throw new SlcException(origArtifact + " should have been excluded");// targetGroupId
292 // =
293 // "org.argeo.tp.eclipse";
294 else
295 targetGroupId = "org.argeo.tp";
296
297 String targetArtifactId = targetSymbolicName.split(";")[0];
298 Artifact targetArtifact = new DefaultArtifact(targetGroupId,
299 targetArtifactId, "jar", origArtifact.getVersion());
300 String targetParentPath = MavenConventionsUtils.artifactParentPath(
301 artifactBasePath, targetArtifact);
302 String targetFileName = MavenConventionsUtils
303 .artifactFileName(targetArtifact);
304 String targetJarPath = targetParentPath + '/' + targetFileName;
305
306 // copy
307 Node targetParentNode = JcrUtils.mkfolders(targetSession,
308 targetParentPath);
309 targetSession.save();
310 if (manifestModified) {
311 Binary origBinary = origJarNode.getNode(Node.JCR_CONTENT)
312 .getProperty(Property.JCR_DATA).getBinary();
313 byte[] targetJarBytes = RepoUtils.modifyManifest(
314 origBinary.getStream(), targetManifest);
315 JcrUtils.copyBytesAsFile(targetParentNode, targetFileName,
316 targetJarBytes);
317 JcrUtils.closeQuietly(origBinary);
318 } else {// just copy
319 targetSession.getWorkspace().copy(sourceWorkspace,
320 origJarNode.getPath(), targetJarPath);
321 }
322 targetSession.save();
323
324 // reindex
325 Node targetJarNode = targetSession.getNode(targetJarPath);
326 artifactIndexer.index(targetJarNode);
327 jarFileIndexer.index(targetJarNode);
328
329 targetSession.save();
330
331 // sources
332 Artifact origSourceArtifact = new DefaultArtifact(
333 origArtifact.getGroupId(), origArtifact.getArtifactId()
334 + ".source", "jar", origArtifact.getVersion());
335 String origSourcePath = MavenConventionsUtils.artifactPath(
336 artifactBasePath, origSourceArtifact);
337 if (origSession.itemExists(origSourcePath)) {
338 Node origSourceJarNode = origSession.getNode(origSourcePath);
339
340 Artifact targetSourceArtifact = new DefaultArtifact(targetGroupId,
341 targetArtifactId + ".source", "jar",
342 origArtifact.getVersion());
343 String targetSourceParentPath = MavenConventionsUtils
344 .artifactParentPath(artifactBasePath, targetSourceArtifact);
345 String targetSourceFileName = MavenConventionsUtils
346 .artifactFileName(targetSourceArtifact);
347 String targetSourceJarPath = targetSourceParentPath + '/'
348 + targetSourceFileName;
349
350 Node targetSourceParentNode = JcrUtils.mkfolders(targetSession,
351 targetSourceParentPath);
352 targetSession.save();
353
354 if (!targetSymbolicName.equals(origSymbolicName)) {
355 Binary origBinary = origSourceJarNode.getNode(Node.JCR_CONTENT)
356 .getProperty(Property.JCR_DATA).getBinary();
357 NameVersion targetNameVersion = RepoUtils
358 .readNameVersion(targetManifest);
359 byte[] targetJarBytes = RepoUtils.packageAsPdeSource(
360 origBinary.getStream(), targetNameVersion);
361 JcrUtils.copyBytesAsFile(targetSourceParentNode,
362 targetSourceFileName, targetJarBytes);
363 JcrUtils.closeQuietly(origBinary);
364 } else {// just copy
365 targetSession.getWorkspace().copy(sourceWorkspace,
366 origSourceJarNode.getPath(), targetSourceJarPath);
367 }
368 targetSession.save();
369
370 // reindex
371 Node targetSourceJarNode = targetSession
372 .getNode(targetSourceJarPath);
373 artifactIndexer.index(targetSourceJarNode);
374 jarFileIndexer.index(targetSourceJarNode);
375
376 targetSession.save();
377 }
378 }
379
380 /*
381 * UTILITIES
382 */
383
384 static NodeIterator listArtifactVersions(Session session)
385 throws RepositoryException {
386 QueryManager queryManager = session.getWorkspace().getQueryManager();
387 QueryObjectModelFactory factory = queryManager.getQOMFactory();
388
389 final String artifactVersionsSelector = "artifactVersions";
390 Selector source = factory.selector(SlcTypes.SLC_ARTIFACT_VERSION_BASE,
391 artifactVersionsSelector);
392
393 Ordering orderByArtifactId = factory.ascending(factory.propertyValue(
394 artifactVersionsSelector, SlcNames.SLC_ARTIFACT_ID));
395 Ordering[] orderings = { orderByArtifactId };
396
397 QueryObjectModel query = factory.createQuery(source, null, orderings,
398 null);
399
400 QueryResult result = query.execute();
401 return result.getNodes();
402 }
403
404 public void setRepository(Repository repository) {
405 this.repository = repository;
406 }
407
408 public void setSourceWorkspace(String sourceWorkspace) {
409 this.sourceWorkspace = sourceWorkspace;
410 }
411
412 public void setTargetWorkspace(String targetWorkspace) {
413 this.targetWorkspace = targetWorkspace;
414 }
415
416 public void setExcludedBundles(List<String> excludedBundles) {
417 this.excludedBundles = excludedBundles;
418 }
419
420 public void setSymbolicNamesMapping(Map<String, String> symbolicNamesMapping) {
421 this.symbolicNamesMapping = symbolicNamesMapping;
422 }
423
424 }