001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * 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, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.core.webservices;
018:
019: import org.apache.openejb.Injection;
020: import org.apache.openejb.InjectionProcessor;
021:
022: import javax.naming.Context;
023: import javax.xml.namespace.QName;
024: import javax.xml.ws.WebServiceException;
025: import javax.xml.ws.handler.Handler;
026: import javax.xml.ws.handler.HandlerResolver;
027: import javax.xml.ws.handler.LogicalHandler;
028: import javax.xml.ws.handler.PortInfo;
029: import java.util.ArrayList;
030: import java.util.Collections;
031: import java.util.Iterator;
032: import java.util.List;
033:
034: public class HandlerResolverImpl implements HandlerResolver {
035: private final List<HandlerChainData> handlerChains;
036: private final List<Injection> injections;
037: private final Context context;
038: private final List<InjectionProcessor<Handler>> handlerInstances = new ArrayList<InjectionProcessor<Handler>>();
039:
040: public HandlerResolverImpl(List<HandlerChainData> handlerChains,
041: List<Injection> injections, Context context) {
042: this .handlerChains = handlerChains;
043: this .injections = injections;
044: this .context = context;
045: }
046:
047: public void destroyHandlers() {
048: List<InjectionProcessor<Handler>> handlerInstances = new ArrayList<InjectionProcessor<Handler>>(
049: this .handlerInstances);
050: this .handlerInstances.clear();
051: for (InjectionProcessor<Handler> handlerInstance : handlerInstances) {
052: handlerInstance.preDestroy();
053: }
054: }
055:
056: public List<Handler> getHandlerChain(
057: javax.xml.ws.handler.PortInfo portInfo) {
058: List<Handler> chain = new ArrayList<Handler>();
059: for (HandlerChainData handlerChain : handlerChains) {
060: List<Handler> handlers = buildHandlers(portInfo,
061: handlerChain);
062: handlers = sortHandlers(handlers);
063: chain.addAll(handlers);
064: }
065: chain = sortHandlers(chain);
066: return chain;
067: }
068:
069: private List<Handler> buildHandlers(
070: javax.xml.ws.handler.PortInfo portInfo,
071: HandlerChainData handlerChain) {
072: if (!matchServiceName(portInfo, handlerChain
073: .getServiceNamePattern())
074: || !matchPortName(portInfo, handlerChain
075: .getPortNamePattern())
076: || !matchBinding(portInfo, handlerChain
077: .getProtocolBindings())) {
078: return Collections.emptyList();
079: }
080:
081: List<Handler> handlers = new ArrayList<Handler>(handlerChain
082: .getHandlers().size());
083: for (HandlerData handler : handlerChain.getHandlers()) {
084: try {
085: Class<? extends Handler> handlerClass = handler
086: .getHandlerClass().asSubclass(Handler.class);
087: InjectionProcessor<Handler> processor = new InjectionProcessor<Handler>(
088: handlerClass, injections, handler
089: .getPostConstruct(), handler
090: .getPreDestroy(), context);
091: processor.createInstance();
092: processor.postConstruct();
093: Handler handlerInstance = processor.getInstance();
094:
095: handlers.add(handlerInstance);
096: handlerInstances.add(processor);
097: } catch (Exception e) {
098: throw new WebServiceException(
099: "Failed to instantiate handler", e);
100: }
101: }
102: return handlers;
103: }
104:
105: private boolean matchServiceName(PortInfo info, String namePattern) {
106: return match((info == null ? null : info.getServiceName()),
107: namePattern);
108: }
109:
110: private boolean matchPortName(PortInfo info, String namePattern) {
111: return match((info == null ? null : info.getPortName()),
112: namePattern);
113: }
114:
115: private boolean matchBinding(PortInfo info, List bindings) {
116: return match((info == null ? null : info.getBindingID()),
117: bindings);
118: }
119:
120: private boolean match(String binding, List bindings) {
121: if (binding == null) {
122: return (bindings == null || bindings.isEmpty());
123: } else {
124: if (bindings == null || bindings.isEmpty()) {
125: return true;
126: } else {
127: String actualBindingURI = JaxWsUtils
128: .getBindingURI(binding);
129: Iterator iter = bindings.iterator();
130: while (iter.hasNext()) {
131: String bindingToken = (String) iter.next();
132: String bindingURI = JaxWsUtils
133: .getBindingURI(bindingToken);
134: if (actualBindingURI.equals(bindingURI)) {
135: return true;
136: }
137: }
138: return false;
139: }
140: }
141: }
142:
143: /**
144: * Performs basic localName matching, namespaces are not checked!
145: */
146: private boolean match(QName name, String namePattern) {
147: if (name == null) {
148: return (namePattern == null || namePattern.equals("*"));
149: } else {
150: if (namePattern == null) {
151: return true;
152: } else {
153: String localNamePattern;
154:
155: // get the local name from pattern
156: int pos = namePattern.indexOf(':');
157: localNamePattern = (pos == -1) ? namePattern
158: : namePattern.substring(pos + 1);
159: localNamePattern = localNamePattern.trim();
160:
161: if (localNamePattern.equals("*")) {
162: // matches anything
163: return true;
164: } else if (localNamePattern.endsWith("*")) {
165: // match start
166: localNamePattern = localNamePattern.substring(0,
167: localNamePattern.length() - 1);
168: return name.getLocalPart().startsWith(
169: localNamePattern);
170: } else {
171: // match exact
172: return name.getLocalPart().equals(localNamePattern);
173: }
174: }
175: }
176: }
177:
178: /**
179: * sorts the handlers into correct order. All of the logical handlers first
180: * followed by the protocol handlers
181: *
182: * @param handlers
183: * @return sorted list of handlers
184: */
185: private List<Handler> sortHandlers(List<Handler> handlers) {
186: List<LogicalHandler> logicalHandlers = new ArrayList<LogicalHandler>();
187: List<Handler> protocolHandlers = new ArrayList<Handler>();
188:
189: for (Handler handler : handlers) {
190: if (handler instanceof LogicalHandler) {
191: logicalHandlers.add((LogicalHandler) handler);
192: } else {
193: protocolHandlers.add(handler);
194: }
195: }
196:
197: List<Handler> sortedHandlers = new ArrayList<Handler>();
198: sortedHandlers.addAll(logicalHandlers);
199: sortedHandlers.addAll(protocolHandlers);
200: return sortedHandlers;
201: }
202: }
|