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