KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xam > ui > customizer > ExternalReferenceCustomizer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.xam.ui.customizer;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.net.URISyntaxException JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Set JavaDoc;
31 import javax.swing.ImageIcon JavaDoc;
32 import javax.swing.event.DocumentEvent JavaDoc;
33 import javax.swing.event.DocumentListener JavaDoc;
34 import javax.swing.tree.TreeSelectionModel JavaDoc;
35 import org.netbeans.api.project.FileOwnerQuery;
36 import org.netbeans.api.project.Project;
37 import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport;
38 import org.netbeans.modules.xml.xam.locator.CatalogModelException;
39 import org.netbeans.spi.project.ui.LogicalViewProvider;
40 import org.openide.explorer.view.BeanTreeView;
41 import org.netbeans.modules.xml.xam.Component;
42 import org.netbeans.modules.xml.xam.Model;
43 import org.openide.explorer.ExplorerManager;
44 import org.openide.filesystems.FileObject;
45 import org.openide.nodes.AbstractNode;
46 import org.openide.nodes.Children;
47 import org.openide.nodes.Node;
48 import org.openide.util.NbBundle;
49 import org.openide.util.Utilities;
50
51 /**
52  * Base class for external reference customizers.
53  *
54  * @author Ajit Bhate
55  * @author Nathan Fiedler
56  */

57 public abstract class ExternalReferenceCustomizer<T extends Component>
58         extends AbstractReferenceCustomizer<T>
59         implements DocumentListener JavaDoc, ExplorerManager.Provider,
60         PropertyChangeListener JavaDoc {
61     /** silence compiler warnings */
62     private static final long serialVersionUID = 1L;
63     /** If true, the prefix was generated and not edited by the user. */
64     private transient boolean prefixGenerated;
65     /** The file being modified (where the import will be added). */
66     private transient FileObject sourceFO;
67     /** The file selected by the user. */
68     private transient FileObject referencedFO;
69     /** Used to deal with project catalogs. */
70     private transient DefaultProjectCatalogSupport catalogSupport;
71     
72     /**
73      * Creates new form ExternalReferenceCustomizer
74      *
75      * @param component external reference to customize.
76      */

77     public ExternalReferenceCustomizer(T component, Model JavaDoc model) {
78         super(component);
79         initComponents();
80         sourceFO = (FileObject) component.getModel().getModelSource().
81                 getLookup().lookup(FileObject.class);
82         catalogSupport = DefaultProjectCatalogSupport.getInstance(sourceFO);
83         init(component, model);
84         initializeUI();
85         // View for selecting an external reference.
86
BeanTreeView locationView = new BeanTreeView();
87         locationView.setPopupAllowed(false);
88         locationView.setDefaultActionAllowed(false);
89         locationView.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
90         locationView.setRootVisible(false);
91         locationView.getAccessibleContext().setAccessibleName(locationLabel.getToolTipText());
92         locationView.getAccessibleContext().setAccessibleDescription(locationLabel.getToolTipText());
93         locationPanel.add(locationView, BorderLayout.CENTER);
94         explorerManager = new ExplorerManager();
95         explorerManager.addPropertyChangeListener(this);
96         explorerManager.setRootContext(createRootNode());
97     }
98
99     @Override JavaDoc
100     public void addNotify() {
101         super.addNotify();
102         // Force the Ok button to be disabled initially.
103
firePropertyChange(PROP_ACTION_APPLY, true, false);
104     }
105
106     public void applyChanges() throws IOException JavaDoc {
107         if (mustNamespaceDiffer() && isPrefixChanged()) {
108             prefixTextField.setEditable(false);
109         }
110         if (isLocationChanged() && referencedFO != null &&
111                 catalogSupport.needsCatalogEntry(sourceFO, referencedFO)) {
112             try {
113                 catalogSupport.createCatalogEntry(sourceFO, referencedFO);
114             } catch (IOException JavaDoc ioe) {
115             } catch (CatalogModelException cme) {
116             }
117         }
118     }
119
120     /**
121      * Retrieves the location value from the interface.
122      *
123      * @return new location value.
124      */

125     protected String JavaDoc getEditedLocation() {
126         if (referencedFO == null) {
127             return getReferenceLocation();
128         }
129         try {
130             return catalogSupport.getReferenceURI(sourceFO, referencedFO).toString();
131         } catch (URISyntaxException JavaDoc ex) {
132         }
133         return null;
134     }
135     
136     /**
137      * Retrieves the namespace value from the interface.
138      *
139      * @return new namespace value, sans leading and trailing whitespace.
140      */

141     protected String JavaDoc getEditedNamespace() {
142         return namespaceTextField.getText().trim();
143     }
144     
145     /**
146      * Retrieves the prefix value from the interface.
147      *
148      * @return new prefix value, sans leading and trailing whitespace.
149      */

150     protected String JavaDoc getEditedPrefix() {
151         return prefixTextField.getText().trim();
152     }
153     
154     /**
155      * Returns the location value from the original component.
156      *
157      * @return original location value.
158      */

159     protected abstract String JavaDoc getReferenceLocation();
160     
161     /**
162      * Returns the namespace value from the original component.
163      *
164      * @return original namespace value.
165      */

166     protected abstract String JavaDoc getNamespace();
167     
168     /**
169      * Returns the prefix value from the original component.
170      *
171      * @return original prefix value.
172      */

173     protected abstract String JavaDoc getPrefix();
174     
175     /**
176      * Generate a unique prefix value (e.g. "ns1") for the component.
177      *
178      * @return unique prefix value.
179      */

180     protected abstract String JavaDoc generatePrefix();
181     
182     /**
183      * Indicates if the location value was changed in the interface.
184      *
185      * @return true if location was changed.
186      */

187     protected boolean isLocationChanged() {
188         String JavaDoc rl = getReferenceLocation();
189         String JavaDoc el = getEditedLocation();
190         if (rl == null) {
191             return el != null;
192         }
193         return !rl.equals(el);
194     }
195     
196     /**
197      * Indicates if the namespace value was changed in the interface.
198      *
199      * @return true if namespace was changed.
200      */

201     protected boolean isNamespaceChanged() {
202         if (!mustNamespaceDiffer()) {
203             return false;
204         }
205         String JavaDoc ns = getNamespace();
206         String JavaDoc ens = getEditedNamespace();
207         if (ns == null) {
208             return ens.length() > 0;
209         }
210         return !ns.equals(ens);
211     }
212     
213     /**
214      * Indicates if the prefix value was changed in the interface.
215      *
216      * @return true if prefix was changed.
217      */

218     protected boolean isPrefixChanged() {
219         if (!mustNamespaceDiffer()) {
220             return false;
221         }
222         if (prefixGenerated) {
223             // User has not yet modified the prefix value.
224
return false;
225         }
226         String JavaDoc p = getPrefix();
227         String JavaDoc ep = getEditedPrefix();
228         if (p == null) {
229             return ep.length() > 0;
230         }
231         return !p.equals(ep);
232     }
233     
234     /**
235      * Called from constructor, after the interface components have been
236      * constructed, but before they have been initialized. Gives subclasses
237      * a chance to perform initialization based on the given component.
238      *
239      * @param component the reference to be customized.
240      * @param model the model passed to the constructor (may be null).
241      */

242     protected void init(T component, Model JavaDoc model) {
243         // Note, do not place any code here, as there is no guarantee
244
// that the subclasses will delegate to this method at all.
245
}
246
247     public void changedUpdate(DocumentEvent JavaDoc e) {
248     }
249
250     public void insertUpdate(DocumentEvent JavaDoc e) {
251         prefixGenerated = false;
252         validateInput();
253     }
254
255     public void removeUpdate(DocumentEvent JavaDoc e) {
256         prefixGenerated = false;
257         validateInput();
258     }
259     
260     protected void initializeUI() {
261         // TODO select in panel
262
if (mustNamespaceDiffer()) {
263             namespaceTextField.setText(getNamespace());
264             prefixTextField.getDocument().removeDocumentListener(this);
265             String JavaDoc prefix = getPrefix();
266             if (prefix != null) {
267                 prefixTextField.setText(prefix);
268                 prefixTextField.setEditable(false);
269                 prefixGenerated = false;
270             } else {
271                 prefix = generatePrefix();
272                 prefixGenerated = true;
273                 prefixTextField.setText(prefix);
274                 prefixTextField.getDocument().addDocumentListener(this);
275             }
276         } else {
277             namespaceLabel.setVisible(false);
278             namespaceTextField.setVisible(false);
279             prefixLabel.setVisible(false);
280             prefixTextField.setVisible(false);
281         }
282     }
283     
284     public ExternalReferenceDataNode createExternalReferenceNode(Node original) {
285         return new ExternalReferenceDataNode(original, getNodeDecorator());
286     }
287     
288     /**
289      * Determine if the user's input is valid or not. This will enable
290      * or disable the save/reset controls based on the results, as well
291      * as issue error messages.
292      */

293     private void validateInput() {
294         boolean lChanged = isLocationChanged();
295         boolean nsChanged = isNamespaceChanged();
296         boolean pChanged = isPrefixChanged();
297         if (!lChanged && !nsChanged && !pChanged) {
298             setSaveEnabled(false);
299             setResetEnabled(false);
300         } else {
301             setResetEnabled(true);
302             String JavaDoc msg = null;
303             if (mustNamespaceDiffer()) {
304                 if (lChanged && getEditedLocation() == null) {
305                     msg = NbBundle.getMessage(ExternalReferenceCustomizer.class,
306                             "LBL_ExternalReferenceCustomizer_InvalidLocation");
307                 }
308                 Map JavaDoc<String JavaDoc, String JavaDoc> prefixMap = getPrefixes(getModelComponent().getModel());
309                 String JavaDoc ep = getEditedPrefix();
310                 if (pChanged && (ep.length() == 0 || prefixMap.containsKey(ep))) {
311                     msg = NbBundle.getMessage(ExternalReferenceCustomizer.class,
312                             "LBL_ExternalReferenceCustomizer_InvalidPrefix");
313                 }
314             }
315             // Changing the location should allow the prefix to change.
316
prefixTextField.setEditable(lChanged);
317             if (msg != null) {
318                 showMessage(msg);
319             }
320             setSaveEnabled(msg == null);
321         }
322     }
323
324     protected void showMessage(String JavaDoc msg) {
325         if (msg == null) {
326             messageLabel.setText(" ");
327             messageLabel.setIcon(null);
328         } else {
329             messageLabel.setText(msg);
330             // Image is in openide/dialogs module.
331
messageLabel.setIcon(new ImageIcon JavaDoc(Utilities.loadImage(
332                     "org/openide/resources/error.gif"))); // NOI18N
333
}
334     }
335
336     protected Node createRootNode() {
337         Set JavaDoc/*<Project>*/ refProjects = null;
338         if (catalogSupport.supportsCrossProject()) {
339             refProjects = catalogSupport.getProjectReferences();
340         }
341         ExternalReferenceDecorator decorator = getNodeDecorator();
342         Node[] rootNodes = new Node[1 + (refProjects == null ? 0 : refProjects.size())];
343         Project prj = FileOwnerQuery.getOwner(sourceFO);
344         LogicalViewProvider viewProvider = (LogicalViewProvider) prj.getLookup().
345                 lookup(LogicalViewProvider.class);
346         rootNodes[0] = decorator.createExternalReferenceNode(
347                 viewProvider.createLogicalView());
348         int rootIndex = 1;
349         List JavaDoc<FileObject> projectRoots = new ArrayList JavaDoc<FileObject>();
350         projectRoots.add(prj.getProjectDirectory());
351         if (refProjects != null) {
352             for (Object JavaDoc o : refProjects) {
353                 Project refPrj = (Project) o;
354                 viewProvider = (LogicalViewProvider) refPrj.getLookup().
355                         lookup(LogicalViewProvider.class);
356                 rootNodes[rootIndex++] = decorator.createExternalReferenceNode(
357                         viewProvider.createLogicalView());
358                 projectRoots.add(refPrj.getProjectDirectory());
359             }
360         }
361         FileObject[] roots = projectRoots.toArray(
362                 new FileObject[projectRoots.size()]);
363         Children fileChildren = new Children.Array();
364         fileChildren.add(rootNodes);
365         Node byFilesNode = new FolderNode(fileChildren);
366         byFilesNode.setDisplayName(NbBundle.getMessage(
367                 ExternalReferenceCustomizer.class,
368                 "LBL_ExternalReferenceCustomizer_Category_By_File"));
369
370         // Construct the By Namespace node.
371
Children nsChildren = new NamespaceChildren(roots, decorator);
372         Node byNSNode = new FolderNode(nsChildren);
373         byNSNode.setDisplayName(NbBundle.getMessage(
374                 ExternalReferenceCustomizer.class,
375                 "LBL_ExternalReferenceCustomizer_Category_By_Namespace"));
376 // Hide the Retrieved node tree until we are sure the runtime can handle
377
// URLs with respect to the catalog.
378
// Node retrievedNode;
379
// CatalogWriteModel cwm = getCatalogWriteModel();
380
// if (cwm != null) {
381
// Children rChildren = new RetrievedFilesChildren(cwm , decorator);
382
// retrievedNode = new ExternalReferenceNode(projectNode, rChildren, decorator);
383
// } else {
384
// retrievedNode = new ExternalReferenceNode(projectNode, Children.LEAF, decorator);
385
// }
386
// retrievedNode.setDisplayName(NbBundle.getMessage(
387
// ExternalReferenceCustomizer.class,
388
// "LBL_ExternalReferenceCustomizer_Category_By_Retrieved"));
389
Children categories = new Children.Array();
390 // categories.add(new Node[]{ byFilesNode, byNSNode, retrievedNode });
391
categories.add(new Node[] { byFilesNode, byNSNode });
392         return new AbstractNode(categories);
393     }
394     
395 // private CatalogWriteModel getCatalogWriteModel() {
396
// try {
397
// FileObject myFobj = (FileObject) getModelComponent().getModel().
398
// getModelSource().getLookup().lookup(FileObject.class);
399
// CatalogWriteModel cwm = CatalogWriteModelFactory.getInstance().
400
// getCatalogWriteModelForProject(myFobj);
401
// return cwm;
402
// } catch (CatalogModelException cme) {
403
// }
404
// return null;
405
// }
406

407     public void propertyChange(PropertyChangeEvent JavaDoc event) {
408         if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) {
409             // Reset everything to assume an invalid selection.
410
showMessage(null);
411             setSaveEnabled(false);
412             String JavaDoc ns = null;
413             referencedFO = null;
414             Node[] nodes = (Node[]) event.getNewValue();
415             // Validate the node selection.
416
if (nodes != null && nodes.length > 0 &&
417                     nodes[0] instanceof ExternalReferenceNode) {
418                 ExternalReferenceNode node = (ExternalReferenceNode) nodes[0];
419                 Model JavaDoc model = node.getModel();
420                 // Without a model, the selection is completely invalid.
421
if (model != null) {
422                     ns = getTargetNamespace(model);
423                     if (model != getModelComponent().getModel()) {
424                         referencedFO = (FileObject) model.getModelSource().
425                                 getLookup().lookup(FileObject.class);
426                     }
427                     // Ask decorator if selection is valid or not.
428
String JavaDoc msg = getNodeDecorator().validate(node);
429                     if (msg != null) {
430                         showMessage(msg);
431                     } else {
432                         // If node is okay, validate the rest of the input.
433
validateInput();
434                     }
435                 }
436             }
437             namespaceTextField.setText(ns);
438         }
439     }
440     
441     public ExplorerManager getExplorerManager() {
442         return explorerManager;
443     }
444     
445     /**
446      * This method is called from within the constructor to
447      * initializeTypeView the form.
448      * WARNING: Do NOT modify this code. The content of this method is
449      * always regenerated by the Form Editor.
450      */

451     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
452
private void initComponents() {
453         locationLabel = new javax.swing.JLabel JavaDoc();
454         locationPanel = new javax.swing.JPanel JavaDoc();
455         namespaceLabel = new javax.swing.JLabel JavaDoc();
456         namespaceTextField = new javax.swing.JTextField JavaDoc();
457         prefixLabel = new javax.swing.JLabel JavaDoc();
458         prefixTextField = new javax.swing.JTextField JavaDoc();
459         messageLabel = new javax.swing.JLabel JavaDoc();
460
461         locationLabel.setLabelFor(locationPanel);
462         org.openide.awt.Mnemonics.setLocalizedText(locationLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Location"));
463         locationLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Location"));
464
465         locationPanel.setLayout(new java.awt.BorderLayout JavaDoc());
466
467         locationPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
468
469         namespaceLabel.setLabelFor(namespaceTextField);
470         org.openide.awt.Mnemonics.setLocalizedText(namespaceLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Namespace"));
471         namespaceLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Namespace"));
472
473         namespaceTextField.setEditable(false);
474
475         prefixLabel.setLabelFor(prefixTextField);
476         org.openide.awt.Mnemonics.setLocalizedText(prefixLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Prefix"));
477         prefixLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Prefix"));
478
479         prefixTextField.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Prefix"));
480
481         messageLabel.setForeground(new java.awt.Color JavaDoc(255, 0, 0));
482         org.openide.awt.Mnemonics.setLocalizedText(messageLabel, " ");
483
484         org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
485         this.setLayout(layout);
486         layout.setHorizontalGroup(
487             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
488             .add(layout.createSequentialGroup()
489                 .addContainerGap()
490                 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
491                     .add(messageLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
492                     .add(locationPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
493                     .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
494                         .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
495                             .add(namespaceLabel)
496                             .add(prefixLabel))
497                         .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
498                         .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
499                             .add(prefixTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)
500                             .add(namespaceTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)))
501                     .add(locationLabel))
502                 .addContainerGap())
503         );
504         layout.setVerticalGroup(
505             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
506             .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
507                 .addContainerGap()
508                 .add(locationLabel)
509                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
510                 .add(locationPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE)
511                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
512                 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
513                     .add(namespaceLabel)
514                     .add(namespaceTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
515                 .add(12, 12, 12)
516                 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
517                     .add(prefixLabel)
518                     .add(prefixTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
519                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
520                 .add(messageLabel)
521                 .addContainerGap())
522         );
523     }// </editor-fold>//GEN-END:initComponents
524

525     // Variables declaration - do not modify//GEN-BEGIN:variables
526
public javax.swing.JLabel JavaDoc locationLabel;
527     public javax.swing.JPanel JavaDoc locationPanel;
528     public javax.swing.JLabel JavaDoc messageLabel;
529     public javax.swing.JLabel JavaDoc namespaceLabel;
530     public javax.swing.JTextField JavaDoc namespaceTextField;
531     public javax.swing.JLabel JavaDoc prefixLabel;
532     public javax.swing.JTextField JavaDoc prefixTextField;
533     // End of variables declaration//GEN-END:variables
534
}
535
Popular Tags