001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.axis2;
017:
018: import java.net.URL;
019: import java.util.ArrayList;
020: import java.util.List;
021:
022: import javax.jws.HandlerChain;
023: import javax.jws.WebService;
024: import javax.xml.ws.WebServiceException;
025: import javax.xml.ws.handler.Handler;
026: import javax.xml.ws.handler.LogicalHandler;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030: import org.apache.geronimo.xbeans.javaee.HandlerChainType;
031: import org.apache.geronimo.xbeans.javaee.HandlerChainsDocument;
032: import org.apache.geronimo.xbeans.javaee.HandlerChainsType;
033: import org.apache.geronimo.xbeans.javaee.PortComponentHandlerType;
034:
035: /**
036: * @version $Rev$ $Date$
037: */
038: public class AnnotationHandlerChainBuilder {
039:
040: private static final Log log = LogFactory
041: .getLog(AnnotationHandlerChainBuilder.class);
042:
043: public AnnotationHandlerChainBuilder() {
044: }
045:
046: /**
047: * @param clz
048: * @param existingHandlers
049: * @return
050: */
051: public List<Handler> buildHandlerChainFromClass(Class<?> clz,
052: List<Handler> existingHandlers) {
053: log.debug("building handler chain");
054: HandlerChainAnnotation hcAnn = findHandlerChainAnnotation(clz,
055: true);
056: List<Handler> chain = null;
057: if (hcAnn == null) {
058: log.debug("no HandlerChain annotation on " + clz);
059: chain = new ArrayList<Handler>();
060: } else {
061: hcAnn.validate();
062:
063: try {
064: URL handlerFileURL = clz.getResource(hcAnn
065: .getFileName());
066: HandlerChainsType handlerChainsType = HandlerChainsDocument.Factory
067: .parse(handlerFileURL).getHandlerChains();
068:
069: if (null == handlerChainsType
070: || handlerChainsType.getHandlerChainArray() == null) {
071: throw new WebServiceException("Chain not specified");
072: }
073:
074: chain = new ArrayList<Handler>();
075: for (HandlerChainType hc : handlerChainsType
076: .getHandlerChainArray()) {
077: chain.addAll(buildHandlerChain(hc, clz
078: .getClassLoader()));
079: }
080:
081: } catch (Exception e) {
082: throw new WebServiceException("Chain not specified", e);
083: }
084: }
085:
086: assert chain != null;
087: if (existingHandlers != null) {
088: chain.addAll(existingHandlers);
089: }
090: return sortHandlers(chain);
091: }
092:
093: public List<Handler> buildHandlerChainFromClass(Class<?> clz) {
094: return buildHandlerChainFromClass(clz, null);
095: }
096:
097: private HandlerChainAnnotation findHandlerChainAnnotation(
098: Class<?> clz, boolean searchSEI) {
099: if (log.isDebugEnabled()) {
100: log.debug("Checking for HandlerChain annotation on "
101: + clz.getName());
102: }
103: HandlerChainAnnotation hcAnn = null;
104: HandlerChain ann = clz.getAnnotation(HandlerChain.class);
105: if (ann == null) {
106: if (searchSEI) {
107: /* HandlerChain annotation can be specified on the SEI
108: * but the implementation bean might not implement the SEI.
109: */
110: WebService ws = clz.getAnnotation(WebService.class);
111: if (ws != null && ws.endpointInterface() != null
112: && ws.endpointInterface().trim().length() > 0) {
113: String seiClassName = ws.endpointInterface().trim();
114: Class seiClass = null;
115: try {
116: seiClass = clz.getClassLoader().loadClass(
117: seiClassName);
118: } catch (ClassNotFoundException e) {
119: throw new WebServiceException(
120: "Failed to load SEI class: "
121: + seiClassName, e);
122: }
123:
124: // check SEI class and its interfaces for HandlerChain annotation
125: hcAnn = findHandlerChainAnnotation(seiClass, false);
126: }
127: }
128: if (hcAnn == null) {
129: // check interfaces for HandlerChain annotation
130: for (Class<?> iface : clz.getInterfaces()) {
131: if (log.isDebugEnabled()) {
132: log
133: .debug("Checking for HandlerChain annotation on "
134: + iface.getName());
135: }
136: ann = iface.getAnnotation(HandlerChain.class);
137: if (ann != null) {
138: hcAnn = new HandlerChainAnnotation(ann, iface);
139: break;
140: }
141: }
142: }
143: } else {
144: hcAnn = new HandlerChainAnnotation(ann, clz);
145: }
146:
147: return hcAnn;
148: }
149:
150: protected List<Handler> buildHandlerChain(HandlerChainType hc,
151: ClassLoader classLoader) {
152: List<Handler> handlerChain = new ArrayList<Handler>();
153: for (PortComponentHandlerType ht : hc.getHandlerArray()) {
154: try {
155: log.debug("loading handler :"
156: + trimString(ht.getHandlerName()
157: .getStringValue()));
158:
159: Class<? extends Handler> handlerClass = Class.forName(
160: trimString(ht.getHandlerClass()
161: .getStringValue()), true, classLoader)
162: .asSubclass(Handler.class);
163:
164: Handler handler = handlerClass.newInstance();
165: log.debug("adding handler to chain: " + handler);
166: handlerChain.add(handler);
167: } catch (Exception e) {
168: throw new WebServiceException(
169: "Failed to instantiate handler", e);
170: }
171: }
172: return handlerChain;
173: }
174:
175: private String trimString(String str) {
176: return str != null ? str.trim() : null;
177: }
178:
179: /**
180: * sorts the handlers into correct order. All of the logical handlers first
181: * followed by the protocol handlers
182: *
183: * @param handlers
184: * @return sorted list of handlers
185: */
186: public List<Handler> sortHandlers(List<Handler> handlers) {
187:
188: List<LogicalHandler> logicalHandlers = new ArrayList<LogicalHandler>();
189: List<Handler> protocolHandlers = new ArrayList<Handler>();
190:
191: for (Handler handler : handlers) {
192: if (handler instanceof LogicalHandler) {
193: logicalHandlers.add((LogicalHandler) handler);
194: } else {
195: protocolHandlers.add(handler);
196: }
197: }
198:
199: List<Handler> sortedHandlers = new ArrayList<Handler>();
200: sortedHandlers.addAll(logicalHandlers);
201: sortedHandlers.addAll(protocolHandlers);
202: return sortedHandlers;
203: }
204:
205: private static class HandlerChainAnnotation {
206: private final Class<?> declaringClass;
207: private final HandlerChain ann;
208:
209: HandlerChainAnnotation(HandlerChain hc, Class<?> clz) {
210: ann = hc;
211: declaringClass = clz;
212: }
213:
214: public Class<?> getDeclaringClass() {
215: return declaringClass;
216: }
217:
218: public String getFileName() {
219: return ann.file();
220: }
221:
222: public void validate() {
223: if (null == ann.file() || "".equals(ann.file())) {
224: throw new WebServiceException(
225: "@HandlerChain annotation does not contain a file name or url.");
226: }
227: }
228:
229: public String toString() {
230: return "[" + declaringClass + "," + ann + "]";
231: }
232: }
233: }
|