]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.client.ui.dist/src/org/argeo/slc/client/ui/dist/editors/BundleDetailPage.java
c73e16eb3d85860ab5564e2dd25a65fb12412b2a
[gpl/argeo-slc.git] / org.argeo.slc.client.ui.dist / src / org / argeo / slc / client / ui / dist / editors / BundleDetailPage.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.editors;
17
18 import java.net.URL;
19
20 import javax.jcr.Node;
21 import javax.jcr.RepositoryException;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.argeo.slc.SlcException;
26 import org.argeo.slc.build.License;
27 import org.argeo.slc.client.ui.dist.DistConstants;
28 import org.argeo.slc.client.ui.dist.utils.HyperlinkAdapter;
29 //import org.argeo.slc.client.ui.specific.OpenJcrFile;
30 //import org.argeo.slc.client.ui.specific.OpenJcrFileCmdId;
31 import org.argeo.slc.jcr.SlcNames;
32 import org.argeo.slc.repo.RepoConstants;
33 import org.argeo.slc.repo.RepoUtils;
34 import org.eclipse.jface.dialogs.IMessageProvider;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.layout.RowLayout;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Label;
41 import org.eclipse.swt.widgets.Text;
42 import org.eclipse.ui.PlatformUI;
43 import org.eclipse.ui.browser.IWebBrowser;
44 import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
45 import org.eclipse.ui.forms.IManagedForm;
46 import org.eclipse.ui.forms.editor.FormEditor;
47 import org.eclipse.ui.forms.editor.FormPage;
48 import org.eclipse.ui.forms.events.HyperlinkEvent;
49 import org.eclipse.ui.forms.widgets.FormToolkit;
50 import org.eclipse.ui.forms.widgets.Hyperlink;
51 import org.eclipse.ui.forms.widgets.ScrolledForm;
52 import org.eclipse.ui.forms.widgets.Section;
53
54 /** Show details for a given bundle. */
55 public class BundleDetailPage extends FormPage implements SlcNames {
56 private final static Log log = LogFactory.getLog(BundleDetailPage.class);
57
58 final static String PAGE_ID = "BundleDetailPage";
59
60 // Business Objects
61 private Node bundle;
62
63 // This page widgets
64 private FormToolkit tk;
65
66 public BundleDetailPage(FormEditor formEditor, String title, Node bundle) {
67 super(formEditor, PAGE_ID, title);
68 this.bundle = bundle;
69 }
70
71 @Override
72 protected void createFormContent(IManagedForm managedForm) {
73 // General settings for this page
74 ScrolledForm form = managedForm.getForm();
75 tk = managedForm.getToolkit();
76 Composite body = form.getBody();
77
78 GridLayout layout = new GridLayout(1, false);
79 layout.marginWidth = 5;
80 layout.marginRight = 15;
81 layout.verticalSpacing = 0;
82 body.setLayout(layout);
83 try {
84 form.setText(bundle.hasProperty(SlcNames.SLC_SYMBOLIC_NAME) ? bundle
85 .getProperty(SlcNames.SLC_SYMBOLIC_NAME).getString() : "");
86 form.setMessage(bundle
87 .hasProperty(DistConstants.SLC_BUNDLE_DESCRIPTION) ? bundle
88 .getProperty(DistConstants.SLC_BUNDLE_DESCRIPTION)
89 .getString() : "", IMessageProvider.NONE);
90 } catch (RepositoryException re) {
91 throw new SlcException("Unable to get bundle name for node "
92 + bundle, re);
93 }
94
95 // Main layout
96 Composite header = tk.createComposite(body);
97 header.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
98 populateHeaderPart(header);
99
100 Composite mavenSnipet = tk.createComposite(body);
101 mavenSnipet.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
102 populateMavenSnippetPart(mavenSnipet);
103 }
104
105 private void populateHeaderPart(Composite parent) {
106 GridLayout layout = new GridLayout(6, false);
107 // layout.marginWidth = layout.horizontalSpacing = layout.marginHeight =
108 // 0;
109 layout.horizontalSpacing = 10;
110 parent.setLayout(layout);
111 try {
112 // 1st Line: Category, name version
113 createLT(parent, "Category",
114 bundle.hasProperty(SlcNames.SLC_GROUP_ID) ? bundle
115 .getProperty(SlcNames.SLC_GROUP_ID).getString()
116 : "");
117 createLT(parent, "Name",
118 bundle.hasProperty(SlcNames.SLC_ARTIFACT_ID) ? bundle
119 .getProperty(SlcNames.SLC_ARTIFACT_ID).getString()
120 : "");
121 createLT(parent, "Version",
122 bundle.hasProperty(SlcNames.SLC_ARTIFACT_VERSION) ? bundle
123 .getProperty(SlcNames.SLC_ARTIFACT_VERSION)
124 .getString() : "");
125
126 // 3rd Line: Vendor, licence, sources
127 createLT(
128 parent,
129 "Vendor",
130 bundle.hasProperty(DistConstants.SLC_BUNDLE_VENDOR) ? bundle
131 .getProperty(DistConstants.SLC_BUNDLE_VENDOR)
132 .getString() : "N/A");
133
134 createLicencesLink(parent, "Licence",
135 DistConstants.SLC_BUNDLE_LICENCE);
136 addSourceLink(parent);
137
138 // 2nd Line: The Jar itself and the Manifest
139 createJarLink(parent);
140 createManifestLink(parent);
141
142 // Last line
143 createPomLink(parent);
144
145 } catch (RepositoryException re) {
146 throw new SlcException("Unable to get bundle name for node "
147 + bundle, re);
148 }
149
150 }
151
152 private void populateMavenSnippetPart(Composite parent) {
153 GridLayout layout = new GridLayout(1, false);
154 layout.marginWidth = layout.horizontalSpacing = layout.horizontalSpacing = layout.marginHeight = 0;
155 parent.setLayout(layout);
156
157 Section section = tk.createSection(parent, Section.TITLE_BAR
158 | Section.DESCRIPTION);
159 section.setText("Maven");
160 section.setDescription("Add the below tag to your Artifact pom dependencies");
161 section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
162 Text snippetTxt = createMavenSnippet(section);
163 section.setClient(snippetTxt);
164 }
165
166 // /////////////////////
167 // HELPERS
168
169 private Text createLT(Composite parent, String labelValue, String textValue) {
170 Label label = tk.createLabel(parent, labelValue, SWT.RIGHT);
171 // label.setFont(EclipseUiUtils.getBoldFont(parent));
172 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
173 // Add a trailing space to workaround a display glitch in RAP 1.3
174 Text text = new Text(parent, SWT.LEFT);
175 text.setText(textValue + " ");
176 text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
177 text.setEditable(false);
178 return text;
179 }
180
181 private void createLicencesLink(Composite parent, String label,
182 String jcrPropName) throws RepositoryException {
183 tk.createLabel(parent, label, SWT.NONE);
184 if (bundle.hasProperty(jcrPropName)) {
185
186 String licenceLinkVal = bundle.getProperty(jcrPropName).getString();
187
188 // FIXME Hack until license generation is done cleanly
189 // Problem is with description that contains a "," like
190 // "Apache License, Version 2"
191 String[] licenceVals;
192 if (licenceLinkVal.contains("description="))
193 licenceVals = new String[] { licenceLinkVal };
194 else
195 // multiple license, form non-regenerated manifests
196 licenceVals = licenceLinkVal.split(", ");
197
198 Composite body = tk.createComposite(parent);
199 body.setLayout(new RowLayout(SWT.WRAP));
200
201 for (final String value : licenceVals) {
202 final License currLicense = parseLicenseString(value);
203
204 Hyperlink link = tk.createHyperlink(body,
205 currLicense.getName(), SWT.NONE);
206 link.addHyperlinkListener(new HyperlinkAdapter() {
207 @Override
208 public void linkActivated(HyperlinkEvent e) {
209 try {
210 IWorkbenchBrowserSupport browserSupport = PlatformUI
211 .getWorkbench().getBrowserSupport();
212 IWebBrowser browser = browserSupport
213 .createBrowser(
214 IWorkbenchBrowserSupport.LOCATION_BAR
215 | IWorkbenchBrowserSupport.NAVIGATION_BAR,
216 "SLC Distribution browser",
217 "SLC Distribution browser",
218 "A tool tip");
219 browser.openURL(new URL(currLicense.getUri()));
220 } catch (Exception ex) {
221 throw new SlcException("error opening browser", ex); //$NON-NLS-1$
222 }
223 }
224 });
225 }
226 } else
227 tk.createLabel(parent, "N/A", SWT.NONE);
228 }
229
230 // TODO this must be moved to a better place once the standard has been
231 // defined
232 // Enable licence encoding in a single JCR Value
233 private final static String LICENSE_SEPARATOR = ";";
234 // The human readable name of the licence
235 private final static String LICENSE_NAME = "description";
236 // A link on the internet with some more info on this licence
237 private final static String LICENSE_LINK = "link";
238
239 private License parseLicenseString(String licenseStr) {
240 String uri = null, name = null, link = null, text = null;
241 // TODO enhance this
242 String[] values = licenseStr.split(LICENSE_SEPARATOR);
243 for (String value : values) {
244 if (value.startsWith(LICENSE_NAME))
245 name = value.substring(LICENSE_NAME.length() + 1); // +1 for the
246 // '='
247 else if (value.startsWith(LICENSE_LINK))
248 link = value.substring(LICENSE_LINK.length() + 1);
249 else if (uri == null)
250 uri = value;
251 // TODO manage text
252 }
253 return new SimpleLicense(name, uri, link, text);
254 }
255
256 class SimpleLicense implements License {
257 private final String name;
258 private final String uri;
259 private final String link;
260 private final String text;
261
262 public SimpleLicense(String name, String uri, String link, String text) {
263 if (uri == null)
264 throw new SlcException(
265 "Cannot manage a licence with a null URI ");
266 this.uri = uri;
267
268 this.name = name;
269 this.link = link;
270 this.text = text;
271 }
272
273 public String getUri() {
274 return uri;
275 }
276
277 public String getText() {
278 return text;
279 }
280
281 public String getName() {
282 return name != null ? name : uri;
283 }
284
285 public String getLink() {
286 return link;
287 }
288 }
289
290 private void createJarLink(Composite parent) throws RepositoryException {
291 Label label = tk.createLabel(parent, "Jar", SWT.RIGHT);
292 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
293
294 Composite body = tk.createComposite(parent);
295 RowLayout rl = new RowLayout(SWT.HORIZONTAL);
296 rl.spacing = 6;
297 body.setLayout(rl);
298 body.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
299
300 Hyperlink jarLink = tk
301 .createHyperlink(body, bundle.getName(), SWT.NONE);
302 jarLink.addHyperlinkListener(new OpenFileLinkListener(bundle.getPath()));
303
304 // Corresponding check sums
305
306 String name = bundle.getName() + ".md5";
307 if (bundle.getParent().hasNode(name)) {
308 Node md5 = bundle.getParent().getNode(name);
309 Hyperlink md5Link = tk.createHyperlink(body, "MD5", SWT.NONE);
310 md5Link.addHyperlinkListener(new OpenFileLinkListener(md5.getPath()));
311 }
312
313 name = bundle.getName() + ".sha1";
314 if (bundle.getParent().hasNode(name)) {
315 Node sha1 = bundle.getParent().getNode(name);
316 Hyperlink sha1Link = tk.createHyperlink(body, "SHA1", SWT.NONE);
317 sha1Link.addHyperlinkListener(new OpenFileLinkListener(sha1
318 .getPath()));
319 }
320 }
321
322 private void createPomLink(Composite parent) throws RepositoryException {
323 Label label = tk.createLabel(parent, "Pom", SWT.RIGHT);
324 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
325
326 String name = bundle.getName().substring(0,
327 bundle.getName().length() - "jar".length())
328 + "pom";
329
330 if (bundle.getParent().hasNode(name)) {
331 Node pom = bundle.getParent().getNode(name);
332
333 Composite body = tk.createComposite(parent);
334 RowLayout rl = new RowLayout(SWT.HORIZONTAL);
335 rl.spacing = 6;
336 body.setLayout(rl);
337 body.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
338 3, 1));
339
340 Hyperlink pomLink = tk.createHyperlink(body, "pom.xml", SWT.NONE);
341 pomLink.addHyperlinkListener(new OpenFileLinkListener(pom.getPath()));
342
343 // Corresponding check sums
344 name = pom.getName() + ".md5";
345 if (pom.getParent().hasNode(name)) {
346 Node md5 = pom.getParent().getNode(name);
347 Hyperlink md5Link = tk.createHyperlink(body, "MD5", SWT.NONE);
348 md5Link.addHyperlinkListener(new OpenFileLinkListener(md5
349 .getPath()));
350 }
351
352 name = pom.getName() + ".sha1";
353 if (pom.getParent().hasNode(name)) {
354 Node sha1 = pom.getParent().getNode(name);
355 Hyperlink sha1Link = tk.createHyperlink(body, "SHA1", SWT.NONE);
356 sha1Link.addHyperlinkListener(new OpenFileLinkListener(sha1
357 .getPath()));
358 }
359 } else
360 tk.createLabel(parent, "N/A", SWT.NONE);
361 }
362
363 private void createManifestLink(Composite parent)
364 throws RepositoryException {
365 tk.createLabel(parent, "Manifest", SWT.NONE);
366 // Hyperlink link =
367 // TODO fix this when file download has been implemented for the
368 // manifest
369 tk.createHyperlink(parent, "MANIFEST.MF", SWT.NONE);
370 // link.addHyperlinkListener(new
371 // OpenFileLinkListener(bundle.getPath()));
372 }
373
374 // private void createHyperlink(Composite parent, String label,
375 // String jcrPropName) throws RepositoryException {
376 // tk.createLabel(parent, label, SWT.NONE);
377 // if (bundle.hasProperty(jcrPropName)) {
378 // final Hyperlink link = tk.createHyperlink(parent, bundle
379 // .getProperty(jcrPropName).getString(), SWT.NONE);
380 // link.addHyperlinkListener(new AbstractHyperlinkListener() {
381 // @Override
382 // public void linkActivated(HyperlinkEvent e) {
383 // try {
384 // IWorkbenchBrowserSupport browserSupport = PlatformUI
385 // .getWorkbench().getBrowserSupport();
386 // IWebBrowser browser = browserSupport
387 // .createBrowser(
388 // IWorkbenchBrowserSupport.LOCATION_BAR
389 // | IWorkbenchBrowserSupport.NAVIGATION_BAR,
390 // "SLC Distribution browser",
391 // "SLC Distribution browser",
392 // "A tool tip");
393 // browser.openURL(new URL(link.getText()));
394 // } catch (Exception ex) {
395 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
396 // }
397 // }
398 // });
399 // } else
400 // tk.createLabel(parent, "N/A", SWT.NONE);
401 // }
402
403 // helper to check if sources are available
404 private void addSourceLink(Composite parent) {
405 try {
406 String srcPath = RepoUtils.relatedPdeSourcePath(
407 RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH, bundle);
408 if (!bundle.getSession().nodeExists(srcPath)) {
409 createLT(parent, "Sources", "N/A");
410 } else {
411 final Node sourcesNode = bundle.getSession().getNode(srcPath);
412
413 String srcName = null;
414 if (sourcesNode.hasProperty(SlcNames.SLC_SYMBOLIC_NAME))
415 srcName = sourcesNode.getProperty(
416 SlcNames.SLC_SYMBOLIC_NAME).getString();
417 else
418 srcName = sourcesNode.getName();
419 Label label = tk.createLabel(parent, "Sources", SWT.RIGHT);
420 label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
421 false));
422 final Hyperlink link = tk.createHyperlink(parent, srcName,
423 SWT.NONE);
424 link.addHyperlinkListener(new OpenFileLinkListener(sourcesNode
425 .getPath()));
426
427 // {
428 // @Override
429 // public void linkActivated(HyperlinkEvent e) {
430 // try {
431 // ModuleEditorInput editorInput = (ModuleEditorInput)
432 // getEditorInput();
433 // Map<String, String> params = new HashMap<String, String>();
434 // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
435 // editorInput.getRepoNodePath());
436 // params.put(OpenJcrFile.PARAM_REPO_URI,
437 // editorInput.getUri());
438 // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
439 // editorInput.getWorkspaceName());
440 // params.put(OpenJcrFile.PARAM_FILE_PATH,
441 // );
442 // CommandUtils.callCommand(OpenJcrFile.ID, params);
443 // } catch (Exception ex) {
444 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
445 // }
446 // }
447 // });
448
449 }
450 } catch (RepositoryException e) {
451 throw new SlcException("Unable to configure sources link for "
452 + bundle, e);
453 }
454 }
455
456 private class OpenFileLinkListener extends HyperlinkAdapter {
457 final private String path;
458
459 public OpenFileLinkListener(String path) {
460 this.path = path;
461 }
462
463 @Override
464 public void linkActivated(HyperlinkEvent e) {
465 log.warn("File download must be implemented. Cannot provide access to "
466 + path);
467
468 // try {
469 // ModuleEditorInput editorInput = (ModuleEditorInput)
470 // getEditorInput();
471 // Map<String, String> params = new HashMap<String, String>();
472 // params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
473 // editorInput.getRepoNodePath());
474 // params.put(OpenJcrFile.PARAM_REPO_URI, editorInput.getUri());
475 // params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
476 // editorInput.getWorkspaceName());
477 // params.put(OpenJcrFile.PARAM_FILE_PATH, path);
478 //
479 // String cmdId = (new OpenJcrFileCmdId()).getCmdId();
480 // if (log.isTraceEnabled())
481 // log.debug("Retrieved openFile Cmd ID: " + cmdId);
482 // CommandUtils.callCommand(cmdId, params);
483 // } catch (Exception ex) {
484 // throw new SlcException("error opening browser", ex); //$NON-NLS-1$
485 // }
486 }
487 }
488
489 /** Creates a text area with corresponding maven snippet */
490 private Text createMavenSnippet(Composite parent) {
491 Text mavenSnippet = new Text(parent, SWT.MULTI | SWT.WRAP);
492 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
493 gd.grabExcessHorizontalSpace = true;
494 gd.heightHint = 100;
495 mavenSnippet.setLayoutData(gd);
496 mavenSnippet.setText(generateXmlSnippet());
497 return mavenSnippet;
498 }
499
500 private String generateXmlSnippet() {
501 try {
502 StringBuffer sb = new StringBuffer();
503 sb.append("<dependency>\n");
504 sb.append("\t<groupId>");
505 sb.append(bundle.getProperty(SLC_GROUP_ID).getString());
506 sb.append("</groupId>\n");
507 sb.append("\t<artifactId>");
508 sb.append(bundle.getProperty(SLC_ARTIFACT_ID).getString());
509 sb.append("</artifactId>\n");
510 sb.append("\t<version>");
511 sb.append(bundle.getProperty(SLC_ARTIFACT_VERSION).getString());
512 sb.append("</version>\n");
513 sb.append("</dependency>");
514 return sb.toString();
515 } catch (RepositoryException re) {
516 throw new SlcException(
517 "unexpected error while generating maven snippet");
518 }
519 }
520 }