From 254ee6f47eebfc00462c10756a92066e82cc1a96 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 21 Jun 2011 15:46:02 +0200 Subject: Initial commit --- .../gui/tabs/outcome/form/OutcomePanel.java | 362 +++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100755 source/com/c2kernel/gui/tabs/outcome/form/OutcomePanel.java (limited to 'source/com/c2kernel/gui/tabs/outcome/form/OutcomePanel.java') diff --git a/source/com/c2kernel/gui/tabs/outcome/form/OutcomePanel.java b/source/com/c2kernel/gui/tabs/outcome/form/OutcomePanel.java new file mode 100755 index 0000000..4bb7347 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/OutcomePanel.java @@ -0,0 +1,362 @@ +package com.c2kernel.gui.tabs.outcome.form; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.URL; +import java.util.Enumeration; + +import javax.swing.Box; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTextArea; +import javax.swing.SwingConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.xml.serialize.Method; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.exolab.castor.xml.schema.ElementDecl; +import org.exolab.castor.xml.schema.Schema; +import org.exolab.castor.xml.schema.reader.SchemaReader; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.c2kernel.gui.MainFrame; +import com.c2kernel.gui.tabs.outcome.InvalidOutcomeException; +import com.c2kernel.gui.tabs.outcome.InvalidSchemaException; +import com.c2kernel.gui.tabs.outcome.OutcomeException; +import com.c2kernel.gui.tabs.outcome.OutcomeHandler; +import com.c2kernel.gui.tabs.outcome.OutcomeNotInitialisedException; +import com.c2kernel.utils.FileStringUtility; +import com.c2kernel.utils.Logger; + +// will load the outcome as instructed by other bits of the gui +// provides the 'save' button and creates the trees of objects to feed to the outcome form + +public class OutcomePanel extends JPanel implements OutcomeHandler +{ + + Schema schemaSOM; + //ASModel schemaASModel; + Document outcomeDOM; + OutcomeStructure documentRoot; + DocumentBuilder parser; + boolean readOnly; + boolean useForm = true; + boolean panelBuilt = false; + boolean unsaved = false; + JScrollPane scrollpane = new JScrollPane(); + HelpPane help = new HelpPane(); + + JTextArea basicView; + + public OutcomePanel() + { + GridBagLayout gridbag = new java.awt.GridBagLayout(); + setLayout(gridbag); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(false); + dbf.setNamespaceAware(false); + try + { + parser = dbf.newDocumentBuilder(); + } + catch (ParserConfigurationException e) + { + e.printStackTrace(); + } + + // Set up panel + + JComponent pane; + if (!MainFrame.getPref("ShowHelp", "true").equals("true")) + pane = scrollpane; + else { + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, scrollpane, help); + splitPane.setOneTouchExpandable(true); + splitPane.setDividerSize(9); + pane = splitPane; + } + + GridBagConstraints c = new GridBagConstraints(); + + c.gridx = 0; + c.gridy = 0; + c.anchor = GridBagConstraints.NORTHWEST; + c.fill = GridBagConstraints.BOTH; + c.weightx = 1.0; + c.weighty = 1.0; + c.ipadx = 5; + c.ipady = 5; + + gridbag.setConstraints(pane, c); + this.add(pane); + } + + public OutcomePanel(boolean readOnly) + { + this(); + setReadOnly(readOnly); + } + + public OutcomePanel(String schema, boolean readOnly) throws OutcomeException + { + this(readOnly); + this.setDescription(schema); + } + + public OutcomePanel(String schema, String outcome, boolean readOnly) throws OutcomeException + { + this(readOnly); + this.setDescription(schema); + this.setOutcome(outcome); + } + + // Parse from URLS + public void setOutcome(URL outcomeURL) throws InvalidOutcomeException + { + + try + { + setOutcome(new InputSource(outcomeURL.openStream())); + } + catch (IOException ex) + { + throw new InvalidOutcomeException("Error creating instance DOM tree: " + ex); + } + } + + public void setDescription(URL schemaURL) throws InvalidSchemaException + { + Logger.msg(7, "OutcomePanel.setDescription() - schemaURL:" + schemaURL.toString()); + try + { + setDescription(new InputSource(schemaURL.openStream())); + } + catch (IOException ex) + { + throw new InvalidSchemaException("Error creating exolab schema object: " + ex); + } + + } + + public OutcomePanel(URL schemaURL, boolean readOnly) throws OutcomeException + { + this(readOnly); + this.setDescription(schemaURL); + } + + public OutcomePanel(URL schemaURL, URL outcomeURL, boolean readOnly) throws OutcomeException + { + this(readOnly); + this.setDescription(schemaURL); + this.setOutcome(outcomeURL); + } + + // Parse from Strings + public void setOutcome(String outcome) throws InvalidOutcomeException + { + + try + { + setOutcome(new InputSource(new StringReader(outcome))); + } + catch (IOException ex) + { + throw new InvalidOutcomeException("Error creating instance DOM tree: " + ex); + } + } + + public void setDescription(String schema) throws InvalidSchemaException + { + if (schema == null) + throw new InvalidSchemaException("Null schema supplied"); + try + { + setDescription(new InputSource(new StringReader(schema))); + } + catch (Exception ex) + { + Logger.error(ex); + } + + } + + public void setReadOnly(boolean readOnly) + { + this.readOnly = readOnly; + } + + public void setDescription(InputSource schemaSource) throws InvalidSchemaException, IOException + { + + SchemaReader mySchemaReader = new SchemaReader(schemaSource); + this.schemaSOM = mySchemaReader.read(); + } + + public void setOutcome(InputSource outcomeSource) throws InvalidOutcomeException, IOException + { + try + { + outcomeDOM = parser.parse(outcomeSource); + } + catch (SAXException ex) + { + throw new InvalidOutcomeException("Sax error parsing Outcome " + ex); + } + } + + public void run() + { + Thread.currentThread().setName("Outcome Panel Builder"); + try + { + makeDisplay(); + } + catch (Exception oe) + { + scrollpane.setViewportView(new JLabel("Outcome View Generation Failed: " + oe.getMessage())); + Logger.error(oe); + } + } + + public void makeDisplay() + { + try + { + initPanel(); + } + catch (OutcomeException ex) + { + // something went wrong + useForm = false; + Box textPanel = Box.createVerticalBox(); + JLabel errorMsg = new JLabel("Could not create outcome view: " + ex.getMessage()); + errorMsg.setHorizontalAlignment(SwingConstants.LEFT); + textPanel.add(errorMsg); + textPanel.add(Box.createVerticalGlue()); + if (outcomeDOM!=null) { + basicView = new JTextArea(serialize(outcomeDOM, true)); + basicView.setEnabled(!readOnly); + textPanel.add(basicView); + } + scrollpane.setViewportView(textPanel); + } + } + + public void initPanel() throws OutcomeException + { + Element docElement; + /*if (panelBuilt) + return;*/ + Logger.msg(5, "Initialising Panel.."); + scrollpane.setViewportView(new JLabel("Building outcome. Please hang on two ticks . . .")); + if (schemaSOM == null) + throw new InvalidSchemaException("A valid schema has not been supplied."); + // create root panel with element declaration and maybe root document element node + + //find the root element declaration in the schema - may need to look for annotation?? + ElementDecl rootElementDecl = null; + docElement = (outcomeDOM == null) ? null : outcomeDOM.getDocumentElement(); + + for (Enumeration globalElements = schemaSOM.getElementDecls(); globalElements.hasMoreElements();) + { + rootElementDecl = (ElementDecl) globalElements.nextElement(); + // REVISIT: We don't detect which is the most likely root element if there is more than one root decl + // xmlspy looks for an element not referenced elsewhere. simple but hard + // if we already have a document then use its root element to find the right decl + if (docElement != null && docElement.getTagName().equals(rootElementDecl.getName())) + break; + } + + if (rootElementDecl == null) + throw new InvalidSchemaException("No root elements defined"); + documentRoot = new DataRecord(rootElementDecl, readOnly, help, false); + + Logger.msg(5, "Finished structure. Populating..."); + if (docElement == null) + { + outcomeDOM = parser.newDocument(); + docElement = documentRoot.initNew(outcomeDOM); + outcomeDOM.appendChild(docElement); + } + else + documentRoot.addInstance(docElement, outcomeDOM); + + // got a fully rendered Outcome! put it in the scrollpane + // initialise container panel + + JTabbedPane outcomeTab = new JTabbedPane(); + outcomeTab.addTab(rootElementDecl.getName(), documentRoot); + outcomeTab.setSelectedIndex(0); + + scrollpane.setViewportView(outcomeTab); + panelBuilt = true; + + revalidate(); + doLayout(); + if (!readOnly) + documentRoot.grabFocus(); + } + + public JPanel getPanel() throws OutcomeNotInitialisedException + { + return this; + } + + public String getOutcome() + { + if (useForm) + { + documentRoot.validateStructure(); + return serialize(outcomeDOM, false); + } + else + { + return basicView.getText(); + } + } + + static public String serialize(Document doc, boolean prettyPrint) + { + String serializedDoc = null; + OutputFormat format = new OutputFormat(Method.XML, null, prettyPrint); + StringWriter stringOut = new StringWriter(); + XMLSerializer serial = new XMLSerializer(stringOut, format); + try + { + serial.asDOMSerializer(); + serial.serialize(doc); + } + catch (java.io.IOException ex) + { + Logger.error(ex.toString()); + } + serializedDoc = stringOut.toString(); + return serializedDoc; + } + + public boolean isUnsaved() { + return unsaved; + } + + public void saved() { + unsaved = false; + } + + public void export(File targetFile) throws Exception { + FileStringUtility.string2File(targetFile, getOutcome()); + } +} -- cgit v1.2.3