1 package org
.argeo
.slc
.repo
.maven
;
3 import java
.io
.IOException
;
4 import java
.util
.ArrayList
;
5 import java
.util
.HashMap
;
8 import java
.util
.jar
.Attributes
.Name
;
9 import java
.util
.jar
.Manifest
;
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
;
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
;
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
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);
54 private Repository repository
;
55 private String sourceWorkspace
;
56 private String targetWorkspace
;
58 private List
<String
> excludedBundles
= new ArrayList
<String
>();
59 private Map
<String
, String
> symbolicNamesMapping
= new HashMap
<String
, String
>();
61 private Session origSession
;
62 private Session targetSession
;
64 private List
<String
> systemPackages
= OsgiProfile
.PROFILE_JAVA_SE_1_6
67 private String artifactBasePath
= "/";
69 private ArtifactIndexer artifactIndexer
= new ArtifactIndexer();
70 private JarFileIndexer jarFileIndexer
= new JarFileIndexer();
72 public void init() throws RepositoryException
{
73 origSession
= JcrUtils
.loginOrCreateWorkspace(repository
,
75 targetSession
= JcrUtils
.loginOrCreateWorkspace(repository
,
78 // works only in OSGi!!
79 // systemPackages = Arrays.asList(System.getProperty(
80 // "org.osgi.framework.system.packages").split(","));
83 public void destroy() {
84 JcrUtils
.logoutQuietly(origSession
);
85 JcrUtils
.logoutQuietly(targetSession
);
92 NodeIterator nit
= targetSession
.getNode(artifactBasePath
)
94 while (nit
.hasNext()) {
95 Node node
= nit
.nextNode();
96 if (node
.isNodeType(NodeType
.NT_FOLDER
)
97 || node
.isNodeType(NodeType
.NT_UNSTRUCTURED
)) {
99 node
.getSession().save();
100 if (log
.isDebugEnabled())
101 log
.debug("Cleared " + node
);
105 NodeIterator origArtifacts
= listArtifactVersions(origSession
);
107 while (origArtifacts
.hasNext()) {
108 Node origArtifactNode
= origArtifacts
.nextNode();
109 if (log
.isTraceEnabled())
110 log
.trace(origArtifactNode
);
112 processOrigArtifactVersion(origArtifactNode
);
114 } catch (Exception e
) {
115 throw new SlcException("Cannot perform v1.3 migration from "
116 + sourceWorkspace
+ " to " + targetWorkspace
, e
);
118 JcrUtils
.discardQuietly(targetSession
);
122 protected void processOrigArtifactVersion(Node origArtifactNode
)
123 throws RepositoryException
, IOException
{
124 Artifact origArtifact
= RepoUtils
.asArtifact(origArtifactNode
);
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
);
138 // skip SpringSource ActiveMQ
139 if (origArtifact
.getArtifactId().startsWith(
140 "com.springsource.org.apache.activemq"))
143 String origJarNodeName
= MavenConventionsUtils
144 .artifactFileName(origArtifact
);
145 if (!origArtifactNode
.hasNode(origJarNodeName
))
146 throw new SlcException("Cannot find jar node for "
148 Node origJarNode
= origArtifactNode
.getNode(origJarNodeName
);
151 Binary manifestBinary
= origJarNode
.getProperty(SLC_MANIFEST
)
153 Manifest origManifest
= new Manifest(manifestBinary
.getStream());
154 JcrUtils
.closeQuietly(manifestBinary
);
156 Boolean manifestModified
= false;
157 Manifest targetManifest
= new Manifest(origManifest
);
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);
170 targetSymbolicName
= origSymbolicName
;
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
);
182 // skip excluded bundles
183 if (excludedBundles
.contains(targetSymbolicName
))
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)\"";
203 targetFragmentHost
= origFragmentHost
;
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
);
216 // we assume there is no Require-Bundle in com.springsource.* bundles
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
)
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 "
242 if (targetVersion
!= null)
243 targetImportPackages
.append(";version=\"")
244 .append(targetVersion
).append("\"");
246 if (importPackage
.hasProperty(SLC_OPTIONAL
)) {
247 Boolean optional
= importPackage
.getProperty(SLC_OPTIONAL
)
250 targetImportPackages
.append(";resolution:=\"optional\"");
253 if (origImportPackages
.hasNext())
254 targetImportPackages
.append(",");
257 if (importPackagesModified
) {
258 targetManifest
.getMainAttributes().putValue(
259 Constants
.IMPORT_PACKAGE
, targetImportPackages
.toString());
260 manifestModified
= true;
263 if (!manifestModified
&& log
.isTraceEnabled()) {
264 log
.trace("MANIFEST of " + origSymbolicName
+ " was not modified");
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
278 // "org.argeo.tp.eclipse";
280 targetGroupId
= "org.argeo.tp";
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
;
292 Node targetParentNode
= JcrUtils
.mkfolders(targetSession
,
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
,
302 JcrUtils
.closeQuietly(origBinary
);
304 targetSession
.getWorkspace().copy(sourceWorkspace
,
305 origJarNode
.getPath(), targetJarPath
);
307 targetSession
.save();
310 Node targetJarNode
= targetSession
.getNode(targetJarPath
);
311 artifactIndexer
.index(targetJarNode
);
312 jarFileIndexer
.index(targetJarNode
);
314 targetSession
.save();
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
);
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
;
335 Node targetSourceParentNode
= JcrUtils
.mkfolders(targetSession
,
336 targetSourceParentPath
);
337 targetSession
.save();
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
);
350 targetSession
.getWorkspace().copy(sourceWorkspace
,
351 origSourceJarNode
.getPath(), targetSourceJarPath
);
353 targetSession
.save();
356 Node targetSourceJarNode
= targetSession
357 .getNode(targetSourceJarPath
);
358 artifactIndexer
.index(targetSourceJarNode
);
359 jarFileIndexer
.index(targetSourceJarNode
);
361 targetSession
.save();
369 static NodeIterator
listArtifactVersions(Session session
)
370 throws RepositoryException
{
371 QueryManager queryManager
= session
.getWorkspace().getQueryManager();
372 QueryObjectModelFactory factory
= queryManager
.getQOMFactory();
374 final String artifactVersionsSelector
= "artifactVersions";
375 Selector source
= factory
.selector(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
,
376 artifactVersionsSelector
);
378 Ordering orderByArtifactId
= factory
.ascending(factory
.propertyValue(
379 artifactVersionsSelector
, SlcNames
.SLC_ARTIFACT_ID
));
380 Ordering
[] orderings
= { orderByArtifactId
};
382 QueryObjectModel query
= factory
.createQuery(source
, null, orderings
,
385 QueryResult result
= query
.execute();
386 return result
.getNodes();
389 public void setRepository(Repository repository
) {
390 this.repository
= repository
;
393 public void setSourceWorkspace(String sourceWorkspace
) {
394 this.sourceWorkspace
= sourceWorkspace
;
397 public void setTargetWorkspace(String targetWorkspace
) {
398 this.targetWorkspace
= targetWorkspace
;
401 public void setExcludedBundles(List
<String
> excludedBundles
) {
402 this.excludedBundles
= excludedBundles
;
405 public void setSymbolicNamesMapping(Map
<String
, String
> symbolicNamesMapping
) {
406 this.symbolicNamesMapping
= symbolicNamesMapping
;