diff options
Diffstat (limited to 'source/com/c2kernel/gui/tabs/outcome')
30 files changed, 3673 insertions, 0 deletions
diff --git a/source/com/c2kernel/gui/tabs/outcome/BasicOutcomeEditor.java b/source/com/c2kernel/gui/tabs/outcome/BasicOutcomeEditor.java new file mode 100755 index 0000000..451b393 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/BasicOutcomeEditor.java @@ -0,0 +1,100 @@ +package com.c2kernel.gui.tabs.outcome;
+
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.io.File;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.PlainDocument;
+
+import com.c2kernel.utils.FileStringUtility;
+
+/**************************************************************************
+ *
+ * $Revision: 1.4 $
+ * $Date: 2005/09/07 13:46:31 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+
+
+public class BasicOutcomeEditor extends JPanel implements OutcomeHandler {
+
+ PlainDocument doc;
+ JTextArea textarea;
+ boolean unsaved;
+
+ public BasicOutcomeEditor() {
+ super();
+ this.setLayout(new GridLayout(1,1));
+ doc = new PlainDocument();
+ textarea = new JTextArea(doc);
+ textarea.setTabSize(2);
+ textarea.setFont(Font.decode("monospaced"));
+ add(new JScrollPane(textarea));
+ doc.addDocumentListener(new DocumentListener() {
+ public void changedUpdate(DocumentEvent e) { unsaved = true; }
+ public void insertUpdate(DocumentEvent e) { unsaved = true; }
+ public void removeUpdate(DocumentEvent e) { unsaved = true; }
+
+ });
+ }
+
+ public void setOutcome(String outcome) throws InvalidOutcomeException {
+ try {
+ doc.insertString(0, outcome, null);
+ unsaved = false;
+ } catch (Exception ex) {
+ throw new InvalidOutcomeException(ex.getMessage());
+ }
+ }
+
+ public void setDescription(String description) throws InvalidSchemaException { }
+
+ public void setReadOnly(boolean readOnly) {
+ textarea.setEditable(!readOnly);
+ }
+
+
+ public JPanel getPanel() throws OutcomeNotInitialisedException {
+ return this;
+ }
+
+ /**
+ *
+ */
+
+ public String getOutcome() throws OutcomeException {
+ try {
+ return doc.getText(0, doc.getLength());
+ } catch (Exception ex) {
+ throw new OutcomeException(ex.getMessage());
+ }
+ }
+
+ /**
+ *
+ */
+
+ public void run() {
+ }
+
+
+ public boolean isUnsaved() {
+ return unsaved;
+ }
+
+ public void saved() {
+ unsaved = false;
+ }
+
+ public void export(File targetFile) throws Exception {
+ FileStringUtility.string2File(targetFile, getOutcome());
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/InvalidOutcomeException.java b/source/com/c2kernel/gui/tabs/outcome/InvalidOutcomeException.java new file mode 100755 index 0000000..bab9050 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/InvalidOutcomeException.java @@ -0,0 +1,11 @@ +package com.c2kernel.gui.tabs.outcome;
+
+public class InvalidOutcomeException extends OutcomeException {
+
+ public InvalidOutcomeException() {
+ super();
+ }
+ public InvalidOutcomeException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/InvalidSchemaException.java b/source/com/c2kernel/gui/tabs/outcome/InvalidSchemaException.java new file mode 100755 index 0000000..5edbcbf --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/InvalidSchemaException.java @@ -0,0 +1,11 @@ +package com.c2kernel.gui.tabs.outcome;
+
+public class InvalidSchemaException extends OutcomeException {
+
+ public InvalidSchemaException() {
+ super();
+ }
+ public InvalidSchemaException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/OutcomeException.java b/source/com/c2kernel/gui/tabs/outcome/OutcomeException.java new file mode 100755 index 0000000..fd608d0 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/OutcomeException.java @@ -0,0 +1,11 @@ +package com.c2kernel.gui.tabs.outcome;
+
+public class OutcomeException extends Exception {
+
+ public OutcomeException() {
+ super();
+ }
+ public OutcomeException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/OutcomeHandler.java b/source/com/c2kernel/gui/tabs/outcome/OutcomeHandler.java new file mode 100755 index 0000000..0d6dc74 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/OutcomeHandler.java @@ -0,0 +1,16 @@ +package com.c2kernel.gui.tabs.outcome;
+import java.io.File;
+
+import javax.swing.JPanel;
+
+public interface OutcomeHandler extends Runnable {
+
+ public void setOutcome(String outcome) throws InvalidOutcomeException;
+ public void setDescription(String description) throws InvalidSchemaException;
+ public void setReadOnly(boolean readOnly);
+ public JPanel getPanel() throws OutcomeNotInitialisedException;
+ public boolean isUnsaved();
+ public void saved();
+ public String getOutcome() throws OutcomeException;
+ public void export(File targetFile) throws Exception;
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/OutcomeNotInitialisedException.java b/source/com/c2kernel/gui/tabs/outcome/OutcomeNotInitialisedException.java new file mode 100755 index 0000000..7b54f33 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/OutcomeNotInitialisedException.java @@ -0,0 +1,11 @@ +package com.c2kernel.gui.tabs.outcome;
+
+public class OutcomeNotInitialisedException extends OutcomeException {
+
+ public OutcomeNotInitialisedException() {
+ super();
+ }
+ public OutcomeNotInitialisedException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/AttributeList.java b/source/com/c2kernel/gui/tabs/outcome/form/AttributeList.java new file mode 100755 index 0000000..08c5ea1 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/AttributeList.java @@ -0,0 +1,158 @@ +package com.c2kernel.gui.tabs.outcome.form;
+
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import org.exolab.castor.xml.schema.AttributeDecl;
+import org.exolab.castor.xml.schema.ComplexType;
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import com.c2kernel.gui.tabs.outcome.form.field.StringEditField;
+import com.c2kernel.utils.Logger;
+
+public class AttributeList extends JPanel {
+
+ ArrayList attrSet = new ArrayList();
+ ElementDecl model;
+ Element myElement;
+ boolean readOnly;
+ static Font labelFont;
+
+ public AttributeList(ElementDecl model, boolean readOnly, HelpPane helpPane) {
+ super();
+ AttributeDecl thisDecl;
+ this.model = model;
+ this.readOnly = readOnly;
+
+ // set up panel
+ GridBagLayout gridbag = new java.awt.GridBagLayout();
+ setLayout(gridbag);
+ if (labelFont == null)
+ labelFont = this.getFont().deriveFont((float)(this.getFont().getSize()-3.0));
+ // retrieve attributes
+ if (!model.getType().isComplexType()) {
+ // simple types have no attributes
+ return;
+ }
+
+ ComplexType content = (ComplexType)model.getType();
+
+ // place on panel
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1.0; c.weighty = 1.0; c.gridx = 0;
+ c.ipadx = 5; c.ipady = 0;
+
+ for (Enumeration fields = content.getAttributeDecls(); fields.hasMoreElements();) {
+ c.gridy = 0;
+ thisDecl = (AttributeDecl)fields.nextElement();
+ Logger.msg(8, "Includes Attribute "+thisDecl.getName());
+
+ // Add Label
+ JLabel heading = new JLabel(thisDecl.getName());
+ heading.setFont(labelFont);
+ heading.setVerticalAlignment(SwingConstants.BOTTOM);
+ gridbag.setConstraints(heading, c);
+ this.add(heading);
+
+ // read help
+ String helpText;
+ String doc = OutcomeStructure.extractHelp(thisDecl);
+ if (doc.length() > 0)
+ helpText = doc.toString();
+ else
+ helpText = "<i>No help is available for this attribute</i>";
+
+
+ c.gridy++;
+
+ // Add entry
+ try {
+ StringEditField entry = StringEditField.getEditField(thisDecl);
+ entry.setHelp(helpPane, helpText);
+ attrSet.add(entry);
+ if (readOnly) entry.setEditable(false);
+ gridbag.setConstraints(entry.getControl(), c);
+ this.add(entry.getControl());
+ } catch (StructuralException e) {
+ JLabel entry = new JLabel("Error");
+ entry.setToolTipText(e.getMessage());
+ gridbag.setConstraints(entry, c);
+ this.add(entry);
+ }
+
+
+ c.gridx++;
+ }
+ }
+
+ public void setInstance(Element data) throws StructuralException {
+ this.myElement = data;
+ for (Iterator e = attrSet.iterator(); e.hasNext();) {
+ StringEditField thisField = (StringEditField)e.next();
+ Logger.msg(8, "Populating Attribute "+thisField.getName());
+ Attr thisAttr = myElement.getAttributeNode(thisField.getName());
+ if (thisAttr == null)
+ thisAttr = newAttribute(myElement, (AttributeDecl)thisField.getModel());
+ thisField.setData(thisAttr);
+ }
+ }
+
+ public Attr newAttribute(Element parent, AttributeDecl attr) {
+
+ parent.setAttribute(attr.getName(), attr.getFixedValue()!=null?attr.getFixedValue():attr.getDefaultValue());
+ return parent.getAttributeNode(attr.getName());
+ }
+
+ public String validateAttributes() {
+ if (model.getType().isComplexType()) {
+ ComplexType content = (ComplexType)model.getType();
+ for (Enumeration fields = content.getAttributeDecls(); fields.hasMoreElements();) {
+ AttributeDecl thisDecl = (AttributeDecl)fields.nextElement();
+ String attrVal = myElement.getAttribute(thisDecl.getName());
+ if (attrVal.length() == 0 && thisDecl.isOptional()) {
+ myElement.removeAttribute(thisDecl.getName());
+ }
+ }
+ }
+ return null;
+ }
+
+ public void initNew(Element parent) {
+ AttributeDecl thisDecl;
+ StringEditField thisField;
+ Attr thisAttr;
+ this.myElement = parent;
+
+ if (model.getType().isSimpleType()) return; // no attributes in simple types
+
+ ComplexType content = (ComplexType)model.getType();
+
+ for (Iterator e = attrSet.iterator(); e.hasNext();) {
+ thisField = (StringEditField)e.next();
+
+ thisDecl = content.getAttributeDecl(thisField.getName());
+ thisAttr = newAttribute(myElement, thisDecl);
+ // add into parent - fill in field
+ try {
+ thisField.setData(thisAttr);
+ } catch (Exception ex) { } // impossible name mismatch
+ }
+ }
+ public void grabFocus() {
+ if (attrSet.size() > 0)
+ ((StringEditField)attrSet.get(0)).grabFocus();
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/CardinalException.java b/source/com/c2kernel/gui/tabs/outcome/form/CardinalException.java new file mode 100755 index 0000000..bb6d039 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/CardinalException.java @@ -0,0 +1,14 @@ +package com.c2kernel.gui.tabs.outcome.form;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+
+public class CardinalException extends OutcomeException {
+
+ public CardinalException() {
+ super();
+ }
+
+ public CardinalException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/DataRecord.java b/source/com/c2kernel/gui/tabs/outcome/form/DataRecord.java new file mode 100755 index 0000000..9d0b633 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/DataRecord.java @@ -0,0 +1,249 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.swing.JLabel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.exolab.castor.xml.schema.ComplexType;
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.utils.Logger;
+
+public class DataRecord extends OutcomeStructure implements ChangeListener {
+
+ AttributeList myAttributes;
+ JTabbedPane DRPanel = null;
+ boolean deferred;
+ ArrayList deferredChildren = new ArrayList();
+ Document parentDoc;
+ GridBagConstraints position;
+ GridBagLayout gridbag;
+
+ public DataRecord(ElementDecl model, boolean readOnly, HelpPane help, boolean deferred) throws OutcomeException {
+ super(model, readOnly, help);
+ this.deferred = deferred;
+ if (!deferred) setupPanel();
+ }
+
+ public synchronized void activate() {
+ deferred = false;
+ try {
+ setupPanel();
+ if (myElement!=null) populateInstance();
+ } catch (OutcomeException ex) {
+ removeAll();
+ setLayout(new FlowLayout());
+ add(new JLabel("Error displaying outcome segment: "+ex.getMessage()));
+ }
+ validate();
+ }
+
+ private void setupPanel() throws OutcomeException {
+ // set up panel
+ gridbag = new java.awt.GridBagLayout();
+ setLayout(gridbag);
+ position = new GridBagConstraints();
+ position.anchor = GridBagConstraints.NORTHWEST;
+ position.fill = GridBagConstraints.NONE;
+ position.weightx = 1.0; position.weighty = 1.0;
+ position.gridx = 0; position.gridy = 0;
+ position.ipadx = 5; position.ipady = 5;
+ position.insets = new Insets(5,5,0,0);
+
+ // attributes at the top
+ myAttributes = new AttributeList(model, readOnly, helpPane);
+ position.gridwidth=3;
+ gridbag.setConstraints(myAttributes, position);
+ add(myAttributes);
+
+ ComplexType elementType;
+ try {
+ elementType = (ComplexType)model.getType();
+ }
+ catch (ClassCastException e) {
+ throw new StructuralException("DataRecord created with non-ComplexType");
+ }
+
+ //loop through all schema sub-elements
+ try {
+ enumerateElements(elementType);
+ } catch (OutcomeException e) {
+ throw new OutcomeException("Element "+model.getName()+" could not be created: "+e.getMessage());
+ }
+ }
+
+ public void addStructure(OutcomeStructure newElement) throws OutcomeException {
+ super.addStructure(newElement);
+ if (newElement == null) return;
+ if (newElement instanceof DataRecord) {
+ DataRecord newRecord = (DataRecord)newElement;
+ // set up enclosing tabbed pane for child drs
+ if (DRPanel == null) {
+ DRPanel = new JTabbedPane();
+ position.gridy++;
+ position.weightx=1.0;
+ position.fill=GridBagConstraints.HORIZONTAL;
+ position.gridwidth=3;
+ gridbag.setConstraints(DRPanel, position);
+ add(DRPanel);
+ // defer further tabs in this pane
+ deferChild = true;
+ }
+ DRPanel.addTab(newRecord.getName(), newRecord);
+ DRPanel.addChangeListener(newRecord);
+ }
+ else {
+ DRPanel = null;// have to make a new tabbed pane now
+ deferChild = false;
+ if (newElement instanceof Field) {
+ Field newField = (Field)newElement;
+ // make some nice columns
+ position.gridwidth=1;
+ position.gridy++;
+ position.gridx=0;
+ position.weightx=2;
+ position.weighty=0;
+ position.fill=GridBagConstraints.NONE;
+ gridbag.setConstraints(newField.getLabel(), position);
+ this.add(newField.getLabel());
+ position.gridy++;
+ position.weighty=1;
+ position.fill = GridBagConstraints.HORIZONTAL;
+ gridbag.setConstraints(newField.getCData(), position);
+ this.add(newField.getCData());
+ position.gridx++;
+ position.gridy--;
+ position.gridheight=2;
+ position.weightx=0;
+ position.fill=GridBagConstraints.NONE;
+ gridbag.setConstraints(newField.getAttributes(), position);
+ this.add(newField.getAttributes());
+ position.gridx=0;
+ position.gridheight=1;
+ position.gridy++;
+ }
+ else {
+ position.fill=GridBagConstraints.HORIZONTAL;
+ position.gridwidth=3;
+ position.weightx=1.0;
+ position.gridy++;
+ position.weighty=1.0;
+ gridbag.setConstraints(newElement, position);
+ add(newElement);
+ }
+ }
+ }
+
+ public void addInstance(Element myElement, Document parentDoc) throws OutcomeException {
+ Logger.msg(8, "Accepting DR "+myElement.getTagName());
+
+ if (this.myElement != null) throw new CardinalException("DataRecord "+this.getName()+" cannot repeat.");
+ this.myElement = myElement;
+ this.parentDoc = parentDoc;
+
+ if (!deferred)
+ populateInstance();
+ }
+
+ public void populateInstance() throws OutcomeException {
+ myAttributes.setInstance(myElement);
+
+ NodeList childElements = myElement.getChildNodes();
+
+ for (int i=0; i<childElements.getLength();i++) {
+ if (!(childElements.item(i) instanceof Element)) // ignore chardata here
+ continue;
+ Element thisElement = (Element) childElements.item(i);
+
+ // find the child structure with this name
+ OutcomeStructure thisStructure = (OutcomeStructure)subStructure.get(thisElement.getTagName());
+ if (thisStructure == null)
+ throw new StructuralException("DR "+model.getName()+" not expecting "+thisElement.getTagName());
+ thisStructure.addInstance(thisElement, parentDoc);
+ }
+
+ // make sure any dimensions have the minimum
+ for (Iterator e=subStructure.keySet().iterator(); e.hasNext();) {
+ String structureName = (String)e.next();
+ OutcomeStructure thisStructure = (OutcomeStructure)subStructure.get(structureName);
+ int count = 0;
+
+ if (thisStructure instanceof Dimension) {
+ Dimension thisDimension = (Dimension)thisStructure;
+ thisDimension.setParentElement(myElement);
+ count = thisDimension.getChildCount();
+ }
+ else
+ count = thisStructure.getElement()==null?0:1;
+
+ int total = thisStructure.getModel().getMinOccurs();
+ //if (total == 0) total++;
+ for (int i = count;i<total;i++) {
+ myElement.appendChild(thisStructure.initNew(parentDoc));
+ }
+ }
+ }
+
+ public Element initNew(Document parent) {
+ Logger.msg(6, "Creating DR "+model.getName());
+ if (deferred) activate();
+
+ // make a new Element
+ myElement = parent.createElement(model.getName());
+ // populate
+ for (Iterator e=order.iterator(); e.hasNext();) {
+ String structureName = (String)e.next();
+ OutcomeStructure thisStructure = (OutcomeStructure)subStructure.get(structureName);
+ if (thisStructure instanceof Dimension)
+ ((Dimension)thisStructure).setParentElement(myElement);
+ int count = 0;
+ while (count < thisStructure.getModel().getMinOccurs()) {
+ myElement.appendChild(thisStructure.initNew(parent));
+ count++;
+ }
+ }
+
+ // set up attributes
+ myAttributes.initNew(myElement);
+
+ return myElement;
+
+ }
+
+ public void stateChanged(ChangeEvent e) {
+ JTabbedPane targetPane = (JTabbedPane)e.getSource();
+ DataRecord targetTab = (DataRecord)targetPane.getSelectedComponent();
+ if (targetTab == this) {
+ helpPane.setHelp(getName(), getHelp());
+ if (deferred) SwingUtilities.invokeLater(
+ new Thread(new Runnable() {
+ public void run() {
+ activate();
+ }
+ }
+ ));
+ }
+ }
+
+ /**
+ * sets focus to first editable child
+ */
+ public void grabFocus() {
+ if (myAttributes.attrSet.size() > 0)
+ myAttributes.grabFocus();
+ else if (order.size()> 0)
+ ((OutcomeStructure)subStructure.get(order.get(0))).grabFocus();
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/Dimension.java b/source/com/c2kernel/gui/tabs/outcome/form/Dimension.java new file mode 100755 index 0000000..8dfa7f5 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/Dimension.java @@ -0,0 +1,377 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.awt.*;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.swing.*;
+import javax.swing.border.EtchedBorder;
+import javax.swing.table.JTableHeader;
+
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.exolab.castor.xml.schema.Particle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.c2kernel.gui.DomainKeyConsumer;
+import com.c2kernel.gui.MainFrame;
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.lookup.DomainPath;
+import com.c2kernel.utils.Logger;
+
+public class Dimension extends OutcomeStructure implements ActionListener {
+
+ DimensionTableModel tableModel;
+ Element parent;
+ GridBagConstraints position;
+ GridBagLayout gridbag;
+ JTabbedPane tabs;
+ JLabel msg;
+ DomKeyPushTable table;
+ Box tableBox;
+ ArrayList instances = new ArrayList(); // stores DimensionInstances if tabs
+ ArrayList elements = new ArrayList(); // stores current children
+
+ JButton addButton;
+ JButton delButton;
+
+ short mode;
+ protected static final short TABLE = 1;
+ protected static final short TABS = 2;
+
+
+ public Dimension(ElementDecl model, boolean readOnly, HelpPane help) {
+ super(model, readOnly, help);
+ // set up panel
+ gridbag = new java.awt.GridBagLayout();
+ setLayout(gridbag);
+ position = new GridBagConstraints();
+ position.anchor = GridBagConstraints.NORTHWEST;
+ position.fill = GridBagConstraints.HORIZONTAL;
+ position.weightx = 1.0; position.weighty = 0.0;
+ position.gridx = 0; position.gridy = 0;
+ position.ipadx = 0; position.ipady = 0;
+ position.insets = new Insets(0,0,0,0);
+
+ // TODO: an element or attribute of the dimension can be flagged as an index, so it can be used as a title for a tab
+
+ // set up the border
+ setBorder(BorderFactory.createTitledBorder(
+ BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), model.getName()));
+
+ msg = new JLabel("No elements");
+ msg.setFont(new Font("SansSerif", Font.ITALIC, msg.getFont().getSize()));
+ gridbag.setConstraints(msg, position);
+ add(msg);
+ position.gridy++;
+
+ // decide whether a table or tabs
+ try {
+ tableModel = new DimensionTableModel(model, readOnly);
+ Logger.msg(8, "DIM "+model.getName()+" - Will be a table");
+ mode = TABLE;
+ tableBox = Box.createVerticalBox();
+ table = new DomKeyPushTable(tableModel, this);
+ new MultiLinePasteAdapter(table, this);
+ if (readOnly) table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ table.setColumnSelectionAllowed(readOnly);
+ JTableHeader tableHeader = table.getTableHeader();
+ tableHeader.setReorderingAllowed(false);
+ tableBox.add(tableHeader);
+ tableBox.add(table);
+ gridbag.setConstraints(tableBox, position);
+ add(tableBox);
+ tableBox.setVisible(false);
+
+ } catch (StructuralException e) {
+ // use tabs
+ Logger.msg(8, "DIM "+model.getName()+" - Will be tabs: "+e.getMessage());
+ mode = TABS;
+ tabs = new JTabbedPane();
+ gridbag.setConstraints(tabs, position);
+ add(tabs);
+ tabs.setVisible(false);
+ }
+ if (!readOnly) {
+ JPanel rowAdjust = new JPanel(new FlowLayout());
+ addButton = new JButton("+");
+ addButton.setActionCommand("add");
+ addButton.addActionListener(this);
+ rowAdjust.add(addButton);
+
+ delButton = new JButton("-");
+ delButton.setActionCommand("del");
+ delButton.addActionListener(this);
+ delButton.setEnabled(false);
+ rowAdjust.add(delButton);
+
+
+ position.gridy++; position.weighty=0; position.weightx=0;
+ gridbag.setConstraints(rowAdjust, position);
+ this.add(rowAdjust);
+ }
+
+ }
+
+ public void setParentElement(Element parent) {
+ this.parent = parent;
+ }
+
+ public void addInstance(Element myElement, Document parentDoc) throws OutcomeException {
+ if (Logger.doLog(6))
+ Logger.msg(6, "DIM - adding instance "+ (elements.size()+1) +" for "+myElement.getTagName());
+ if (parent == null) setParentElement((Element)myElement.getParentNode());
+ // if table, pass to table model
+ if (mode == TABLE) {
+ tableModel.addInstance(myElement, -1);
+ elements.add(myElement);
+ }
+ else {
+ DimensionInstance target;
+ elements.add(myElement);
+ if (instances.size() < elements.size())
+ target = newInstance();
+ else
+ target = (DimensionInstance)instances.get(elements.size()-1);
+ target.addInstance(myElement, parentDoc);
+ }
+ checkButtons();
+ }
+
+ public int getChildCount() {
+ return elements.size();
+ }
+
+ public DimensionInstance newInstance() {
+ DimensionInstance newInstance = null;
+ try {
+ newInstance = new DimensionInstance(model, readOnly, helpPane, deferChild);
+ instances.add(newInstance);
+ newInstance.setTabNumber(instances.size());
+ newInstance.setParent(this);
+ deferChild = true;
+ tabs.addTab(newInstance.getName(), newInstance);
+ tabs.addChangeListener(newInstance);
+ } catch (OutcomeException e) {
+ // shouldn't happen, we've already done it once
+ Logger.error(e);
+ }
+ return newInstance;
+ }
+
+ public String validateStructure() {
+ if (mode == TABLE)
+ return table.validateStructure();
+ else {
+ StringBuffer errors = new StringBuffer();
+ for (Iterator iter = instances.iterator(); iter.hasNext();) {
+ OutcomeStructure element = (OutcomeStructure)iter.next();
+ errors.append(element.validateStructure());
+ }
+ return errors.toString();
+ }
+ }
+
+ public void checkButtons() {
+ // check if data visible
+ boolean dataVisible = elements.size() > 0;
+ if (mode == TABS) tabs.setVisible(dataVisible);
+ else tableBox.setVisible(dataVisible);
+ msg.setVisible(!dataVisible);
+
+ if (readOnly) return;
+
+ if (elements.size() <= model.getMinOccurs() || elements.size() == 0) {
+ delButton.setEnabled(false);
+ delButton.setToolTipText("Minimum row count of "+model.getMinOccurs()+" reached.");
+ } else {
+ delButton.setEnabled(true);
+ delButton.setToolTipText(null);
+ }
+
+ if (elements.size() < model.getMaxOccurs() || model.getMaxOccurs() == Particle.UNBOUNDED) {
+ addButton.setEnabled(true);
+ addButton.setToolTipText(null);
+ } else {
+ addButton.setEnabled(false);
+ addButton.setToolTipText("Maximum row count of "+model.getMaxOccurs()+" reached.");
+ }
+ }
+
+ public Element initNew(Document parent) {
+ Element newElement;
+
+ if (mode == TABLE) {
+ newElement = tableModel.initNew(parent, -1);
+ elements.add(newElement);
+ checkButtons();
+ return newElement;
+ }
+ else {
+ DimensionInstance newTab = null;
+ if (instances.size() < elements.size()+1)
+ newTab = newInstance();
+ else
+ newTab = (DimensionInstance)instances.get(elements.size()-1);
+ newElement = newTab.initNew(parent);
+ elements.add(newElement);
+ checkButtons();
+ return newElement;
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ int index;
+ if (mode == TABS) index = tabs.getSelectedIndex();
+ else {
+ index = table.getSelectedRow();
+ if (index == -1) index = tableModel.getRowCount();
+ }
+ try {
+ if (table == null || table.getCellEditor() == null || table.getCellEditor().stopCellEditing()) {
+ if (e.getActionCommand().equals("add"))
+ addRow(index);
+ else if (e.getActionCommand().equals("del"))
+ removeRow(index);
+ }
+ } catch (CardinalException ex) {
+ JOptionPane.showMessageDialog(null, ex.getMessage(), "Table error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ public void addRow(int index) throws CardinalException {
+ if (elements.size() == model.getMaxOccurs())
+ throw new CardinalException("Maximum size of table reached");
+
+ if (mode == TABLE) {
+ Element newRow = tableModel.initNew(parent.getOwnerDocument(), index);
+ elements.add(index, newRow);
+ try {
+ Element following = (Element)elements.get(index+1);
+ parent.insertBefore(newRow, following);
+ } catch (IndexOutOfBoundsException ex) {
+ parent.appendChild(newRow);
+ }
+ table.clearSelection();
+ table.setRowSelectionInterval(index, index);
+ }
+ else {
+ Element newTab = initNew(parent.getOwnerDocument());
+ parent.appendChild(newTab);
+ }
+ checkButtons();
+
+ }
+
+ public void removeRow(int index) throws CardinalException {
+ if (elements.size() <= model.getMinOccurs())
+ throw new CardinalException("Minimum size of table reached");
+ if (mode == TABLE) {
+ parent.removeChild(tableModel.removeRow(index));
+ int selectRow = index;
+ if (index >= tableModel.getRowCount()) selectRow--;
+ if (tableModel.getRowCount() > 0) {
+ table.clearSelection();
+ table.setRowSelectionInterval(selectRow, selectRow);
+ }
+ }
+ else {
+ Element elementToGo = (Element)elements.get(index);
+ parent.removeChild(elementToGo);
+ instances.remove(index);
+ tabs.remove(index);
+ for (int i = index; i<instances.size(); i++) {
+ DimensionInstance thisInstance = (DimensionInstance)instances.get(i);
+ thisInstance.setTabNumber(i+1);
+ tabs.setTitleAt(i, thisInstance.getName());
+ }
+ }
+ elements.remove(index);
+ checkButtons();
+ }
+
+ private class DomKeyPushTable extends JTable implements DomainKeyConsumer, FocusListener {
+
+ Dimension dim;
+ public DomKeyPushTable(DimensionTableModel model, Dimension parent) {
+ super(model);
+ addFocusListener(this);
+ this.dim = parent;
+ }
+
+ public void push(DomainPath key) {
+ push(key.getName());
+ }
+
+ public void push(String name) {
+ int col = getSelectedColumn();
+ int row = getSelectedRow();
+ if (cellEditor != null)
+ cellEditor.stopCellEditing();
+ Logger.msg(8, "Pushing "+name+" to table at "+row+","+col);
+ if (col > -1 && row > -1) {
+ if (dataModel.getValueAt(row, col).toString().length()==0)
+ dataModel.setValueAt(name, row, col);
+ else {
+ if (row+1 == getRowCount()) {
+ try {
+ dim.addRow(row+1);
+ dataModel.setValueAt(name, row+1, col);
+ } catch (CardinalException ex) {
+ JOptionPane.showMessageDialog(null, ex.getMessage(), "Table error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+ if (row+1 < getRowCount()) {
+ Logger.msg(8, "Shifting selection to row "+(row+1));
+ changeSelection(row+1, col, false, false);
+ }
+ }
+ }
+
+ public void focusGained(FocusEvent e) {
+ if (!readOnly)
+ MainFrame.itemFinder.setConsumer(this, "Insert");
+ }
+
+ public void focusLost(FocusEvent e) {
+ // release the itemFinder
+ if (!readOnly)
+ MainFrame.itemFinder.clearConsumer(this);
+ }
+
+ public String validateStructure() {
+ if (cellEditor != null)
+ cellEditor.stopCellEditing();
+ return null;
+ }
+
+ public void changeSelection( int rowIndex, int columnIndex, boolean toggle, boolean extend) {
+ super.changeSelection(rowIndex, columnIndex, toggle, extend);
+ DimensionTableModel dimModel = (DimensionTableModel)dataModel;
+ helpPane.setHelp(dimModel.getColumnName(columnIndex), dimModel.getHelp(columnIndex));
+ }
+
+ }
+
+ public void grabFocus() {
+ if (mode == TABLE) {
+ if (table.getSelectedRow() == -1 && table.getRowCount() > 0) {
+ table.changeSelection(0, 0, false, false);
+ table.editCellAt(0,0);
+ }
+ table.requestFocus();
+ }
+ else if (instances.size()> 0)
+ ((DimensionInstance)instances.get(0)).grabFocus();
+ }
+
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/DimensionInstance.java b/source/com/c2kernel/gui/tabs/outcome/form/DimensionInstance.java new file mode 100755 index 0000000..07fbe1b --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/DimensionInstance.java @@ -0,0 +1,32 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import org.exolab.castor.xml.schema.ElementDecl;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+
+public class DimensionInstance extends DataRecord {
+
+ //probably will be needed to synch edits later
+ Dimension parentDimension;
+ int tabNumber;
+ String tabName = null;
+
+ public DimensionInstance(ElementDecl model, boolean readOnly , HelpPane help, boolean deferred) throws OutcomeException {
+ super(model, readOnly, help, deferred);
+ }
+
+ public void setTabNumber(int tabNumber) {
+ this.tabNumber=tabNumber;
+ }
+
+ public void setParent(Dimension parent) {
+ this.parentDimension = parent;
+ }
+
+ public String getName() {
+ //TODO appinfo for picking out attributes or child elements for tab name
+ if (tabName == null)
+ return Integer.toString(tabNumber);
+ else
+ return tabName;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/DimensionTableModel.java b/source/com/c2kernel/gui/tabs/outcome/form/DimensionTableModel.java new file mode 100755 index 0000000..b19c1d2 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/DimensionTableModel.java @@ -0,0 +1,308 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import javax.swing.table.AbstractTableModel;
+
+import org.exolab.castor.xml.schema.*;
+import org.w3c.dom.*;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.utils.Language;
+import com.c2kernel.utils.Logger;
+
+public class DimensionTableModel extends AbstractTableModel {
+
+ ElementDecl model;
+ ArrayList columnHeadings = new ArrayList();
+ ArrayList columnClasses = new ArrayList();
+ ArrayList columnDecls = new ArrayList();
+ ArrayList colReadOnly = new ArrayList();
+ ArrayList colHelp = new ArrayList();
+ ArrayList rows = new ArrayList();
+ ArrayList elements = new ArrayList();
+ boolean readOnly;
+
+ public DimensionTableModel(ElementDecl model, boolean readOnly) throws StructuralException {
+ XMLType modelContent = model.getType();
+
+ this.model = model;
+ this.readOnly = readOnly;
+ // use text node for simple types
+ if (modelContent.isSimpleType()) {
+ SimpleType elementType = (SimpleType)modelContent;
+ SimpleType baseType = elementType.getBuiltInBaseType();
+ addColumn(model.getName(), baseType, baseType.getTypeCode(), new Boolean(model.getFixedValue() != null));
+ }
+ else if (modelContent.isComplexType()) { // if complex type, process child elements
+ ComplexType elementType = (ComplexType)modelContent;
+
+ // find out if a CDATA type is used for this complex type
+ XMLType baseType = elementType.getBaseType();
+ while (!(baseType instanceof SimpleType) && baseType != null) {
+ baseType = baseType.getBaseType();
+ }
+ if (baseType != null) {
+ int typeCode = ((SimpleType)baseType).getTypeCode();
+ addColumn(model.getName(), baseType, typeCode, new Boolean(model.getFixedValue() != null));
+ }
+ // process attributes
+ for (Enumeration e = elementType.getAttributeDecls(); e.hasMoreElements();) {
+ AttributeDecl thisAttr = (AttributeDecl)e.nextElement();
+ addColumn(thisAttr.getName(), thisAttr, thisAttr.getSimpleType().getTypeCode(), new Boolean(thisAttr.isFixed()));
+ }
+
+ // enumerate child elements
+ enumerateElements(elementType);
+ }
+ }
+
+ public synchronized void addColumn(String heading, Annotated decl, int typeCode, Boolean readOnly) {
+ Logger.msg(8, "Column "+heading+" contains "+decl.getClass().getName()+" readOnly="+readOnly.toString());
+ columnHeadings.add(heading);
+ columnDecls.add(decl);
+ columnClasses.add(OutcomeStructure.getJavaClass(typeCode));
+ colReadOnly.add(readOnly);
+
+ // read help
+ String helpText;
+ if (decl instanceof SimpleType)
+ helpText = OutcomeStructure.extractHelp(model);
+ else
+ helpText = OutcomeStructure.extractHelp(decl);
+
+ if (helpText.length() == 0)
+ helpText = "<i>"+Language.translate("No help is available for this cell")+"</i>";
+
+ colHelp.add(helpText);
+
+ }
+
+
+ public void enumerateElements(ContentModelGroup group) throws StructuralException {
+ for (Enumeration childElements = group.enumerate(); childElements.hasMoreElements(); ) {
+ Particle thisParticle = (Particle)childElements.nextElement();
+ String extraHeader = "";
+ if (thisParticle instanceof Group) {
+ Group thisGroup = (Group)thisParticle;
+ Order order = thisGroup.getOrder();
+ if (order == Order.sequence || order == Order.all)
+ enumerateElements(thisGroup);
+ else // we only support sequences in data structures such as these
+ throw new StructuralException("Element "+thisGroup.getName()+". Expecting sequence or all. Got "+thisGroup.getOrder());
+ }
+ else if (thisParticle instanceof ElementDecl) {
+ ElementDecl thisElement = (ElementDecl)thisParticle;
+ int typeCode = SimpleTypesFactory.INVALID_TYPE;
+ //make sure not too complex
+ if (thisElement.getType() != null) {
+ if (thisElement.getType().isComplexType()) {
+ ComplexType elementType = (ComplexType)thisElement.getType();
+ if (elementType.getParticleCount() > 0 ||
+ thisElement.getMaxOccurs() > 1)
+ throw new StructuralException("Too deep for a table");
+ for (Enumeration attrs = elementType.getAttributeDecls(); attrs.hasMoreElements();) {
+ AttributeDecl thisAttr = (AttributeDecl)attrs.nextElement();
+ if (!thisAttr.isFixed())
+ throw new StructuralException("Non-fixed attributes of child elements not supported in tables.");
+ else
+ extraHeader=extraHeader+" ("+thisAttr.getName()+":"+(thisAttr.getFixedValue()!=null?thisAttr.getFixedValue():thisAttr.getDefaultValue())+")";
+ }
+ // find type
+ XMLType parentType = thisElement.getType();
+ while (!(parentType instanceof SimpleType) && parentType != null) {
+ parentType = parentType.getBaseType();
+ if (parentType != null) typeCode = ((SimpleType)parentType).getTypeCode();
+ }
+ }
+ else
+ typeCode = ((SimpleType)thisElement.getType()).getTypeCode();
+ }
+
+ //add to list
+ addColumn(thisElement.getName()+extraHeader, thisElement, typeCode, new Boolean(thisElement.getFixedValue() != null));
+ }
+ else throw new StructuralException("Particle "+thisParticle.getClass()+" not implemented");
+ }
+ }
+
+ public void addInstance(Element myElement, int index) throws OutcomeException {
+ if (index == -1) index = elements.size();
+ Object[] newRow = new Object[columnHeadings.size()];
+ for (int i=0; i<columnDecls.size(); i++) {
+ if (columnDecls.get(i) instanceof ElementDecl) { // sub element - get the node from it
+ ElementDecl thisElementDecl = (ElementDecl)columnDecls.get(i);
+ NodeList childElements = myElement.getElementsByTagName(thisElementDecl.getName());
+ switch (childElements.getLength()) {
+ case 1: // element exists - read the contents
+ Element childElement = (Element)childElements.item(0);
+ if (childElement.hasChildNodes()) {
+ Node thisNode = childElement.getFirstChild();
+ if (thisNode.getNodeType() == Node.TEXT_NODE)
+ newRow[i] = OutcomeStructure.getTypedValue(((Text)thisNode).getData(), (Class)columnClasses.get(i));
+ else
+ throw new StructuralException("First child of Field " + thisElementDecl.getName() + " was not Text. (NodeType:"+thisNode.getNodeType()+")");
+ }
+ else { // create text node
+ newRow[i] = this.setupDefaultElement(thisElementDecl, childElement, (Class)columnClasses.get(i));
+ }
+ break;
+ case 0: // element is missing - create it
+ Element newElement = myElement.getOwnerDocument().createElement(thisElementDecl.getName());
+ myElement.appendChild(newElement); //TODO: not in the right place in sequence. should insert it
+ newRow[i] = setupDefaultElement(thisElementDecl, newElement, (Class)columnClasses.get(i));
+ break;
+ default:
+ throw new CardinalException("Element "+thisElementDecl.getName()+" appeared more than once.");
+ }
+ }
+ else if (columnDecls.get(i) instanceof AttributeDecl) { //attribute
+ AttributeDecl thisAttrDecl = (AttributeDecl)columnDecls.get(i);
+ newRow[i] = OutcomeStructure.getTypedValue(myElement.getAttribute(thisAttrDecl.getName()), (Class)columnClasses.get(i));
+ }
+ else { // first child node
+ Node thisNode = myElement.getFirstChild();
+ if (thisNode == null) {
+ thisNode = myElement.getOwnerDocument().createTextNode("");
+ myElement.appendChild(thisNode);
+ }
+ if (thisNode.getNodeType() == Node.TEXT_NODE || thisNode.getNodeType() == Node.CDATA_SECTION_NODE)
+ newRow[i] = OutcomeStructure.getTypedValue(((Text)thisNode).getData(), (Class)columnClasses.get(i));
+ else
+ throw new StructuralException("First child of Column " + myElement.getTagName() + " was not Text");
+ }
+ }
+ elements.add(index, myElement);
+ rows.add(index, newRow);
+ fireTableRowsInserted(index, index);
+ }
+ public Class getColumnClass(int columnIndex) {
+ return (Class)columnClasses.get(columnIndex);
+ }
+
+ public String getColumnName(int columnIndex) {
+ return (String)columnHeadings.get(columnIndex);
+ }
+
+ public int getRowCount() {
+ return rows.size();
+ }
+
+ public int getColumnCount() {
+ return columnHeadings.size();
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ boolean isReadOnly = readOnly || ((Boolean)colReadOnly.get(columnIndex)).booleanValue();
+ return !isReadOnly;
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ Object[] thisRow = (Object[])rows.get(rowIndex);
+ thisRow[columnIndex]=aValue;
+ Element myElement = (Element)elements.get(rowIndex);
+ // update node
+ if (columnDecls.get(columnIndex) instanceof ElementDecl) { // sub element
+ ElementDecl thisDecl = (ElementDecl)columnDecls.get(columnIndex);
+ NodeList childElements = myElement.getElementsByTagName(thisDecl.getName());
+ // depend on one element with a Text child - this should have been enforced on init.
+ Text childNode = (Text)(childElements.item(0).getFirstChild());
+ childNode.setData(aValue.toString());
+ }
+ else if (columnDecls.get(columnIndex) instanceof AttributeDecl) { //attribute
+ AttributeDecl thisDecl = (AttributeDecl) columnDecls.get(columnIndex);
+ myElement.setAttribute(thisDecl.getName(), aValue.toString());
+ }
+ else { // first child node
+ Text textNode = (Text)myElement.getFirstChild();
+ textNode.setData(aValue.toString());
+ }
+ fireTableCellUpdated(rowIndex, columnIndex);
+ }
+
+ public Element removeRow(int rowIndex) {
+ Element elementToGo = (Element)elements.get(rowIndex);
+ elements.remove(rowIndex);
+ rows.remove(rowIndex);
+ fireTableRowsDeleted(rowIndex,rowIndex);
+ return elementToGo;
+ }
+
+ public Object setupDefaultElement(ElementDecl thisDecl, Element parent, Class type) {
+ Object newValue;
+ String defaultValue = thisDecl.getFixedValue();
+ if (defaultValue == null)
+ defaultValue = thisDecl.getDefaultValue();
+ if (readOnly)
+ newValue = "";
+ else
+ newValue = OutcomeStructure.getTypedValue(defaultValue, type);
+
+ Text newNode = parent.getOwnerDocument().createTextNode(newValue.toString());
+ parent.appendChild(newNode);
+ // fixed attributes
+ try {
+ ComplexType content = (ComplexType)thisDecl.getType();
+ for (Enumeration attrs = content.getAttributeDecls(); attrs.hasMoreElements();) {
+ AttributeDecl thisAttr = (AttributeDecl)attrs.nextElement();
+ parent.setAttribute(thisAttr.getName(), thisAttr.getFixedValue()!=null?thisAttr.getFixedValue():thisAttr.getDefaultValue());
+ }
+ } catch (ClassCastException ex) { } // only complex types have attributes
+ return newValue;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ Object[] thisRow = (Object[])rows.get(rowIndex);
+ if (!(getColumnClass(columnIndex).equals(thisRow[columnIndex].getClass())))
+ Logger.warning(thisRow[columnIndex]+" should be "+getColumnClass(columnIndex)+" is a "+thisRow[columnIndex].getClass().getName());
+ return thisRow[columnIndex];
+ }
+
+ public String validateStructure() { // remove empty rows
+ for (int j=0; j < rows.size(); j++) {
+ Object[] elems = (Object[])rows.get(j);
+ boolean empty = true;
+ for (int i = 0; i < elems.length && empty; i++)
+ empty &= OutcomeStructure.isEmpty(elems[i]);
+ if (empty)
+ if (model.getMinOccurs() < rows.size())
+ removeRow(j);
+ else
+ return "Too many empty rows in table "+model.getName();
+ }
+ return null;
+ }
+
+ public Element initNew(Document parent, int index) {
+ if (index == -1) index = elements.size();
+ Object[] newRow = new Object[columnHeadings.size()];
+ Element myElement = parent.createElement(model.getName());
+ for (int i=0; i<columnDecls.size(); i++) {
+ if (columnDecls.get(i) instanceof ElementDecl) { // sub element
+ ElementDecl childElementDecl = (ElementDecl)columnDecls.get(i);
+ Element childElement = parent.createElement(childElementDecl.getName());
+ Object newValue = setupDefaultElement(childElementDecl, childElement, (Class)columnClasses.get(i));
+ myElement.appendChild(childElement);
+ newRow[i] = newValue;
+ }
+ else if (columnDecls.get(i) instanceof AttributeDecl) { //attribute
+ AttributeDecl thisAttrDecl = (AttributeDecl)columnDecls.get(i);
+ String newValue = thisAttrDecl.getFixedValue()!=null?thisAttrDecl.getFixedValue():thisAttrDecl.getDefaultValue();
+ newRow[i] = OutcomeStructure.getTypedValue(newValue, (Class)columnClasses.get(i));
+ myElement.setAttribute(thisAttrDecl.getName(), newRow[i].toString());
+ }
+ else { // first child node
+ newRow[i] = setupDefaultElement(model, myElement, (Class)columnClasses.get(i));
+ }
+ }
+ elements.add(index,myElement);
+ rows.add(index, newRow);
+ fireTableRowsInserted(index,index);
+ return myElement;
+ }
+
+ public String getHelp(int i) {
+ return (String)colHelp.get(i);
+ }
+
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/Field.java b/source/com/c2kernel/gui/tabs/outcome/form/Field.java new file mode 100755 index 0000000..e1bc35c --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/Field.java @@ -0,0 +1,137 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.awt.Component;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.gui.tabs.outcome.form.field.StringEditField;
+import com.c2kernel.utils.Logger;
+
+
+public class Field extends OutcomeStructure {
+
+ StringEditField myElementPanel = null;
+ AttributeList myAttributes;
+ JLabel tagName;
+ Text textNode;
+ boolean fixed;
+ public static final JPanel nullPanel = new JPanel();
+
+ public Field(ElementDecl model, boolean readOnly, HelpPane helpPane) {
+ super(model, readOnly, helpPane);
+
+ try {
+ myElementPanel = StringEditField.getEditField(model);
+ Logger.msg(6, "Field type: "+myElementPanel.getClass().getName());
+ myElementPanel.setHelp(helpPane, help);
+ if (readOnly) myElementPanel.setEditable(false);
+
+ } catch (StructuralException e) { // no base type for field - only attributes
+ myElementPanel = null;
+ }
+
+ myAttributes = new AttributeList(model, readOnly, helpPane);
+
+ tagName = new JLabel(model.getName());
+ tagName.setVerticalAlignment(SwingConstants.BOTTOM);
+ }
+
+ public JComponent getLabel() {
+ return tagName;
+ }
+
+ public Component getCData() {
+ if (myElementPanel == null)
+ return nullPanel;
+ return myElementPanel.getControl();
+ }
+
+ public JComponent getAttributes() {
+ return myAttributes;
+ }
+
+ public void addStructure(OutcomeStructure newElement) throws StructuralException {
+ throw new StructuralException("Field "+model.getName()+" cannot have child structures");
+ }
+
+ public void addInstance(Element myElement, Document parentDoc) throws OutcomeException {
+ Logger.msg(6, "Accepting Field "+myElement.getTagName());
+ if (this.myElement != null) throw new CardinalException("Field "+this.getName()+" cannot repeat");
+ this.myElement = myElement;
+
+ try {
+ if (myElementPanel == null)
+ Logger.error("Field should be empty. Discarding contents.");
+ else {
+ if (myElement.hasChildNodes())
+ textNode = (Text)myElement.getFirstChild();
+ else {
+ textNode = parentDoc.createTextNode(getDefaultValue());
+ myElement.appendChild(textNode);
+ }
+
+ myElementPanel.setData(textNode);
+ }
+ } catch (ClassCastException ex) {
+ throw new StructuralException("First child node of Field " + this.getName() + " was not Text: "+myElement.getFirstChild().getNodeType());
+ }
+ myAttributes.setInstance(myElement);
+ }
+
+ // check if valid
+
+ public String validateStructure() {
+ myAttributes.validateAttributes();
+ if (myElementPanel != null) myElementPanel.updateNode();
+ Text contents = (Text)myElement.getFirstChild();
+ if (!myElement.hasAttributes() && model.getMinOccurs() < 1 &&
+ (contents == null || contents.getData().length() == 0))
+ // empty - should remove if optional
+ myElement.getParentNode().removeChild(myElement);
+ return null;
+ }
+
+ public Element initNew(Document parent) {
+ Logger.msg(6, "Creating Field "+this.getName());
+
+ // make a new Element
+ myElement = parent.createElement(this.getName());
+
+ // see if there is a default/fixed value
+ if (myElementPanel != null) {
+ // populate
+ String defaultVal = readOnly?"":getDefaultValue();
+ textNode = parent.createTextNode(defaultVal);
+ myElement.appendChild(textNode);
+ myElementPanel.setData(textNode);
+ }
+
+ // set up attributes
+ myAttributes.initNew(myElement);
+
+ return myElement;
+ }
+
+ private String getDefaultValue() {
+ String defaultValue = model.getFixedValue();
+ if (defaultValue == null) defaultValue = model.getDefaultValue();
+ if (defaultValue == null) defaultValue = myElementPanel.getDefaultValue();
+ return defaultValue;
+ }
+
+ public void grabFocus() {
+ if (myElementPanel != null)
+ myElementPanel.grabFocus();
+ else
+ myAttributes.grabFocus();
+ }
+
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/HelpPane.java b/source/com/c2kernel/gui/tabs/outcome/form/HelpPane.java new file mode 100755 index 0000000..0f0f812 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/HelpPane.java @@ -0,0 +1,55 @@ +package com.c2kernel.gui.tabs.outcome.form;
+
+import javax.swing.JEditorPane;
+import javax.swing.text.html.HTMLEditorKit;
+
+import com.c2kernel.utils.Language;
+
+/**************************************************************************
+ *
+ * $Revision: 1.3 $
+ * $Date: 2004/08/24 12:44:02 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public class HelpPane extends JEditorPane {
+
+ public static final String header = "<h2><font color=\"blue\">"+Language.translate("Help")+"</font></h2>";
+
+ public HelpPane() {
+ super();
+ setEditable(false);
+ setEditorKit(new HTMLEditorKit());
+ setContentType("text/html");
+ setPreferredSize(new java.awt.Dimension(200,400));
+ }
+
+ public void setHelp(String title, String helpText) {
+ setText(header+"<h3>"+title+"</h3><br>"+toHTML(helpText));
+ }
+
+
+ /**
+ * Unfortunately JEditorPane will only display HTML3.2, whereas to embed HTML in an xsd we must
+ * use XHTML so it will be valid XML. This method does a quick and dirty removal of stuff that
+ * the JEditorPane cannot display
+ *
+ * @param xhtml
+ * @return
+ */
+ public static String toHTML(String xhtml) {
+ int startPos, endPos;
+ //remove xml header
+ while((startPos = xhtml.indexOf("<?")) != -1 &&
+ (endPos = xhtml.indexOf("?>")) != -1) {
+ xhtml = xhtml.substring(0,startPos)+xhtml.substring(endPos+2);
+ }
+ // remove slash in <tags/>
+ while ((startPos = xhtml.indexOf("/>")) != -1) {
+ xhtml = xhtml.substring(0, startPos)+xhtml.substring(startPos+1);
+ }
+ return xhtml;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/MultiLinePasteAdapter.java b/source/com/c2kernel/gui/tabs/outcome/form/MultiLinePasteAdapter.java new file mode 100755 index 0000000..d9f6b55 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/MultiLinePasteAdapter.java @@ -0,0 +1,133 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+import com.c2kernel.utils.Logger;
+
+import java.awt.datatransfer.*;
+import java.util.*;
+/**
+* ExcelAdapter enables Copy-Paste Clipboard functionality on JTables.
+* The clipboard data format used by the adapter is compatible with
+* the clipboard format used by Excel. This provides for clipboard
+* interoperability between enabled JTables and Excel.
+*/
+public class MultiLinePasteAdapter implements ActionListener {
+ private String rowstring, value;
+ private Clipboard system;
+ private StringSelection stsel;
+ private JTable jTable1;
+ private Dimension parent;
+ /**
+ * The Excel Adapter is constructed with a
+ * JTable on which it enables Copy-Paste and acts
+ * as a Clipboard listener.
+ */
+ public MultiLinePasteAdapter(JTable myJTable, Dimension parent) {
+ jTable1 = myJTable;
+ this.parent = parent;
+ KeyStroke copy =
+ KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK, false);
+ // Identifying the copy KeyStroke user can modify this
+ // to copy on some other Key combination.
+ KeyStroke paste =
+ KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK, false);
+ // Identifying the Paste KeyStroke user can modify this
+ //to copy on some other Key combination.
+ jTable1.registerKeyboardAction(
+ this,
+ "Copy",
+ copy,
+ JComponent.WHEN_FOCUSED);
+ jTable1.registerKeyboardAction(
+ this,
+ "Paste",
+ paste,
+ JComponent.WHEN_FOCUSED);
+ system = Toolkit.getDefaultToolkit().getSystemClipboard();
+ }
+ /**
+ * Public Accessor methods for the Table on which this adapter acts.
+ */
+ public JTable getJTable() {
+ return jTable1;
+ }
+ public void setJTable(JTable jTable1) {
+ this.jTable1 = jTable1;
+ }
+ /**
+ * This method is activated on the Keystrokes we are listening to
+ * in this implementation. Here it listens for Copy and Paste ActionCommands.
+ * Selections comprising non-adjacent cells result in invalid selection and
+ * then copy action cannot be performed.
+ * Paste is done by aligning the upper left corner of the selection with the
+ * 1st element in the current selection of the JTable.
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().compareTo("Copy") == 0) {
+ StringBuffer sbf = new StringBuffer();
+ // Check to ensure we have selected only a contiguous block of
+ // cells
+ int numcols = jTable1.getSelectedColumnCount();
+ int numrows = jTable1.getSelectedRowCount();
+ int[] rowsselected = jTable1.getSelectedRows();
+ int[] colsselected = jTable1.getSelectedColumns();
+ if (!((numrows - 1
+ == rowsselected[rowsselected.length - 1] - rowsselected[0]
+ && numrows == rowsselected.length)
+ && (numcols - 1
+ == colsselected[colsselected.length - 1] - colsselected[0]
+ && numcols == colsselected.length))) {
+ JOptionPane.showMessageDialog(
+ null,
+ "Invalid Copy Selection",
+ "Invalid Copy Selection",
+ JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ for (int i = 0; i < numrows; i++) {
+ for (int j = 0; j < numcols; j++) {
+ sbf.append(
+ jTable1.getValueAt(rowsselected[i], colsselected[j]));
+ if (j < numcols - 1)
+ sbf.append("\t");
+ }
+ sbf.append("\n");
+ }
+ stsel = new StringSelection(sbf.toString());
+ system = Toolkit.getDefaultToolkit().getSystemClipboard();
+ system.setContents(stsel, stsel);
+ }
+ if (e.getActionCommand().compareTo("Paste") == 0) {
+ Logger.msg(5, "Trying to Paste");
+ int startRow = (jTable1.getSelectedRows())[0];
+ int startCol = (jTable1.getSelectedColumns())[0];
+ try {
+ String trstring =
+ (String) (system.getContents(this).getTransferData(DataFlavor.stringFlavor));
+ Logger.msg(8, "String is:" + trstring);
+ StringTokenizer st1 = new StringTokenizer(trstring, "\n\r");
+ for (int i = 0; st1.hasMoreTokens(); i++) {
+ rowstring = st1.nextToken();
+ StringTokenizer st2 = new StringTokenizer(rowstring, "\t");
+ for (int j = 0; st2.hasMoreTokens(); j++) {
+ value = st2.nextToken();
+ if (startRow + i == jTable1.getRowCount())
+ parent.addRow(startRow+i);
+ if (startRow + i < jTable1.getRowCount()
+ && startCol + j < jTable1.getColumnCount())
+ jTable1.setValueAt(
+ value,
+ startRow + i,
+ startCol + j);
+ Logger.msg(5, "Putting "+value+" at row="+(startRow+i)+" column="+(startCol+j));
+ }
+ }
+ } catch (Exception ex) {
+ Logger.exceptionDialog(ex);
+ }
+
+ }
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/OutcomeEditor.java b/source/com/c2kernel/gui/tabs/outcome/form/OutcomeEditor.java new file mode 100755 index 0000000..10c3542 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/OutcomeEditor.java @@ -0,0 +1,214 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import com.c2kernel.persistency.outcome.OutcomeValidator;
+import com.c2kernel.persistency.outcome.Schema;
+import com.c2kernel.utils.FileStringUtility;
+import com.c2kernel.utils.Logger;
+
+
+class OutcomeEditor extends JFrame implements ActionListener {
+
+ boolean readOnly = false;
+ File schemaFile = null;
+ File instanceFile = null;
+ JFileChooser chooser;
+ OutcomePanel outcome;
+ OutcomeValidator thisValid;
+
+ public OutcomeEditor(File schema, File instance, boolean readOnly) {
+ URL schemaURL = null;
+ URL instanceURL = null;
+ schemaFile = schema;
+ instanceFile = instance;
+ this.readOnly = readOnly;
+
+ try {
+ chooser = new JFileChooser();
+ chooser.setCurrentDirectory(new File(new File(".").getCanonicalPath()));
+ } catch (IOException e) {
+ System.out.println("Could not initialise file dialog");
+ System.exit(0);
+ }
+
+
+ this.setTitle("Outcome Editor");
+ GridBagLayout gridbag = new GridBagLayout();
+ getContentPane().setLayout(gridbag);
+
+ addWindowListener(
+ new java.awt.event.WindowAdapter() {
+ public void windowClosing(java.awt.event.WindowEvent evt) {
+ System.exit(0);
+ }
+ }
+ );
+ // select files if url is empty
+
+ if (schemaFile == null) { // prompt for schema
+ schemaFile = getFile("Choose Schema File", "xsd");
+ if (schemaFile == null) {
+ System.out.println("Cannot function without a schema");
+ System.exit(1);
+ }
+ }
+
+ try {
+ schemaURL = schemaFile.toURL();
+ } catch (Exception e) {
+ System.out.println("Invalid schema URL");
+ System.exit(1);
+ }
+
+ if (instanceFile == null) { // prompt for schema
+ instanceFile = getFile("Choose Instance File", "xml");
+ }
+
+ try {
+ instanceURL = instanceFile.toURL();
+ } catch (Exception e) { }
+
+ try {
+ if (instanceFile != null && instanceFile.exists())
+ outcome = new OutcomePanel(schemaURL, instanceURL, readOnly);
+ else
+ outcome = new OutcomePanel(schemaURL, readOnly);
+
+ Schema thisSchema = new Schema();
+ thisSchema.docType = schemaURL.getFile();
+ thisSchema.docVersion = -1;
+ thisSchema.schema = FileStringUtility.url2String(schemaURL);
+ thisValid = OutcomeValidator.getValidator(thisSchema);
+
+ } catch (Exception e) { e.printStackTrace(); System.exit(0);}
+
+
+ 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.gridwidth = 2; c.ipadx = 5; c.ipady = 5;
+ gridbag.setConstraints(outcome, c);
+ this.getContentPane().add(outcome);
+
+ JButton saveButton = new JButton("Save");
+ saveButton.setActionCommand("save");
+ saveButton.addActionListener(this);
+ c.gridy++; c.weighty = 0; c.gridwidth = 1;
+ gridbag.setConstraints(saveButton, c);
+ this.getContentPane().add(saveButton);
+ if (readOnly) saveButton.setEnabled(false);
+
+ JButton saveAsButton = new JButton("Save As");
+ saveAsButton.setActionCommand("saveas");
+ saveAsButton.addActionListener(this);
+ c.gridx++; c.weighty = 0;
+ gridbag.setConstraints(saveAsButton, c);
+ this.getContentPane().add(saveAsButton);
+ if (readOnly) saveAsButton.setEnabled(false);
+ System.out.println("Building Outcome Panel. Please wait . . .");
+ outcome.run();
+ pack();
+ setVisible(true);
+ super.toFront();
+
+ }
+
+ public File getFile(String title, String fileType) {
+ File targetFile = null;
+ chooser.setFileFilter(new SimpleFilter(fileType));
+ chooser.setDialogTitle(title);
+ int returnVal = chooser.showDialog(this, "Select");
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ targetFile = chooser.getSelectedFile();
+ }
+ try {
+ System.out.println(fileType+"="+targetFile.toURL());
+ } catch (Exception ex) { }
+ return targetFile;
+ }
+
+ public static void usage() {
+ System.out.println("-schema file:///schema.xsd");
+ System.out.println("-inst file:///instance.xml");
+ System.out.println("Leave one out to get a file open box.");
+ System.exit(0);
+ }
+ public static void main( String[] argv ) {
+ Logger.addLogStream(System.out, 6);
+ File instance = null;
+ File schema = null;
+ boolean readOnly = false;
+ for (int i = 0; i < argv.length; i++) {
+ if (argv[i].equals("-schema"))
+ schema = new File(argv[++i]);
+ if (argv[i].equals("-inst"))
+ instance = new File(argv[++i]);
+ if (argv[i].equals("-readOnly"))
+ readOnly = true;
+ if (argv[i].equals("-help") || argv[i].equals("-h"))
+ usage();
+ }
+ new OutcomeEditor(schema, instance, readOnly);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().indexOf("save") == 0) {
+ String output;
+ output = outcome.getOutcome();
+
+ String errors = thisValid.validate(output);
+ if (errors != null && errors.length() > 0) {
+ int choice = JOptionPane.showConfirmDialog(null, errors+"\n\nSave anyway?", "Errors validating document", JOptionPane.YES_NO_OPTION);
+ if (choice != JOptionPane.YES_OPTION)
+ return;
+ }
+
+ if (instanceFile == null || e.getActionCommand().equals("saveas")) {
+ instanceFile = getFile("Choose Instance File", "xml");
+ if (instanceFile == null) {
+ System.out.println(output);
+ return;
+ }
+ }
+ try {
+ FileOutputStream targetStream = new FileOutputStream(instanceFile);
+ targetStream.write(output.getBytes());
+ targetStream.close();
+ } catch (Exception ex) {ex.printStackTrace();}
+ }
+ }
+
+ private class SimpleFilter extends javax.swing.filechooser.FileFilter {
+ String extension;
+
+ public SimpleFilter(String extension) {
+ super();
+ this.extension = extension;
+ }
+
+ public String getDescription() {
+ return extension.toUpperCase()+" Files";
+ }
+
+ public boolean accept(File f) {
+ if ((f.isFile() && f.getName().endsWith(extension.toLowerCase())) || f.isDirectory()) {
+ return true;
+ }
+ return false;
+ }
+ }
+}
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());
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java b/source/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java new file mode 100755 index 0000000..9333bf8 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java @@ -0,0 +1,283 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+
+import org.exolab.castor.types.AnyNode;
+import org.exolab.castor.xml.schema.Annotated;
+import org.exolab.castor.xml.schema.Annotation;
+import org.exolab.castor.xml.schema.ComplexType;
+import org.exolab.castor.xml.schema.ContentModelGroup;
+import org.exolab.castor.xml.schema.Documentation;
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.exolab.castor.xml.schema.Group;
+import org.exolab.castor.xml.schema.ModelGroup;
+import org.exolab.castor.xml.schema.Order;
+import org.exolab.castor.xml.schema.Particle;
+import org.exolab.castor.xml.schema.SimpleType;
+import org.exolab.castor.xml.schema.SimpleTypesFactory;
+import org.exolab.castor.xml.schema.XMLType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.utils.Language;
+import com.c2kernel.utils.Logger;
+
+// contains child outcome elements - creates new ones
+public abstract class OutcomeStructure extends JPanel {
+
+ ElementDecl model;
+ Element myElement = null;
+ boolean readOnly;
+ HashMap subStructure = new HashMap();
+ ArrayList order = new ArrayList();
+ String help = "<i>"+Language.translate("No help is available for this element")+"</i>";
+ HelpPane helpPane;
+ boolean deferChild = false;
+
+ public OutcomeStructure(ElementDecl model, boolean readOnly , HelpPane helpPane) {
+ this.model = model;
+ this.readOnly = readOnly;
+ this.helpPane = helpPane;
+ subStructure = new HashMap();
+ Logger.msg(8, "Creating " + model.getName() + " structure as " +
+ this.getClass().getName().substring(this.getClass().getName().lastIndexOf('.') + 1));
+
+ String doc = extractHelp(model);
+ if (doc.length() > 0) help = doc;
+ }
+
+ public boolean getReadOnly() {
+ return readOnly;
+ }
+ /** Contains the rules for deciding which OutcomeStructure will represent a chosen Element Declaration.
+ * In this order
+ * <ol>
+ * <li>if maxOccurs>1 then Dimension
+ * <li> SimpleTypes are Fields
+ * <li> No element children is a Field
+ * <li> Everything else is a DataRecord
+ * </ol>
+ */
+ public OutcomeStructure createStructure(ElementDecl model, boolean readOnly, HelpPane help) throws OutcomeException {
+ XMLType elementType = model.getType();
+ ComplexType elementComplexType;
+
+ if (model.getMaxOccurs() == 0) return null;
+
+ // if more than one can occur - dimension
+ if (model.getMaxOccurs() > 1
+ || model.getMaxOccurs() == Particle.UNBOUNDED
+ || model.getMinOccurs() == 0)
+ return new Dimension(model, readOnly, help);
+
+ // must have a type from now on
+ if (elementType == null)
+ throw new StructuralException("Element "+model.getName()+" is elementary yet has no type.");
+ // simple types will be fields
+ if (elementType instanceof SimpleType) return new Field(model, readOnly, help);
+
+ // otherwise is a complex type
+ try {
+ elementComplexType = (ComplexType)elementType;
+ }
+ catch (ClassCastException e) {
+ throw new StructuralException("Unknown XMLType for element " + model.getName());
+ }
+
+ //when no element children - field
+ if (elementComplexType.getParticleCount() == 0) return new Field(model, readOnly, help);
+
+ //everything else is a data record
+ return new DataRecord(model, readOnly, help, deferChild);
+ }
+
+ /** Extracts child Element declarations from a content group and recursively from any group
+ * (not Element) of that group. calls createStructure() to find the corresponding OutcomeStructure
+ * then adds it to this structure.
+ */
+ public void enumerateElements(ContentModelGroup group) throws OutcomeException {
+
+ // process base types first if complex type
+ //HACK: castor does not include elements from basetype, so we do it manually. if they fix it, this will duplicate child elements.
+ if (group instanceof ComplexType) {
+ XMLType base = ((ComplexType)group).getBaseType();
+ if (base instanceof ComplexType)
+ enumerateElements((ComplexType)base);
+ }
+
+ for (Enumeration elements = group.enumerate(); elements.hasMoreElements(); ) {
+ Particle thisParticle = (Particle)elements.nextElement();
+ if (thisParticle instanceof Group) {
+ Group thisGroup = (Group)thisParticle;
+ if (thisGroup instanceof ModelGroup) {
+ // HACK: Castor strangeness - model groups don't seem to resolve their own references. If fixed, this will still work
+ ModelGroup thisModel = (ModelGroup)thisGroup;
+ if (thisModel.hasReference()) thisGroup = thisModel.getReference();
+ }
+ Order thisOrder = thisGroup.getOrder();
+ if (thisOrder == Order.sequence || thisOrder == Order.all) enumerateElements(thisGroup);
+ else // we only support sequences in data structures such as these
+ throw new StructuralException("The '"+thisGroup.getOrder()+"' group is not supported");
+ }
+ else if (thisParticle instanceof ElementDecl) {
+ ElementDecl thisElement = (ElementDecl)thisParticle;
+ addStructure(createStructure(thisElement, readOnly, helpPane));
+ }
+ else throw new StructuralException("Particle " + thisParticle.getClass() + " not implemented");
+ }
+ }
+
+ /** Adds a generated OutcomeStructure as a child of this one. A separate structure as is often overridden.
+ */
+ public void addStructure(OutcomeStructure newElement) throws OutcomeException {
+ if (newElement == null) return;
+ subStructure.put(newElement.getName(), newElement);
+ order.add(newElement.getName());
+ }
+
+ /** After schema processing, addInstance() propogates the XML instance document down the layout.
+ * Most OutcomeStructures will throw an exception if called more than once, except Dimension, which is the only
+ * Outcome Structure to support maxOccurs>1
+ */
+ public abstract void addInstance(Element myElement, Document parentDoc) throws OutcomeException;
+
+ public Element getElement() {
+ return myElement;
+ }
+
+ public String getName() {
+ if (model == null) return null;
+ return model.getName();
+ }
+
+ public ElementDecl getModel() {
+ return model;
+ }
+
+ public String getHelp() {
+ return help;
+ }
+
+ public String validateStructure() {
+ StringBuffer errors = new StringBuffer();
+ for (Iterator iter = subStructure.values().iterator(); iter.hasNext();) {
+ OutcomeStructure element = (OutcomeStructure)iter.next();
+ errors.append(element.validateStructure());
+ }
+ return errors.toString();
+ }
+
+ public abstract Element initNew(Document parent);
+
+ public static String extractHelp(Annotated model) {
+ Enumeration e = model.getAnnotations();
+ StringBuffer doc = new StringBuffer();
+ if (e.hasMoreElements()) { // look for HTML
+ Annotation note = (Annotation)e.nextElement();
+ for (Enumeration g = note.getDocumentation(); g.hasMoreElements();) {
+ Documentation thisDoc = (Documentation)g.nextElement();
+ for (Enumeration h = thisDoc.getObjects(); h.hasMoreElements();) {
+ AnyNode node = (AnyNode)h.nextElement();
+ String line = node.toString();
+ if (line.length() == 0)
+ line = node.getStringValue();
+ if (line.length() > 0) {
+ doc.append(line).append("\n");
+ }
+ }
+ }
+ }
+
+ return doc.toString();
+ }
+
+ public abstract void grabFocus();
+
+ public static Class getJavaClass(int typeCode) {
+ switch (typeCode) {
+
+ // boolean
+ case SimpleTypesFactory.BOOLEAN_TYPE:
+ return Boolean.class;
+
+ // integers
+ case SimpleTypesFactory.INTEGER_TYPE:
+ case SimpleTypesFactory.NON_POSITIVE_INTEGER_TYPE:
+ case SimpleTypesFactory.NEGATIVE_INTEGER_TYPE:
+ case SimpleTypesFactory.NON_NEGATIVE_INTEGER_TYPE:
+ case SimpleTypesFactory.POSITIVE_INTEGER_TYPE:
+ case SimpleTypesFactory.INT_TYPE:
+ case SimpleTypesFactory.UNSIGNED_INT_TYPE:
+ case SimpleTypesFactory.SHORT_TYPE:
+ case SimpleTypesFactory.UNSIGNED_SHORT_TYPE:
+ case SimpleTypesFactory.LONG_TYPE:
+ case SimpleTypesFactory.UNSIGNED_LONG_TYPE:
+ case SimpleTypesFactory.BYTE_TYPE:
+ case SimpleTypesFactory.UNSIGNED_BYTE_TYPE:
+ return BigInteger.class;
+ // floats
+ case SimpleTypesFactory.FLOAT_TYPE:
+ case SimpleTypesFactory.DOUBLE_TYPE:
+ case SimpleTypesFactory.DECIMAL_TYPE:
+ return BigDecimal.class;
+
+ // images
+ case SimpleTypesFactory.BASE64BINARY_TYPE:
+ case SimpleTypesFactory.HEXBINARY_TYPE:
+ return ImageIcon.class;
+
+ // everything else is a string for now
+ default:
+ return String.class;
+ }
+ }
+
+ public static Object getTypedValue(String value, Class type) {
+ try {
+ if (type.equals(Boolean.class))
+ if (value == null || value.equals(""))
+ return Boolean.FALSE;
+ else
+ return Boolean.valueOf(value);
+ else if (type.equals(BigInteger.class))
+ if (value == null || value.equals(""))
+ return new BigInteger("0");
+ else
+ return new BigInteger(value);
+ else if (type.equals(BigDecimal.class))
+ if (value == null || value.equals(""))
+ return new BigDecimal(0);
+ else
+ return new BigDecimal(value);
+ } catch (Exception ex) {
+ Logger.error("Cannot convert value '"+value+"' to a "+type.getName());
+ }
+ return value==null?"":value;
+ }
+
+ public static boolean isEmpty(Object value) {
+ if (value == null) return true;
+
+ if (value instanceof String) {
+ if (((String)value).length() == 0) return true;
+ }
+ else if (value instanceof Boolean) {
+ if (((Boolean)value).booleanValue() == false) return true;
+ }
+ else if (value instanceof BigInteger) {
+ if (((BigInteger)value).intValue() == 0) return true;
+ }
+ else if (value instanceof BigDecimal) {
+ if (((BigDecimal)value).floatValue() == 0.0) return true;
+ }
+ return false;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/StructuralException.java b/source/com/c2kernel/gui/tabs/outcome/form/StructuralException.java new file mode 100755 index 0000000..5aff436 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/StructuralException.java @@ -0,0 +1,12 @@ +package com.c2kernel.gui.tabs.outcome.form;
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+
+public class StructuralException extends OutcomeException {
+
+ public StructuralException() {
+ super();
+ }
+ public StructuralException(String ex) {
+ super(ex);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayEditField.java new file mode 100755 index 0000000..e7dc8bc --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayEditField.java @@ -0,0 +1,166 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.text.JTextComponent;
+
+import org.exolab.castor.xml.schema.SimpleType;
+
+import com.c2kernel.utils.Language;
+
+/**************************************************************************
+ *
+ * $Revision: 1.7 $
+ * $Date: 2006/05/24 07:51:51 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public class ArrayEditField extends StringEditField implements ActionListener {
+
+ Box arrayBox;
+ Box expandBox;
+ Box editBox;
+ JScrollPane arrayView;
+ JButton arrayButton;
+ JButton expandButton;
+ JButton contractButton;
+ JButton addButton;
+ JButton removeButton;
+ ArrayTableModel arrayModel;
+ JLabel arrayLabel = new JLabel("Array");
+ boolean panelShown = false;
+ boolean readOnly = false;
+
+ public ArrayEditField(SimpleType type) {
+ arrayBox = Box.createVerticalBox();
+ arrayBox.add(arrayLabel);
+ arrayButton = new JButton(Language.translate("Show"));
+ arrayButton.addActionListener(this);
+ arrayButton.setActionCommand("toggle");
+ arrayBox.add(arrayButton);
+
+ expandBox = Box.createHorizontalBox();
+ expandButton = new JButton(">>");
+ expandButton.setToolTipText("Increase the number of columns displaying this array");
+ expandButton.addActionListener(this);
+ expandButton.setActionCommand("extend");
+
+ contractButton = new JButton("<<");
+ contractButton.setToolTipText("Decrease the number of columns displaying this array");
+ contractButton.addActionListener(this);
+ contractButton.setActionCommand("contract");
+
+ expandBox.add(contractButton);
+ expandBox.add(Box.createHorizontalGlue());
+ expandBox.add(expandButton);
+
+ arrayModel = new ArrayTableModel(type);
+ if (arrayModel.getColumnCount() < 2) contractButton.setEnabled(false);
+ arrayView = new JScrollPane(new JTable(arrayModel));
+
+ editBox = Box.createHorizontalBox();
+ addButton = new JButton("+");
+ addButton.setToolTipText("Add a field to the end of this array");
+ addButton.addActionListener(this);
+ addButton.setActionCommand("add");
+ removeButton = new JButton("-");
+ removeButton.setToolTipText("Remove the last field from this array");
+ removeButton.addActionListener(this);
+ removeButton.setActionCommand("remove");
+ editBox.add(addButton);
+ editBox.add(Box.createHorizontalGlue());
+ editBox.add(removeButton);
+ }
+ /**
+ *
+ */
+ public String getDefaultValue() {
+ return "";
+ }
+ /**
+ *
+ */
+ public String getText() {
+ return arrayModel.getData();
+ }
+ /**
+ *
+ */
+ public void setText(String text) {
+ arrayModel.setData(text);
+ arrayLabel.setText("Array ("+arrayModel.getArrayLength()+" values)");
+ }
+ /**
+ *
+ */
+ public Component getControl() {
+ return arrayBox;
+ }
+ /**
+ *
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("toggle")) {
+ arrayBox.removeAll();
+ if (panelShown) {
+ arrayBox.add(arrayLabel);
+ arrayBox.add(Box.createVerticalStrut(7));
+ arrayBox.add(arrayButton);
+ arrayButton.setText("Show");
+ }
+ else {
+ arrayBox.add(arrayLabel);
+ arrayBox.add(Box.createVerticalStrut(7));
+ arrayBox.add(arrayButton);
+ arrayBox.add(Box.createVerticalStrut(7));
+ arrayBox.add(expandBox);
+ arrayBox.add(Box.createVerticalStrut(7));
+ arrayBox.add(arrayView);
+ if (!readOnly) arrayBox.add(editBox);
+ arrayButton.setText("Hide");
+ }
+ panelShown = !panelShown;
+ arrayBox.validate();
+ }
+ else if (e.getActionCommand().equals("add")) {
+ arrayModel.addField();
+ arrayLabel.setText("Array ("+arrayModel.getArrayLength()+" values)");
+ }
+ else if (e.getActionCommand().equals("remove")) {
+ arrayModel.removeField();
+ arrayLabel.setText("Array ("+arrayModel.getArrayLength()+" values)");
+ }
+ else {
+ int currentCols = arrayModel.getColumnCount();
+ if (e.getActionCommand().equals("extend"))
+ currentCols++;
+ else if (e.getActionCommand().equals("contract"))
+ currentCols--;
+ arrayModel.setColumnCount(currentCols);
+ contractButton.setEnabled(currentCols > 1);
+ }
+
+ }
+
+ /**
+ *
+ */
+ public JTextComponent makeTextField() {
+ // not used by array
+ return null;
+ }
+ public void setEditable(boolean editable) {
+ readOnly = !editable;
+ arrayModel.setReadOnly(!readOnly);
+ }
+
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayTableModel.java b/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayTableModel.java new file mode 100755 index 0000000..0807f78 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/ArrayTableModel.java @@ -0,0 +1,106 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import javax.swing.table.AbstractTableModel;
+
+import org.exolab.castor.xml.schema.SimpleType;
+
+import com.c2kernel.gui.tabs.outcome.form.OutcomeStructure;
+import com.c2kernel.utils.Language;
+
+/**************************************************************************
+ *
+ * $Revision: 1.2 $
+ * $Date: 2006/05/24 07:51:53 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public class ArrayTableModel extends AbstractTableModel {
+
+ ArrayList contents = new ArrayList();
+ Class type;
+ int numCols = 1;
+ boolean readOnly = false;
+
+ public ArrayTableModel(SimpleType type) {
+ super();
+ this.type = OutcomeStructure.getJavaClass(type.getTypeCode());
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ }
+
+ public void setData(String data) {
+ contents.clear();
+ StringTokenizer tok = new StringTokenizer(data);
+ while(tok.hasMoreTokens())
+ contents.add(OutcomeStructure.getTypedValue(tok.nextToken(), type));
+ fireTableStructureChanged();
+ }
+
+ public String getData() {
+ if (contents.size() == 0) return "";
+ Iterator iter = contents.iterator();
+ StringBuffer result = new StringBuffer(iter.next().toString());
+ while (iter.hasNext())
+ result.append(" ").append(iter.next().toString());
+ return result.toString();
+ }
+
+ public void addField() {
+ contents.add(OutcomeStructure.getTypedValue("", type));
+ fireTableStructureChanged();
+ }
+
+ public void removeField() {
+ contents.remove(contents.size()-1);
+ fireTableStructureChanged();
+ }
+
+ public Class getColumnClass(int columnIndex) {
+ return type;
+ }
+
+ public int getColumnCount() {
+ return numCols;
+ }
+
+ public int getArrayLength() {
+ return contents.size();
+ }
+
+ public void setColumnCount(int newCols) {
+ numCols = newCols;
+ fireTableStructureChanged();
+ }
+
+ public String getColumnName(int column) {
+ return Language.translate("Value");
+ }
+
+ public int getRowCount() {
+ return (contents.size()/numCols)+1;
+ }
+
+ public Object getValueAt(int arg0, int arg1) {
+ int index = arg1+(arg0 * numCols);
+ if (index >= contents.size())
+ return null;
+ return contents.get(arg1+(arg0 * numCols));
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ if (columnIndex+(rowIndex*numCols) > contents.size()-1) return false;
+ return !readOnly;
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ contents.set(columnIndex+(rowIndex*numCols), aValue);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/BooleanEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/BooleanEditField.java new file mode 100755 index 0000000..5776f73 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/BooleanEditField.java @@ -0,0 +1,68 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Component;
+import java.awt.event.FocusEvent;
+
+import javax.swing.JCheckBox;
+import javax.swing.text.JTextComponent;
+
+import com.c2kernel.utils.Logger;
+
+/**************************************************************************
+ *
+ * $Revision: 1.7 $
+ * $Date: 2005/08/16 13:59:56 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public class BooleanEditField extends StringEditField {
+
+ JCheckBox checkbox;
+
+ public BooleanEditField() {
+ checkbox = new JCheckBox();
+ checkbox.setSelected(false);
+ checkbox.addFocusListener(this);
+ }
+
+ public String getText() {
+ return String.valueOf(checkbox.isSelected());
+ }
+
+ public void setText(String text) {
+ boolean newState = false;
+ try {
+ newState = Boolean.valueOf(text).booleanValue();
+ } catch (Exception ex) {
+ Logger.error("Invalid value for checkbox: "+text);
+ }
+ checkbox.setSelected(newState);
+ }
+
+ public void setEditable(boolean editable) {
+ super.setEditable(editable);
+ checkbox.setEnabled(editable);
+ }
+
+ public Component getControl() {
+ return checkbox;
+ }
+
+ public String getDefaultValue() {
+ return "false";
+ }
+
+ /** don't reserve the item finder for a boolean */
+ public void focusGained(FocusEvent e) {
+ helpPane.setHelp(name, helpText);
+ }
+
+ /**
+ *
+ */
+ public JTextComponent makeTextField() {
+ // not used by boolean
+ return null;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/ComboField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/ComboField.java new file mode 100755 index 0000000..2a0b34a --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/ComboField.java @@ -0,0 +1,135 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Component;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.text.JTextComponent;
+
+import org.exolab.castor.types.AnyNode;
+import org.exolab.castor.xml.schema.AttributeDecl;
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.exolab.castor.xml.schema.Facet;
+import org.exolab.castor.xml.schema.SimpleType;
+
+import com.c2kernel.gui.tabs.outcome.form.StructuralException;
+import com.c2kernel.scripting.Script;
+import com.c2kernel.utils.Logger;
+
+/*******************************************************************************
+ *
+ * $Revision: 1.4 $ $Date: 2005/08/16 13:59:56 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research All
+ * rights reserved.
+ ******************************************************************************/
+
+public class ComboField extends StringEditField {
+
+ JComboBox comboField;
+ ListOfValues vals;
+ DefaultComboBoxModel comboModel;
+ AnyNode listNode;
+
+ public ComboField(SimpleType type, AnyNode listNode) {
+ super();
+ comboField = new JComboBox();
+ content = type;
+ this.listNode = listNode;
+ createLOV();
+ }
+
+ public String getDefaultValue() {
+ if (vals.getDefaultKey() != null)
+ return vals.get(vals.getDefaultKey()).toString();
+ else
+ return "";
+ }
+
+ public String getText() {
+ return vals.get(comboModel.getSelectedItem()).toString();
+ }
+
+ public JTextComponent makeTextField() {
+ // not used by this control
+ return null;
+ }
+
+ public void setText(String text) {
+ comboModel.setSelectedItem(text);
+ }
+
+ public Component getControl() {
+ return comboField;
+ }
+
+ private void createLOV() {
+ vals = new ListOfValues();
+
+ if (listNode != null) { // schema instructions for list building
+ String lovType = listNode.getLocalName();
+ String param = listNode.getFirstChild().getStringValue();
+ if (lovType.equals("ScriptList"))
+ populateLOVFromScript(param);
+ if (lovType.equals("PathList"))
+ populateLOVFromLDAP(param);
+ }
+
+ // handle enumerations
+ // TODO: should be ANDed with above results
+ if (content.hasFacet(Facet.ENUMERATION)) {
+ //ListOfValues andList = new ListOfValues();
+ Enumeration enums = content.getFacets(Facet.ENUMERATION);
+ while (enums.hasMoreElements()) {
+ Facet thisEnum = (Facet)enums.nextElement();
+ vals.put(thisEnum.getValue(), thisEnum.getValue(), false);
+ }
+ }
+
+ comboModel = new DefaultComboBoxModel(vals.keySet().toArray());
+ comboModel.setSelectedItem(vals.getDefaultKey());
+ comboField.setModel(comboModel);
+ }
+
+ /**
+ * @param param
+ */
+ private void populateLOVFromLDAP(String param) {
+ // TODO '/root/path;prop=val;prop=val'
+
+
+ }
+
+ private void populateLOVFromScript(String scriptName) {
+ try {
+ StringTokenizer tok = new StringTokenizer(scriptName, "_");
+ if (tok.countTokens() != 2)
+ throw new Exception("Invalid LOVScript name");
+ Script lovscript = new Script(tok.nextToken(), Integer.parseInt(tok.nextToken()));
+ lovscript.setInputParamValue("LOV", vals);
+ lovscript.execute();
+ } catch (Exception ex) {
+ Logger.exceptionDialog(ex);
+ }
+ }
+
+ public void setDecl(AttributeDecl model) throws StructuralException {
+ super.setDecl(model);
+ createLOV();
+ }
+
+ public void setDecl(ElementDecl model) throws StructuralException {
+ super.setDecl(model);
+ createLOV();
+ }
+
+ /**
+ *
+ */
+
+ public void setEditable(boolean editable) {
+ comboField.setEditable(editable);
+ }
+}
\ No newline at end of file diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/DecimalEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/DecimalEditField.java new file mode 100755 index 0000000..d77dff3 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/DecimalEditField.java @@ -0,0 +1,115 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Toolkit;
+import java.math.BigDecimal;
+
+import javax.swing.JTextField;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
+/**************************************************************************
+ *
+ * $Revision: 1.3 $
+ * $Date: 2005/08/16 13:59:56 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public class DecimalEditField extends StringEditField {
+
+ public DecimalEditField() {
+ super();
+ field.addFocusListener(this);
+ field.setToolTipText("This field must contains a decimal number e.g. 3.14159265");
+ }
+
+ public String getText() {
+ return field.getText();
+ }
+
+ public void setText(String text) {
+ field.setText(text);
+ }
+
+ public String getDefaultValue() {
+ return "0.0";
+ }
+
+ public JTextComponent makeTextField() {
+ return new DecimalTextField();
+ }
+
+ private class DecimalTextField extends JTextField {
+
+ public DecimalTextField() {
+ super();
+ setHorizontalAlignment(RIGHT);
+ }
+ protected Document createDefaultModel() {
+ return new Decimal();
+ }
+ }
+
+ private class Decimal extends PlainDocument {
+
+ BigDecimal currentVal = new BigDecimal(0.0);
+
+
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+
+ if (str == null || str.equals("")) {
+ return;
+ }
+
+ String proposedResult = null;
+
+ if (getLength() == 0) {
+ proposedResult = str;
+ } else {
+ StringBuffer currentBuffer = new StringBuffer( this.getText(0, getLength()) );
+ currentBuffer.insert(offs, str);
+ proposedResult = currentBuffer.toString();
+ }
+
+ try {
+ currentVal = parse(proposedResult);
+ super.insertString(offs, str, a);
+ } catch (Exception e) {
+ Toolkit.getDefaultToolkit().beep();
+ }
+
+ }
+
+ public void remove(int offs, int len) throws BadLocationException {
+
+ String currentText = this.getText(0, getLength());
+ String beforeOffset = currentText.substring(0, offs);
+ String afterOffset = currentText.substring(len + offs, currentText.length());
+ String proposedResult = beforeOffset + afterOffset;
+
+ if (proposedResult.length() == 0) { // empty is ok
+ super.remove(offs, len);
+ return;
+ }
+ try {
+ currentVal = parse(proposedResult);
+ super.remove(offs, len);
+ } catch (Exception e) {
+ Toolkit.getDefaultToolkit().beep();
+ }
+
+ }
+
+ public BigDecimal parse(String proposedResult) throws NumberFormatException {
+
+ BigDecimal value = new BigDecimal(0);
+ if ( proposedResult.length() != 0) {
+ value = new BigDecimal(proposedResult);
+ }
+ return value;
+ }
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/FieldConstraints.java b/source/com/c2kernel/gui/tabs/outcome/form/field/FieldConstraints.java new file mode 100755 index 0000000..d09cd91 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/FieldConstraints.java @@ -0,0 +1,51 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.util.Enumeration;
+
+import org.exolab.castor.types.AnyNode;
+import org.exolab.castor.xml.schema.Annotation;
+import org.exolab.castor.xml.schema.AppInfo;
+import org.exolab.castor.xml.schema.XMLType;
+
+/**************************************************************************
+ *
+ * $Revision: 1.1 $
+ * $Date: 2005/04/26 06:48:12 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public class FieldConstraints {
+
+ XMLType content;
+ ListOfValues lov;
+ int rows = 1;
+
+ public FieldConstraints(XMLType content) {
+ this.content = content;
+ Enumeration e = content.getAnnotations();
+ while (e.hasMoreElements()) {
+ Annotation note = (Annotation)e.nextElement();
+ for (Enumeration f = note.getAppInfo(); f.hasMoreElements();) {
+ addAppInfo((AppInfo)f.nextElement());
+ }
+ }
+ }
+
+ private void addAppInfo(AppInfo element) {
+ Enumeration e = element.getObjects();
+ while (e.hasMoreElements()) {
+ AnyNode node = (AnyNode)e.nextElement();
+
+ }
+ }
+
+ public ListOfValues getLOV() {
+ return lov;
+ }
+
+ public int getRows() {
+ return rows;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/ImageEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/ImageEditField.java new file mode 100755 index 0000000..b0bb079 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/ImageEditField.java @@ -0,0 +1,104 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.reflect.Array;
+
+import javax.swing.Box;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+
+import org.apache.xerces.impl.dv.util.Base64;
+
+import com.c2kernel.utils.Logger;
+
+public class ImageEditField extends StringEditField {
+
+ JLabel imageLabel;
+
+ Box imagePanel;
+
+ JButton browseButton;
+
+ String encodedImage;
+
+ static JFileChooser chooser = new JFileChooser();
+ static {
+ chooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {
+ public String getDescription() {
+ return "Image Files";
+ }
+
+ public boolean accept(File f) {
+ return (f.isDirectory() || (f.isFile() && (f.getName()
+ .endsWith(".gif")
+ || f.getName().endsWith(".jpg")
+ || f.getName().endsWith(".jpeg")
+ || f.getName().endsWith(".png"))));
+ }
+ });
+ }
+
+ public ImageEditField() {
+ super();
+ imageLabel = new JLabel();
+ imagePanel = Box.createVerticalBox();
+ browseButton = new JButton("Browse");
+ browseButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ int returnVal = chooser.showOpenDialog(null);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ File file = chooser.getSelectedFile();
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ byte[] bArray = (byte[]) Array.newInstance(byte.class,
+ (int) file.length());
+ fis.read(bArray, 0, (int) file.length());
+ fis.close();
+
+ ImageIcon newImage = new ImageIcon(Toolkit
+ .getDefaultToolkit().createImage(bArray));
+ imageLabel.setIcon(newImage);
+ encodedImage = Base64.encode(bArray);
+ } catch (Exception ex) {
+ Logger.exceptionDialog(ex);
+ }
+ }
+ }
+ });
+ imagePanel.add(imageLabel);
+ imagePanel.add(Box.createVerticalStrut(5));
+ imagePanel.add(browseButton);
+ }
+
+ public String getDefaultValue() {
+ return "";
+ }
+
+ public Component getControl() {
+ return imagePanel;
+ }
+
+ public String getText() {
+ return encodedImage == null ? "" : encodedImage;
+ }
+
+ public void setText(String text) {
+ encodedImage = text;
+ if (text != null && text.length() > 0) {
+ byte[] decodedImage = Base64.decode(encodedImage);
+ imageLabel.setIcon(new ImageIcon(Toolkit.getDefaultToolkit()
+ .createImage(decodedImage)));
+ }
+ }
+
+ public void setEditable(boolean editable) {
+ browseButton.setVisible(false);
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/IntegerEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/IntegerEditField.java new file mode 100755 index 0000000..7c858a4 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/IntegerEditField.java @@ -0,0 +1,113 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Toolkit;
+import java.math.BigInteger;
+
+import javax.swing.JTextField;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
+/**************************************************************************
+ *
+ * $Revision: 1.4 $
+ * $Date: 2005/08/16 13:59:56 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public class IntegerEditField extends StringEditField {
+
+ public IntegerEditField() {
+ super();
+ field.setToolTipText("This field must contains a whole number e.g. 3");
+ }
+
+ public String getText() {
+ return field.getText();
+ }
+
+ public void setText(String text) {
+ field.setText(text);
+ }
+
+ public String getDefaultValue() {
+ return "0";
+ }
+
+ public JTextComponent makeTextField() {
+ return new IntegerTextField();
+ }
+
+ private class IntegerTextField extends JTextField {
+
+ public IntegerTextField() {
+ super();
+ setHorizontalAlignment(RIGHT);
+ }
+ protected Document createDefaultModel() {
+ return new IntegerDocument();
+ }
+ }
+
+ private class IntegerDocument extends PlainDocument {
+
+ BigInteger currentVal = new BigInteger("0");
+
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+
+ if (str == null || str.equals("")) {
+ return;
+ }
+
+ String proposedResult = null;
+
+ if (getLength() == 0) {
+ proposedResult = str;
+ } else {
+ StringBuffer currentBuffer = new StringBuffer( this.getText(0, getLength()) );
+ currentBuffer.insert(offs, str);
+ proposedResult = currentBuffer.toString();
+ }
+
+ try {
+ currentVal = parse(proposedResult);
+ super.insertString(offs, str, a);
+ } catch (Exception e) {
+ Toolkit.getDefaultToolkit().beep();
+ }
+
+ }
+
+ public void remove(int offs, int len) throws BadLocationException {
+
+ String currentText = this.getText(0, getLength());
+ String beforeOffset = currentText.substring(0, offs);
+ String afterOffset = currentText.substring(len + offs, currentText.length());
+ String proposedResult = beforeOffset + afterOffset;
+ if (proposedResult.length() == 0) { // empty is ok
+ super.remove(offs, len);
+ return;
+ }
+
+ try {
+ currentVal = parse(proposedResult);
+ super.remove(offs, len);
+ } catch (Exception e) {
+ Toolkit.getDefaultToolkit().beep();
+ }
+
+ }
+
+ public BigInteger parse(String proposedResult) throws NumberFormatException {
+
+ BigInteger value = new BigInteger("0");
+ if ( proposedResult.length() != 0) {
+ value = new BigInteger(proposedResult);
+ }
+ return value;
+ }
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/ListOfValues.java b/source/com/c2kernel/gui/tabs/outcome/form/field/ListOfValues.java new file mode 100755 index 0000000..2557cbe --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/ListOfValues.java @@ -0,0 +1,31 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.util.HashMap;
+
+/**************************************************************************
+ *
+ * $Revision: 1.2 $
+ * $Date: 2005/04/26 06:48:12 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+
+public class ListOfValues extends HashMap {
+
+ String defaultKey = null;
+
+ public ListOfValues() {
+ super();
+ }
+
+ public String put(String key, String value, boolean isDefaultKey) {
+ if (isDefaultKey) defaultKey = key;
+ return (String)super.put(key, value);
+ }
+
+ public String getDefaultKey() {
+ return defaultKey;
+ }
+
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/LongStringEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/LongStringEditField.java new file mode 100755 index 0000000..b782c65 --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/LongStringEditField.java @@ -0,0 +1,38 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+
+import java.awt.Component;
+
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.text.JTextComponent;
+
+import com.c2kernel.utils.Language;
+
+
+/**************************************************************************
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public class LongStringEditField extends StringEditField {
+
+ JTextArea bigText;
+ JScrollPane bigScroller;
+ public LongStringEditField() {
+ super();
+ field.setToolTipText(Language.translate("This field can contain any string."));
+ }
+
+ public JTextComponent makeTextField() {
+ return new JTextArea();
+ }
+ public Component getControl() {
+ if (bigScroller == null) {
+ bigScroller = new JScrollPane(field);
+ }
+ return bigScroller;
+ }
+}
diff --git a/source/com/c2kernel/gui/tabs/outcome/form/field/StringEditField.java b/source/com/c2kernel/gui/tabs/outcome/form/field/StringEditField.java new file mode 100755 index 0000000..310ee2e --- /dev/null +++ b/source/com/c2kernel/gui/tabs/outcome/form/field/StringEditField.java @@ -0,0 +1,252 @@ +package com.c2kernel.gui.tabs.outcome.form.field;
+import java.awt.Component;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import javax.swing.ImageIcon;
+import javax.swing.JTextField;
+import javax.swing.text.JTextComponent;
+
+import org.exolab.castor.types.AnyNode;
+import org.exolab.castor.xml.schema.Annotation;
+import org.exolab.castor.xml.schema.AppInfo;
+import org.exolab.castor.xml.schema.AttributeDecl;
+import org.exolab.castor.xml.schema.ElementDecl;
+import org.exolab.castor.xml.schema.Facet;
+import org.exolab.castor.xml.schema.SimpleType;
+import org.exolab.castor.xml.schema.Structure;
+import org.exolab.castor.xml.schema.XMLType;
+import org.exolab.castor.xml.schema.simpletypes.ListType;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import com.c2kernel.gui.DomainKeyConsumer;
+import com.c2kernel.gui.MainFrame;
+import com.c2kernel.gui.tabs.outcome.OutcomeException;
+import com.c2kernel.gui.tabs.outcome.form.HelpPane;
+import com.c2kernel.gui.tabs.outcome.form.OutcomeStructure;
+import com.c2kernel.gui.tabs.outcome.form.StructuralException;
+import com.c2kernel.lookup.DomainPath;
+
+/** Superclass for the entry field for Field and AttributeList.
+ */
+public class StringEditField implements FocusListener, DomainKeyConsumer {
+
+ Node data;
+ Structure model;
+ protected SimpleType content;
+ HelpPane helpPane;
+ String helpText;
+ protected JTextComponent field;
+
+ boolean isValid = true;
+ boolean editable = true;
+ String name;
+
+
+ public StringEditField() {
+ field = makeTextField();
+ if (field != null)
+ field.addFocusListener(this);
+ }
+
+ private static StringEditField getFieldForType(SimpleType type) {
+ // handle lists special
+ if (type instanceof ListType)
+ return new ArrayEditField(type.getBuiltInBaseType());
+
+ // is a combobox
+ if (type.hasFacet(Facet.ENUMERATION))
+ return new ComboField(type, null);
+ //find LOVscript
+ Enumeration e = type.getAnnotations();
+ while (e.hasMoreElements()) {
+ Annotation note = (Annotation)e.nextElement();
+ for (Enumeration f = note.getAppInfo(); f.hasMoreElements();) {
+ AppInfo thisAppInfo = (AppInfo)f.nextElement();
+ for (Enumeration g = thisAppInfo.getObjects(); g.hasMoreElements();) {
+ AnyNode appInfoNode = (AnyNode)g.nextElement();
+ if (appInfoNode.getLocalName().equals("ScriptList")
+ || appInfoNode.getLocalName().equals("LDAPList")) {
+ return new ComboField(type, appInfoNode);
+ }
+ }
+ }
+ }
+ // find info on length before we go to the base type
+ long length = -1;
+ if (type.getLength()!=null) length = type.getLength().longValue();
+ else if (type.getMaxLength()!=null) length = type.getMaxLength().longValue();
+ else if (type.getMinLength()!=null) length = type.getMinLength().longValue();
+
+ // find base type if derived
+ if (!(type.isBuiltInType()))
+ type = type.getBuiltInBaseType();
+ // else derive the class
+ Class contentClass = OutcomeStructure.getJavaClass(type.getTypeCode());
+ // disable list edits for the moment
+ if (contentClass.equals(Boolean.class))
+ return new BooleanEditField();
+ else if (contentClass.equals(BigInteger.class))
+ return new IntegerEditField();
+ else if (contentClass.equals(BigDecimal.class))
+ return new DecimalEditField();
+ else if (contentClass.equals(ImageIcon.class))
+ return new ImageEditField();
+ else if (length > 60)
+ return new LongStringEditField();
+ else return new StringEditField();
+ }
+
+ public static StringEditField getEditField(AttributeDecl model) throws StructuralException {
+ StringEditField newField = getFieldForType(model.getSimpleType());
+ newField.setDecl(model);
+ return newField;
+ }
+
+ public static StringEditField getEditField(ElementDecl model) throws StructuralException {
+ try {
+ XMLType baseType = model.getType();
+ while (!(baseType instanceof SimpleType))
+ baseType = baseType.getBaseType();
+ StringEditField newField = getFieldForType((SimpleType)baseType);
+ newField.setDecl(model);
+ return newField;
+ } catch (Exception ex) {
+ throw new StructuralException("No type defined in model");
+ }
+ }
+
+ public void setDecl(AttributeDecl model) throws StructuralException {
+ this.model=model;
+ this.content=model.getSimpleType();
+ this.name = model.getName();
+ if (model.isFixed()) setEditable(false);
+ }
+
+ public void setDecl(ElementDecl model) throws StructuralException {
+ this.model=model;
+ this.name = model.getName();
+ XMLType type = model.getType();
+
+ // derive base type
+ if (type.isSimpleType())
+ this.content = (SimpleType)type;
+ else
+ this.content = (SimpleType)(type.getBaseType());
+
+ if (this.content == null) throw new StructuralException("No declared base type of element");
+
+ //
+ if (model.getFixedValue() != null) setEditable(false);
+
+ }
+
+ public void setData(Attr newData) throws StructuralException {
+ if (!(newData.getName().equals(name)))
+ throw new StructuralException("Tried to add a "+newData.getName()+" into a "+name+" attribute.");
+
+ this.data = newData;
+ setText(newData.getValue());
+ }
+
+ public void setData(Text newData) {
+ String contents = newData.getData();
+ this.data = newData;
+ setText(contents);
+ }
+
+ public void setData(String newData) throws OutcomeException {
+ if (data == null) throw new OutcomeException("No node exists");
+ setText(newData);
+ updateNode();
+
+ }
+
+ public Structure getModel() {
+ return model;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Node getData() {
+ return data;
+ }
+
+ public String getDefaultValue() {
+ return "";
+ }
+
+ public void setHelp(HelpPane helpPane, String helpText) {
+ this.helpPane = helpPane;
+ this.helpText = helpText;
+ }
+
+ public void focusLost(FocusEvent e) {
+ if (MainFrame.itemFinder != null)
+ MainFrame.itemFinder.clearConsumer(this);
+ updateNode();
+ }
+
+ public void focusGained(FocusEvent e) {
+ helpPane.setHelp(name, helpText);
+ if (editable && MainFrame.itemFinder != null)
+ MainFrame.itemFinder.setConsumer(this, "Insert");
+ }
+
+ public void updateNode() {
+ if (data == null) return;
+ if (data instanceof Text) {
+ ((Text)data).setData(getText());
+ }
+ else { //attribute
+ ((Attr)data).setValue(getText());
+ }
+ }
+
+ /**
+ * Read domkey from barcode input
+ */
+ public void push(DomainPath key) {
+ setText(key.getName());
+ }
+
+ /**
+ * Read string from barcode input
+ */
+ public void push(String key) {
+ setText(key);
+ }
+
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ if (field != null)
+ field.setEditable(editable);
+ }
+
+ public String getText() {
+ return field.getText();
+ }
+
+ public void setText(String text) {
+ field.setText(text);
+ }
+
+ public JTextComponent makeTextField() {
+ return new JTextField();
+ }
+
+ public Component getControl() {
+ return field;
+ }
+
+ public void grabFocus() {
+ getControl().requestFocus();
+ }
+}
|
