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.jaxws.handler;
019:
020: import java.net.URL;
021: import java.util.ArrayList;
022: import java.util.List;
023: import java.util.ResourceBundle;
024: import java.util.logging.Level;
025: import java.util.logging.Logger;
026:
027: import javax.jws.HandlerChain;
028: import javax.jws.WebService;
029: import javax.xml.bind.JAXBContext;
030: import javax.xml.bind.JAXBElement;
031: import javax.xml.bind.Unmarshaller;
032: import javax.xml.namespace.QName;
033: import javax.xml.ws.WebServiceException;
034: import javax.xml.ws.handler.Handler;
035:
036: import org.apache.cxf.Bus;
037: import org.apache.cxf.common.i18n.Message;
038: import org.apache.cxf.common.logging.LogUtils;
039: import org.apache.cxf.common.util.StringUtils;
040: import org.apache.cxf.jaxws.javaee.HandlerChainType;
041: import org.apache.cxf.jaxws.javaee.HandlerChainsType;
042:
043: public class AnnotationHandlerChainBuilder extends HandlerChainBuilder {
044:
045: private static final Logger LOG = LogUtils
046: .getL7dLogger(AnnotationHandlerChainBuilder.class);
047: private static final ResourceBundle BUNDLE = LOG
048: .getResourceBundle();
049:
050: public AnnotationHandlerChainBuilder() {
051: }
052:
053: public AnnotationHandlerChainBuilder(Bus bus) {
054: super (bus);
055: }
056:
057: /**
058: * @param clz
059: * @param existingHandlers
060: * @return
061: */
062: public List<Handler> buildHandlerChainFromClass(Class<?> clz,
063: List<Handler> existingHandlers, QName endpointName) {
064: LOG.fine("building handler chain");
065: HandlerChainAnnotation hcAnn = findHandlerChainAnnotation(clz,
066: true);
067: List<Handler> chain = null;
068: if (hcAnn == null) {
069: LOG.fine("no HandlerChain annotation on " + clz);
070: chain = new ArrayList<Handler>();
071: } else {
072: hcAnn.validate();
073:
074: try {
075: JAXBContext jc = JAXBContext
076: .newInstance(org.apache.cxf.jaxws.javaee.ObjectFactory.class);
077: Unmarshaller u = jc.createUnmarshaller();
078: URL handlerFileURL = resolveHandlerChainFile(clz, hcAnn
079: .getFileName());
080:
081: if (handlerFileURL == null) {
082: throw new WebServiceException(new Message(
083: "HANDLER_CFG_FILE_NOT_FOUND_EXC", BUNDLE,
084: hcAnn.getFileName()).toString());
085: }
086:
087: JAXBElement<?> o = (JAXBElement<?>) u
088: .unmarshal(handlerFileURL);
089:
090: HandlerChainsType handlerChainsType = (HandlerChainsType) o
091: .getValue();
092:
093: if (null == handlerChainsType
094: || handlerChainsType.getHandlerChain().size() == 0) {
095: throw new WebServiceException(BUNDLE
096: .getString("CHAIN_NOT_SPECIFIED_EXC"));
097: }
098:
099: chain = new ArrayList<Handler>();
100: for (HandlerChainType hc : handlerChainsType
101: .getHandlerChain()) {
102: //Only add handlers if <port-name-pattern> is not presented or is matched.
103: //TODO: match the namespace, match the wild card etc. JSR-181, Appendix B.
104: if (hc.getPortNamePattern() != null
105: && endpointName != null) {
106: String portNamePattern = hc
107: .getPortNamePattern();
108: String localPart = portNamePattern.substring(
109: portNamePattern.indexOf(':') + 1,
110: portNamePattern.length());
111: if (!localPart.equals(endpointName
112: .getLocalPart())) {
113: continue;
114: }
115: }
116: chain.addAll(buildHandlerChain(hc, clz
117: .getClassLoader()));
118: }
119:
120: } catch (Exception e) {
121: throw new WebServiceException(BUNDLE
122: .getString("CHAIN_NOT_SPECIFIED_EXC"), e);
123: }
124: }
125: assert chain != null;
126: if (existingHandlers != null) {
127: chain.addAll(existingHandlers);
128: }
129: return sortHandlers(chain);
130: }
131:
132: protected URL resolveHandlerChainAnnotationFile(Class clazz,
133: String name) {
134: return clazz.getResource(name);
135: }
136:
137: public List<Handler> buildHandlerChainFromClass(Class<?> clz,
138: QName endpointName) {
139: return buildHandlerChainFromClass(clz, null, endpointName);
140: }
141:
142: public List<Handler> buildHandlerChainFromClass(Class<?> clz) {
143: return buildHandlerChainFromClass(clz, null, null);
144: }
145:
146: private HandlerChainAnnotation findHandlerChainAnnotation(
147: Class<?> clz, boolean searchSEI) {
148: if (LOG.isLoggable(Level.FINE)) {
149: LOG.fine("Checking for HandlerChain annotation on "
150: + clz.getName());
151: }
152: HandlerChainAnnotation hcAnn = null;
153: HandlerChain ann = clz.getAnnotation(HandlerChain.class);
154: if (ann == null) {
155: if (searchSEI) {
156: /* HandlerChain annotation can be specified on the SEI
157: * but the implementation bean might not implement the SEI.
158: */
159: WebService ws = clz.getAnnotation(WebService.class);
160: if (ws != null
161: && !StringUtils.isEmpty(ws.endpointInterface())) {
162: String seiClassName = ws.endpointInterface().trim();
163: Class seiClass = null;
164: try {
165: seiClass = clz.getClassLoader().loadClass(
166: seiClassName);
167: } catch (ClassNotFoundException e) {
168: throw new WebServiceException(BUNDLE
169: .getString("SEI_LOAD_FAILURE_EXC"), e);
170: }
171:
172: // check SEI class and its interfaces for HandlerChain annotation
173: hcAnn = findHandlerChainAnnotation(seiClass, false);
174: }
175: }
176: if (hcAnn == null) {
177: // check interfaces for HandlerChain annotation
178: for (Class<?> iface : clz.getInterfaces()) {
179: if (LOG.isLoggable(Level.FINE)) {
180: LOG
181: .fine("Checking for HandlerChain annotation on "
182: + iface.getName());
183: }
184: ann = iface.getAnnotation(HandlerChain.class);
185: if (ann != null) {
186: hcAnn = new HandlerChainAnnotation(ann, iface);
187: break;
188: }
189: }
190: }
191: } else {
192: hcAnn = new HandlerChainAnnotation(ann, clz);
193: }
194:
195: return hcAnn;
196: }
197:
198: private static class HandlerChainAnnotation {
199: private final Class<?> declaringClass;
200: private final HandlerChain ann;
201:
202: HandlerChainAnnotation(HandlerChain hc, Class<?> clz) {
203: ann = hc;
204: declaringClass = clz;
205: }
206:
207: public Class<?> getDeclaringClass() {
208: return declaringClass;
209: }
210:
211: public String getFileName() {
212: return ann.file();
213: }
214:
215: public void validate() {
216: if (null == ann.file() || "".equals(ann.file())) {
217: throw new WebServiceException(BUNDLE
218: .getString("ANNOTATION_WITHOUT_URL_EXC"));
219: }
220: }
221:
222: public String toString() {
223: return "[" + declaringClass + "," + ann + "]";
224: }
225: }
226: }
|