001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.jaxb.property;
031:
032: import java.io.IOException;
033:
034: import static javax.xml.XMLConstants.*;
035:
036: import javax.xml.bind.JAXBException;
037: import javax.xml.bind.Marshaller;
038: import javax.xml.bind.Unmarshaller;
039: import javax.xml.bind.annotation.XmlElementWrapper;
040:
041: import javax.xml.namespace.QName;
042:
043: import javax.xml.stream.XMLStreamException;
044: import javax.xml.stream.XMLStreamReader;
045: import javax.xml.stream.XMLStreamWriter;
046:
047: import org.w3c.dom.Node;
048:
049: import com.caucho.jaxb.BinderImpl;
050: import com.caucho.jaxb.NodeIterator;
051: import com.caucho.jaxb.mapping.ConstantNamer;
052: import com.caucho.jaxb.mapping.Namer;
053: import com.caucho.util.L10N;
054:
055: /**
056: * represents a property in a skeleton
057: */
058: public class WrapperProperty extends Property {
059: public static final L10N L = new L10N(WrapperProperty.class);
060:
061: private final Namer _wrappedNamer;
062: private final String _name;
063: private final String _namespace;
064: private final QName _wrappedQName;
065: private final QName _wrapperQName;
066: private final Property _property;
067: private final boolean _nillable;
068:
069: public WrapperProperty(Property property,
070: XmlElementWrapper elementWrapper, String wrappedNamespace,
071: String wrappedName) {
072: _wrappedQName = new QName(wrappedNamespace, wrappedName);
073:
074: if ("##default".equals(elementWrapper.name()))
075: _name = wrappedName;
076: else
077: _name = elementWrapper.name();
078:
079: if ("##default".equals(elementWrapper.namespace()))
080: _namespace = wrappedNamespace;
081: else
082: _namespace = elementWrapper.namespace();
083:
084: _wrapperQName = new QName(_namespace, _name);
085: _property = property;
086: _nillable = elementWrapper.nillable();
087:
088: _wrappedNamer = ConstantNamer.getConstantNamer(_wrappedQName);
089: }
090:
091: public WrapperProperty(Property property, QName wrapperQName,
092: QName wrappedQName) {
093: _name = wrapperQName.getLocalPart();
094:
095: if (wrapperQName.getNamespaceURI() != null
096: && !"".equals(wrapperQName.getNamespaceURI()))
097: _namespace = wrapperQName.getNamespaceURI();
098: else
099: _namespace = null;
100:
101: _wrapperQName = wrapperQName;
102: _wrappedQName = wrappedQName;
103: _nillable = false;
104: _property = property;
105:
106: _wrappedNamer = ConstantNamer.getConstantNamer(_wrappedQName);
107: }
108:
109: public QName getWrapperQName() {
110: return _wrapperQName;
111: }
112:
113: //
114: // Schema generation methods
115: //
116: public boolean isXmlPrimitiveType() {
117: return _property.isXmlPrimitiveType(); // XXX
118: }
119:
120: public String getMinOccurs() {
121: return "0";
122: }
123:
124: public String getMaxOccurs() {
125: return null;
126: }
127:
128: public boolean isNullable() {
129: return false;
130: }
131:
132: public QName getSchemaType() {
133: return _property.getSchemaType(); // XXX
134: }
135:
136: //
137: // R/W methods
138: //
139:
140: public Object read(Unmarshaller u, XMLStreamReader in,
141: Object previous) throws IOException, XMLStreamException,
142: JAXBException {
143: if (_nillable) {
144: String nil = in.getAttributeValue(
145: W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
146:
147: if ("true".equals(nil)) {
148: in.nextTag(); // skip wrapper
149: // XXX make sure nothing is in between the start and end wrapper
150: in.next(); // skip wrapper
151:
152: return null;
153: }
154: }
155:
156: in.nextTag(); // skip wrapper
157:
158: while (in.getEventType() == in.START_ELEMENT
159: && _wrappedQName.equals(in.getName()))
160: previous = _property.read(u, in, previous);
161:
162: in.nextTag();
163:
164: return previous;
165: }
166:
167: public Object bindFrom(BinderImpl binder, NodeIterator node,
168: Object previous) throws IOException, JAXBException {
169: throw new UnsupportedOperationException();
170: }
171:
172: public void write(Marshaller m, XMLStreamWriter out, Object value,
173: Namer namer) throws IOException, XMLStreamException,
174: JAXBException {
175: if (value != null || _nillable) {
176: if (_namespace != null && !"".equals(_namespace))
177: out.writeStartElement(_namespace, _name);
178: else
179: out.writeStartElement(_name);
180:
181: if (value == null && _nillable) {
182: out.writeNamespace("xsi",
183: W3C_XML_SCHEMA_INSTANCE_NS_URI);
184: out.writeAttribute(W3C_XML_SCHEMA_INSTANCE_NS_URI,
185: "nil", "true");
186: }
187: }
188:
189: _property.write(m, out, value, _wrappedNamer);
190:
191: if (value != null || _nillable) {
192: out.writeEndElement();
193: }
194: }
195:
196: public Node bindTo(BinderImpl binder, Node node, Object value,
197: Namer namer) throws IOException, JAXBException {
198: throw new UnsupportedOperationException();
199: }
200: }
|