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: package org.netbeans.modules.xml.wsdl.ui.wizard;
042:
043: import java.awt.Component;
044: import java.awt.Container;
045: import java.io.BufferedOutputStream;
046: import java.io.File;
047: import java.io.IOException;
048: import java.io.OutputStream;
049: import java.io.OutputStreamWriter;
050: import java.io.Writer;
051: import java.net.URI;
052: import java.net.URISyntaxException;
053: import java.util.ArrayList;
054: import java.util.Arrays;
055: import java.util.Collection;
056: import java.util.HashSet;
057: import java.util.Iterator;
058: import java.util.List;
059: import java.util.NoSuchElementException;
060: import java.util.Set;
061: import java.util.logging.Level;
062: import java.util.logging.Logger;
063:
064: import javax.swing.JComponent;
065: import javax.swing.JTextField;
066: import javax.swing.event.ChangeListener;
067: import javax.swing.text.BadLocationException;
068: import javax.swing.text.Document;
069:
070: import org.netbeans.api.project.Project;
071: import org.netbeans.api.project.SourceGroup;
072: import org.netbeans.api.project.Sources;
073: import org.netbeans.modules.xml.api.EncodingUtil;
074: import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport;
075: import org.netbeans.modules.xml.schema.model.Import;
076: import org.netbeans.modules.xml.schema.model.Schema;
077: import org.netbeans.modules.xml.schema.model.SchemaModel;
078: import org.netbeans.modules.xml.wsdl.model.Definitions;
079: import org.netbeans.modules.xml.wsdl.model.Types;
080: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
081: import org.netbeans.modules.xml.wsdl.model.extensions.xsd.WSDLSchema;
082: import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
083: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
084: import org.netbeans.modules.xml.xam.ui.ProjectConstants;
085: import org.netbeans.spi.project.ui.templates.support.Templates;
086: import org.openide.ErrorManager;
087: import org.openide.WizardDescriptor;
088: import org.openide.WizardDescriptor.Panel;
089: import org.openide.filesystems.FileLock;
090: import org.openide.filesystems.FileObject;
091: import org.openide.filesystems.FileSystem;
092: import org.openide.filesystems.FileUtil;
093: import org.openide.loaders.DataFolder;
094: import org.openide.loaders.DataObject;
095: import org.openide.loaders.TemplateWizard;
096:
097: public final class NewWSDLWizardIterator implements
098: TemplateWizard.Iterator {
099:
100: private int index;
101: private WizardDescriptor.Panel[] panels;
102: private WizardDescriptor.Panel folderPanel;
103: private static final Logger logger = Logger
104: .getLogger(NewWSDLWizardIterator.class.getName());
105:
106: /**
107: * Initialize panels representing individual wizard's steps and sets
108: * various properties for them influencing wizard appearance.
109: */
110: private Panel[] createPanels(Project project, TemplateWizard wizard) {
111: Sources sources = project.getLookup().lookup(
112: org.netbeans.api.project.Sources.class);
113: List<SourceGroup> roots = new ArrayList<SourceGroup>();
114: SourceGroup[] javaRoots = sources
115: .getSourceGroups(ProjectConstants.JAVA_SOURCES_TYPE);
116: roots.addAll(Arrays.asList(javaRoots));
117: if (roots.isEmpty()) {
118: SourceGroup[] sourceGroups = sources
119: .getSourceGroups(Sources.TYPE_GENERIC);
120: roots.addAll(Arrays.asList(sourceGroups));
121: }
122: DataFolder folder = DataFolder.findFolder(roots.get(0)
123: .getRootFolder());
124: DataFolder projectFolder = DataFolder.findFolder(project
125: .getProjectDirectory());
126: try {
127: if (wizard.getTargetFolder().equals(projectFolder)) {
128: wizard.setTargetFolder(folder);
129: }
130: } catch (IOException ioe) {
131: wizard.setTargetFolder(folder);
132: }
133: SourceGroup[] sourceGroups = roots
134: .toArray(new SourceGroup[roots.size()]);
135: folderPanel = new WsdlPanel(project);
136: // creates simple wizard panel with bottom panel
137: WizardDescriptor.Panel firstPanel = new WizardNewWSDLStep(
138: Templates.createSimpleTargetChooser(project,
139: sourceGroups, folderPanel));
140: JComponent c = (JComponent) firstPanel.getComponent();
141: // the bottom panel should listen to changes on file name text field
142: ((WsdlPanel) folderPanel).setNameTF(findFileNameField(c,
143: Templates.getTargetName(wizard)));
144:
145: WizardDescriptor.Panel secondPanel = new WizardPortTypeConfigurationStep(
146: project);
147: WizardDescriptor.Panel thirdPanel = new WizardBindingConfigurationStep();
148:
149: return new WizardDescriptor.Panel[] { firstPanel, secondPanel,
150: thirdPanel };
151: }
152:
153: public Set<DataObject> instantiate(final TemplateWizard wiz)
154: throws IOException {
155: //Copy contents of temp model to a new file.
156: //find the dataobject for the new file and return it.
157: final FileObject dir = Templates.getTargetFolder(wiz);
158: final String encoding = (String) wiz
159: .getProperty(WsdlPanel.ENCODING);
160: final String name = Templates.getTargetName(wiz);
161: FileSystem filesystem = dir.getFileSystem();
162: final FileObject[] fileObject = new FileObject[1];
163: FileSystem.AtomicAction fsAction = new FileSystem.AtomicAction() {
164:
165: public void run() throws IOException {
166:
167: FileObject fo = dir.createData(name, "wsdl"); //NOI18N
168:
169: FileLock lock = null;
170: try {
171: lock = fo.lock();
172: OutputStream out = fo.getOutputStream(lock);
173: out = new BufferedOutputStream(out);
174: Writer writer = new OutputStreamWriter(out,
175: encoding);
176: WSDLModel tempModel = (WSDLModel) wiz
177: .getProperty(WizardPortTypeConfigurationStep.TEMP_WSDLMODEL);
178:
179: DefaultProjectCatalogSupport catalogSupport = DefaultProjectCatalogSupport
180: .getInstance(fo);
181:
182: if (tempModel != null) {
183: try {
184: postProcessImports(tempModel, fo,
185: catalogSupport);
186: addSchemaImport(tempModel, fo,
187: catalogSupport);
188: } catch (Exception ex) {
189: ErrorManager.getDefault().notify(ex);
190: }
191:
192: Document doc = tempModel.getBaseDocument();
193: try {
194: writer.write(doc
195: .getText(0, doc.getLength()));
196: writer.flush();
197: } catch (BadLocationException e) {
198: ErrorManager.getDefault().notify(e);
199: } finally {
200: writer.close();
201: }
202:
203: fileObject[0] = fo;
204: }
205: } finally {
206: if (lock != null) {
207: lock.releaseLock();
208: }
209: }
210: }
211: };
212:
213: filesystem.runAtomicAction(fsAction);
214:
215: Set set = new HashSet(1);
216: DataObject createdObject = DataObject.find(fileObject[0]);
217: set.add(createdObject);
218: return set;
219:
220: }
221:
222: private void postProcessImports(WSDLModel model, FileObject fobj,
223: DefaultProjectCatalogSupport catalogSupport)
224: throws Exception {
225: Types types = model.getDefinitions().getTypes();
226: if (types != null) {
227: Collection<WSDLSchema> schemas = types
228: .getExtensibilityElements(WSDLSchema.class);
229:
230: if (schemas != null) {
231:
232: if (schemas.iterator().hasNext()) {
233: WSDLSchema wsdlSchema = schemas.iterator().next();
234: SchemaModel sModel = wsdlSchema.getSchemaModel();
235: if (sModel != null) {
236: Schema schema = sModel.getSchema();
237: if (schema != null
238: && schema.getImports() != null) {
239: model.startTransaction();
240: Iterator<Import> it = schema.getImports()
241: .iterator();
242: while (it.hasNext()) {
243: Import imp = it.next();
244: postProcessImport(imp, sModel, fobj,
245: catalogSupport);
246: }
247: model.endTransaction();
248: }
249:
250: }
251: }
252: }
253: }
254: }
255:
256: private void postProcessImport(Import imp, SchemaModel model,
257: FileObject fobj, DefaultProjectCatalogSupport catalogSupport) {
258: String namespace = imp.getNamespace();
259: Collection<Schema> schemas = model.findSchemas(namespace);
260: Iterator<Schema> it = schemas.iterator();
261: while (it.hasNext()) {
262: Schema schema = it.next();
263: SchemaModel sModel = schema.getModel();
264: FileObject schemaFileObj = sModel.getModelSource()
265: .getLookup().lookup(FileObject.class);
266: URI uri = null;
267: try {
268: uri = schemaFileObj.getURL().toURI();
269: } catch (Exception e) {
270: logger
271: .log(Level.SEVERE, "Not able to convert "
272: + schemaFileObj.getName()
273: + "to a valid URI", e);
274: }
275: String location = getRelativePathOfSchema(fobj, uri,
276: catalogSupport);
277: imp.setSchemaLocation(location);
278: }
279: }
280:
281: private void addSchemaImport(WSDLModel model, FileObject fobj,
282: DefaultProjectCatalogSupport catalogSupport) {
283: WsdlPanel panel = (WsdlPanel) folderPanel;
284: WsdlUIPanel.SchemaInfo[] infos = panel.getSchemas();
285: if (panel.isImport() && infos.length > 0) {
286: String targetNamespace = panel.getNS();
287:
288: Schema schema = null;
289: WSDLSchema wsdlSchema = null;
290:
291: for (int i = 0; i < infos.length; i++) {
292: String ns = infos[i].getNamespace();
293: if (ns.length() == 0) {
294: ns = targetNamespace;
295: }
296:
297: String prefix = "ns" + String.valueOf(i + 1);
298:
299: String relativePath = null;
300: String schemaFileName = infos[i].getSchemaName();
301: File schemaFile = new File(schemaFileName);
302: URI schemaFileURI = null;
303: if (schemaFile.exists()) {
304: schemaFile = FileUtil.normalizeFile(schemaFile);
305: FileObject schemaFO = FileUtil
306: .toFileObject(schemaFile);
307: try {
308: schemaFileURI = schemaFO.getURL().toURI();
309: } catch (Exception e) {
310: logger.log(Level.SEVERE, "Not able to convert "
311: + schemaFileName + "to a valid URI", e);
312: }
313: }
314: if (schemaFileURI == null) {
315: try {
316: schemaFileURI = new URI(schemaFileName);
317: } catch (URISyntaxException e) {
318: logger.log(Level.SEVERE, schemaFileName
319: + "is not a valid URI", e);
320: }
321: }
322: relativePath = getRelativePathOfSchema(fobj,
323: schemaFileURI, catalogSupport);
324:
325: Definitions def = model.getDefinitions();
326: model.startTransaction();
327: try {
328: Types types = def.getTypes();
329: if (types == null) {
330: types = model.getFactory().createTypes();
331: def.setTypes(types);
332: }
333:
334: List<WSDLSchema> wsdlSchemas = types
335: .getExtensibilityElements(WSDLSchema.class);
336:
337: if (wsdlSchemas == null || wsdlSchemas.size() == 0) {
338: wsdlSchema = model.getFactory()
339: .createWSDLSchema();
340: SchemaModel schemaModel = wsdlSchema
341: .getSchemaModel();
342: schema = schemaModel.getSchema();
343: schema.setTargetNamespace(model
344: .getDefinitions().getTargetNamespace());
345: types.addExtensibilityElement(wsdlSchema);
346: } else {
347: wsdlSchema = wsdlSchemas.get(0);
348: SchemaModel schemaModel = wsdlSchema
349: .getSchemaModel();
350: schema = schemaModel.getSchema();
351: }
352:
353: if (!isSchemaImportExists(relativePath, ns, schema)) {
354: schema.addPrefix(prefix, ns);
355: ((AbstractDocumentComponent) def).addPrefix(
356: prefix, ns);
357:
358: org.netbeans.modules.xml.schema.model.Import schemaImport = schema
359: .getModel().getFactory().createImport();
360: schemaImport.setNamespace(ns);
361: schemaImport.setSchemaLocation(relativePath);
362:
363: schema.addExternalReference(schemaImport);
364: }
365: } finally {
366: model.endTransaction();
367: }
368: }
369: }
370:
371: }
372:
373: private boolean isSchemaImportExists(String schemaLocation,
374: String namespace, Schema schema) {
375: boolean isImportExist = false;
376: Collection<Import> imports = schema.getImports();
377: Iterator<Import> it = imports.iterator();
378: while (it.hasNext()) {
379: Import imp = it.next();
380:
381: String sLoc = imp.getSchemaLocation();
382: String ns = imp.getNamespace();
383:
384: if (ns != null && ns.equals(namespace) && sLoc != null
385: && sLoc.equals(schemaLocation)) {
386: isImportExist = true;
387: break;
388: }
389: }
390:
391: return isImportExist;
392: }
393:
394: private String getRelativePathOfSchema(FileObject fo,
395: URI schemaURI, DefaultProjectCatalogSupport catalogSupport) {
396: File f = FileUtil.toFile(fo);
397: FileObject schemaFO = FileUtil
398: .toFileObject(new File(schemaURI));
399:
400: String relativePath = null;
401: if (catalogSupport != null
402: && catalogSupport.needsCatalogEntry(fo, schemaFO)) {
403: // Remove the previous catalog entry, then create new one.
404: URI uri;
405: try {
406: uri = catalogSupport.getReferenceURI(fo, schemaFO);
407: catalogSupport.removeCatalogEntry(uri);
408: catalogSupport.createCatalogEntry(fo, schemaFO);
409: relativePath = catalogSupport.getReferenceURI(fo,
410: schemaFO).toString();
411: } catch (URISyntaxException use) {
412: ErrorManager.getDefault().notify(use);
413: } catch (IOException ioe) {
414: ErrorManager.getDefault().notify(ioe);
415: } catch (CatalogModelException cme) {
416: ErrorManager.getDefault().notify(cme);
417: }
418: } else {
419: relativePath = org.netbeans.modules.xml.retriever.catalog.Utilities
420: .relativize(f.toURI(), schemaURI);
421: }
422: return relativePath;
423: }
424:
425: public void initialize(TemplateWizard wiz) {
426: index = 0;
427: Project project = Templates.getProject(wiz);
428: panels = createPanels(project, wiz);
429:
430: // Creating steps.
431: Object prop = wiz.getProperty("WizardPanel_contentData"); // NOI18N
432: String[] beforeSteps = null;
433: if (prop != null && prop instanceof String[]) {
434: beforeSteps = (String[]) prop;
435: }
436: String[] steps = Utilities.createSteps(beforeSteps, panels);
437:
438: for (int i = 0; i < panels.length; i++) {
439: Component c = panels[i].getComponent();
440: if (steps[i] == null) {
441: // Default step name to component name of panel.
442: // Mainly useful for getting the name of the target
443: // chooser to appear in the list of steps.
444: steps[i] = c.getName();
445: }
446: if (c instanceof JComponent) { // assume Swing components
447: JComponent jc = (JComponent) c;
448: // Step #.
449: jc.putClientProperty(
450: "WizardPanel_contentSelectedIndex",
451: new Integer(i)); // NOI18N
452: // Step name (actually the whole list for reference).
453: jc.putClientProperty("WizardPanel_contentData", steps); // NOI18N
454: }
455: }
456:
457: String encoding = EncodingUtil.getProjectEncoding(project
458: .getProjectDirectory());
459: if (encoding == null) {
460: encoding = "UTF8";
461: }
462: wiz.putProperty(WsdlPanel.ENCODING, encoding);
463:
464: }
465:
466: public void uninitialize(TemplateWizard wiz) {
467:
468: panels = null;
469: folderPanel = null;
470: wiz.putProperty(WizardPortTypeConfigurationStep.TEMP_WSDLMODEL,
471: null);
472:
473: File file = (File) wiz
474: .getProperty(WizardPortTypeConfigurationStep.TEMP_WSDLFILE);
475: wiz.putProperty(WizardPortTypeConfigurationStep.TEMP_WSDLFILE,
476: null);
477:
478: if (file != null && file.exists()) {
479: file = FileUtil.normalizeFile(file);
480: FileObject fileObj = FileUtil.toFileObject(file);
481: if (fileObj != null) {
482: DataObject dobj;
483: try {
484: dobj = DataObject.find(fileObj);
485: dobj.delete();
486: } catch (Exception e) {
487: //ignore.
488: }
489:
490: }
491: }
492:
493: }
494:
495: public WizardDescriptor.Panel current() {
496: return panels[index];
497: }
498:
499: public String name() {
500: return index + 1 + ". from " + panels.length;
501: }
502:
503: public boolean hasNext() {
504: return index < panels.length - 1;
505: }
506:
507: public boolean hasPrevious() {
508: return index > 0;
509: }
510:
511: public void nextPanel() {
512: if (!hasNext()) {
513: throw new NoSuchElementException();
514: }
515: index++;
516: }
517:
518: public void previousPanel() {
519: if (!hasPrevious()) {
520: throw new NoSuchElementException();
521: }
522: index--;
523: }
524:
525: // If nothing unusual changes in the middle of the wizard, simply:
526: public void addChangeListener(ChangeListener l) {
527: }
528:
529: public void removeChangeListener(ChangeListener l) {
530: }
531:
532: //from schema wizard
533: private JTextField findFileNameField(Component panel, String text) {
534: Collection<Component> allComponents = new ArrayList<Component>();
535: getAllComponents(new Component[] { panel }, allComponents);
536: for (Component c : allComponents) {
537: // we assume that the first text field is the file text field
538: if (c instanceof JTextField) {
539: JTextField tf = (JTextField) c;
540: //if (text.equals(tf.getText())) {
541: return tf;
542: //}
543: }
544: }
545: return null;
546: }
547:
548: /*
549: * Recursively gets all components in the components array and puts it in allComponents
550: */
551: public void getAllComponents(Component[] components,
552: Collection<Component> allComponents) {
553: for (int i = 0; i < components.length; i++) {
554: if (components[i] != null) {
555: allComponents.add(components[i]);
556: if (((Container) components[i]).getComponentCount() != 0) {
557: getAllComponents(((Container) components[i])
558: .getComponents(), allComponents);
559: }
560: }
561: }
562: }
563: }
|