alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

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;
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.