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