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