blob: eaa4723a02b1d08132e5ce36e23fc6f7ec136b77 [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.axis2.transport.base;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.TransportInDescription;
/**
* Partial implementation of {@link AbstractTransportListener} with a higher level
* of abstraction. It maintains the mapping between services and protocol specific
* endpoints.
* <p>
* Note: the intention is to eventually merge the code in this class into
* {@link AbstractTransportListener}
*
* @param <E> the type of protocol endpoint for this transport
*/
public abstract class AbstractTransportListenerEx<E extends ProtocolEndpoint>
extends AbstractTransportListener {
/**
* The collection of protocol specific endpoints configured at the service level.
*/
private List<E> serviceEndpoints = new ArrayList<E>();
/**
* The endpoint configured at the transport level. <code>null</code> if no
* such endpoint is configured.
*/
private E globalEndpoint;
@Override
public final void init(ConfigurationContext cfgCtx,
TransportInDescription transportIn) throws AxisFault {
super.init(cfgCtx, transportIn);
doInit();
// Create endpoint configured at transport level (if available)
E endpoint = createEndpoint();
endpoint.init(this, null);
if (endpoint.loadConfiguration(transportIn)) {
globalEndpoint = endpoint;
}
}
/**
* Initialize the transport. This method will be called after the initialization work in
* {@link AbstractTransportListener} and before the first endpoint is created, i.e. before the
* first call to {@link #createEndpoint()}.
*
* @throws AxisFault
*/
protected abstract void doInit() throws AxisFault;
@Override
public void start() throws AxisFault {
super.start();
// Explicitly start the endpoint configured at the transport level. All other endpoints will
// be started by startListeningForService.
if (globalEndpoint != null) {
startEndpoint(globalEndpoint);
}
}
@Override
public void stop() throws AxisFault {
super.stop();
// Explicitly stop the endpoint configured at the transport level. All other endpoints will
// be stopped by stopListeningForService.
if (globalEndpoint != null) {
stopEndpoint(globalEndpoint);
}
}
@Override
public EndpointReference[] getEPRsForService(String serviceName, String ip) throws AxisFault {
// strip out the endpoint name if present
if (serviceName.indexOf('.') != -1) {
serviceName = serviceName.substring(0, serviceName.indexOf('.'));
}
for (E endpoint : serviceEndpoints) {
AxisService service = endpoint.getService();
if (service.getName().equals(serviceName)) {
return endpoint.getEndpointReferences(service, ip);
}
}
// If we get here, this means that the service is not explicitly configured
// with a specific protocol endpoint. However, it is still exposed over the
// transport. In this case, we build the EPR using the endpoint configured
// at the transport level, if there is one.
if (globalEndpoint != null) {
AxisService service = cfgCtx.getAxisConfiguration().getService(serviceName);
if (service == null) {
// Oops, something strange is happening here
return null;
} else {
return globalEndpoint.getEndpointReferences(service, ip);
}
} else {
return null;
}
}
/**
* Get the collection of all protocol endpoints managed by this transport, including the
* endpoint configured at the transport level.
*
* @return the collection of all protocol endpoints
*/
public final Collection<E> getEndpoints() {
if (globalEndpoint == null) {
return Collections.unmodifiableCollection(serviceEndpoints);
} else {
List<E> endpoints = new ArrayList<E>(serviceEndpoints.size() + 1);
endpoints.add(globalEndpoint);
endpoints.addAll(serviceEndpoints);
return endpoints;
}
}
protected abstract E createEndpoint();
@Override
protected final void startListeningForService(AxisService service) throws AxisFault {
E endpoint = createEndpoint();
endpoint.init(this, service);
if (endpoint.loadConfiguration(service)) {
startEndpoint(endpoint);
serviceEndpoints.add(endpoint);
} else if (globalEndpoint != null) {
return;
} else {
throw new AxisFault("Service doesn't have configuration information for transport " +
getTransportName());
}
}
protected abstract void startEndpoint(E endpoint) throws AxisFault;
@Override
protected final void stopListeningForService(AxisService service) {
for (E endpoint : serviceEndpoints) {
if (service == endpoint.getService()) {
stopEndpoint(endpoint);
serviceEndpoints.remove(endpoint);
return;
}
}
if (globalEndpoint == null) {
log.error("Unable to stop service : " + service.getName() +
" - unable to find the corresponding protocol endpoint");
}
}
protected abstract void stopEndpoint(E endpoint);
}