]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/commands/NormalizeDistribution.java
Fix licence management
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui.dist / src / main / java / org / argeo / slc / client / ui / dist / commands / NormalizeDistribution.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 package org.argeo.slc.client.ui.dist.commands;
17
18 import javax.jcr.Binary;
19 import javax.jcr.Credentials;
20 import javax.jcr.Node;
21 import javax.jcr.NodeIterator;
22 import javax.jcr.Property;
23 import javax.jcr.Repository;
24 import javax.jcr.RepositoryException;
25 import javax.jcr.RepositoryFactory;
26 import javax.jcr.Session;
27 import javax.jcr.nodetype.NodeType;
28 import javax.jcr.query.Query;
29 import javax.jcr.query.QueryResult;
30 import javax.jcr.util.TraversingItemVisitor;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.argeo.ArgeoMonitor;
35 import org.argeo.eclipse.ui.EclipseArgeoMonitor;
36 import org.argeo.jcr.JcrUtils;
37 import org.argeo.slc.NameVersion;
38 import org.argeo.slc.SlcException;
39 import org.argeo.slc.aether.AetherUtils;
40 import org.argeo.slc.client.ui.dist.DistPlugin;
41 import org.argeo.slc.jcr.SlcNames;
42 import org.argeo.slc.jcr.SlcTypes;
43 import org.argeo.slc.repo.ArtifactIndexer;
44 import org.argeo.slc.repo.JarFileIndexer;
45 import org.argeo.slc.repo.RepoConstants;
46 import org.argeo.slc.repo.RepoUtils;
47 import org.argeo.slc.repo.maven.MavenConventionsUtils;
48 import org.argeo.slc.repo.osgi.NormalizeGroup;
49 import org.argeo.util.security.Keyring;
50 import org.eclipse.core.commands.AbstractHandler;
51 import org.eclipse.core.commands.ExecutionEvent;
52 import org.eclipse.core.commands.ExecutionException;
53 import org.eclipse.core.runtime.IProgressMonitor;
54 import org.eclipse.core.runtime.IStatus;
55 import org.eclipse.core.runtime.Status;
56 import org.eclipse.core.runtime.jobs.Job;
57 import org.eclipse.jface.dialogs.Dialog;
58 import org.eclipse.jface.dialogs.IMessageProvider;
59 import org.eclipse.jface.dialogs.TitleAreaDialog;
60 import org.eclipse.jface.resource.ImageDescriptor;
61 import org.eclipse.swt.SWT;
62 import org.eclipse.swt.graphics.Point;
63 import org.eclipse.swt.layout.GridData;
64 import org.eclipse.swt.layout.GridLayout;
65 import org.eclipse.swt.widgets.Button;
66 import org.eclipse.swt.widgets.Composite;
67 import org.eclipse.swt.widgets.Control;
68 import org.eclipse.swt.widgets.Label;
69 import org.eclipse.swt.widgets.Shell;
70 import org.eclipse.swt.widgets.Text;
71 import org.eclipse.ui.handlers.HandlerUtil;
72 import org.sonatype.aether.artifact.Artifact;
73 import org.sonatype.aether.util.artifact.DefaultArtifact;
74
75 /** Legacy - Make sure than Maven and OSGi metadata are consistent */
76 public class NormalizeDistribution extends AbstractHandler implements SlcNames {
77 private final static Log log = LogFactory
78 .getLog(NormalizeDistribution.class);
79
80 public final static String ID = DistPlugin.ID + ".normalizeDistribution";
81 public final static String DEFAULT_LABEL = "Legacy Normalization...";
82 public final static ImageDescriptor DEFAULT_ICON = DistPlugin
83 .getImageDescriptor("icons/normalize.gif");
84
85 public final static String PARAM_WORKSPACE_NAME = "workspaceName";
86 public final static String PARAM_TARGET_REPO_PATH = "targetRepoPath";
87
88 private String artifactBasePath = RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH;
89
90 private ArtifactIndexer artifactIndexer = new ArtifactIndexer();
91 private JarFileIndexer jarFileIndexer = new JarFileIndexer();
92
93 // DEPENDENCY INJECTION
94 private RepositoryFactory repositoryFactory;
95 private Keyring keyring;
96 private Repository nodeRepository;
97
98 public Object execute(ExecutionEvent event) throws ExecutionException {
99
100 String targetRepoPath = event.getParameter(PARAM_TARGET_REPO_PATH);
101 String wkspName = event.getParameter(PARAM_WORKSPACE_NAME);
102
103 Session nodeSession = null;
104 NormalizeJob job;
105 try {
106
107 NormalizationDialog dialog = new NormalizationDialog(
108 HandlerUtil.getActiveShell(event));
109 if (dialog.open() != Dialog.OK)
110 return null;
111
112 nodeSession = nodeRepository.login();
113 Node repoNode = nodeSession.getNode(targetRepoPath);
114 Repository repository = RepoUtils.getRepository(repositoryFactory,
115 keyring, repoNode);
116 Credentials credentials = RepoUtils.getRepositoryCredentials(
117 keyring, repoNode);
118
119 String version = dialog.getVersion();
120 Boolean overridePoms = dialog.getOverridePoms();
121
122 job = new NormalizeJob(repository.login(credentials, wkspName),
123 version, overridePoms);
124 job.setUser(true);
125 job.schedule();
126 } catch (RepositoryException e) {
127 throw new SlcException("Cannot normalize " + wkspName, e);
128 } finally {
129 JcrUtils.logoutQuietly(nodeSession);
130 }
131 return null;
132 }
133
134 protected void packageSourcesAsPdeSource(Node sourcesNode) {
135 Binary origBinary = null;
136 Binary osgiBinary = null;
137 try {
138 Session session = sourcesNode.getSession();
139 Artifact sourcesArtifact = AetherUtils.convertPathToArtifact(
140 sourcesNode.getPath(), null);
141
142 // read name version from manifest
143 Artifact osgiArtifact = new DefaultArtifact(
144 sourcesArtifact.getGroupId(),
145 sourcesArtifact.getArtifactId(),
146 sourcesArtifact.getExtension(),
147 sourcesArtifact.getVersion());
148 String osgiPath = MavenConventionsUtils.artifactPath(
149 artifactBasePath, osgiArtifact);
150 osgiBinary = session.getNode(osgiPath).getNode(Node.JCR_CONTENT)
151 .getProperty(Property.JCR_DATA).getBinary();
152
153 NameVersion nameVersion = RepoUtils.readNameVersion(osgiBinary
154 .getStream());
155
156 // create PDe sources artifact
157 Artifact pdeSourceArtifact = new DefaultArtifact(
158 sourcesArtifact.getGroupId(),
159 sourcesArtifact.getArtifactId() + ".source",
160 sourcesArtifact.getExtension(),
161 sourcesArtifact.getVersion());
162 String targetSourceParentPath = MavenConventionsUtils
163 .artifactParentPath(artifactBasePath, pdeSourceArtifact);
164 String targetSourceFileName = MavenConventionsUtils
165 .artifactFileName(pdeSourceArtifact);
166 String targetSourceJarPath = targetSourceParentPath + '/'
167 + targetSourceFileName;
168
169 Node targetSourceParentNode = JcrUtils.mkfolders(session,
170 targetSourceParentPath);
171 origBinary = sourcesNode.getNode(Node.JCR_CONTENT)
172 .getProperty(Property.JCR_DATA).getBinary();
173 byte[] targetJarBytes = RepoUtils.packageAsPdeSource(
174 origBinary.getStream(), nameVersion);
175 JcrUtils.copyBytesAsFile(targetSourceParentNode,
176 targetSourceFileName, targetJarBytes);
177
178 // reindex
179 Node targetSourceJarNode = session.getNode(targetSourceJarPath);
180 artifactIndexer.index(targetSourceJarNode);
181 jarFileIndexer.index(targetSourceJarNode);
182 } catch (RepositoryException e) {
183 throw new SlcException("Cannot add PDE sources for " + sourcesNode,
184 e);
185 } finally {
186 JcrUtils.closeQuietly(origBinary);
187 JcrUtils.closeQuietly(osgiBinary);
188 }
189
190 }
191
192 private class NormalizeJob extends Job {
193 private Session session;
194 private String version;
195 private Boolean overridePoms;
196
197 public NormalizeJob(Session session, String version,
198 Boolean overridePoms) {
199 super("Normalize Distribution");
200 this.session = session;
201 this.version = version;
202 this.overridePoms = overridePoms;
203 }
204
205 @Override
206 protected IStatus run(IProgressMonitor progressMonitor) {
207
208 try {
209 ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
210 // normalize artifacts
211 Query countQuery = session
212 .getWorkspace()
213 .getQueryManager()
214 .createQuery("select file from [nt:file] as file",
215 Query.JCR_SQL2);
216 QueryResult result = countQuery.execute();
217 Long expectedCount = result.getNodes().getSize();
218 monitor.beginTask("Normalize artifacts of "
219 + session.getWorkspace().getName(),
220 expectedCount.intValue());
221 NormalizingTraverser tiv = new NormalizingTraverser(monitor);
222 session.getNode(artifactBasePath).accept(tiv);
223
224 // normalize groups
225 Query groupQuery = session
226 .getWorkspace()
227 .getQueryManager()
228 .createQuery(
229 "select group from [" + SlcTypes.SLC_GROUP_BASE
230 + "] as group", Query.JCR_SQL2);
231 NodeIterator groups = groupQuery.execute().getNodes();
232 monitor.beginTask("Normalize groups of "
233 + session.getWorkspace().getName(),
234 (int) groups.getSize());
235 while (groups.hasNext()) {
236 NormalizeGroup.processGroupNode(groups.nextNode(), version,
237 overridePoms, monitor);
238 }
239 } catch (Exception e) {
240 return new Status(IStatus.ERROR, DistPlugin.ID,
241 "Cannot normalize distribution "
242 + session.getWorkspace().getName(), e);
243 } finally {
244 JcrUtils.logoutQuietly(session);
245 }
246 return Status.OK_STATUS;
247 }
248
249 }
250
251 private class NormalizingTraverser extends TraversingItemVisitor {
252 ArgeoMonitor monitor;
253
254 public NormalizingTraverser(ArgeoMonitor monitor) {
255 super();
256 this.monitor = monitor;
257 }
258
259 @Override
260 protected void entering(Property property, int level)
261 throws RepositoryException {
262 }
263
264 @Override
265 protected void entering(Node node, int level)
266 throws RepositoryException {
267 if (node.isNodeType(NodeType.NT_FILE)) {
268 if (node.getName().endsWith("-sources.jar")) {
269 monitor.subTask(node.getName());
270 packageSourcesAsPdeSource(node);
271 node.getSession().save();
272 monitor.worked(1);
273 if (log.isDebugEnabled())
274 log.debug("Processed source artifact " + node.getPath());
275 } else if (node.getName().endsWith(".jar")) {
276 if (jarFileIndexer.support(node.getPath()))
277 if (artifactIndexer.support(node.getPath())) {
278 monitor.subTask(node.getName());
279 artifactIndexer.index(node);
280 jarFileIndexer.index(node);
281 node.getSession().save();
282 monitor.worked(1);
283 if (log.isDebugEnabled())
284 log.debug("Processed artifact "
285 + node.getPath());
286 }
287 } else {
288 monitor.worked(1);
289 }
290 }
291 }
292
293 @Override
294 protected void leaving(Property property, int level)
295 throws RepositoryException {
296 }
297
298 @Override
299 protected void leaving(Node node, int level) throws RepositoryException {
300 }
301
302 }
303
304 public class NormalizationDialog extends TitleAreaDialog {
305 private Text versionT;
306 private String version;
307 private Button overridePomsC;
308 private Boolean overridePoms;
309
310 public NormalizationDialog(Shell parentShell) {
311 super(parentShell);
312 }
313
314 protected Point getInitialSize() {
315 return new Point(300, 250);
316 }
317
318 protected Control createDialogArea(Composite parent) {
319 Composite dialogarea = (Composite) super.createDialogArea(parent);
320 dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
321 true));
322 Composite composite = new Composite(dialogarea, SWT.NONE);
323 composite.setLayout(new GridLayout(2, false));
324 composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
325 false));
326 versionT = createLT(composite, "Version");
327 overridePomsC = createLC(composite, "Override POMs");
328 setMessage("Configure normalization", IMessageProvider.NONE);
329
330 parent.pack();
331 return composite;
332 }
333
334 @Override
335 protected void okPressed() {
336 version = versionT.getText();
337 overridePoms = overridePomsC.getSelection();
338 super.okPressed();
339 }
340
341 /** Creates label and text. */
342 protected Text createLT(Composite parent, String label) {
343 new Label(parent, SWT.NONE).setText(label);
344 Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER
345 | SWT.NONE);
346 text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
347 return text;
348 }
349
350 /** Creates label and check. */
351 protected Button createLC(Composite parent, String label) {
352 new Label(parent, SWT.NONE).setText(label);
353 Button check = new Button(parent, SWT.CHECK);
354 check.setSelection(false);
355 check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
356 return check;
357 }
358
359 protected void configureShell(Shell shell) {
360 super.configureShell(shell);
361 shell.setText("Normalize...");
362 }
363
364 public String getVersion() {
365 return version;
366 }
367
368 public Boolean getOverridePoms() {
369 return overridePoms;
370 }
371
372 }
373
374 /* DEPENDENCY INJECTION */
375 public void setNodeRepository(Repository nodeRepository) {
376 this.nodeRepository = nodeRepository;
377 }
378
379 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
380 this.repositoryFactory = repositoryFactory;
381 }
382
383 public void setKeyring(Keyring keyring) {
384 this.keyring = keyring;
385 }
386 }