/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © 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_DOWN_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_DOWN_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); } } } }