2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.repo
.maven
;
18 import java
.io
.IOException
;
19 import java
.util
.ArrayList
;
20 import java
.util
.HashMap
;
21 import java
.util
.List
;
23 import java
.util
.jar
.Attributes
.Name
;
24 import java
.util
.jar
.Manifest
;
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
;
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
.eclipse
.aether
.artifact
.Artifact
;
53 import org
.eclipse
.aether
.artifact
.DefaultArtifact
;
54 import org
.osgi
.framework
.Constants
;
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
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);
69 private Repository repository
;
70 private String sourceWorkspace
;
71 private String targetWorkspace
;
73 private List
<String
> excludedBundles
= new ArrayList
<String
>();
74 private Map
<String
, String
> symbolicNamesMapping
= new HashMap
<String
, String
>();
76 private Session origSession
;
77 private Session targetSession
;
79 private List
<String
> systemPackages
= OsgiProfile
.PROFILE_JAVA_SE_1_6
82 private String artifactBasePath
= "/";
84 private ArtifactIndexer artifactIndexer
= new ArtifactIndexer();
85 private JarFileIndexer jarFileIndexer
= new JarFileIndexer();
87 public void init() throws RepositoryException
{
88 origSession
= JcrUtils
.loginOrCreateWorkspace(repository
,
90 targetSession
= JcrUtils
.loginOrCreateWorkspace(repository
,
93 // works only in OSGi!!
94 // systemPackages = Arrays.asList(System.getProperty(
95 // "org.osgi.framework.system.packages").split(","));
98 public void destroy() {
99 JcrUtils
.logoutQuietly(origSession
);
100 JcrUtils
.logoutQuietly(targetSession
);
107 NodeIterator nit
= targetSession
.getNode(artifactBasePath
)
109 while (nit
.hasNext()) {
110 Node node
= nit
.nextNode();
111 if (node
.isNodeType(NodeType
.NT_FOLDER
)
112 || node
.isNodeType(NodeType
.NT_UNSTRUCTURED
)) {
114 node
.getSession().save();
115 if (log
.isDebugEnabled())
116 log
.debug("Cleared " + node
);
120 NodeIterator origArtifacts
= listArtifactVersions(origSession
);
122 while (origArtifacts
.hasNext()) {
123 Node origArtifactNode
= origArtifacts
.nextNode();
124 if (log
.isTraceEnabled())
125 log
.trace(origArtifactNode
);
127 processOrigArtifactVersion(origArtifactNode
);
129 } catch (Exception e
) {
130 throw new SlcException("Cannot perform v1.3 migration from "
131 + sourceWorkspace
+ " to " + targetWorkspace
, e
);
133 JcrUtils
.discardQuietly(targetSession
);
137 protected void processOrigArtifactVersion(Node origArtifactNode
)
138 throws RepositoryException
, IOException
{
139 Artifact origArtifact
= RepoUtils
.asArtifact(origArtifactNode
);
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
);
153 // skip SpringSource ActiveMQ
154 if (origArtifact
.getArtifactId().startsWith(
155 "com.springsource.org.apache.activemq"))
158 String origJarNodeName
= MavenConventionsUtils
159 .artifactFileName(origArtifact
);
160 if (!origArtifactNode
.hasNode(origJarNodeName
))
161 throw new SlcException("Cannot find jar node for "
163 Node origJarNode
= origArtifactNode
.getNode(origJarNodeName
);
166 Binary manifestBinary
= origJarNode
.getProperty(SLC_MANIFEST
)
168 Manifest origManifest
= new Manifest(manifestBinary
.getStream());
169 JcrUtils
.closeQuietly(manifestBinary
);
171 Boolean manifestModified
= false;
172 Manifest targetManifest
= new Manifest(origManifest
);
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);
185 targetSymbolicName
= origSymbolicName
;
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
);
197 // skip excluded bundles
198 if (excludedBundles
.contains(targetSymbolicName
))
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)\"";
218 targetFragmentHost
= origFragmentHost
;
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
);
231 // we assume there is no Require-Bundle in com.springsource.* bundles
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
)
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 "
257 if (targetVersion
!= null)
258 targetImportPackages
.append(";version=\"")
259 .append(targetVersion
).append("\"");
261 if (importPackage
.hasProperty(SLC_OPTIONAL
)) {
262 Boolean optional
= importPackage
.getProperty(SLC_OPTIONAL
)
265 targetImportPackages
.append(";resolution:=\"optional\"");
268 if (origImportPackages
.hasNext())
269 targetImportPackages
.append(",");
272 if (importPackagesModified
) {
273 targetManifest
.getMainAttributes().putValue(
274 Constants
.IMPORT_PACKAGE
, targetImportPackages
.toString());
275 manifestModified
= true;
278 if (!manifestModified
&& log
.isTraceEnabled()) {
279 log
.trace("MANIFEST of " + origSymbolicName
+ " was not modified");
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
293 // "org.argeo.tp.eclipse";
295 targetGroupId
= "org.argeo.tp";
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
;
307 Node targetParentNode
= JcrUtils
.mkfolders(targetSession
,
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
,
317 JcrUtils
.closeQuietly(origBinary
);
319 targetSession
.getWorkspace().copy(sourceWorkspace
,
320 origJarNode
.getPath(), targetJarPath
);
322 targetSession
.save();
325 Node targetJarNode
= targetSession
.getNode(targetJarPath
);
326 artifactIndexer
.index(targetJarNode
);
327 jarFileIndexer
.index(targetJarNode
);
329 targetSession
.save();
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
);
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
;
350 Node targetSourceParentNode
= JcrUtils
.mkfolders(targetSession
,
351 targetSourceParentPath
);
352 targetSession
.save();
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
);
365 targetSession
.getWorkspace().copy(sourceWorkspace
,
366 origSourceJarNode
.getPath(), targetSourceJarPath
);
368 targetSession
.save();
371 Node targetSourceJarNode
= targetSession
372 .getNode(targetSourceJarPath
);
373 artifactIndexer
.index(targetSourceJarNode
);
374 jarFileIndexer
.index(targetSourceJarNode
);
376 targetSession
.save();
384 static NodeIterator
listArtifactVersions(Session session
)
385 throws RepositoryException
{
386 QueryManager queryManager
= session
.getWorkspace().getQueryManager();
387 QueryObjectModelFactory factory
= queryManager
.getQOMFactory();
389 final String artifactVersionsSelector
= "artifactVersions";
390 Selector source
= factory
.selector(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
,
391 artifactVersionsSelector
);
393 Ordering orderByArtifactId
= factory
.ascending(factory
.propertyValue(
394 artifactVersionsSelector
, SlcNames
.SLC_ARTIFACT_ID
));
395 Ordering
[] orderings
= { orderByArtifactId
};
397 QueryObjectModel query
= factory
.createQuery(source
, null, orderings
,
400 QueryResult result
= query
.execute();
401 return result
.getNodes();
404 public void setRepository(Repository repository
) {
405 this.repository
= repository
;
408 public void setSourceWorkspace(String sourceWorkspace
) {
409 this.sourceWorkspace
= sourceWorkspace
;
412 public void setTargetWorkspace(String targetWorkspace
) {
413 this.targetWorkspace
= targetWorkspace
;
416 public void setExcludedBundles(List
<String
> excludedBundles
) {
417 this.excludedBundles
= excludedBundles
;
420 public void setSymbolicNamesMapping(Map
<String
, String
> symbolicNamesMapping
) {
421 this.symbolicNamesMapping
= symbolicNamesMapping
;