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