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