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