|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.xml.core.wizard;
import java.awt.event.ActionEvent;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.Set;
import java.io.IOException;
import java.net.URL;
import java.text.DateFormat;
import java.util.Date;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.JComponent;
import org.openide.loaders.TemplateWizard;
import org.openide.WizardDescriptor;
import org.openide.loaders.DataFolder;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.filesystems.FileLock;
import org.openide.nodes.Node;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.SystemAction;
/**
* Controls new XML Docuemnt wizard. It is kind of dynamic wizard with
* multiple way of diferent length.
*
* @author Petr Kuzel
*/
public class XMLWizardIterator implements TemplateWizard.Iterator {
/** Serial Version UID */
private static final long serialVersionUID = 5070430920636117204L;
private static final String XML_EXT = "xml"; // NOI18N
// parent wizard
private transient TemplateWizard templateWizard;
// model collecting our data
private transient DocumentModel model;
// panels
private transient int current;
private static final int TARGET_PANEL = 0;
private transient WizardDescriptor.Panel targetPanel;
private static final int DOCUMENT_PANEL = 1;
private transient DocumentPanel documentPanel;
private static final int CONSTRAINT_PANEL = 2;
private transient SchemaPanel schemaPanel;
private transient DTDPanel dtdPanel;
/** Singleton instance of JavaWizardIterator, should it be ever needed.
*/
private static XMLWizardIterator instance;
private transient Map listenersMap = new HashMap(2);
private transient String[] beforeSteps;
private transient Object targetSteps;
/** Returns JavaWizardIterator singleton instance. This method is used
* for constructing the instance from filesystem.attributes.
*/
public static synchronized XMLWizardIterator singleton() {
if (instance == null) {
instance = new XMLWizardIterator();
}
return instance;
}
public void initialize(TemplateWizard templateWizard) {
this.templateWizard = templateWizard;
current = TARGET_PANEL;
URL targetFolderURL = null;
try {
DataFolder folder = templateWizard.getTargetFolder();
targetFolderURL = folder.getPrimaryFile().getURL();
//#25604 workaround
if (targetFolderURL.toExternalForm().endsWith("/") == false) {
targetFolderURL = new URL(targetFolderURL.toExternalForm() + "/");
}
} catch (IOException ignore) {
}
model = new DocumentModel(targetFolderURL);
Object prop = templateWizard.getProperty ("WizardPanel_contentData"); // NOI18N
if (prop != null && prop instanceof String[]) {
beforeSteps = (String[])prop;
}
}
public void uninitialize(TemplateWizard templateWizard) {
current = -1;
model = null;
templateWizard = null;
schemaPanel = null;
dtdPanel = null;
documentPanel = null;
if (targetPanel!=null) {
((JComponent)targetPanel.getComponent()).putClientProperty("WizardPanel_contentData", targetSteps);
targetPanel = null;
}
}
public Set instantiate(TemplateWizard templateWizard) throws IOException {
final DataFolder folder = templateWizard.getTargetFolder();
final String extension = XML_EXT;
// #22812 we do not control validity constrains of target panel
// assure uniquess to "" name
String targetName = templateWizard.getTargetName();
if (targetName == null || "null".equals(targetName)) { // NOI18N
targetName = "XMLDocument"; // NOI18N
}
final FileObject targetFolder = folder.getPrimaryFile();
String uniqueTargetName = targetName;
int i = 2;
while (targetFolder.getFileObject(uniqueTargetName, extension) != null) {
uniqueTargetName = targetName + i;
i++;
}
final String name = uniqueTargetName;
// in atomic action create data object and return it
FileSystem filesystem = targetFolder.getFileSystem();
final FileObject[] fileObject = new FileObject[1];
FileSystem.AtomicAction fsAction = new FileSystem.AtomicAction() {
public void run() throws IOException {
FileObject fo = targetFolder.createData(name, extension);
FileLock lock = null;
try {
lock = fo.lock();
OutputStream out = fo.getOutputStream(lock);
out = new BufferedOutputStream(out, 999);
Writer writer = new OutputStreamWriter(out, "UTF8"); // NOI18N
String root = model.getRoot();
if (root == null) root = "root";
// generate file content
// header
writer.write("\n"); // NOI18N
writer.write("\n"); // NOI18N
// comment
String nameExt = name + "." + extension; // NOI18N
Date now = new Date();
String currentDate = DateFormat.getDateInstance (DateFormat.LONG).format (now);
String currentTime = DateFormat.getTimeInstance (DateFormat.SHORT).format (now);
String userName = System.getProperty ("user.name");
writer.write ("\n"); // NOI18N
writer.write ("\n"); // NOI18N
if (model.getType() == model.DTD) {
if (model.getPublicID() == null) {
writer.write("\n"); // NOI18N
} else {
writer.write("\n"); // NOI18N
}
writer.write("<" + root + ">\n"); // NOI18N
} else if (model.getType() == model.SCHEMA) {
String namespace = model.getNamespace();
if (namespace == null || "".equals(namespace)) {
writer.write("<" + root + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"); // NOI18N
writer.write(" xsi:noNamespaceSchemaLocation='" + model.getSystemID() + "'>\n"); // NOI18N
} else {
writer.write("<" + root + " xmlns='" + namespace + "'\n"); // NOI18N
writer.write(" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"); // NOI18N
writer.write(" xsi:schemaLocation='" + namespace + " " + model.getSystemID() + "'>\n"); // NOI18N
}
} else {
writer.write("<" + root + ">\n"); // NOI18N
}
writer.write("\n"); // NOI18N
writer.write("\n"); // NOI18N
writer.flush();
writer.close();
// return DataObject
lock.releaseLock();
lock = null;
fileObject[0] = fo;
} finally {
if (lock != null) lock.releaseLock();
}
}
};
filesystem.runAtomicAction(fsAction);
// perform default action and return
Set set = new HashSet(1);
DataObject createdObject = DataObject.find(fileObject[0]);
Util.performDefaultAction(createdObject);
set.add(createdObject);
return set;
}
public WizardDescriptor.Panel current() {
WizardDescriptor.Panel panel = currentComponent();
if (panel.getComponent() instanceof JComponent) {
((JComponent)panel.getComponent()).putClientProperty(
"WizardPanel_contentSelectedIndex", // NOI18N
new Integer(current)
);
}
return panel;
}
private WizardDescriptor.Panel currentComponent() {
switch (current) {
case TARGET_PANEL:
return getTargetPanel();
case DOCUMENT_PANEL:
return getDocumentPanel();
case CONSTRAINT_PANEL:
switch (model.getType()) {
case DocumentModel.DTD:
return getDTDPanel();
case DocumentModel.SCHEMA:
return getSchemaPanel();
default:
throw new IllegalStateException();
}
default:
throw new IllegalStateException();
}
}
public boolean hasNext() {
boolean none = model.getType() == model.NONE;
int length = none ? DOCUMENT_PANEL : CONSTRAINT_PANEL;
return current < length;
}
public boolean hasPrevious() {
return current > TARGET_PANEL;
}
public String name() {
return "//TODO";
}
public void nextPanel() {
current++;
}
public void previousPanel() {
current--;
}
// events source ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// To symplify synchronization use bridge listeners delegating to model
// events. We do not need to sample listeners in sync block and then fire
// changes over the sampled listener copies out-of the sync block.
//
public void removeChangeListener(ChangeListener changeListener) {
if (changeListener == null) return;
synchronized (listenersMap) {
Object bridge = listenersMap.remove(changeListener);
if (bridge == null) return;
if (model == null) return;
model.removePropertyChangeListener((PropertyChangeListener) bridge);
}
}
public void addChangeListener(final ChangeListener changeListener) {
if (changeListener == null) return;
synchronized (listenersMap) {
PropertyChangeListener listenerBridge = new PropertyChangeListener() {
final ChangeEvent EVENT = new ChangeEvent(XMLWizardIterator.this);
public void propertyChange(PropertyChangeEvent e) {
changeListener.stateChanged(EVENT);
}
};
if (listenersMap.put(changeListener, listenerBridge) == null) {
model.addPropertyChangeListener(listenerBridge);
}
}
}
// implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private WizardDescriptor.Panel getDocumentPanel() {
if (documentPanel == null) {
documentPanel = new DocumentPanel();
documentPanel.setObject(model);
String[] steps = new String[3];
steps[0] = getTargetPanelName();
steps[1] = getDocumentPanelName();
steps[2] = Util.THIS.getString("MSG_unknown");
String[] newSteps = createSteps(beforeSteps,steps);
documentPanel.putClientProperty(
"WizardPanel_contentData", // NOI18N
newSteps
);
}
return new AbstractPanel.WizardStep(documentPanel);
}
private WizardDescriptor.Panel getDTDPanel() {
if (dtdPanel == null) {
dtdPanel = new DTDPanel();
dtdPanel.setObject(model);
String[] steps = new String[3];
steps[0] = getTargetPanelName();
steps[1] = getDocumentPanelName();
steps[2] = getDTDPanelName();
String[] newSteps = createSteps(beforeSteps,steps);
dtdPanel.putClientProperty(
"WizardPanel_contentData", // NOI18N
newSteps
);
}
return new AbstractPanel.WizardStep(dtdPanel);
}
private WizardDescriptor.Panel getSchemaPanel() {
if (schemaPanel == null) {
schemaPanel = new SchemaPanel();
schemaPanel.setObject(model);
String[] steps = new String[3];
steps[0] = getTargetPanelName();
steps[1] = getDocumentPanelName();
steps[2] = getSchemaPanelName();
String[] newSteps = createSteps(beforeSteps,steps);
schemaPanel.putClientProperty(
"WizardPanel_contentData", // NOI18N
newSteps
);
}
return new AbstractPanel.WizardStep(schemaPanel);
}
private WizardDescriptor.Panel getTargetPanel() {
if (targetPanel == null) {
targetPanel = templateWizard.targetChooser();
// fill component with step hints
if (targetPanel.getComponent() instanceof JComponent) {
JComponent panel = (JComponent) targetPanel.getComponent();
targetSteps = panel.getClientProperty("WizardPanel_contentData");
String[] steps = new String[3];
//steps[0] = "Hello";
steps[0] = getTargetPanelName();
steps[1] = getDocumentPanelName();
steps[2] = Util.THIS.getString("MSG_unknown");
String[] newSteps = createSteps(beforeSteps,steps);
panel.putClientProperty(
"WizardPanel_contentData", // NOI18N
newSteps
);
}
}
return targetPanel;
}
private String getTargetPanelName() {
Object panel = getTargetPanel().getComponent();
if (panel instanceof JComponent) {
return ((JComponent)panel).getName();
} else {
return ""; //??? some fallback
}
}
private String getDocumentPanelName() {
return Util.THIS.getString("PROP_doc_panel_name");
}
private String getDTDPanelName() {
return Util.THIS.getString("PROP_dtd_panel_name");
}
private String getSchemaPanelName() {
return Util.THIS.getString("PROP_schema_panel_name");
}
private static String[] createSteps(String[] before, String[] panelNames) {
//assert panels != null;
// hack to use the steps set before this panel processed
int diff = 0;
if (before == null) {
before = new String[0];
} else if (before.length > 0) {
diff = ("...".equals (before[before.length - 1])) ? 1 : 0; // NOI18N
}
String[] res = new String[ (before.length - diff) + panelNames.length];
for (int i = 0; i < res.length; i++) {
if (i < (before.length - diff)) {
res[i] = before[i];
} else {
res[i] = panelNames[i - before.length + diff];
}
}
return res;
}
}
|