/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
package xml;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.KeyStroke;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import ilog.views.gantt.IlvGanttModel;
import ilog.views.gantt.IlvHierarchyChart;
import ilog.views.gantt.action.IlvAction;
import ilog.views.gantt.action.IlvZoomToFitAction;
import ilog.views.gantt.event.GanttModelChangedEvent;
import ilog.views.gantt.event.GanttModelListener;
import ilog.views.gantt.model.IlvDefaultGanttModel;
import ilog.views.gantt.xml.IlvGanttDocumentReader;
import ilog.views.gantt.xml.IlvGanttDocumentWriter;
import ilog.views.gantt.xml.IlvGanttStreamWriter;
import ilog.views.util.IlvLocaleUtil;
import ilog.views.util.swing.IlvSwingUtil;
/**
* This class groups a number of IlvAction(s) that can be used to open an XML
* file and to save a Gantt model to an XML file.
*/
public final class XMLGanttActions {
/**
* The XML file chooser.
*/
private static XMLFileChooser fileChooser;
/**
* Prevent instance creation.
*/
private XMLGanttActions() {
}
/**
* Returns the file chooser used to select XML files.
*
* @return The XML file chooser.
*/
private static XMLFileChooser getXMLFileChooser() {
if (fileChooser == null) {
fileChooser = new XMLFileChooser();
}
return fileChooser;
}
/**
* Returns the current directory of the XML file chooser.
*
* @return The current directory of the file chooser.
*/
public static File getCurrentDirectory() {
return getXMLFileChooser().getCurrentDirectory();
}
/**
* Sets the current directory of the XML file chooser. Passing in
* <code>null</code> sets the file chooser to point to the user's default
* directory.
*
* @param dir
* The current directory of the file chooser.
*/
public static void setCurrentDirectory(File dir) {
getXMLFileChooser().setCurrentDirectory(dir);
}
/**
* Parses the SDXL file at the specified URL and returns the resulting Gantt
* data model. This method will return <code>null</code> if the selected file
* does not exist or any other problem is encountered.
*
* @param url
* The URL of the SDXL data file.
* @param docReader
* The document reader that will be used to parse an XML
* <code>Document</code> into a Gantt data model.
* @param errorComponent
* The component that will be used as the parent of any error
* dialogs.
* @return The Gantt data model or <code>null</code>.
*/
public static IlvGanttModel readXMLURL(URL url, IlvGanttDocumentReader docReader, Component errorComponent) {
// Create an InputSource
InputSource source = new InputSource(url.toString());
// Create the document
Document document;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(source);
} catch (Exception ex) {
IlvSwingUtil.showErrorDialog(errorComponent, ex);
return null;
}
// Create a default Gantt model
IlvGanttModel model = new IlvDefaultGanttModel();
// Read the document into the Gantt model.
try {
docReader.readGanttModel(document, model);
} catch (Exception ex) {
IlvSwingUtil.showErrorDialog(errorComponent, ex);
return null;
}
return model;
}
/**
* Parses the SDXL file at the specified URL and returns the resulting Gantt
* data model. This method will return <code>null</code> if the selected file
* does not exist or any other problem is encountered. A default
* <code>IlvGanttDocumentReader</code> will be used to parse an XML file into
* a Gantt data model.
*
* @param url
* The URL of the SDXL data file.
* @param errorComponent
* The component that will be used as the parent of any error
* dialogs.
* @return The Gantt data model or <code>null</code>.
*/
public static IlvGanttModel readXMLURL(URL url, Component errorComponent) {
return readXMLURL(url, new IlvGanttDocumentReader(), errorComponent);
}
/**
* An action that opens an XML data file in SDXL format.
*/
public static class OpenXMLAction extends IlvAction {
/**
* The chart to which the action is attached.
*/
private IlvHierarchyChart chart;
/**
* The Gantt document reader.
*/
private IlvGanttDocumentReader docReader;
/**
* The zoom-to-fit action.
*/
private IlvZoomToFitAction zoomToFitAction;
/**
* Creates a new <code>OpenXMLAction</code> for the specified chart.
*
* @param chart
* The chart.
* @param docReader
* The document reader that will be used to parse an XML
* <code>Document</code> into a Gantt data model.
*/
public OpenXMLAction(IlvHierarchyChart chart, IlvGanttDocumentReader docReader) {
super("Open...", null, KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK), "Open Project",
"Opens An Existing XML Project.");
setIcon(XMLGanttActions.class, "images/open.gif");
this.chart = chart;
this.docReader = docReader;
this.zoomToFitAction = new IlvZoomToFitAction(chart, "", null, null, "", "");
}
/**
* Creates a new <code>OpenXMLAction</code> for the specified chart. A
* default <code>IlvGanttDocumentReader</code> will be used to parse an XML
* file into a Gantt data model.
*
* @param chart
* The chart.
*/
public OpenXMLAction(IlvHierarchyChart chart) {
this(chart, new IlvGanttDocumentReader());
}
/**
* Returns the chart with which this action is associated.
*
* @return The chart.
*/
public IlvHierarchyChart getChart() {
return chart;
}
/**
* Parses the SDXL file at the specified URL and returns the resulting Gantt
* data model. This method will return <code>null</code> if the selected
* file does not exist or any other problem is encountered.
*
* @param url
* The URL of the SDXL data file.
* @return The Gantt data model or <code>null</code>.
*/
public IlvGanttModel readXMLURL(URL url) {
return XMLGanttActions.readXMLURL(url, docReader, chart);
}
/**
* Prompts the user for an XML data file to open, parses the file, and
* returns the resulting Gantt data model. This method will return
* <code>null</code> if the user cancels, the selected file does not exist,
* or any other problem is encountered.
*
* @return The Gantt data model or <code>null</code>.
*/
public IlvGanttModel readXMLFile() {
// Choose an XML file to open.
String filename = getXMLFileChooser().showOpenDialog(chart);
if (filename == null) {
return null;
}
// Get the URL of the selected file.
URL url;
try {
url = new File(filename).toURI().toURL();
} catch (MalformedURLException ex) {
IlvSwingUtil.showErrorDialog(chart, ex);
return null;
}
// Parse the file.
return readXMLURL(url);
}
/**
* Returns the zoom-to-fit action that is performed when an XML schedule is
* opened.
*
* @return The zoom-to-fit action.
*/
protected IlvZoomToFitAction getZoomToFitAction() {
return zoomToFitAction;
}
/**
* Zooms the chart to fit the data model's time interval.
*/
protected void zoomToFit() {
getZoomToFitAction().perform();
}
/**
* This function is called when the user wants to open an XML file.
*
* @param event
* The event.
*/
Override
public void actionPerformed(ActionEvent event) {
IlvGanttModel model = readXMLFile();
// Change the Gantt model of the Gantt chart
if (model != null) {
chart.setGanttModel(model);
chart.expandAllRows();
zoomToFit();
}
}
}
/**
* An action that saves the current data model to an XML data file in SDXL
* format.
*/
public static class SaveAsXMLAction extends IlvAction {
/**
* The chart to which the action is attached.
*/
private IlvHierarchyChart chart;
/**
* The Gantt document writer.
*/
private IlvGanttDocumentWriter docWriter;
/**
* The Gantt stream writer.
*/
private IlvGanttStreamWriter streamWriter;
/**
* Creates a new <code>SaveAsXMLAction</code> for the specified chart.
*
* @param chart
* The chart.
* @param docWriter
* The document writer that will be used to convert a Gantt data
* model into an XML <code>Document</code>.
* @param streamWriter
* The stream writer that will be used to write an XML
* <code>Document</code> to an output stream.
*/
public SaveAsXMLAction(IlvHierarchyChart chart, IlvGanttDocumentWriter docWriter,
IlvGanttStreamWriter streamWriter) {
super("Save As...", null, KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK), "Save Project As XML",
"Saves the current project as XML.");
setIcon(XMLGanttActions.class, "images/save.gif");
this.chart = chart;
this.docWriter = docWriter;
this.streamWriter = streamWriter;
// We do not want the action to be enabled if the data model is null.
// So register a Gantt model listener, to update the action only when
// the data model is not null.
chart.addGanttModelListener(new GanttModelListener() {
Override
public void ganttModelChanged(GanttModelChangedEvent event) {
computeEnabled();
}
});
computeEnabled();
}
/**
* Computes whether this action should be enabled or not.
*/
private void computeEnabled() {
setEnabled(chart.getGanttModel() != null);
}
/**
* Creates a new <code>SaveAsXMLAction</code> for the specified chart. A
* default <code>IlvGanttDocumentWriter</code> will be used to convert a
* Gantt data model into an XML <code>Document</code> and a default
* <code>IlvGanttStreamWriter</code> will be used to write an XML
* <code>Document</code> to an output stream.
*
* @param chart
* The chart.
*/
public SaveAsXMLAction(IlvHierarchyChart chart) {
this(chart, new IlvGanttDocumentWriter(IlvLocaleUtil.getCurrentLocale()), new IlvGanttStreamWriter());
}
/**
* Returns the chart with which this action is associated.
*
* @return The chart.
*/
public IlvHierarchyChart getChart() {
return chart;
}
/**
* This function is called when the user wants to save the current Gantt
* model to an XML file.
*
* @param event
* The event.
*/
Override
public void actionPerformed(ActionEvent event) {
String filename = getXMLFileChooser().showSaveDialog(chart);
if (filename == null) {
return;
}
// Create the document
Document document;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.newDocument();
} catch (Exception ex) {
IlvSwingUtil.showErrorDialog(chart, ex);
return;
}
// Write the Gantt model into the document. Then, write the document
// to the file.
try {
docWriter.writeGanttModel(document, chart.getGanttModel());
FileOutputStream outstream = new FileOutputStream(filename);
streamWriter.writeDocument(outstream, document);
outstream.close();
} catch (Exception ex) {
IlvSwingUtil.showErrorDialog(chart, ex);
}
}
}
}