001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.aegis.type.basic;
019:
020: import java.beans.PropertyDescriptor;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.xml.namespace.QName;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030: import org.apache.cxf.aegis.DatabindingException;
031: import org.apache.cxf.aegis.util.NamespaceHelper;
032: import org.jdom.Element;
033:
034: public class XMLBeanTypeInfo extends BeanTypeInfo {
035: private static final Log LOG = LogFactory
036: .getLog(XMLBeanTypeInfo.class);
037: private List mappings;
038:
039: /**
040: * Map used for storing meta data about each property
041: */
042: private Map<QName, BeanTypePropertyInfo> name2PropertyInfo = new HashMap<QName, BeanTypePropertyInfo>();
043:
044: public XMLBeanTypeInfo(Class typeClass, List mappings,
045: String defaultNS) {
046: super (typeClass, defaultNS);
047:
048: this .mappings = mappings;
049: }
050:
051: @Override
052: protected boolean registerType(PropertyDescriptor desc) {
053: Element e = getPropertyElement(desc.getName());
054: if (e != null && e.getAttributeValue("type") != null) {
055: return false;
056: }
057:
058: return super .registerType(desc);
059: }
060:
061: @Override
062: protected void mapProperty(PropertyDescriptor pd) {
063: Element e = getPropertyElement(pd.getName());
064: String style = null;
065: QName mappedName = null;
066:
067: if (e != null) {
068: String ignore = e.getAttributeValue("ignore");
069: if (ignore != null && ignore.equals("true")) {
070: return;
071: }
072:
073: LOG.debug("Found mapping for property " + pd.getName());
074:
075: style = e.getAttributeValue("style");
076: mappedName = NamespaceHelper.createQName(e, e
077: .getAttributeValue("mappedName"),
078: getDefaultNamespace());
079: }
080:
081: if (style == null) {
082: style = "element";
083: }
084: if (mappedName == null) {
085: mappedName = createMappedName(pd);
086: }
087:
088: if (e != null) {
089: QName mappedType = NamespaceHelper.createQName(e, e
090: .getAttributeValue("typeName"),
091: getDefaultNamespace());
092: if (mappedType != null) {
093: mapTypeName(mappedName, mappedType);
094: }
095:
096: String nillableVal = e.getAttributeValue("nillable");
097: if (nillableVal != null && nillableVal.length() > 0) {
098: ensurePropertyInfo(mappedName).setNillable(
099: Boolean.valueOf(nillableVal).booleanValue());
100: }
101:
102: String minOccurs = e.getAttributeValue("minOccurs");
103: if (minOccurs != null && minOccurs.length() > 0) {
104: ensurePropertyInfo(mappedName).setMinOccurs(
105: Integer.parseInt(minOccurs));
106: }
107: }
108:
109: try {
110: // logger.debug("Mapped " + pd.getName() + " as " + style + " with
111: // name " + mappedName);
112: if ("element".equals(style)) {
113: mapElement(pd.getName(), mappedName);
114: } else if ("attribute".equals(style)) {
115: mapAttribute(pd.getName(), mappedName);
116: } else {
117: throw new DatabindingException("Invalid style: "
118: + style);
119: }
120: } catch (DatabindingException ex) {
121: ex.prepend("Couldn't create type for property "
122: + pd.getName() + " on " + getTypeClass());
123:
124: throw ex;
125: }
126: }
127:
128: private Element getPropertyElement(String name2) {
129: for (Iterator itr = mappings.iterator(); itr.hasNext();) {
130: Element mapping2 = (Element) itr.next();
131: List elements = mapping2.getChildren("property");
132: for (int i = 0; i < elements.size(); i++) {
133: Element e = (Element) elements.get(i);
134: String name = e.getAttributeValue("name");
135:
136: if (name != null && name.equals(name2)) {
137: return e;
138: }
139: }
140: }
141:
142: return null;
143: }
144:
145: /**
146: * Grab Nillable by looking in PropertyInfo map if no entry found, revert to
147: * parent class
148: */
149: @Override
150: public boolean isNillable(QName name) {
151: BeanTypePropertyInfo info = getPropertyInfo(name);
152: if (info != null) {
153: return info.isNillable();
154: }
155: return super .isNillable(name);
156: }
157:
158: /**
159: * Grab Min Occurs by looking in PropertyInfo map if no entry found, revert
160: * to parent class
161: */
162: @Override
163: public int getMinOccurs(QName name) {
164: BeanTypePropertyInfo info = getPropertyInfo(name);
165: if (info != null) {
166: return info.getMinOccurs();
167: }
168: return super .getMinOccurs(name);
169: }
170:
171: /**
172: * Grab the Property Info for the given property
173: *
174: * @param name
175: * @return the BeanTypePropertyInfo for the property or NULL if none found
176: */
177: private BeanTypePropertyInfo getPropertyInfo(QName name) {
178: return name2PropertyInfo.get(name);
179: }
180:
181: /**
182: * Grab the Property Info for the given property but if not found create one
183: * and add it to the map
184: *
185: * @param name
186: * @return the BeanTypePropertyInfo for the property
187: */
188: private BeanTypePropertyInfo ensurePropertyInfo(QName name) {
189: BeanTypePropertyInfo result = getPropertyInfo(name);
190: if (result == null) {
191: result = new BeanTypePropertyInfo();
192: name2PropertyInfo.put(name, result);
193: }
194: return result;
195: }
196: }
|