blob: dfb88f1a738d59a6595e8b759f4a6347ebaea795 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.core.webservices;
import org.apache.openejb.Injection;
import org.apache.openejb.InjectionProcessor;
import static org.apache.openejb.InjectionProcessor.unwrap;
import javax.naming.Context;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.PortInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class HandlerResolverImpl implements HandlerResolver {
private final List<HandlerChainData> handlerChains;
private final Collection<Injection> injections;
private final Context context;
private final List<InjectionProcessor<Handler>> handlerInstances = new ArrayList<InjectionProcessor<Handler>>();
public HandlerResolverImpl(List<HandlerChainData> handlerChains, Collection<Injection> injections, Context context) {
this.handlerChains = handlerChains;
this.injections = injections;
this.context = context;
}
public void destroyHandlers() {
List<InjectionProcessor<Handler>> handlerInstances = new ArrayList<InjectionProcessor<Handler>>(this.handlerInstances);
this.handlerInstances.clear();
for (InjectionProcessor<Handler> handlerInstance : handlerInstances) {
handlerInstance.preDestroy();
}
}
public List<Handler> getHandlerChain(javax.xml.ws.handler.PortInfo portInfo) {
List<Handler> chain = new ArrayList<Handler>();
for (HandlerChainData handlerChain : handlerChains) {
List<Handler> handlers = buildHandlers(portInfo, handlerChain);
handlers = sortHandlers(handlers);
chain.addAll(handlers);
}
chain = sortHandlers(chain);
return chain;
}
private List<Handler> buildHandlers(javax.xml.ws.handler.PortInfo portInfo, HandlerChainData handlerChain) {
if (!matchServiceName(portInfo, handlerChain.getServiceNamePattern()) ||
!matchPortName(portInfo, handlerChain.getPortNamePattern()) ||
!matchBinding(portInfo, handlerChain.getProtocolBindings())) {
return Collections.emptyList();
}
List<Handler> handlers = new ArrayList<Handler>(handlerChain.getHandlers().size());
for (HandlerData handler : handlerChain.getHandlers()) {
try {
Class<? extends Handler> handlerClass = handler.getHandlerClass().asSubclass(Handler.class);
InjectionProcessor<Handler> processor = new InjectionProcessor<Handler>(handlerClass,
injections,
handler.getPostConstruct(),
handler.getPreDestroy(),
unwrap(context));
processor.createInstance();
processor.postConstruct();
Handler handlerInstance = processor.getInstance();
handlers.add(handlerInstance);
handlerInstances.add(processor);
} catch (Exception e) {
throw new WebServiceException("Failed to instantiate handler", e);
}
}
return handlers;
}
private boolean matchServiceName(PortInfo info, QName namePattern) {
return match((info == null ? null : info.getServiceName()), namePattern);
}
private boolean matchPortName(PortInfo info, QName namePattern) {
return match((info == null ? null : info.getPortName()), namePattern);
}
private boolean matchBinding(PortInfo info, List bindings) {
return match((info == null ? null : info.getBindingID()), bindings);
}
private boolean match(String binding, List bindings) {
if (binding == null) {
return (bindings == null || bindings.isEmpty());
} else {
if (bindings == null || bindings.isEmpty()) {
return true;
} else {
String actualBindingURI = JaxWsUtils.getBindingURI(binding);
Iterator iter = bindings.iterator();
while (iter.hasNext()) {
String bindingToken = (String) iter.next();
String bindingURI = JaxWsUtils.getBindingURI(bindingToken);
if (actualBindingURI.equals(bindingURI)) {
return true;
}
}
return false;
}
}
}
/**
* Performs basic localName matching
*/
private boolean match(QName name, QName namePattern) {
if (name == null) {
return (namePattern == null || namePattern.getLocalPart().equals("*"));
} else {
if (namePattern == null) {
return true;
} else if (namePattern.getNamespaceURI() != null && !name.getNamespaceURI().equals(namePattern.getNamespaceURI())) {
return false;
} else {
String localNamePattern = namePattern.getLocalPart();
if (localNamePattern.equals("*")) {
// matches anything
return true;
} else if (localNamePattern.endsWith("*")) {
// match start
localNamePattern = localNamePattern.substring(0, localNamePattern.length() - 1);
return name.getLocalPart().startsWith(localNamePattern);
} else {
// match exact
return name.getLocalPart().equals(localNamePattern);
}
}
}
}
/**
* sorts the handlers into correct order. All of the logical handlers first
* followed by the protocol handlers
*
* @param handlers
* @return sorted list of handlers
*/
private List<Handler> sortHandlers(List<Handler> handlers) {
List<LogicalHandler> logicalHandlers = new ArrayList<LogicalHandler>();
List<Handler> protocolHandlers = new ArrayList<Handler>();
for (Handler handler : handlers) {
if (handler instanceof LogicalHandler) {
logicalHandlers.add((LogicalHandler) handler);
} else {
protocolHandlers.add(handler);
}
}
List<Handler> sortedHandlers = new ArrayList<Handler>();
sortedHandlers.addAll(logicalHandlers);
sortedHandlers.addAll(protocolHandlers);
return sortedHandlers;
}
}