KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > core > wizard > XMLWizardIterator


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-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.xml.core.wizard;
20
21 import java.awt.event.ActionEvent JavaDoc;
22 import java.io.OutputStream JavaDoc;
23 import java.io.BufferedOutputStream JavaDoc;
24 import java.io.Writer JavaDoc;
25 import java.io.OutputStreamWriter JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.beans.PropertyChangeListener JavaDoc;
30 import java.beans.PropertyChangeEvent JavaDoc;
31 import java.util.Set JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.net.URL JavaDoc;
34 import java.text.DateFormat JavaDoc;
35 import java.util.Date JavaDoc;
36
37 import javax.swing.event.ChangeListener JavaDoc;
38 import javax.swing.event.ChangeEvent JavaDoc;
39 import javax.swing.JComponent JavaDoc;
40
41 import org.openide.loaders.TemplateWizard;
42 import org.openide.WizardDescriptor;
43 import org.openide.loaders.DataFolder;
44 import org.openide.filesystems.FileSystem;
45 import org.openide.filesystems.FileObject;
46 import org.openide.loaders.DataObject;
47 import org.openide.filesystems.FileLock;
48 import org.openide.nodes.Node;
49 import org.openide.util.actions.CallableSystemAction;
50 import org.openide.util.actions.SystemAction;
51
52 /**
53  * Controls new XML Docuemnt wizard. It is kind of dynamic wizard with
54  * multiple way of diferent length.
55  *
56  * @author Petr Kuzel
57  */

58 public class XMLWizardIterator implements TemplateWizard.Iterator {
59     /** Serial Version UID */
60     private static final long serialVersionUID = 5070430920636117204L;
61     
62
63     private static final String JavaDoc XML_EXT = "xml"; // NOI18N
64

65     // parent wizard
66

67     private transient TemplateWizard templateWizard;
68     
69     // model collecting our data
70

71     private transient DocumentModel model;
72
73     // panels
74

75     private transient int current;
76     
77     private static final int TARGET_PANEL = 0;
78     private transient WizardDescriptor.Panel targetPanel;
79     
80     private static final int DOCUMENT_PANEL = 1;
81     private transient DocumentPanel documentPanel;
82     
83     private static final int CONSTRAINT_PANEL = 2;
84     private transient SchemaPanel schemaPanel;
85     private transient DTDPanel dtdPanel;
86     
87     /** Singleton instance of JavaWizardIterator, should it be ever needed.
88      */

89     private static XMLWizardIterator instance;
90
91     private transient Map JavaDoc listenersMap = new HashMap JavaDoc(2);
92     private transient String JavaDoc[] beforeSteps;
93     private transient Object JavaDoc targetSteps;
94     
95
96     /** Returns JavaWizardIterator singleton instance. This method is used
97      * for constructing the instance from filesystem.attributes.
98      */

99     public static synchronized XMLWizardIterator singleton() {
100         if (instance == null) {
101             instance = new XMLWizardIterator();
102         }
103         return instance;
104     }
105
106     public void initialize(TemplateWizard templateWizard) {
107         this.templateWizard = templateWizard;
108         current = TARGET_PANEL;
109         URL JavaDoc targetFolderURL = null;
110         try {
111             DataFolder folder = templateWizard.getTargetFolder();
112             targetFolderURL = folder.getPrimaryFile().getURL();
113             //#25604 workaround
114
if (targetFolderURL.toExternalForm().endsWith("/") == false) {
115                 targetFolderURL = new URL JavaDoc(targetFolderURL.toExternalForm() + "/");
116             }
117         } catch (IOException JavaDoc ignore) {
118         }
119         model = new DocumentModel(targetFolderURL);
120         Object JavaDoc prop = templateWizard.getProperty ("WizardPanel_contentData"); // NOI18N
121
if (prop != null && prop instanceof String JavaDoc[]) {
122             beforeSteps = (String JavaDoc[])prop;
123         }
124     }
125
126     public void uninitialize(TemplateWizard templateWizard) {
127         if (targetPanel!=null) {
128             ((JComponent JavaDoc)targetPanel.getComponent()).putClientProperty("WizardPanel_contentData", targetSteps);
129             targetPanel = null;
130         }
131         current = -1;
132         model = null;
133         templateWizard = null;
134         schemaPanel = null;
135         dtdPanel = null;
136         documentPanel = null;
137     }
138     
139     public Set JavaDoc instantiate(TemplateWizard templateWizard) throws IOException JavaDoc {
140         final DataFolder folder = templateWizard.getTargetFolder();
141         
142         final String JavaDoc extension = XML_EXT;
143
144         // #22812 we do not control validity constrains of target panel
145
// assure uniquess to "<default>" name
146

147         String JavaDoc targetName = templateWizard.getTargetName();
148         if (targetName == null || "null".equals(targetName)) { // NOI18N
149
targetName = "XMLDocument"; // NOI18N
150
}
151         final FileObject targetFolder = folder.getPrimaryFile();
152         String JavaDoc uniqueTargetName = targetName;
153         int i = 2;
154         
155         while (targetFolder.getFileObject(uniqueTargetName, extension) != null) {
156             uniqueTargetName = targetName + i;
157             i++;
158         }
159
160         final String JavaDoc name = uniqueTargetName;
161
162         // in atomic action create data object and return it
163

164         FileSystem filesystem = targetFolder.getFileSystem();
165         
166         final FileObject[] fileObject = new FileObject[1];
167         FileSystem.AtomicAction fsAction = new FileSystem.AtomicAction() {
168             public void run() throws IOException JavaDoc {
169                 FileObject fo = targetFolder.createData(name, extension);
170                 FileLock lock = null;
171                 try {
172                     lock = fo.lock();
173                     OutputStream JavaDoc out = fo.getOutputStream(lock);
174                     out = new BufferedOutputStream JavaDoc(out, 999);
175                     Writer JavaDoc writer = new OutputStreamWriter JavaDoc(out, "UTF8"); // NOI18N
176

177                     String JavaDoc root = model.getRoot();
178                     if (root == null) root = "root";
179                     
180                     // generate file content
181
// header
182
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); // NOI18N
183
writer.write("\n"); // NOI18N
184
// comment
185
String JavaDoc nameExt = name + "." + extension; // NOI18N
186
Date JavaDoc now = new Date JavaDoc();
187                     String JavaDoc currentDate = DateFormat.getDateInstance (DateFormat.LONG).format (now);
188                     String JavaDoc currentTime = DateFormat.getTimeInstance (DateFormat.SHORT).format (now);
189                     String JavaDoc userName = System.getProperty ("user.name");
190                     writer.write ("<!--\n"); // NOI18N
191
writer.write (" Document : " + nameExt + "\n"); // NOI18N
192
writer.write (" Created on : " + currentDate + ", " + currentTime + "\n"); // NOI18N
193
writer.write (" Author : " + userName + "\n"); // NOI18N
194
writer.write (" Description:\n"); // NOI18N
195
writer.write (" Purpose of the document follows.\n"); // NOI18N
196
writer.write ("-->\n"); // NOI18N
197
writer.write ("\n"); // NOI18N
198

199                     if (model.getType() == model.DTD) {
200                         if (model.getPublicID() == null) {
201                             writer.write("<!DOCTYPE " + root + " SYSTEM '" + model.getSystemID() + "'>\n"); // NOI18N
202
} else {
203                             writer.write("<!DOCTYPE " + root + " PUBLIC '" + model.getPublicID() + "' '" + model.getSystemID() + "'>\n"); // NOI18N
204
}
205                         writer.write("<" + root + ">\n"); // NOI18N
206
} else if (model.getType() == model.SCHEMA) {
207                         String JavaDoc namespace = model.getNamespace();
208                         if (namespace == null || "".equals(namespace)) {
209                             writer.write("<" + root + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"); // NOI18N
210
writer.write(" xsi:noNamespaceSchemaLocation='" + model.getSystemID() + "'>\n"); // NOI18N
211
} else {
212                             writer.write("<" + root + " xmlns='" + namespace + "'\n"); // NOI18N
213
writer.write(" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"); // NOI18N
214
writer.write(" xsi:schemaLocation='" + namespace + " " + model.getSystemID() + "'>\n"); // NOI18N
215
}
216                     } else {
217                         writer.write("<" + root + ">\n"); // NOI18N
218
}
219                     writer.write("\n"); // NOI18N
220
writer.write("</" + root + ">\n"); // NOI18N
221

222                     writer.flush();
223                     writer.close();
224                     
225                     // return DataObject
226
lock.releaseLock();
227                     lock = null;
228                     
229                     fileObject[0] = fo;
230                     
231                 } finally {
232                     if (lock != null) lock.releaseLock();
233                 }
234             }
235         };
236         
237                 
238         filesystem.runAtomicAction(fsAction);
239
240         // perform default action and return
241

242         Set JavaDoc set = new HashSet JavaDoc(1);
243         DataObject createdObject = DataObject.find(fileObject[0]);
244         Util.performDefaultAction(createdObject);
245         set.add(createdObject);
246         return set;
247     }
248     
249     
250     public WizardDescriptor.Panel current() {
251         WizardDescriptor.Panel panel = currentComponent();
252         if (panel.getComponent() instanceof JComponent JavaDoc) {
253             ((JComponent JavaDoc)panel.getComponent()).putClientProperty(
254                 "WizardPanel_contentSelectedIndex", // NOI18N
255
new Integer JavaDoc(current)
256             );
257         }
258         return panel;
259     }
260     
261     
262     private WizardDescriptor.Panel currentComponent() {
263         switch (current) {
264             case TARGET_PANEL:
265                 return getTargetPanel();
266             case DOCUMENT_PANEL:
267                 return getDocumentPanel();
268             case CONSTRAINT_PANEL:
269                 switch (model.getType()) {
270                     case DocumentModel.DTD:
271                         return getDTDPanel();
272                     case DocumentModel.SCHEMA:
273                         return getSchemaPanel();
274                     default:
275                         throw new IllegalStateException JavaDoc();
276                 }
277             default:
278                 throw new IllegalStateException JavaDoc();
279         }
280     }
281     
282     public boolean hasNext() {
283         boolean none = model.getType() == model.NONE;
284         int length = none ? DOCUMENT_PANEL : CONSTRAINT_PANEL;
285         return current < length;
286     }
287     
288     public boolean hasPrevious() {
289         return current > TARGET_PANEL;
290     }
291             
292     public String JavaDoc name() {
293         return "//TODO";
294     }
295     
296     public void nextPanel() {
297         current++;
298     }
299     
300     public void previousPanel() {
301         current--;
302     }
303
304     // events source ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305

306     //
307
// To symplify synchronization use bridge listeners delegating to model
308
// events. We do not need to sample listeners in sync block and then fire
309
// changes over the sampled listener copies out-of the sync block.
310
//
311

312     public void removeChangeListener(ChangeListener JavaDoc changeListener) {
313         if (changeListener == null) return;
314         synchronized (listenersMap) {
315             Object JavaDoc bridge = listenersMap.remove(changeListener);
316             if (bridge == null) return;
317             if (model == null) return;
318             model.removePropertyChangeListener((PropertyChangeListener JavaDoc) bridge);
319         }
320     }
321
322     public void addChangeListener(final ChangeListener JavaDoc changeListener) {
323         if (changeListener == null) return;
324         synchronized (listenersMap) {
325             PropertyChangeListener JavaDoc listenerBridge = new PropertyChangeListener JavaDoc() {
326                 final ChangeEvent JavaDoc EVENT = new ChangeEvent JavaDoc(XMLWizardIterator.this);
327                 public void propertyChange(PropertyChangeEvent JavaDoc e) {
328                     changeListener.stateChanged(EVENT);
329                 }
330             };
331             
332             if (listenersMap.put(changeListener, listenerBridge) == null) {
333                 model.addPropertyChangeListener(listenerBridge);
334             }
335         }
336     }
337     
338     // implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
339

340     private WizardDescriptor.Panel getDocumentPanel() {
341         if (documentPanel == null) {
342             documentPanel = new DocumentPanel();
343             documentPanel.setObject(model);
344             
345             String JavaDoc[] steps = new String JavaDoc[3];
346             steps[0] = getTargetPanelName();
347             steps[1] = getDocumentPanelName();
348             steps[2] = Util.THIS.getString("MSG_unknown");
349             String JavaDoc[] newSteps = createSteps(beforeSteps,steps);
350             documentPanel.putClientProperty(
351                 "WizardPanel_contentData", // NOI18N
352
newSteps
353             );
354             
355         }
356         return new AbstractPanel.WizardStep(documentPanel);
357     }
358
359     private WizardDescriptor.Panel getDTDPanel() {
360         if (dtdPanel == null) {
361             dtdPanel = new DTDPanel();
362             dtdPanel.setObject(model);
363             
364             String JavaDoc[] steps = new String JavaDoc[3];
365             steps[0] = getTargetPanelName();
366             steps[1] = getDocumentPanelName();
367             steps[2] = getDTDPanelName();
368             String JavaDoc[] newSteps = createSteps(beforeSteps,steps);
369             dtdPanel.putClientProperty(
370                 "WizardPanel_contentData", // NOI18N
371
newSteps
372             );
373             
374         }
375         return new AbstractPanel.WizardStep(dtdPanel);
376     }
377
378     private WizardDescriptor.Panel getSchemaPanel() {
379         if (schemaPanel == null) {
380             schemaPanel = new SchemaPanel();
381             schemaPanel.setObject(model);
382             
383             String JavaDoc[] steps = new String JavaDoc[3];
384             steps[0] = getTargetPanelName();
385             steps[1] = getDocumentPanelName();
386             steps[2] = getSchemaPanelName();
387             String JavaDoc[] newSteps = createSteps(beforeSteps,steps);
388             schemaPanel.putClientProperty(
389                 "WizardPanel_contentData", // NOI18N
390
newSteps
391             );
392         }
393         return new AbstractPanel.WizardStep(schemaPanel);
394     }
395     
396     private WizardDescriptor.Panel getTargetPanel() {
397         if (targetPanel == null) {
398             targetPanel = templateWizard.targetChooser();
399             // fill component with step hints
400

401             if (targetPanel.getComponent() instanceof JComponent JavaDoc) {
402                 JComponent JavaDoc panel = (JComponent JavaDoc) targetPanel.getComponent();
403                 targetSteps = panel.getClientProperty("WizardPanel_contentData");
404                 String JavaDoc[] steps = new String JavaDoc[3];
405                 //steps[0] = "Hello";
406
steps[0] = getTargetPanelName();
407                 steps[1] = getDocumentPanelName();
408                 steps[2] = Util.THIS.getString("MSG_unknown");
409                 String JavaDoc[] newSteps = createSteps(beforeSteps,steps);
410                 panel.putClientProperty(
411                     "WizardPanel_contentData", // NOI18N
412
newSteps
413                 );
414             }
415             
416         }
417         return targetPanel;
418     }
419     
420     private String JavaDoc getTargetPanelName() {
421         Object JavaDoc panel = getTargetPanel().getComponent();
422         if (panel instanceof JComponent JavaDoc) {
423             return ((JComponent JavaDoc)panel).getName();
424         } else {
425             return ""; //??? some fallback
426
}
427     }
428     
429     private String JavaDoc getDocumentPanelName() {
430         return Util.THIS.getString("PROP_doc_panel_name");
431     }
432         
433     private String JavaDoc getDTDPanelName() {
434         return Util.THIS.getString("PROP_dtd_panel_name");
435     }
436     
437     private String JavaDoc getSchemaPanelName() {
438         return Util.THIS.getString("PROP_schema_panel_name");
439     }
440     
441     private static String JavaDoc[] createSteps(String JavaDoc[] before, String JavaDoc[] panelNames) {
442         //assert panels != null;
443
// hack to use the steps set before this panel processed
444
int diff = 0;
445         if (before == null) {
446             before = new String JavaDoc[0];
447         } else if (before.length > 0) {
448             diff = ("...".equals (before[before.length - 1])) ? 1 : 0; // NOI18N
449
}
450         String JavaDoc[] res = new String JavaDoc[ (before.length - diff) + panelNames.length];
451         for (int i = 0; i < res.length; i++) {
452             if (i < (before.length - diff)) {
453                 res[i] = before[i];
454             } else {
455                 res[i] = panelNames[i - before.length + diff];
456             }
457         }
458         return res;
459     }
460 }
461
Popular Tags