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