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.compapp.projects.common.ui;
043:
044: import java.awt.BorderLayout;
045: import java.awt.event.MouseAdapter;
046: import java.awt.event.MouseEvent;
047: import java.beans.PropertyChangeEvent;
048: import java.beans.PropertyChangeListener;
049: import java.io.IOException;
050: import java.lang.reflect.InvocationTargetException;
051: import java.util.ArrayList;
052: import java.util.Collection;
053: import java.util.HashMap;
054: import java.util.LinkedList;
055: import java.util.List;
056: import java.util.Map;
057: import java.util.Set;
058: import javax.swing.ImageIcon;
059: import javax.swing.tree.TreePath;
060: import javax.swing.tree.TreeSelectionModel;
061: import org.netbeans.api.project.FileOwnerQuery;
062: import org.netbeans.api.project.Project;
063: import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport;
064: import org.netbeans.modules.xml.xam.Component;
065: import org.netbeans.modules.xml.xam.Model;
066: import org.netbeans.modules.xml.xam.ui.ModelCookie;
067: import org.netbeans.modules.xml.xam.ui.customizer.AbstractReferenceCustomizer;
068: import org.netbeans.modules.xml.xam.ui.customizer.ExternalReferenceDataNode;
069: import org.netbeans.modules.xml.xam.ui.customizer.ExternalReferenceDecorator;
070: import org.netbeans.modules.xml.xam.ui.customizer.ExternalReferenceNode;
071: import org.netbeans.modules.xml.xam.ui.customizer.FolderNode;
072: import org.netbeans.modules.xml.xam.ui.customizer.RetrievedFilesChildren;
073: import org.netbeans.spi.project.ui.LogicalViewProvider;
074: import org.openide.explorer.ExplorerManager;
075: import org.openide.explorer.view.TreeTableView;
076: import org.openide.explorer.view.Visualizer;
077: import org.openide.filesystems.FileObject;
078: import org.openide.loaders.DataObject;
079: import org.openide.nodes.AbstractNode;
080: import org.openide.nodes.Children;
081: import org.openide.nodes.Node;
082: import org.openide.nodes.PropertySupport;
083: import org.openide.util.NbBundle;
084: import org.openide.util.Utilities;
085:
086: /**
087: * Base class for external reference creators.
088: *
089: * Modified from the original xam ui to allow showing both wsdl and xsd files
090: * and namespaces.
091: *
092: * @author xam ui (orig)
093: * @author chikkala
094: */
095: public abstract class NamespaceReferenceCreator<T extends Component>
096: extends AbstractReferenceCustomizer<T> implements
097: ExplorerManager.Provider, PropertyChangeListener {
098: /** silence compiler warnings */
099: private static final long serialVersionUID = 1L;
100: /** Map of registered nodes, keyed by their representative DataObject. */
101: private Map<DataObject, NodeSet> registeredNodes;
102: /** The file being modified (where the import will be added). */
103: private transient FileObject sourceFO;
104: /** Used to deal with project catalogs. */
105: private transient DefaultProjectCatalogSupport catalogSupport;
106:
107: /**
108: * Creates new form ExternalReferenceCreator
109: *
110: * @param component component in which to create new components.
111: * @param model model in which to create components.
112: */
113: public NamespaceReferenceCreator(T component, Model model) {
114: super (component);
115: registeredNodes = new HashMap<DataObject, NodeSet>();
116: initComponents();
117: sourceFO = (FileObject) component.getModel().getModelSource()
118: .getLookup().lookup(FileObject.class);
119: catalogSupport = DefaultProjectCatalogSupport
120: .getInstance(sourceFO);
121: init(component, model);
122: // View for selecting an external reference.
123: TreeTableView locationView = new LocationView();
124: locationView.setDefaultActionAllowed(false);
125: locationView.setPopupAllowed(false);
126: locationView
127: .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
128: locationView.setRootVisible(false);
129: locationView.getAccessibleContext().setAccessibleName(
130: locationLabel.getToolTipText());
131: locationView.getAccessibleContext().setAccessibleDescription(
132: locationLabel.getToolTipText());
133: Node.Property[] columns = new Node.Property[] {
134: new Column(ExternalReferenceDataNode.PROP_NAME,
135: String.class, true),
136: new ImportColumn(referenceTypeName()),
137: new Column(ExternalReferenceDataNode.PROP_PREFIX,
138: String.class, false), };
139: locationView.setProperties(columns);
140: locationView.setTreePreferredWidth(200);
141: locationView.setTableColumnPreferredWidth(0, 25);
142: locationView.setTableColumnPreferredWidth(1, 25);
143: locationPanel.add(locationView, BorderLayout.CENTER);
144: explorerManager = new ExplorerManager();
145: explorerManager.addPropertyChangeListener(this );
146: explorerManager.setRootContext(createRootNode());
147: }
148:
149: public void applyChanges() throws IOException {
150: // NOOP. This will not update the catalog as
151: // ImplicitCatalogSupport will update both catalog.xml and catalog.wsdl.
152: }
153:
154: /**
155: * Return the target namespace of the given model.
156: *
157: * @param model the model for which to get the namespace.
158: * @return target namespace, or null if none.
159: */
160: protected abstract String getTargetNamespace(Model model);
161:
162: /**
163: * Retrieve the list of nodes that the user selected.
164: *
165: * @return list of selected nodes (empty if none).
166: */
167: protected List<Node> getSelectedNodes() {
168: List<Node> results = new LinkedList<Node>();
169: Collection<NodeSet> sets = registeredNodes.values();
170: // System.out.println("getSelectedNodes: Registered Node count : "+registeredNodes.size());
171: for (NodeSet set : sets) {
172: if (set.isSelected()) {
173: List<ExternalReferenceDataNode> nodes = set.getNodes();
174: if (nodes.size() > 0) {
175: // Use just one of the corresponding nodes, as the
176: // others are basically duplicates.
177: results.add(nodes.get(0));
178: }
179: }
180: }
181: // System.out.println("getSelectedNodes: seletected result: "+results.size());
182: return results;
183: }
184:
185: /**
186: * Check if prefix is unique on UI.
187: *
188: * @return true if Prefix is not unique on UI, false otherwise.
189: */
190: private boolean isValidPrefix(ExternalReferenceDataNode node) {
191: DataObject dobj = (DataObject) node.getLookup().lookup(
192: DataObject.class);
193: NodeSet nodeSet = registeredNodes.get(dobj);
194: Collection<NodeSet> sets = registeredNodes.values();
195: for (NodeSet set : sets) {
196: // Ignore the set which contains the given node, and those
197: // sets which are not selected.
198: if (!set.equals(nodeSet) && set.isSelected()) {
199: // Only need to check the first node, as all of them have
200: // the same prefix (or at least that is the idea).
201: ExternalReferenceDataNode other = set.getNodes().get(0);
202: if (node.getPrefix().equals(other.getPrefix())) {
203: return false;
204: }
205: }
206: }
207: return true;
208: }
209:
210: /**
211: * Determine the number of nodes that the user selected, useful for
212: * knowing if any nodes are selected or not.
213: *
214: * @return number of selected nodes.
215: */
216: private int countSelectedNodes() {
217: int results = 0;
218: Collection<NodeSet> sets = registeredNodes.values();
219: for (NodeSet set : sets) {
220: if (set.isSelected()) {
221: List<ExternalReferenceDataNode> nodes = set.getNodes();
222: if (nodes.size() > 0) {
223: results++;
224: }
225: }
226: }
227: return results;
228: }
229:
230: /**
231: * Return the existing external reference prefixes for the given model.
232: *
233: * @param model the model for which to get the namespace.
234: * @return set of prefixes; empty if none.
235: */
236: protected abstract Map<String, String> getPrefixes(Model model);
237:
238: /**
239: * Returns the NodeDecorator for this customizer, if any.
240: *
241: * @return node decorator for files nodes, or null if none.
242: */
243: protected abstract ExternalReferenceDecorator getNodeDecorator();
244:
245: /**
246: * Indicates if the namespace value must be different than that of
247: * the model containing the component being customized. If false,
248: * then the opposite must hold - the namespace must be the same.
249: * The one exception is if the namespace is not defined at all.
250: *
251: * @return true if namespace must differ, false if same.
252: */
253: public abstract boolean mustNamespaceDiffer();
254:
255: /**
256: * Return the proper name of the type of reference this creator is to
257: * be used for. This will become the title of the first column in the
258: * tree-table. Generally this should be something of the form of
259: * "Import", "Include", "Redefine", etc.
260: *
261: * @return human-readable name for the first column title.
262: */
263: protected abstract String referenceTypeName();
264:
265: /**
266: * Called from constructor, after the interface components have been
267: * constructed, but before they have been initialized. Gives subclasses
268: * a chance to perform initialization based on the given component.
269: *
270: * @param component the reference to be customized.
271: * @param model the model passed to the constructor (may be null).
272: */
273: protected void init(T component, Model model) {
274: // Note, do not place any code here, as there is no guarantee
275: // that the subclasses will delegate to this method at all.
276: }
277:
278: protected void initializeUI() {
279: if (!mustNamespaceDiffer()) {
280: namespaceLabel.setVisible(false);
281: namespaceTextField.setVisible(false);
282: }
283: }
284:
285: public ExternalReferenceDataNode createExternalReferenceNode(
286: Node original) {
287: DataObject dobj = (DataObject) original.getLookup().lookup(
288: DataObject.class);
289: NodeSet set = registeredNodes.get(dobj);
290: if (set == null) {
291: set = new NodeSet(this );
292: registeredNodes.put(dobj, set);
293: }
294: //CHIK
295: ExternalReferenceDataNode erdn = new ImplicitReferenceDataNode(
296: original, getNodeDecorator());
297: set.add(erdn);
298: if (set.isSelected() && erdn.canSelect()) {
299: erdn.setSelected(true);
300: }
301: erdn.addPropertyChangeListener(this );
302: return erdn;
303: }
304:
305: /**
306: * Indicate if this creator allows the user to select no files at all.
307: * This is useful from the new file wizard which needs to allow the
308: * user to deselect what they had previously selected.
309: *
310: * @return true if user may select no files and still be considered
311: * as valid input, false to require one or more selections.
312: */
313: protected boolean allowEmptySelection() {
314: // By default we require the user to select at least one file.
315: return false;
316: }
317:
318: /**
319: * Determine if the user's input is valid or not. This will enable
320: * or disable the save/reset controls based on the results, as well
321: * as issue error messages.
322: *
323: * @param node selected node.
324: */
325: private void validateInput(ExternalReferenceNode node) {
326: String msg = null;
327: if (mustNamespaceDiffer()
328: && node instanceof ExternalReferenceDataNode) {
329: ExternalReferenceDataNode erdn = (ExternalReferenceDataNode) node;
330: Map<String, String> prefixMap = getPrefixes(getModelComponent()
331: .getModel());
332: String ep = erdn.getPrefix();
333: // Must be a non-empty prefix, that is not already in use, and
334: // is unique among the selected nodes (and be selected itself).
335: if (ep.length() == 0 || prefixMap.containsKey(ep)
336: || (!isValidPrefix(erdn) && erdn.isSelected())) {
337: msg = NbBundle.getMessage(
338: NamespaceReferenceCreator.class,
339: "LBL_ExternalReferenceCreator_InvalidPrefix");
340: }
341: }
342: if (node instanceof RetrievedFilesChildren.RetrievedFileNode) {
343: RetrievedFilesChildren.RetrievedFileNode rNode = (RetrievedFilesChildren.RetrievedFileNode) node;
344: if (!rNode.isValid()) {
345: msg = NbBundle
346: .getMessage(NamespaceReferenceCreator.class,
347: "LBL_ExternalReferenceCreator_InvalidCatalogEntry");
348: }
349: }
350: if (msg != null) {
351: showMessage(msg);
352: }
353: int selected = countSelectedNodes();
354: // Must have selected nodes, and no error messages.
355: setSaveEnabled((allowEmptySelection() || selected > 0)
356: && msg == null);
357: }
358:
359: protected void showMessage(String msg) {
360: if (msg == null) {
361: messageLabel.setText(" ");
362: messageLabel.setIcon(null);
363: } else {
364: messageLabel.setText(msg);
365: messageLabel
366: .setIcon(new ImageIcon(
367: Utilities
368: .loadImage("org/netbeans/modules/xml/xam/ui/resources/error.gif"))); // NOI18N
369: }
370: }
371:
372: /**
373: * A TreeTableView that toggles the selection of the external reference
374: * data nodes using a single mouse click.
375: */
376: private class LocationView extends TreeTableView {
377: /** silence compiler warnings */
378: private static final long serialVersionUID = 1L;
379:
380: /**
381: * Creates a new instance of LocationView.
382: */
383: public LocationView() {
384: super ();
385: tree.addMouseListener(new MouseAdapter() {
386: @Override
387: public void mouseClicked(MouseEvent e) {
388: // Invert the selection of the data node, if such a
389: // node was clicked on.
390: TreePath path = tree.getPathForLocation(e.getX(), e
391: .getY());
392: if (path != null) {
393: Object comp = path.getLastPathComponent();
394: Node node = Visualizer.findNode(comp);
395: if (node instanceof ExternalReferenceDataNode) {
396: ExternalReferenceDataNode erdn = (ExternalReferenceDataNode) node;
397: if (erdn.canSelect()) {
398: boolean selected = !erdn.isSelected();
399: String ns = null;
400: if (selected) {
401: // Have to collect the namespace value
402: // when the node is selected.
403: Model model = erdn.getModel();
404: if (model != null) {
405: ns = getTargetNamespace(model);
406: }
407: }
408: // This will clear the field if the user has
409: // deselected the file, which is to prevent
410: // the user from being confused as to what
411: // the namespace field represents.
412: namespaceTextField.setText(ns);
413: erdn.setSelected(selected);
414: }
415: }
416: }
417: }
418: });
419: }
420: }
421:
422: protected Node createRootNode() {
423: Set/*<Project>*/refProjects = null;
424: if (catalogSupport.supportsCrossProject()) {
425: refProjects = catalogSupport.getProjectReferences();
426: }
427: ExternalReferenceDecorator decorator = getNodeDecorator();
428: Node[] rootNodes = new Node[1 + (refProjects == null ? 0
429: : refProjects.size())];
430: Project prj = FileOwnerQuery.getOwner(sourceFO);
431: LogicalViewProvider viewProvider = (LogicalViewProvider) prj
432: .getLookup().lookup(LogicalViewProvider.class);
433: rootNodes[0] = decorator
434: .createExternalReferenceNode(viewProvider
435: .createLogicalView());
436: int rootIndex = 1;
437: List<FileObject> projectRoots = new ArrayList<FileObject>();
438: projectRoots.add(prj.getProjectDirectory());
439: if (refProjects != null) {
440: for (Object o : refProjects) {
441: Project refPrj = (Project) o;
442: viewProvider = (LogicalViewProvider) refPrj.getLookup()
443: .lookup(LogicalViewProvider.class);
444: rootNodes[rootIndex++] = decorator
445: .createExternalReferenceNode(viewProvider
446: .createLogicalView());
447: projectRoots.add(refPrj.getProjectDirectory());
448: }
449: }
450: FileObject[] roots = projectRoots
451: .toArray(new FileObject[projectRoots.size()]);
452: Children fileChildren = new Children.Array();
453: fileChildren.add(rootNodes);
454: Node byFilesNode = new FolderNode(fileChildren);
455: byFilesNode.setDisplayName(NbBundle.getMessage(
456: NamespaceReferenceCreator.class,
457: "LBL_ExternalReferenceCreator_Category_By_File"));
458:
459: // Construct the By Namespace node.
460: Children nsChildren = new ImplicitNamespaceChildren(roots,
461: decorator); ////CHIK
462: Node byNsNode = new FolderNode(nsChildren);
463: byNsNode.setDisplayName(NbBundle.getMessage(
464: NamespaceReferenceCreator.class,
465: "LBL_ExternalReferenceCreator_Category_By_Namespace"));
466: // Hide the Retrieved node tree until we are sure the runtime can handle
467: // URLs with respect to the catalog.
468: // Node retrievedNode;
469: // CatalogWriteModel cwm = getCatalogWriteModel();
470: // if (cwm != null) {
471: // Children rChildren = new RetrievedFilesChildren(cwm , decorator);
472: // retrievedNode = new ExternalReferenceNode(projectNode, rChildren, decorator);
473: // } else {
474: // retrievedNode = new ExternalReferenceNode(projectNode, Children.LEAF, decorator);
475: // }
476: // retrievedNode.setDisplayName(NbBundle.getMessage(
477: // ExternalReferenceCreator.class,
478: // "LBL_ExternalReferenceCreator_Category_By_Retrieved"));
479: Children categories = new Children.Array();
480: // categories.add(new Node[]{ byFilesNode, byNsNode, retrievedNode });
481: categories.add(new Node[] { byFilesNode, byNsNode });
482: Node rootNode = new AbstractNode(categories);
483: // Surprisingly, this becomes the name and description of the first column.
484: rootNode.setDisplayName(NbBundle.getMessage(
485: NamespaceReferenceCreator.class,
486: "CTL_ExternalReferenceCreator_Column_Name_name"));
487: rootNode.setShortDescription(NbBundle.getMessage(
488: NamespaceReferenceCreator.class,
489: "CTL_ExternalReferenceCreator_Column_Desc_name"));
490: return rootNode;
491: }
492:
493: // private CatalogWriteModel getCatalogWriteModel() {
494: // try {
495: // FileObject myFobj = (FileObject) getModelComponent().getModel().
496: // getModelSource().getLookup().lookup(FileObject.class);
497: // CatalogWriteModel cwm = CatalogWriteModelFactory.getInstance().
498: // getCatalogWriteModelForProject(myFobj);
499: // return cwm;
500: // } catch (CatalogModelException cme) {
501: // }
502: // return null;
503: // }
504:
505: public void propertyChange(PropertyChangeEvent event) {
506: String pname = event.getPropertyName();
507:
508: if (ExplorerManager.PROP_SELECTED_NODES.equals(pname)) {
509: showMessage(null);
510: Node[] nodes = (Node[]) event.getNewValue();
511: // Validate the node selection.
512: if (nodes != null && nodes.length > 0
513: && nodes[0] instanceof ExternalReferenceNode) {
514: ExternalReferenceNode node = (ExternalReferenceNode) nodes[0];
515: Model model = node.getModel();
516: // Without a model, the selection is completely invalid.
517: if (model != null) {
518: // Ask decorator if selection is valid or not.
519: String msg = getNodeDecorator().validate(node);
520: if (msg != null) {
521: showMessage(msg);
522: } else {
523: // If node is okay, validate the rest of the input.
524: validateInput(node);
525: }
526: }
527: }
528: } else if (pname.equals(ExternalReferenceDataNode.PROP_PREFIX)) {
529: ExternalReferenceDataNode erdn = (ExternalReferenceDataNode) event
530: .getSource();
531: // Look up the node in the map of sets, and ensure they all
532: // have the same prefix.
533: String prefix = (String) event.getNewValue();
534: DataObject dobj = (DataObject) erdn.getLookup().lookup(
535: DataObject.class);
536: NodeSet set = registeredNodes.get(dobj);
537: // Ideally the set should already exist, but cope gracefully.
538: assert set != null : "node not created by customizer";
539: if (set == null) {
540: set = new NodeSet(this );
541: set.add(erdn);
542: }
543: set.setPrefix(prefix);
544: validateInput(erdn);
545: } else if (pname
546: .equals(ExternalReferenceDataNode.PROP_SELECTED)) {
547:
548: ExternalReferenceDataNode erdn = (ExternalReferenceDataNode) event
549: .getSource();
550: // Look up the node in the map of sets, and ensure they are all
551: // selected as a unit.
552: boolean selected = ((Boolean) event.getNewValue())
553: .booleanValue();
554: DataObject dobj = (DataObject) erdn.getLookup().lookup(
555: DataObject.class);
556: NodeSet set = registeredNodes.get(dobj);
557: // Ideally the set should already exist, but cope gracefully.
558: assert set != null : "node not created by customizer";
559: if (set == null) {
560: set = new NodeSet(this );
561: set.add(erdn);
562: }
563: set.setSelected(selected);
564: // Check if the current selection is valid.
565: validateInput(erdn);
566: }
567: }
568:
569: /**
570: * Get the URI location for the given node.
571: *
572: * @param node Node from which to retrieve location value.
573: * @return location for given Node, or null.
574: */
575: protected String getLocation(Node node) {
576: //NOTE: since cross-project location for the catalog entry is calculated
577: // during addtion of this namespace to catalog.wsdl, we need not worry
578: // about gettting the relative location.
579:
580: // just return the default file location uri.
581: String location = "";
582:
583: return location;
584:
585: }
586:
587: //// //TODO: if the location needed, it should be calculated using Implicit
588: //// // catalog support implementation.
589: //// /**
590: //// * Get the URI location for the given node.
591: //// *
592: //// * @param node Node from which to retrieve location value.
593: //// * @return location for given Node, or null.
594: //// */
595: //// protected String getLocation(Node node) {
596: //// String location = null;
597: //// if (node instanceof RetrievedFilesChildren.RetrievedFileNode) {
598: //// RetrievedFilesChildren.RetrievedFileNode rNode =
599: //// (RetrievedFilesChildren.RetrievedFileNode) node;
600: //// if (rNode.isValid()) {
601: //// String ns = rNode.getNamespace();
602: //// if (ns == null || mustNamespaceDiffer() !=
603: //// ns.equals(getTargetNamespace())) {
604: //// location = rNode.getLocation();
605: //// }
606: //// }
607: //// } else {
608: //// DataObject dobj = (DataObject) node.getLookup().
609: //// lookup(DataObject.class);
610: //// if (dobj != null && dobj.isValid()) {
611: //// FileObject fileObj = dobj.getPrimaryFile();
612: //// ModelCookie cookie = (ModelCookie) dobj.getCookie(
613: //// ModelCookie.class);
614: //// Model model;
615: //// try {
616: //// if (cookie != null && (model = cookie.getModel()) !=
617: //// getModelComponent().getModel()) {
618: //// String ns = getTargetNamespace(model);
619: //// if (ns == null || mustNamespaceDiffer() !=
620: //// ns.equals(getTargetNamespace())) {
621: //// return catalogSupport.getReferenceURI(
622: //// sourceFO, fileObj).toString();
623: //// }
624: //// }
625: //// } catch (URISyntaxException urise) {
626: //// ErrorManager.getDefault().notify(urise);
627: //// } catch (IOException ioe) {
628: //// ErrorManager.getDefault().notify(ioe);
629: //// }
630: //// }
631: //// }
632: //// if (location != null) {
633: //// try {
634: //// URI uri = new URI("file", location, null);
635: //// uri = uri.normalize();
636: //// location = uri.getRawSchemeSpecificPart();
637: //// } catch (URISyntaxException use) {
638: //// showMessage(use.toString());
639: //// // Despite this, we can still use the location we have.
640: //// }
641: //// }
642: //// return location;
643: //// }
644:
645: /**
646: * Get the namespace for the given node.
647: *
648: * @param node Node from which to retrieve namespace value.
649: * @return namespace for given Node, or null.
650: */
651: protected String getNamespace(Node node) {
652: String ns = null;
653: if (node instanceof RetrievedFilesChildren.RetrievedFileNode) {
654: RetrievedFilesChildren.RetrievedFileNode rNode = (RetrievedFilesChildren.RetrievedFileNode) node;
655: if (!rNode.isValid()) {
656: return null;
657: }
658: ns = rNode.getNamespace();
659: } else {
660: DataObject dobj = (DataObject) node.getLookup().lookup(
661: DataObject.class);
662: if (dobj != null && dobj.isValid()) {
663: ModelCookie cookie = (ModelCookie) dobj
664: .getCookie(ModelCookie.class);
665: Model model;
666: try {
667: if (cookie != null
668: && (model = cookie.getModel()) != getModelComponent()
669: .getModel()) {
670: ns = getTargetNamespace(model);
671: }
672: } catch (IOException ioe) {
673: // Fall through and return null.
674: }
675: }
676: }
677: return ns;
678: }
679:
680: public ExplorerManager getExplorerManager() {
681: return explorerManager;
682: }
683:
684: /**
685: * A column for the reference customizer table.
686: *
687: * @author Nathan Fiedler
688: */
689: protected class Column extends PropertySupport.ReadOnly {
690: /** The keyword for this column. */
691: private String key;
692:
693: /**
694: * Constructs a new instance of Column.
695: *
696: * @param key keyword for this column.
697: * @param type type of the property (e.g. String.class).
698: * @param tree true if this is the 'tree' column.
699: */
700: public Column(String key, Class type, boolean tree) {
701: super (key, type, NbBundle.getMessage(Column.class,
702: "CTL_ExternalReferenceCreator_Column_Name_" + key),
703: NbBundle.getMessage(Column.class,
704: "CTL_ExternalReferenceCreator_Column_Desc_"
705: + key));
706: this .key = key;
707: setValue("TreeColumnTTV", Boolean.valueOf(tree));
708: }
709:
710: public Object getValue() throws IllegalAccessException,
711: InvocationTargetException {
712: return key;
713: }
714: }
715:
716: /**
717: * Special column for the reference customizer table's import column.
718: *
719: * @author Nathan Fiedler
720: */
721: protected class ImportColumn extends PropertySupport.ReadOnly {
722: /** The keyword for this column. */
723: private String key;
724:
725: /**
726: * Creates a new instance of ImportColumn.
727: *
728: * @param name the column's name.
729: */
730: public ImportColumn(String name) {
731: super (
732: "selected",
733: Boolean.TYPE,
734: name,
735: NbBundle
736: .getMessage(Column.class,
737: "CTL_ExternalReferenceCreator_Column_Desc_selected"));
738: this .key = "selected";
739: setValue("TreeColumnTTV", Boolean.FALSE);
740: }
741:
742: public Object getValue() throws IllegalAccessException,
743: InvocationTargetException {
744: return key;
745: }
746: }
747:
748: /**
749: * Manages the state of a set of nodes.
750: */
751: private static class NodeSet {
752: /** The property change listener for each node. */
753: private PropertyChangeListener listener;
754: /** Nodes in this set. */
755: private List<ExternalReferenceDataNode> nodes;
756: /** True if this set is selected, false otherwise. */
757: private boolean selected;
758:
759: /**
760: * Creates a new instance of NodeSet.
761: *
762: * @param listener listens to the Node.
763: */
764: public NodeSet(PropertyChangeListener listener) {
765: this .listener = listener;
766: }
767:
768: /**
769: * Add the given node to this set.
770: *
771: * @param node node to be added to set.
772: */
773: public void add(ExternalReferenceDataNode node) {
774: if (nodes == null) {
775: nodes = new LinkedList<ExternalReferenceDataNode>();
776: }
777: nodes.add(node);
778: }
779:
780: /**
781: * Returns the list of nodes in this set.
782: *
783: * @return list of nodes.
784: */
785: public List<ExternalReferenceDataNode> getNodes() {
786: return nodes;
787: }
788:
789: /**
790: * Indicates if this set is selected or not.
791: *
792: * @return true if selected, false otherwise.
793: */
794: public boolean isSelected() {
795: return selected;
796: }
797:
798: /**
799: * Set the prefix for Nodes in this group.
800: *
801: * @param prefix new namespace prefix.
802: */
803: public void setPrefix(String prefix) {
804: for (ExternalReferenceDataNode node : nodes) {
805: if (!node.getPrefix().equals(prefix)) {
806: node.removePropertyChangeListener(listener);
807: node.setPrefix(prefix);
808: node.addPropertyChangeListener(listener);
809: }
810: }
811: }
812:
813: /**
814: * Set this group of Nodes as being selected.
815: *
816: * @param select true to select, false to de-select.
817: */
818: public void setSelected(boolean select) {
819: selected = select;
820: for (ExternalReferenceDataNode node : nodes) {
821: if (node.canSelect()) {
822: node.removePropertyChangeListener(listener);
823: node.setSelected(select);
824: node.addPropertyChangeListener(listener);
825: }
826: }
827: }
828: }
829:
830: /**
831: * This method is called from within the constructor to
832: * initializeTypeView the form.
833: * WARNING: Do NOT modify this code. The content of this method is
834: * always regenerated by the Form Editor.
835: */
836: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
837: private void initComponents() {
838:
839: locationLabel = new javax.swing.JLabel();
840: locationPanel = new javax.swing.JPanel();
841: namespaceLabel = new javax.swing.JLabel();
842: namespaceTextField = new javax.swing.JTextField();
843: messageLabel = new javax.swing.JLabel();
844:
845: locationLabel.setLabelFor(locationPanel);
846: org.openide.awt.Mnemonics.setLocalizedText(locationLabel,
847: org.openide.util.NbBundle.getBundle(
848: NamespaceReferenceCreator.class).getString(
849: "LBL_ExternalReferenceCreator_Location")); // NOI18N
850: locationLabel.setToolTipText(org.openide.util.NbBundle
851: .getBundle(NamespaceReferenceCreator.class).getString(
852: "TIP_ExternalReferenceCreator_Location")); // NOI18N
853:
854: locationPanel.setBorder(javax.swing.BorderFactory
855: .createEtchedBorder());
856: locationPanel.setLayout(new java.awt.BorderLayout());
857:
858: namespaceLabel.setLabelFor(namespaceTextField);
859: org.openide.awt.Mnemonics.setLocalizedText(namespaceLabel,
860: org.openide.util.NbBundle.getBundle(
861: NamespaceReferenceCreator.class).getString(
862: "LBL_ExternalReferenceCreator_Namespace")); // NOI18N
863: namespaceLabel.setToolTipText(org.openide.util.NbBundle
864: .getBundle(NamespaceReferenceCreator.class).getString(
865: "TIP_ExternalReferenceCreator_Namespace")); // NOI18N
866:
867: namespaceTextField.setEditable(false);
868:
869: messageLabel.setForeground(new java.awt.Color(255, 0, 0));
870: org.openide.awt.Mnemonics.setLocalizedText(messageLabel, " ");
871:
872: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
873: this );
874: this .setLayout(layout);
875: layout
876: .setHorizontalGroup(layout
877: .createParallelGroup(
878: org.jdesktop.layout.GroupLayout.LEADING)
879: .add(
880: layout
881: .createSequentialGroup()
882: .addContainerGap()
883: .add(
884: layout
885: .createParallelGroup(
886: org.jdesktop.layout.GroupLayout.LEADING)
887: .add(
888: locationPanel,
889: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
890: 382,
891: Short.MAX_VALUE)
892: .add(
893: org.jdesktop.layout.GroupLayout.TRAILING,
894: layout
895: .createSequentialGroup()
896: .add(
897: namespaceLabel)
898: .addPreferredGap(
899: org.jdesktop.layout.LayoutStyle.RELATED)
900: .add(
901: namespaceTextField,
902: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
903: 319,
904: Short.MAX_VALUE))
905: .add(
906: locationLabel)
907: .add(
908: messageLabel,
909: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
910: 382,
911: Short.MAX_VALUE))
912: .addContainerGap()));
913: layout
914: .setVerticalGroup(layout
915: .createParallelGroup(
916: org.jdesktop.layout.GroupLayout.LEADING)
917: .add(
918: org.jdesktop.layout.GroupLayout.TRAILING,
919: layout
920: .createSequentialGroup()
921: .addContainerGap()
922: .add(locationLabel)
923: .addPreferredGap(
924: org.jdesktop.layout.LayoutStyle.RELATED)
925: .add(
926: locationPanel,
927: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
928: 329, Short.MAX_VALUE)
929: .addPreferredGap(
930: org.jdesktop.layout.LayoutStyle.RELATED)
931: .add(
932: layout
933: .createParallelGroup(
934: org.jdesktop.layout.GroupLayout.TRAILING)
935: .add(
936: namespaceLabel)
937: .add(
938: namespaceTextField,
939: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
940: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
941: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
942: .addPreferredGap(
943: org.jdesktop.layout.LayoutStyle.RELATED)
944: .add(messageLabel)
945: .addContainerGap()));
946: }// </editor-fold>//GEN-END:initComponents
947:
948: // Variables declaration - do not modify//GEN-BEGIN:variables
949: public javax.swing.JLabel locationLabel;
950: public javax.swing.JPanel locationPanel;
951: public javax.swing.JLabel messageLabel;
952: public javax.swing.JLabel namespaceLabel;
953: public javax.swing.JTextField namespaceTextField;
954: // End of variables declaration//GEN-END:variables
955:
956: }
|