summaryrefslogtreecommitdiff
path: root/source/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java
diff options
context:
space:
mode:
Diffstat (limited to 'source/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java')
-rwxr-xr-xsource/com/c2kernel/gui/tabs/outcome/form/OutcomeStructure.java283
1 files changed, 283 insertions, 0 deletions
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;
+ }
+}