Index: org/apache/ws/jaxme/generator/sg/impl/ccsg/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 --- org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java 30 Jul 2005 21:05:15 -0000 1.4 +++ org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java 5 Aug 2005 11:01:20 -0000 @@ -17,11 +17,13 @@ import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import java.util.Set; import javax.xml.bind.ValidationEvent; import javax.xml.namespace.QName; +import org.apache.ws.jaxme.IDREF; import org.apache.ws.jaxme.ValidationEvents; import org.apache.ws.jaxme.generator.sg.AttributeSG; import org.apache.ws.jaxme.generator.sg.ComplexTypeSG; @@ -29,13 +31,18 @@ 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.JavaConstructor; +import org.apache.ws.jaxme.js.JavaField; +import org.apache.ws.jaxme.js.JavaInnerClass; import org.apache.ws.jaxme.js.JavaMethod; import org.apache.ws.jaxme.js.JavaQName; import org.apache.ws.jaxme.js.JavaQNameImpl; import org.apache.ws.jaxme.js.JavaSource; import org.apache.ws.jaxme.js.LocalJavaField; +import org.apache.ws.jaxme.js.Parameter; 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 +59,7 @@ private DirectAccessible paramResult; private DirectAccessible paramQName; private DirectAccessible paramAttrs; + private JavaInnerClass idrefImplClass; protected HandlerSGImpl(ComplexTypeSG pType, JavaSource pJs) { ctSG = pType; @@ -116,6 +124,7 @@ JavaQName resultType = ctSG.getClassContext().getXMLInterfaceName(); LocalJavaField result = jm.newJavaField(resultType); + result.setFinal(true); result.addLine("(", resultType, ") result"); Set uris = createSetOfExplicitURIs(myAttributes); @@ -138,9 +147,42 @@ jm.addIf(firstInNamespace, JavaSource.getQuoted(attr.getName().getLocalName()), ".equals(", pLocalName, ")"); firstInNamespace = false; - createSimpleTypeConversion(jm, myAttributes[i].getTypeSG(), pValue, - "@" + myAttributes[i].getName(), - attr.getPropertySG(), result); + boolean idref = false; + XsQName typeName = attr.getTypeSG().getName(); + if ("http://www.w3.org/2001/XMLSchema".equals(typeName.getNamespaceURI())) { + if ("ID".equals(typeName.getLocalName())) { + jm.addLine("getHandler().addId(", pValue, ", ", result, ");"); + } else if ("IDREF".equals(typeName.getLocalName())) { + idref = true; + try { + // FIXME how to make method parameter 'pValue' final, to avoid this temp variable? + LocalJavaField idField = jm.newJavaField(String.class); + idField.setFinal(true); + idField.addLine(pValue, ";"); + + // FIXME how to properly create anonymous innner class? + LocalJavaField idrefField = jm.newJavaField(IDREF.class, "idref"); + idrefField.addLine("new ", IDREF.class, "() {"); + idrefField.addLine(" public void validate(", Map.class, " pIds) throws ", SAXException.class, " {"); + idrefField.addLine(" Object o = pIds.get(", idField, ");"); + idrefField.addLine(" if (o != null) {"); + idrefField.addLine(" ", result, ".", attr.getPropertySG().getXMLSetMethodName(), "(", "o", ");"); + idrefField.addLine(" } else {"); + idrefField.addLine(" throw new ", SAXException.class, "(", JavaSource.getQuoted("ID attribute '"), " + ", idField, " + ", JavaSource.getQuoted("' is not unique"), ");"); + idrefField.addLine(" }"); + idrefField.addLine(" }"); + idrefField.addLine("};"); + jm.addLine("getHandler().addIdref(", idrefField, ");"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + if (!idref) { + createSimpleTypeConversion(jm, myAttributes[i].getTypeSG(), pValue, + "@" + myAttributes[i].getName(), + attr.getPropertySG(), result); + } jm.addLine("return;"); } if (!firstInNamespace) { Index: org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java =================================================================== RCS file: /home/cvspublic/ws-jaxme/src/jaxme/org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java,v retrieving revision 1.9 diff -u -r1.9 JMUnmarshallerHandlerImpl.java --- org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java 30 Jun 2005 08:16:13 -0000 1.9 +++ org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java 5 Aug 2005 11:01:21 -0000 @@ -17,7 +17,10 @@ package org.apache.ws.jaxme.impl; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.xml.bind.DatatypeConverterInterface; import javax.xml.bind.JAXBException; @@ -28,6 +31,7 @@ import javax.xml.bind.helpers.ValidationEventLocatorImpl; import javax.xml.namespace.QName; +import org.apache.ws.jaxme.IDREF; import org.apache.ws.jaxme.JMManager; import org.apache.ws.jaxme.JMUnmarshaller; import org.apache.ws.jaxme.JMUnmarshallerHandler; @@ -74,6 +78,8 @@ private final StringBuffer sb = new StringBuffer(); private Observer observer; private Object result; + private final Map idMap = new HashMap(); + private final List idrefs = new ArrayList(); public int getLevel() { return level; } @@ -131,6 +137,10 @@ } public void endDocument() throws SAXException { + for (Iterator i = idrefs.iterator(); i.hasNext();) { + IDREF idref = (IDREF) i.next(); + idref.validate(idMap); + } } public void startPrefixMapping(String pPrefix, String pURI) throws SAXException { @@ -394,4 +404,24 @@ state = STATE_GROUP; } } + + /** + * @param id XML ID attribute of JAXB object + * @param jaxbObject the JAXB object + * @throws SAXException if duplicate ID + */ + public void addId(String id, Object jaxbObject) throws SAXException { + if (idMap.containsKey(id)) { + throw new SAXException("ID '" + id + "' is not unique"); + } + idMap.put(id, jaxbObject); + } + + /** + * @param idref + */ + public void addIdref(IDREF idref) { + idrefs.add(idref); + } + } Index: org/apache/ws/jaxme/IDREF.java =================================================================== RCS file: org/apache/ws/jaxme/IDREF.java diff -N org/apache/ws/jaxme/IDREF.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ org/apache/ws/jaxme/IDREF.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,19 @@ +package org.apache.ws.jaxme; + +import java.util.Map; + +import org.xml.sax.SAXException; + +/** + * @author Fredrik Vraalsen + * + */ +public interface IDREF { + + /** + * @param pIds the map of IDs->objects + * @throws SAXException if IDREF references non-existing ID + */ + public void validate(Map pIds) throws SAXException; + +}