Jochen Wiedmann wrote:
Hi, Fredrik,

both things shouldn't be technically too difficult. I'll start with
the ID/IDREF thing, we may return to the xjc:dom implementation later.

Forgetting for a moment, that the actual bean classes need changes,
I'll suggest that we start with validating the IDREF's. We'll later
see, that this is actually most of the work, if we do it right.

If an object has embedded ID/IDREF's, then its generated SAX handler
needs two additional objects:

  - A Map for storing the ID's and and the elements, to which are
being mapped. An
    element is added to this Map, whenever the SAX handler detects an
ID. The Map
    keys are the ID's and the Map elements are the associated elements.
  - A List for storing the IDREF's. Whenever the SAX handler detects
an IDREF, then
    it adds an implementation of the interface

            interface IDREF {
                void validate(Map pIds) throws SAXException;
            }

    The idea is, that the SAX handler will invoke all the IDREF's
within endDocument().
    Obviously, if the IDREF implementation is a suitable inner class,
then it can not
    only validate the reference, but invoke a proper setter as well.

For that first step, you should be able to work within the class
DriverSGImpl and its subclasses only, so a deeper understanding of all
the JaxMe details shouldn't be required.

Dear Jochen,

I started looking at this. I've attached a first small patch to retrieve and store IDs from attributes in the SAX handler. I haven't added checking for duplicate IDs yet. However, to make this work properly (both duplicate checking and IDREF lookup), I think this map may need to be made global across all SAX handlers in some way? Otherwise, we will need to check the ID maps of all SAX handlers for duplicate IDs and when looking up an object via an IDREF. The map of IDREFs, on the other hand, could be local to the SAX handler I think.

I don't know how to handle elements of type ID. This isn't really relevant for my use at least, not even sure if it really makes sense. Anyway, if I have an element declared as

<xs:schema targetNamespace="http://www.clixml.org/clix/1.0";
[...]
    <xs:complexType>
      <xs:sequence>
        <xs:element name="id" type="xs:ID"/>
[...]

then the type ('childType' in GroupHandlerSG.handleEndElementState) of the element is the namespace URI ("http://www.clixml.org/clix/1.0";) and local name ("id") of the element. How do you retrieve the actual type of the element declared in the schema?

I've also attached the schema I'm interested in compiling with JaxMe, in case you are interested.


Best regards,

Fredrik Vraalsen
SINTEF
Index: HandlerSGImpl.java
===================================================================
RCS file: 
/home/cvspublic/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java,v
retrieving revision 1.4
diff -u -r1.4 HandlerSGImpl.java
--- HandlerSGImpl.java  30 Jul 2005 21:05:15 -0000      1.4
+++ HandlerSGImpl.java  2 Aug 2005 13:14:37 -0000
@@ -15,8 +15,10 @@
  */
 package org.apache.ws.jaxme.generator.sg.impl.ccsg;
 
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.bind.ValidationEvent;
@@ -29,6 +31,7 @@
 import org.apache.ws.jaxme.generator.sg.TypeSG;
 import org.apache.ws.jaxme.generator.types.StringSG;
 import org.apache.ws.jaxme.js.DirectAccessible;
+import org.apache.ws.jaxme.js.JavaField;
 import org.apache.ws.jaxme.js.JavaMethod;
 import org.apache.ws.jaxme.js.JavaQName;
 import org.apache.ws.jaxme.js.JavaQNameImpl;
@@ -36,6 +39,7 @@
 import org.apache.ws.jaxme.js.LocalJavaField;
 import org.apache.ws.jaxme.js.TypedValue;
 import org.apache.ws.jaxme.js.impl.TypedValueImpl;
+import org.apache.ws.jaxme.xs.xml.XsQName;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
@@ -52,6 +56,7 @@
        private DirectAccessible paramResult;
        private DirectAccessible paramQName;
        private DirectAccessible paramAttrs;
+       private JavaField idMapField;
 
        protected HandlerSGImpl(ComplexTypeSG pType, JavaSource pJs) {
                ctSG = pType;
@@ -99,6 +104,14 @@
                return result;
        }
 
+       protected JavaField getIdMapField() {
+               if (idMapField == null) {
+                       idMapField = getJavaSource().newJavaField("__idMap", 
Map.class, JavaSource.PRIVATE);
+                       idMapField.addLine("new ", HashMap.class, "()");
+               }
+               return idMapField;
+       }
+       
        public JavaMethod newAddAttributeMethod() throws SAXException {
                AttributeSG[] myAttributes = ctSG.getAttributes();
                if (myAttributes.length == 0) {
@@ -141,6 +154,12 @@
                                createSimpleTypeConversion(jm, 
myAttributes[i].getTypeSG(), pValue,
                                                                                
   "@" + myAttributes[i].getName(),
                                                                                
   attr.getPropertySG(), result);
+                               XsQName typeName = attr.getTypeSG().getName();
+                               if 
("http://www.w3.org/2001/XMLSchema".equals(typeName.getNamespaceURI())
+                                               && 
"ID".equals(typeName.getLocalName())) {
+                                       // TODO check for duplicate IDs - ID 
map should be global?
+                                       jm.addLine(getIdMapField(), ".put(", 
pValue, ", ", result, ");");
+                               }
                                jm.addLine("return;");
                        }
                        if (!firstInNamespace) {
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.clixml.org/clix/1.0"; xmlns="http://www.clixml.org/clix/1.0"; xmlns:clix="http://www.clixml.org/clix/1.0"; xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:jaxb="http://java.sun.com/xml/ns/jaxb";
           xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"; jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0" elementFormDefault="qualified" attributeFormDefault="unqualified">

	<xs:annotation>
		<xs:appinfo>
			<jaxb:globalBindings>
				<xjc:noMarshaller/>
				<xjc:noValidator/>
				<xjc:noValidatingUnmarshaller/>
			</jaxb:globalBindings>
		</xs:appinfo>
	</xs:annotation>

	<xs:element name="rules">
		<xs:annotation>
			<xs:documentation>Root element for CLiX rule files.</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:sequence>
				<xs:element name="rule" maxOccurs="unbounded">
					<xs:annotation>
						<xs:documentation>A CLiX rule with a rule identifier</xs:documentation>
					</xs:annotation>
					<xs:complexType>
						<xs:sequence>
							<xs:group ref="formulaGroup"/>
						</xs:sequence>
						<xs:attribute name="id" type="xs:ID" use="required"/>
						<xs:attribute name="disabled" type="xs:boolean" use="optional"/>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="version" type="xs:string" use="optional" default="1.1"/>
		</xs:complexType>
	</xs:element>

	<xs:group name="formulaGroup">
		<xs:choice>
			<xs:element ref="forall"/>
			<xs:element ref="exists"/>
			<xs:element ref="equal"/>
			<xs:element ref="notEqual"/>
			<xs:element ref="same"/>
			<xs:element ref="less"/>
			<xs:element ref="greater"/>
			<xs:element ref="lessOrEqual"/>
			<xs:element ref="greaterOrEqual"/>
			<xs:element ref="and"/>
			<xs:element ref="or"/>
			<xs:element ref="implies"/>
			<xs:element ref="iff"/>
			<xs:element ref="ifThenElse"/>
			<xs:element ref="not"/>
			<xs:element ref="operator"/>
			<xs:element ref="true"/>
		</xs:choice>
	</xs:group>

	<xs:complexType name="QuantifierType">
		<xs:group ref="formulaGroup" minOccurs="0"/>
		<xs:attribute name="var" type="xs:string" use="required"/>
		<xs:attribute name="in" type="xs:string" use="required"/>
	</xs:complexType>

	<xs:complexType name="BinaryOperatorType">
		<xs:group ref="formulaGroup" minOccurs="2" maxOccurs="2"/>
	</xs:complexType>

	<xs:complexType name="BinaryPredicateType">
		<xs:attribute name="op1" type="xs:string" use="required"/>
		<xs:attribute name="op2" type="xs:string" use="required"/>
	</xs:complexType>

	<xs:element name="forall" type="QuantifierType"/>
	<xs:element name="and" type="BinaryOperatorType"/>
	<xs:element name="or" type="BinaryOperatorType"/>
	<xs:element name="implies" type="BinaryOperatorType"/>
	<xs:element name="iff" type="BinaryOperatorType"/>
	<xs:element name="not">
		<xs:complexType>
			<xs:group ref="formulaGroup"/>
		</xs:complexType>
	</xs:element>
	<xs:element name="exists" type="QuantifierType"/>
	<xs:element name="equal" type="BinaryPredicateType"/>
	<xs:element name="notEqual" type="BinaryPredicateType"/>
	<xs:element name="same" type="BinaryPredicateType"/>
	<xs:element name="less" type="BinaryPredicateType"/>
	<xs:element name="greater" type="BinaryPredicateType"/>
	<xs:element name="lessOrEqual" type="BinaryPredicateType"/>
	<xs:element name="greaterOrEqual" type="BinaryPredicateType"/>
	<xs:element name="operator">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="param" minOccurs="0" maxOccurs="unbounded">
					<xs:complexType>
						<xs:attribute name="name" type="xs:string" use="required"/>
						<xs:attribute name="value" type="xs:string" use="required"/>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="name" type="xs:string" use="required"/>
		</xs:complexType>
	</xs:element>
	<xs:element name="ifThenElse">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="if">
					<xs:complexType>
						<xs:group ref="formulaGroup"/>
					</xs:complexType>
				</xs:element>
				<xs:element name="then">
					<xs:complexType>
						<xs:group ref="formulaGroup"/>
					</xs:complexType>
				</xs:element>
				<xs:element name="else">
					<xs:complexType>
						<xs:group ref="formulaGroup"/>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="true">
		<xs:complexType/>
	</xs:element>
</xs:schema>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to