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.ivm.naming;
018:
019: import org.apache.openejb.Injection;
020: import org.apache.openejb.core.webservices.HandlerChainData;
021: import org.apache.openejb.core.webservices.HandlerResolverImpl;
022: import org.apache.openejb.core.webservices.PortRefData;
023: import org.apache.openejb.core.webservices.ProviderWrapper;
024: import org.apache.openejb.core.webservices.ServiceRefData;
025: import org.apache.openejb.core.webservices.PortAddressRegistry;
026: import org.apache.openejb.core.webservices.PortAddress;
027: import org.apache.openejb.loader.SystemInstance;
028:
029: import javax.naming.InitialContext;
030: import javax.naming.NamingException;
031: import javax.xml.namespace.QName;
032: import javax.xml.ws.Service;
033: import javax.xml.ws.handler.HandlerResolver;
034: import java.net.MalformedURLException;
035: import java.net.URL;
036: import java.util.ArrayList;
037: import java.util.HashMap;
038: import java.util.List;
039: import java.util.Map;
040: import java.util.Set;
041:
042: public class JaxWsServiceReference extends Reference {
043: private final String id;
044: private final QName serviceQName;
045: private final QName portQName;
046: private final Class<? extends Service> serviceClass;
047: private final Class<?> referenceClass;
048: private final URL wsdlUrl;
049: private final List<HandlerChainData> handlerChains = new ArrayList<HandlerChainData>();
050: private final List<Injection> injections;
051: private PortAddressRegistry portAddressRegistry;
052: private final List<PortRefData> portRefs = new ArrayList<PortRefData>();
053:
054: public JaxWsServiceReference(String id, QName serviceQName,
055: Class<? extends Service> serviceClass, QName portQName,
056: Class<?> referenceClass, URL wsdlUrl,
057: List<PortRefData> portRefs,
058: List<HandlerChainData> handlerChains,
059: List<Injection> injections) {
060: this .id = id;
061: this .serviceQName = serviceQName;
062: this .serviceClass = serviceClass;
063: this .portQName = portQName;
064: this .referenceClass = referenceClass;
065: this .wsdlUrl = wsdlUrl;
066: if (portRefs != null) {
067: this .portRefs.addAll(portRefs);
068: }
069: if (handlerChains != null) {
070: this .handlerChains.addAll(handlerChains);
071: }
072: this .injections = injections;
073: }
074:
075: public Object getObject() throws javax.naming.NamingException {
076: String referenceClassName = referenceClass != null ? referenceClass
077: .getName()
078: : null;
079: Set<PortAddress> portAddresses = getPortAddressRegistry()
080: .getPorts(id, serviceQName, referenceClassName);
081:
082: // if we only have one address, use that address for the wsdl and the serviceQName
083: URL wsdlUrl = this .wsdlUrl;
084: QName serviceQName = this .serviceQName;
085: if (portAddresses.size() == 1) {
086: PortAddress portAddress = portAddresses.iterator().next();
087: try {
088: wsdlUrl = new URL(portAddress.getAddress() + "?wsdl");
089: } catch (MalformedURLException e) {
090: }
091: serviceQName = portAddress.getServiceQName();
092: }
093:
094: // add the port addresses to the portRefData
095: Map<QName, PortRefData> portsByQName = new HashMap<QName, PortRefData>();
096: List<PortRefData> ports = new ArrayList<PortRefData>(portRefs
097: .size()
098: + portAddresses.size());
099: for (PortRefData portRef : portRefs) {
100: PortRefData port = new PortRefData(portRef);
101: if (port.getQName() != null) {
102: portsByQName.put(port.getQName(), port);
103: }
104: ports.add(port);
105: }
106:
107: // add PortRefData for any portAddress not added above
108: for (PortAddress portAddress : portAddresses) {
109: PortRefData port = portsByQName.get(portAddress
110: .getPortQName());
111: if (port == null) {
112: port = new PortRefData();
113: port.setQName(portAddress.getPortQName());
114: port.setServiceEndpointInterface(portAddress
115: .getServiceEndpointInterface());
116: port.getAddresses().add(portAddress.getAddress());
117: ports.add(port);
118: } else {
119: port.getAddresses().add(portAddress.getAddress());
120: if (port.getServiceEndpointInterface() == null) {
121: port.setServiceEndpointInterface(portAddress
122: .getServiceEndpointInterface());
123: }
124: }
125: }
126:
127: ProviderWrapper.beforeCreate(ports);
128: Service instance;
129: try {
130: instance = null;
131: if (Service.class.equals(serviceClass)) {
132: instance = Service.create(wsdlUrl, serviceQName);
133: } else {
134: try {
135: instance = serviceClass.getConstructor(URL.class,
136: QName.class).newInstance(wsdlUrl,
137: serviceQName);
138: } catch (Throwable e) {
139: throw (NamingException) new NamingException(
140: "Could not instantiate jax-ws service class "
141: + serviceClass.getName())
142: .initCause(e);
143: }
144: }
145: } finally {
146: ProviderWrapper.afterCreate();
147: }
148:
149: if (!handlerChains.isEmpty()) {
150: HandlerResolver handlerResolver = new HandlerResolverImpl(
151: handlerChains, injections, new InitialContext());
152: instance.setHandlerResolver(handlerResolver);
153: }
154:
155: Object port;
156: if (referenceClass != null
157: && !Service.class.isAssignableFrom(referenceClass)) {
158: // do port lookup
159: port = instance.getPort(referenceClass);
160: } else {
161: // return service
162: port = instance;
163: }
164:
165: // register the service data so it can be fetched when the service is passed over the EJBd protocol
166: ServiceRefData serviceRefData = new ServiceRefData(id,
167: serviceQName, serviceClass, portQName, referenceClass,
168: wsdlUrl, handlerChains, portRefs);
169: ServiceRefData.putServiceRefData(port, serviceRefData);
170:
171: return port;
172: }
173:
174: private PortAddressRegistry getPortAddressRegistry() {
175: if (portAddressRegistry == null) {
176: portAddressRegistry = SystemInstance.get().getComponent(
177: PortAddressRegistry.class);
178: }
179: return portAddressRegistry;
180: }
181: }
|