001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.visualweb.complib.ui;
043:
044: import java.awt.Dialog;
045: import java.awt.event.ActionEvent;
046: import java.io.IOException;
047: import java.text.MessageFormat;
048: import java.util.ArrayList;
049: import java.util.Collections;
050: import java.util.List;
051: import java.util.Set;
052:
053: import javax.swing.AbstractAction;
054: import javax.swing.Action;
055: import javax.swing.JButton;
056: import javax.swing.JMenu;
057: import javax.swing.JMenuItem;
058:
059: import org.netbeans.api.project.Project;
060: import org.netbeans.modules.visualweb.complib.ComplibServiceProvider;
061: import org.netbeans.modules.visualweb.complib.ExtensionComplib;
062: import org.netbeans.modules.visualweb.complib.IdeUtil;
063: import org.netbeans.modules.visualweb.complib.ComplibServiceProvider.RelatedComplibs;
064: import org.netbeans.modules.visualweb.complib.api.ComplibEvent;
065: import org.netbeans.modules.visualweb.complib.api.ComplibListener;
066: import org.openide.DialogDescriptor;
067: import org.openide.DialogDisplayer;
068: import org.openide.NotifyDescriptor;
069: import org.openide.awt.Mnemonics;
070: import org.openide.nodes.AbstractNode;
071: import org.openide.nodes.Children;
072: import org.openide.nodes.Node;
073: import org.openide.nodes.PropertySupport;
074: import org.openide.nodes.Sheet;
075: import org.openide.util.HelpCtx;
076: import org.openide.util.NbBundle;
077: import org.openide.util.actions.Presenter;
078:
079: /**
080: * ComplibsRootNode displays a list of embedded complibs for a project.
081: *
082: * @author Edwin Goei
083: */
084: public class ComplibsRootNode extends AbstractNode {
085: private static final String COMPLIBS_ROOT_ICON_BASE;
086: static {
087: COMPLIBS_ROOT_ICON_BASE = ComplibsRootNode.class.getPackage()
088: .getName().replace('.', '/')
089: + "/images/libraries.png";
090: }
091:
092: private Project project;
093:
094: public ComplibsRootNode(Project project) {
095: super (new ComplibsChildren(project));
096: this .project = project;
097:
098: // Nodes API documentation says to set these items like this
099: setIconBaseWithExtension(COMPLIBS_ROOT_ICON_BASE);
100: setName("Complibs");
101: setDisplayName(NbBundle.getMessage(ComplibsRootNode.class,
102: "ComplibsRootNode.displayName"));
103: setShortDescription(NbBundle.getMessage(ComplibsRootNode.class,
104: "ComplibsRootNode.tooltip"));
105: setValue("propertiesHelpID",
106: "projrave_ui_elements_project_nav_node_complib_node");
107: }
108:
109: public boolean canCopy() {
110: return false;
111: }
112:
113: @Override
114: public Action[] getActions(boolean context) {
115: ArrayList<Action> actions = new ArrayList<Action>();
116: actions.add(new AddComplibAction(project));
117:
118: String sharedCompLibs = System
119: .getProperty("complib.sharedCompLibs");
120: if ("true".equalsIgnoreCase(sharedCompLibs)) {
121: actions.add(new SharedComplibAction());
122: }
123: return actions.toArray(new Action[0]);
124: }
125:
126: private static class ComplibsChildren extends Children.Keys
127: implements ComplibListener {
128: private static final ComplibServiceProvider csp = ComplibServiceProvider
129: .getInstance();
130:
131: private Project project;
132:
133: ComplibsChildren(Project project) {
134: this .project = project;
135: }
136:
137: protected void addNotify() {
138: csp.addComplibListener(this );
139: setKeys(getKeys());
140: }
141:
142: protected void removeNotify() {
143: csp.removeComplibListener(this );
144: setKeys(Collections.EMPTY_SET);
145: }
146:
147: protected Node[] createNodes(Object obj) {
148: ExtensionComplib complib = (ExtensionComplib) obj;
149: Node node = new ComplibNode(complib, project);
150: return new Node[] { node };
151: }
152:
153: private List getKeys() {
154: Set<ExtensionComplib> prjComplibs = csp
155: .getComplibsForProject(project);
156: return new ArrayList<ExtensionComplib>(prjComplibs);
157: }
158:
159: public void paletteChanged(ComplibEvent event) {
160: setKeys(getKeys());
161: }
162: }
163:
164: private static class ComplibNode extends AbstractNode {
165: private static final String COMPLIB_ICON_BASE;
166: static {
167: COMPLIB_ICON_BASE = ComplibNode.class.getPackage()
168: .getName().replace('.', '/')
169: + "/images/library.png";
170: }
171:
172: private Project project;
173:
174: private ExtensionComplib complib;
175:
176: public ComplibNode(ExtensionComplib complib, Project project) {
177: super (Children.LEAF);
178: this .complib = complib;
179: this .project = project;
180:
181: // Nodes API documentation says to set these items like this
182: setIconBaseWithExtension(COMPLIB_ICON_BASE);
183: setName("complib");
184: setDisplayName(complib.getVersionedTitle());
185: }
186:
187: public Action[] getActions(boolean context) {
188: return new Action[] {
189: new UpgradeComplibAction(complib, project),
190: new ReplaceComplibAction(complib, project),
191: new RemoveComplibAction(complib, project) };
192: }
193:
194: public boolean canCopy() {
195: return false;
196: }
197:
198: @Override
199: protected Sheet createSheet() {
200: Sheet sheet = Sheet.createDefault();
201: Sheet.Set set = Sheet.createPropertiesSet();
202:
203: Property prop = getProperty("title", complib.getTitle());
204: set.put(prop);
205: prop = getProperty("namespaceUri", complib.getIdentifier()
206: .getNamespaceUriString());
207: set.put(prop);
208: prop = getProperty("version", complib.getIdentifier()
209: .getVersionString());
210: set.put(prop);
211:
212: sheet.put(set);
213: return sheet;
214: }
215:
216: private Property getProperty(String propName, final String value) {
217: String msg = NbBundle.getMessage(ComplibNode.class,
218: "ComplibsRootNode." + propName);
219: Property prop = new PropertySupport.ReadOnly(propName,
220: String.class, msg, null) {
221: public Object getValue() {
222: return value;
223: };
224: };
225: return prop;
226: }
227: }
228:
229: private static class AddComplibAction extends AbstractAction {
230: protected static final String NEW_COMPLIB = "NEW_COMPLIB";
231:
232: protected static final ComplibServiceProvider csp = ComplibServiceProvider
233: .getInstance();
234:
235: protected Project project;
236:
237: public AddComplibAction(Project project) {
238: super (NbBundle.getMessage(AddComplibAction.class,
239: "ComplibsRootNode.addComplibAction"));
240: this .project = project;
241: }
242:
243: public void actionPerformed(ActionEvent e) {
244: JButton addBtn = new JButton();
245: String addBtnMsg = NbBundle.getMessage(
246: ComplibsRootNode.class,
247: "ComplibsRootNode.addComplibBtn");
248: Mnemonics.setLocalizedText(addBtn, addBtnMsg);
249: addBtn.getAccessibleContext().setAccessibleDescription(
250: addBtnMsg);
251: addBtn.setEnabled(false);
252: Object[] options = new Object[] { addBtn,
253: DialogDescriptor.CANCEL_OPTION };
254: ComplibChooser panel = new ComplibChooser(addBtn, project);
255: String dialogTitle = NbBundle.getMessage(
256: ComplibsRootNode.class,
257: "ComplibsRootNode.addComplibTitle");
258: DialogDescriptor desc = new DialogDescriptor(panel,
259: dialogTitle, true, options, options[0],
260: DialogDescriptor.DEFAULT_ALIGN, null, null);
261:
262: desc.setHelpCtx(new HelpCtx(
263: "projrave_ui_elements_dialogs_add_complib")); // NOI18N
264:
265: Dialog dlg = DialogDisplayer.getDefault()
266: .createDialog(desc);
267: dlg.setVisible(true);
268: if (desc.getValue() == options[0]) {
269: ArrayList<ExtensionComplib> newComplibs = panel
270: .getSelectedComplibs();
271: for (ExtensionComplib complib : newComplibs) {
272: try {
273: csp.addProjectComplib(project, complib);
274: } catch (Exception ex) {
275: IdeUtil
276: .logError(
277: "Unable to embedded a complib into project",
278: ex);
279: }
280: }
281: }
282: dlg.dispose();
283: }
284: }
285:
286: private static class ReplaceComplibAction extends AbstractAction
287: implements Presenter.Popup {
288: protected static final String NEW_COMPLIB = "NEW_COMPLIB";
289:
290: protected static final ComplibServiceProvider csp = ComplibServiceProvider
291: .getInstance();
292:
293: protected Project project;
294:
295: protected ExtensionComplib origComplib;
296:
297: public ReplaceComplibAction(ExtensionComplib origComplib,
298: Project project) {
299: this .project = project;
300: this .origComplib = origComplib;
301: }
302:
303: public JMenuItem getPopupPresenter() {
304: String msg = NbBundle.getMessage(
305: ReplaceComplibAction.class,
306: "ComplibsRootNode.replaceComplib");
307: JMenu submenu = new JMenu(msg);
308:
309: RelatedComplibs relatedComplibs = csp
310: .getRelatedComplibs(origComplib);
311:
312: List<ExtensionComplib> olderComplibs = relatedComplibs
313: .getOlderComplibs();
314: if (olderComplibs.isEmpty()) {
315: msg = NbBundle.getMessage(ReplaceComplibAction.class,
316: "ComplibsRootNode.noOlderComplibs");
317: JMenuItem item = new JMenuItem(msg);
318: item.setEnabled(false);
319: item.setToolTipText(getComplibManagerToolTip());
320: submenu.add(item);
321: } else {
322: for (ExtensionComplib iComplib : olderComplibs) {
323: ReplaceComplibAction action = new ReplaceComplibAction(
324: origComplib, project);
325: String versionedTitle = iComplib
326: .getVersionedTitle();
327: action.putValue(NAME, versionedTitle);
328: action.putValue(NEW_COMPLIB, iComplib);
329: action.putValue(SHORT_DESCRIPTION,
330: getComplibManagerToolTip());
331: JMenuItem item = new JMenuItem(action);
332: submenu.add(item);
333: }
334: }
335:
336: return submenu;
337: }
338:
339: public void actionPerformed(ActionEvent e) {
340: ExtensionComplib newComplib = getNewComplib(e);
341: if (newComplib == null) {
342: return;
343: }
344:
345: // Confirmation dialog
346: String msg = NbBundle.getMessage(
347: ReplaceComplibAction.class,
348: "ComplibsRootNode.confirmReplaceComplib");
349: msg = MessageFormat.format(msg, origComplib
350: .getVersionedTitle(), newComplib
351: .getVersionedTitle());
352: NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
353: msg, NotifyDescriptor.OK_CANCEL_OPTION);
354: nd.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
355: Object result = DialogDisplayer.getDefault().notify(nd);
356: if (NotifyDescriptor.OK_OPTION == result) {
357: try {
358: csp.replaceProjectComplib(project, origComplib,
359: newComplib);
360: } catch (Exception ex) {
361: IdeUtil
362: .logError(
363: "Unable to replace embedded complib in project",
364: ex);
365: }
366: }
367: }
368:
369: static ExtensionComplib getNewComplib(ActionEvent e) {
370: Object source = e.getSource();
371: if (!(source instanceof JMenuItem)) {
372: return null;
373: }
374: JMenuItem item = (JMenuItem) source;
375:
376: Action action = item.getAction();
377: if (!(action instanceof ReplaceComplibAction)) {
378: return null;
379: }
380: ReplaceComplibAction addAction = (ReplaceComplibAction) action;
381:
382: ExtensionComplib newComplib = (ExtensionComplib) addAction
383: .getValue(NEW_COMPLIB);
384: if (newComplib == null) {
385: return null;
386: }
387: return newComplib;
388: }
389:
390: static String getComplibManagerToolTip() {
391: return NbBundle.getMessage(ReplaceComplibAction.class,
392: "ComplibsRootNode.useComplibManager");
393: }
394: }
395:
396: private static class UpgradeComplibAction extends
397: ReplaceComplibAction {
398:
399: public UpgradeComplibAction(ExtensionComplib origComplib,
400: Project project) {
401: super (origComplib, project);
402: }
403:
404: public JMenuItem getPopupPresenter() {
405: String msg = NbBundle.getMessage(
406: UpgradeComplibAction.class,
407: "ComplibsRootNode.upgradeComplib");
408: JMenu submenu = new JMenu(msg);
409:
410: RelatedComplibs relatedComplibs = csp
411: .getRelatedComplibs(origComplib);
412: List<ExtensionComplib> newerComplibs = relatedComplibs
413: .getNewerComplibs();
414: if (newerComplibs.isEmpty()) {
415: msg = NbBundle.getMessage(ReplaceComplibAction.class,
416: "ComplibsRootNode.noUpgradableComplibs");
417: JMenuItem item = new JMenuItem(msg);
418: item.setEnabled(false);
419: item.setToolTipText(getComplibManagerToolTip());
420: submenu.add(item);
421: return submenu;
422: }
423:
424: for (ExtensionComplib iComplib : newerComplibs) {
425: UpgradeComplibAction action = new UpgradeComplibAction(
426: origComplib, project);
427: String versionedTitle = iComplib.getVersionedTitle();
428: action.putValue(NAME, versionedTitle);
429: action.putValue(NEW_COMPLIB, iComplib);
430: action.putValue(SHORT_DESCRIPTION,
431: getComplibManagerToolTip());
432: JMenuItem item = new JMenuItem(action);
433: submenu.add(item);
434: }
435: return submenu;
436: }
437:
438: public void actionPerformed(ActionEvent e) {
439: ExtensionComplib newComplib = getNewComplib(e);
440: if (newComplib == null) {
441: return;
442: }
443:
444: // Confirmation dialog
445: String msg = NbBundle.getMessage(
446: UpgradeComplibAction.class,
447: "ComplibsRootNode.confirmUpgradeComplib");
448: msg = MessageFormat.format(msg, origComplib
449: .getVersionedTitle(), newComplib
450: .getVersionedTitle());
451: NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
452: msg, NotifyDescriptor.OK_CANCEL_OPTION);
453: Object result = DialogDisplayer.getDefault().notify(nd);
454: if (NotifyDescriptor.OK_OPTION == result) {
455: try {
456: csp.replaceProjectComplib(project, origComplib,
457: newComplib);
458: } catch (Exception ex) {
459: IdeUtil
460: .logError(
461: "Unable to upgrade embedded complib in project",
462: ex);
463: }
464: }
465: }
466: }
467:
468: private static class RemoveComplibAction extends AbstractAction {
469: private ExtensionComplib complib;
470:
471: private Project project;
472:
473: public RemoveComplibAction(ExtensionComplib complib,
474: Project project) {
475: super (NbBundle.getMessage(RemoveComplibAction.class,
476: "ComplibsRootNode.removeComplibAction"));
477: this .complib = complib;
478: this .project = project;
479: }
480:
481: public void actionPerformed(ActionEvent e) {
482: // Confirmation dialog
483: String msg = NbBundle.getMessage(RemoveComplibAction.class,
484: "ComplibsRootNode.confirmRemoveComplib");
485: msg = MessageFormat
486: .format(msg, complib.getVersionedTitle());
487: NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
488: msg, NotifyDescriptor.OK_CANCEL_OPTION);
489: nd.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
490: Object result = DialogDisplayer.getDefault().notify(nd);
491: if (NotifyDescriptor.OK_OPTION == result) {
492: try {
493: ComplibServiceProvider.getInstance()
494: .removeComplibFromProject(project, complib);
495: } catch (IOException ex) {
496: IdeUtil
497: .logError(
498: "Unable to remove embedded complib from project",
499: ex);
500: }
501:
502: }
503: }
504: }
505: }
|