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