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.ws.policy.builder.jaxb;
019:
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.logging.Level;
023: import java.util.logging.Logger;
024:
025: import javax.xml.bind.JAXBContext;
026: import javax.xml.bind.JAXBElement;
027: import javax.xml.bind.JAXBException;
028: import javax.xml.bind.Unmarshaller;
029: import javax.xml.namespace.QName;
030:
031: import org.w3c.dom.Element;
032:
033: import org.apache.cxf.common.classloader.ClassLoaderUtils;
034: import org.apache.cxf.common.logging.LogUtils;
035: import org.apache.cxf.common.util.PackageUtils;
036: import org.apache.cxf.jaxb.JAXBUtils;
037: import org.apache.cxf.ws.policy.AssertionBuilder;
038: import org.apache.neethi.Assertion;
039: import org.apache.neethi.Constants;
040:
041: public class JaxbAssertionBuilder<T> implements AssertionBuilder {
042:
043: private static final Logger LOG = LogUtils
044: .getL7dLogger(JaxbAssertionBuilder.class);
045: private Unmarshaller unmarshaller;
046: private Collection<QName> supportedTypes;
047: private Class<T> type;
048:
049: /**
050: * Constructs a JAXBAssertionBuilder from the QName of the schema type
051: * @param qn the schema type
052: * @throws JAXBException
053: * @throws ClassNotFoundException
054: */
055: public JaxbAssertionBuilder(QName qn) throws JAXBException,
056: ClassNotFoundException {
057: this (JAXBUtils.namespaceURIToPackage(qn.getNamespaceURI())
058: + "."
059: + JAXBUtils.nameToIdentifier(qn.getLocalPart(),
060: JAXBUtils.IdentifierType.CLASS), qn);
061: }
062:
063: /**
064: * Constructs a JAXBAssertionBuilder from the specified class name and schema type.
065: * @param className the name of the class to which the schema type is mapped
066: * @param qn the schema type
067: * @throws JAXBException
068: * @throws ClassNotFoundException
069: */
070: @SuppressWarnings("unchecked")
071: public JaxbAssertionBuilder(String className, QName qn)
072: throws JAXBException, ClassNotFoundException {
073: this (ClassLoaderUtils.loadClass(className,
074: JaxbAssertionBuilder.class), qn);
075: }
076:
077: /**
078: * Constructs a JAXBAssertionBuilder from the specified class and schema type.
079: * @param type the class to which the schema type is mapped
080: * @param qn the schema type
081: * @throws JAXBException
082: * @throws ClassNotFoundException
083: */
084: public JaxbAssertionBuilder(Class<T> type, QName qn)
085: throws JAXBException {
086: this .type = type;
087: supportedTypes = Collections.singletonList(qn);
088: }
089:
090: protected Unmarshaller getUnmarshaller() {
091: if (unmarshaller == null) {
092: try {
093: createUnmarhsaller();
094: } catch (JAXBException e) {
095: throw new RuntimeException(e);
096: }
097: }
098:
099: return unmarshaller;
100: }
101:
102: protected synchronized void createUnmarhsaller()
103: throws JAXBException {
104: if (unmarshaller != null) {
105: return;
106: }
107:
108: JAXBContext context = JAXBContext.newInstance(PackageUtils
109: .getPackageName(type), type.getClassLoader());
110: unmarshaller = context.createUnmarshaller();
111: }
112:
113: public Assertion build(Element element) {
114: QName name = new QName(element.getNamespaceURI(), element
115: .getLocalName());
116: JaxbAssertion<T> assertion = buildAssertion();
117: assertion.setName(name);
118: assertion.setOptional(getOptionality(element));
119: assertion.setData(getData(element));
120: return assertion;
121: }
122:
123: public Collection<QName> getKnownElements() {
124: return supportedTypes;
125: }
126:
127: @SuppressWarnings("unchecked")
128: public Assertion buildCompatible(Assertion a, Assertion b) {
129: if (a.equal(b)) {
130: JaxbAssertion<T> ja = (JaxbAssertion<T>) a;
131: JaxbAssertion<T> compatible = buildAssertion();
132: compatible.setName(a.getName());
133: compatible.setOptional(a.isOptional() && b.isOptional());
134: compatible.setData(ja.getData());
135: return compatible;
136: }
137: return null;
138: }
139:
140: protected JaxbAssertion<T> buildAssertion() {
141: return new JaxbAssertion<T>();
142: }
143:
144: protected boolean getOptionality(Element element) {
145: boolean optional = false;
146: String value = element.getAttributeNS(
147: Constants.Q_ELEM_OPTIONAL_ATTR.getNamespaceURI(),
148: Constants.Q_ELEM_OPTIONAL_ATTR.getLocalPart());
149: if (Boolean.valueOf(value)) {
150: optional = true;
151: }
152: return optional;
153: }
154:
155: @SuppressWarnings("unchecked")
156: protected T getData(Element element) {
157: Object obj = null;
158: try {
159: obj = getUnmarshaller().unmarshal(element);
160: } catch (JAXBException ex) {
161: LogUtils
162: .log(LOG, Level.SEVERE, "UNMARSHAL_ELEMENT_EXC", ex);
163: }
164: if (obj instanceof JAXBElement<?>) {
165: JAXBElement<?> el = (JAXBElement<?>) obj;
166: obj = el.getValue();
167: }
168: if (null != obj && LOG.isLoggable(Level.FINE)) {
169: LOG.fine("Unmarshaled element into object of type: "
170: + obj.getClass().getName() + " value: " + obj);
171: }
172: return (T) obj;
173: }
174:
175: }
|