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.xml.wizard;
043:
044: import java.io.File;
045: import java.net.URI;
046: import java.net.URISyntaxException;
047: import org.openide.loaders.DataObject;
048: import org.openide.nodes.FilterNode;
049: import org.openide.nodes.Node;
050: import org.openide.ErrorManager;
051: import org.openide.filesystems.FileObject;
052: import org.openide.filesystems.FileUtil;
053: import org.openide.nodes.Node.Property;
054: import org.openide.nodes.PropertySupport.Reflection;
055: import org.openide.nodes.Sheet;
056: import org.openide.nodes.Sheet.Set;
057: import org.openide.util.NbBundle;
058:
059: /**
060: * Represents a collection of external references, or a single file.
061: *
062: * @author Ajit Bhate
063: * @author Nathan Fiedler
064: */
065: public class ExternalReferenceDataNode extends FilterNode {
066: /** Name of the 'selected' property. */
067: public static final String PROP_SELECTED = "selected";
068: /** Name of the 'prefix' property. */
069: public static final String PROP_PREFIX = "prefix";
070: /** Set of PropertySets. */
071: private Sheet sheet;
072: /** True if selected, false otherwise. */
073: private boolean selected;
074: /** The namespace prefix, if specified. */
075: private String prefix = null;
076: private static int counter = 0;
077: private ExternalReferenceDecorator decorator;
078:
079: /**
080: * Creates a new instance of ExternalReferenceDataNode.
081: *
082: * @param original the delegate Node.
083: * @param decorator the external reference decorator.
084: */
085: public ExternalReferenceDataNode(Node original,
086: ExternalReferenceDecorator dec) {
087: super (original, new Children(original, dec));
088: this .decorator = dec;
089:
090: }
091:
092: public boolean canRename() {
093: // Disable rename as it serves no purpose here and makes the
094: // single-click-select-toggle difficult to use.
095: return false;
096: }
097:
098: /**
099: * Indicates if this node allows setting it selected.
100: *
101: * @return true if this node can be selected, false otherwise.
102: */
103: public boolean canSelect() {
104: DataObject dobj = (DataObject) getLookup().lookup(
105: DataObject.class);
106: return dobj != null && !dobj.getPrimaryFile().isFolder();
107: }
108:
109: /**
110: * Creates a node property of the given key (same as the column keys)
111: * and specific getter/setter methods on the given object.
112: *
113: * @param key property name (same as matching column).
114: * @param type Class of the property (e.g. String.class).
115: * @param inst object on which to reflect.
116: * @param getter name of getter method for property value.
117: * @param setter name of setter method for property value (may be null).
118: * @return new property.
119: */
120: private Node.Property createProperty(String key, Class type,
121: Object inst, String getter, String setter) {
122: Property prop = null;
123: try {
124: prop = new Reflection(inst, type, getter, setter);
125: prop.setName(key);
126: prop.setDisplayName(NbBundle.getMessage(
127: ExternalReferenceDataNode.class,
128: "CTL_SchemaPanel_Column_Name_" + key));
129: prop.setShortDescription(NbBundle.getMessage(
130: ExternalReferenceDataNode.class,
131: "CTL_SchemaPanel_Column_Desc_" + key));
132: } catch (NoSuchMethodException nsme) {
133: ErrorManager.getDefault().notify(nsme);
134: }
135: return prop;
136: }
137:
138: protected Sheet createSheet() {
139: Sheet sheet = Sheet.createDefault();
140: Set set = sheet.get(Sheet.PROPERTIES);
141: set.put(createProperty(PROP_NAME, String.class, this ,
142: "getHtmlDisplayName", null));
143: if (canSelect()) {
144: set.put(createProperty(PROP_SELECTED, Boolean.TYPE, this ,
145: "isSelected", "setSelected"));
146: // Node.Property prop = createProperty(PROP_PREFIX, String.class,
147: // this, "getPrefix", "setPrefix");
148: // Suppress the [...] button because it is not needed.
149: // prop.setValue("suppressCustomEditor", Boolean.TRUE);
150: // set.put(prop);
151: } /*else {
152: // Do not include this property so the checkbox is not shown.
153: //set.put(createProperty(PROP_SELECTED, Boolean.TYPE, this,
154: // "isSelected", null));
155: Node.Property prop = createProperty(PROP_PREFIX, String.class,
156: this, "getPrefix", null);
157: // Suppress the [...] button because it is not needed.
158: prop.setValue("suppressCustomEditor", Boolean.TRUE);
159: set.put(prop);
160: }*/
161: return sheet;
162: }
163:
164: protected final synchronized Sheet getSheet() {
165: if (sheet != null) {
166: return sheet;
167: }
168: sheet = createSheet();
169: firePropertySetsChange(null, null);
170: return sheet;
171: }
172:
173: public PropertySet[] getPropertySets() {
174: Sheet s = getSheet();
175: return s.toArray();
176: }
177:
178: public String getHtmlDisplayName() {
179: String name = getOriginal().getHtmlDisplayName();
180: return name;
181: }
182:
183: public String getPrefix() {
184:
185: if (prefix == null) {
186: DataObject dobj = (DataObject) getLookup().lookup(
187: DataObject.class);
188: if (dobj != null && !(dobj.getPrimaryFile().isFolder()))
189: prefix = decorator.generatePrefix(prefix, dobj);
190: else
191: prefix = "";
192: }
193: return prefix;
194: }
195:
196: public boolean isSelected() {
197: return selected;
198: }
199:
200: public void setDisplayName(String s) {
201: super .disableDelegation(DELEGATE_GET_DISPLAY_NAME
202: | DELEGATE_SET_DISPLAY_NAME);
203: super .setDisplayName(s);
204: }
205:
206: /**
207: * Set the namespace prefix for this node.
208: *
209: * @param prefix new namespace prefix.
210: */
211: public void setPrefix(String prefix) {
212: String old = this .prefix;
213: this .prefix = prefix;
214: firePropertyChange(PROP_PREFIX, old, prefix);
215: }
216:
217: /**
218: * Mark this node as selected.
219: *
220: * @param selected true to select, false to unselect.
221: */
222: public void setSelected(boolean selected) {
223: if (!canSelect()) {
224: throw new IllegalStateException("node cannot be selected");
225: }
226: boolean old = this .selected;
227: this .selected = selected;
228: firePropertyChange(PROP_SELECTED, new Boolean(old),
229: new Boolean(selected));
230: }
231:
232: public String getNamespace() {
233: DataObject dobj = (DataObject) getLookup().lookup(
234: DataObject.class);
235: if (dobj != null) {
236: FileObject fobj = dobj.getPrimaryFile();
237: return Util.getNamespace(fobj);
238: }
239: return null;
240: }
241:
242: public String getSchemaFileName() {
243: DataObject dobj = (DataObject) getLookup().lookup(
244: DataObject.class);
245: if (dobj != null) {
246: FileObject fobj = dobj.getPrimaryFile();
247: File file = FileUtil.toFile(fobj);
248: String uri = file.getPath();
249: if (uri != null) {
250: try {
251: // escape the non-ASCII characters
252: uri = new URI(uri).toASCIIString();
253: } catch (URISyntaxException e) {
254: // the specified uri is not valid, it is too late to fix it now
255: }
256: }
257: return uri;
258: }
259:
260: return null;
261:
262: }
263:
264: private static class Children extends FilterNode.Children {
265: /** Controls the appearance of child nodes. */
266: ExternalReferenceDecorator decorator;
267:
268: public Children(Node original, ExternalReferenceDecorator dec) {
269: super (original);
270: this .decorator = dec;
271: }
272:
273: protected Node[] createNodes(Node n) {
274: DataObject dobj = (DataObject) n.getLookup().lookup(
275: DataObject.class);
276: if (dobj != null) {
277: FileObject fobj = dobj.getPrimaryFile();
278: if (fobj.isFolder()
279: && fobj.getNameExt().equals("nbproject")
280: && fobj.getFileObject("project.xml") != null) {
281: // It is the NetBeans project folder, ignore it.
282: return new Node[0];
283: }
284: String fname = fobj.getNameExt();
285: String ext = decorator.getDocumentType();
286: if (fobj.isFolder() || fname.endsWith(ext)) {
287: return super .createNodes(n);
288: }
289: }
290: return new Node[0];
291: }
292:
293: protected Node copyNode(Node node) {
294: return decorator.createExternalReferenceNode(node);
295: }
296:
297: }
298: }
|