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