001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.xjc.api.impl.s2j;
027:
028: import java.util.ArrayList;
029: import java.util.Collection;
030: import java.util.List;
031:
032: import javax.xml.namespace.QName;
033:
034: import com.sun.tools.internal.xjc.api.Mapping;
035: import com.sun.tools.internal.xjc.api.Property;
036: import com.sun.tools.internal.xjc.model.CClassInfo;
037: import com.sun.tools.internal.xjc.model.CElement;
038: import com.sun.tools.internal.xjc.model.CElementInfo;
039: import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
040: import com.sun.tools.internal.xjc.model.CPropertyInfo;
041: import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
042: import com.sun.tools.internal.xjc.model.CTypeRef;
043: import com.sun.xml.internal.bind.v2.model.core.ClassInfo;
044: import com.sun.xml.internal.bind.v2.model.core.ReferencePropertyInfo;
045:
046: /**
047: * Partial common implementation between {@link ElementMappingImpl} and {@link BeanMappingImpl}
048: *
049: * @author Kohsuke Kawaguchi
050: */
051: abstract class AbstractMappingImpl<InfoT extends CElement> implements
052: Mapping {
053:
054: protected final JAXBModelImpl parent;
055: protected final InfoT clazz;
056:
057: /**
058: * Lazily computed.
059: *
060: * @see #getWrapperStyleDrilldown()
061: */
062: private List<Property> drilldown = null;
063: private boolean drilldownComputed = false;
064:
065: protected AbstractMappingImpl(JAXBModelImpl parent, InfoT clazz) {
066: this .parent = parent;
067: this .clazz = clazz;
068: }
069:
070: public final QName getElement() {
071: return clazz.getElementName();
072: }
073:
074: public final String getClazz() {
075: return clazz.getType().fullName();
076: }
077:
078: public final List<? extends Property> getWrapperStyleDrilldown() {
079: if (!drilldownComputed) {
080: drilldownComputed = true;
081: drilldown = calcDrilldown();
082: }
083: return drilldown;
084: }
085:
086: protected abstract List<Property> calcDrilldown();
087:
088: /**
089: * Derived classes can use this method to implement {@link #calcDrilldown}.
090: */
091: protected List<Property> buildDrilldown(CClassInfo typeBean) {
092: List<Property> result;
093:
094: CClassInfo bc = typeBean.getBaseClass();
095: if (bc != null) {
096: result = buildDrilldown(bc);
097: if (result == null)
098: return null; // aborted
099: } else
100: result = new ArrayList<Property>();
101:
102: for (CPropertyInfo p : typeBean.getProperties()) {
103: if (p instanceof CElementPropertyInfo) {
104: CElementPropertyInfo ep = (CElementPropertyInfo) p;
105: // wrong. A+,B,C is eligible for drill-down.
106: // if(ep.isCollection())
107: // // content model like A+,B,C is not eligible
108: // return null;
109:
110: List<? extends CTypeRef> ref = ep.getTypes();
111: if (ref.size() != 1)
112: // content model like (A|B),C is not eligible
113: return null;
114:
115: result.add(createPropertyImpl(ep, ref.get(0)
116: .getTagName()));
117: } else if (p instanceof ReferencePropertyInfo) {
118: CReferencePropertyInfo rp = (CReferencePropertyInfo) p;
119:
120: Collection<CElement> elements = rp.getElements();
121: if (elements.size() != 1)
122: return null;
123:
124: CElement ref = elements.iterator().next();
125: if (ref instanceof ClassInfo) {
126: result.add(createPropertyImpl(rp, ref
127: .getElementName()));
128: } else {
129: CElementInfo eref = (CElementInfo) ref;
130: if (!eref.getSubstitutionMembers().isEmpty())
131: return null; // elements with a substitution group isn't qualified for the wrapper style
132:
133: // JAX-WS doesn't want to see JAXBElement, so we have to hide it for them.
134: ElementAdapter fr;
135: if (rp.isCollection())
136: fr = new ElementCollectionAdapter(
137: parent.outline.getField(rp), eref);
138: else
139: fr = new ElementSingleAdapter(parent.outline
140: .getField(rp), eref);
141:
142: result.add(new PropertyImpl(this , fr, eref
143: .getElementName()));
144: }
145: } else
146: // to be eligible for the wrapper style, only elements are allowed.
147: // according to the JAX-RPC spec 2.3.1.2, element refs are disallowed
148: return null;
149:
150: }
151:
152: return result;
153: }
154:
155: private Property createPropertyImpl(CPropertyInfo p, QName tagName) {
156: return new PropertyImpl(this, parent.outline.getField(p),
157: tagName);
158: }
159: }
|