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-2006 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: package org.netbeans.modules.xml.wsdl.ui.api.property;
042:
043: import java.io.File;
044: import java.io.FileFilter;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import java.util.Collections;
048: import java.util.List;
049: import java.util.Set;
050:
051: import javax.xml.XMLConstants;
052:
053: import org.netbeans.api.project.FileOwnerQuery;
054: import org.netbeans.api.project.Project;
055: import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport;
056: import org.netbeans.modules.xml.schema.model.GlobalComplexType;
057: import org.netbeans.modules.xml.schema.model.GlobalElement;
058: import org.netbeans.modules.xml.schema.model.GlobalSimpleType;
059: import org.netbeans.modules.xml.schema.model.Schema;
060: import org.netbeans.modules.xml.schema.model.SchemaComponent;
061: import org.netbeans.modules.xml.schema.model.SchemaComponentReference;
062: import org.netbeans.modules.xml.schema.model.SchemaModel;
063: import org.netbeans.modules.xml.schema.model.SchemaModelFactory;
064: import org.netbeans.modules.xml.schema.ui.nodes.categorized.CategorizedSchemaNodeFactory;
065: import org.netbeans.modules.xml.wsdl.model.Definitions;
066: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
067: import org.netbeans.modules.xml.wsdl.ui.view.treeeditor.NodesFactory;
068: import org.netbeans.modules.xml.wsdl.ui.wsdl.nodes.BuiltInTypeFolderNode;
069: import org.netbeans.modules.xml.xam.Model;
070: import org.netbeans.modules.xml.xam.ModelSource;
071: import org.netbeans.modules.xml.xam.ui.customizer.FolderNode;
072: import org.netbeans.spi.project.ui.LogicalViewProvider;
073: import org.openide.filesystems.FileObject;
074: import org.openide.filesystems.FileUtil;
075: import org.openide.loaders.DataObject;
076: import org.openide.nodes.FilterNode;
077: import org.openide.nodes.Node;
078: import org.openide.nodes.FilterNode.Children;
079: import org.openide.util.Lookup;
080: import org.openide.util.NbBundle;
081:
082: public class ElementOrTypeChooserHelper extends
083: ChooserHelper<SchemaComponent> {
084:
085: private Node inlineSchemaFolderNode;
086: private Node builtinSchemaFolderNode;
087: private Node projectsFolderNode;
088: private WSDLModel model;
089: private List<Class<? extends SchemaComponent>> filters;
090: private Project project;
091:
092: public ElementOrTypeChooserHelper(WSDLModel model) {
093: this .model = model;
094: }
095:
096: //Called from wizard. the model may not be in the project, if created in temporary location
097: public ElementOrTypeChooserHelper(Project project, WSDLModel model) {
098: this .model = model;
099: this .project = project;
100: }
101:
102: @Override
103: public void populateNodes(Node parentNode) {
104: ArrayList<Node> chooserFolders = new ArrayList<Node>();
105: filters = new ArrayList<Class<? extends SchemaComponent>>();
106: filters.add(GlobalSimpleType.class);
107: filters.add(GlobalComplexType.class);
108: filters.add(GlobalElement.class);
109:
110: if (project == null) {
111: FileObject wsdlFile = model.getModelSource().getLookup()
112: .lookup(FileObject.class);
113: if (wsdlFile != null) {
114: project = FileOwnerQuery.getOwner(wsdlFile);
115: }
116: }
117: if (project != null) {
118: projectsFolderNode = new FolderNode(new Children.Array());
119: projectsFolderNode.setDisplayName(NbBundle.getMessage(
120: ElementOrTypeChooserHelper.class,
121: "LBL_ByFile_DisplayName"));
122: LogicalViewProvider viewProvider = project.getLookup()
123: .lookup(LogicalViewProvider.class);
124:
125: ArrayList<Node> nodes = new ArrayList<Node>();
126: nodes
127: .add(new EnabledNode(new SchemaProjectFolderNode(
128: viewProvider.createLogicalView(), project,
129: filters)));
130:
131: DefaultProjectCatalogSupport catalogSupport = new DefaultProjectCatalogSupport(
132: project);
133: Set refProjects = catalogSupport.getProjectReferences();
134: if (refProjects != null && refProjects.size() > 0) {
135: for (Object o : refProjects) {
136: Project refPrj = (Project) o;
137: viewProvider = refPrj.getLookup().lookup(
138: LogicalViewProvider.class);
139: nodes.add(new EnabledNode(
140: new SchemaProjectFolderNode(viewProvider
141: .createLogicalView(), refPrj,
142: filters)));
143: }
144: }
145: projectsFolderNode.getChildren().add(
146: nodes.toArray(new Node[nodes.size()]));
147: }
148:
149: if (model != null) {
150: Definitions def = model.getDefinitions();
151: if (def.getTypes() != null) {
152: Collection<Schema> schemas = def.getTypes()
153: .getSchemas();
154: if (schemas != null && !schemas.isEmpty()) {
155: List<Schema> filteredSchemas = new ArrayList<Schema>();
156: for (Schema schema : schemas) {
157: Collection<SchemaComponent> children = schema
158: .getChildren();
159: for (SchemaComponent comp : children) {
160: boolean isInstance = false;
161: for (Class clazz : filters) {
162: if (clazz.isInstance(comp)) {
163: isInstance = true;
164: break;
165: }
166: }
167: if (isInstance) {
168: filteredSchemas.add(schema);
169: break;
170: }
171: }
172: }
173: if (filteredSchemas.size() > 0) {
174: inlineSchemaFolderNode = new InlineTypesFolderNode(
175: NodesFactory.getInstance().create(
176: def.getTypes()),
177: filteredSchemas, filters);
178: }
179: }
180: }
181: }
182:
183: builtinSchemaFolderNode = new BuiltInTypeFolderNode();
184:
185: if (projectsFolderNode != null) {
186: chooserFolders.add(projectsFolderNode);
187: }
188: if (inlineSchemaFolderNode != null) {
189: chooserFolders.add(inlineSchemaFolderNode);
190: }
191:
192: chooserFolders.add(builtinSchemaFolderNode);
193:
194: parentNode.getChildren()
195: .add(
196: chooserFolders.toArray(new Node[chooserFolders
197: .size()]));
198: }
199:
200: @Override
201: public Node selectNode(SchemaComponent comp) {
202: if (comp == null)
203: return null;
204: Node selected = null;
205: if (comp != null) {
206: String tns = comp.getModel().getSchema()
207: .getTargetNamespace();
208: if (tns != null) {
209: if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(tns)) {
210: selected = selectNode(builtinSchemaFolderNode, comp);
211: } else {
212: if (inlineSchemaFolderNode == null
213: || (selected = selectNode(
214: inlineSchemaFolderNode, comp)) == null) {
215: selected = projectsFolderNode != null ? selectNode(
216: projectsFolderNode, comp)
217: : null;
218: }
219: }
220: } else {
221: // must be inline.
222: if (inlineSchemaFolderNode != null) {
223: selected = selectNode(inlineSchemaFolderNode, comp);
224: }
225: }
226: }
227: return selected;
228: }
229:
230: private Node selectNode(Node parentNode, SchemaComponent element) {
231: org.openide.nodes.Children children = parentNode.getChildren();
232: for (Node node : children.getNodes()) {
233: SchemaComponent sc = null;
234: SchemaComponentReference reference = node.getLookup()
235: .lookup(SchemaComponentReference.class);
236: if (reference != null) {
237: sc = reference.get();
238: }
239: if (sc == null) {
240: sc = node.getLookup().lookup(SchemaComponent.class);
241: }
242:
243: if (sc == element) {
244: return node;
245: }
246:
247: Node node1 = null;
248: if ((node1 = selectNode(node, element)) != null) {
249: return node1;
250: }
251: }
252: return null;
253: }
254:
255: class SchemaProjectFolderNode extends FilterNode {
256: public SchemaProjectFolderNode(Node original, Project project,
257: List<Class<? extends SchemaComponent>> filters) {
258: super (original, new SchemaProjectFolderChildren(project,
259: filters));
260: }
261: }
262:
263: class SchemaProjectFolderChildren extends Children.Keys<FileObject> {
264:
265: private final FileObject projectDir;
266: private final Project wsdlProject;
267: private final List<Class<? extends SchemaComponent>> schemaComponentFilters;
268: private Set<FileObject> emptySet = Collections.emptySet();
269:
270: public SchemaProjectFolderChildren(Project project,
271: List<Class<? extends SchemaComponent>> filters) {
272: this .wsdlProject = project;
273: this .schemaComponentFilters = filters;
274: this .projectDir = project.getProjectDirectory();
275: }
276:
277: @Override
278: public Node[] createNodes(FileObject fo) {
279: ModelSource modelSource = org.netbeans.modules.xml.retriever.catalog.Utilities
280: .getModelSource(fo, false);
281: SchemaModel schemaModel = SchemaModelFactory.getDefault()
282: .getModel(modelSource);
283: CategorizedSchemaNodeFactory factory = new CategorizedSchemaNodeFactory(
284: schemaModel, schemaComponentFilters, Lookup.EMPTY);
285: return new Node[] { new FileNode(factory
286: .createNode(schemaModel.getSchema()), FileUtil
287: .getRelativePath(projectDir, fo)) };
288:
289: }
290:
291: @Override
292: protected void addNotify() {
293: resetKeys();
294: }
295:
296: @Override
297: protected void removeNotify() {
298: this .setKeys(emptySet);
299:
300: }
301:
302: private void resetKeys() {
303: ArrayList<FileObject> keys = new ArrayList<FileObject>();
304: LogicalViewProvider viewProvider = wsdlProject.getLookup()
305: .lookup(LogicalViewProvider.class);
306: Node node = viewProvider.createLogicalView();
307: org.openide.nodes.Children children = node.getChildren();
308: for (Node child : children.getNodes()) {
309: DataObject dobj = child.getCookie(DataObject.class);
310: if (dobj != null) {
311: File[] files = recursiveListFiles(FileUtil
312: .toFile(dobj.getPrimaryFile()),
313: new SchemaFileFilter());
314: for (File file : files) {
315: FileObject fo = FileUtil.toFileObject(file);
316: ModelSource modelSource = org.netbeans.modules.xml.retriever.catalog.Utilities
317: .getModelSource(fo, false);
318: SchemaModel schemaModel = SchemaModelFactory
319: .getDefault().getModel(modelSource);
320: if (schemaModel != null
321: && schemaModel.getState() == Model.State.VALID
322: && schemaModel.getSchema()
323: .getTargetNamespace() != null) {
324: keys.add(fo);
325: }
326: }
327: }
328: }
329: this .setKeys(keys);
330: }
331:
332: }
333:
334: public static final String SCHEMA_FILE_EXTENSION = "xsd";
335:
336: static class SchemaFileFilter implements FileFilter {
337:
338: public boolean accept(File pathname) {
339: boolean result = false;
340: String fileName = pathname.getName();
341: String fileExtension = null;
342: int dotIndex = fileName.lastIndexOf('.');
343: if (dotIndex != -1) {
344: fileExtension = fileName.substring(dotIndex + 1);
345: }
346:
347: if (fileExtension != null
348: && (fileExtension
349: .equalsIgnoreCase(SCHEMA_FILE_EXTENSION))) {
350: result = true;
351: }
352:
353: return result;
354: }
355: }
356:
357: static class InlineTypesFolderNode extends FilterNode {
358: private Collection<Schema> mSchemas;
359: private List<Class<? extends SchemaComponent>> filters;
360:
361: public InlineTypesFolderNode(Node node,
362: Collection<Schema> schemas,
363: List<Class<? extends SchemaComponent>> filters) {
364: super (node);
365: mSchemas = schemas;
366: this .filters = filters;
367: setDisplayName(NbBundle.getMessage(
368: ElementOrTypeChooserHelper.class,
369: "INLINE_SCHEMATYPE_NAME"));
370: setChildren(new TypesChildren());
371: }
372:
373: class TypesChildren extends Children.Keys<Schema> {
374:
375: Set<Schema> set = Collections.emptySet();
376:
377: public TypesChildren() {
378:
379: }
380:
381: @Override
382: protected Node[] createNodes(Schema key) {
383: CategorizedSchemaNodeFactory factory = new CategorizedSchemaNodeFactory(
384: key.getModel(), filters, Lookup.EMPTY);
385: Node node = factory.createNode(key);
386: return new Node[] { node };
387:
388: }
389:
390: @Override
391: protected void addNotify() {
392: resetKeys();
393: }
394:
395: @Override
396: protected void removeNotify() {
397: this .setKeys(set);
398:
399: }
400:
401: private void resetKeys() {
402: this.setKeys(mSchemas);
403: }
404:
405: }
406: }
407:
408: }
|