You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2014/05/05 22:08:32 UTC
[18/51] [partial] FLEX-34306 - [BlazeDS] Make the BlazeDS build run
on Windows machines - Added some mkdir commands to the ANT Build.java - Did
some fine-tuning to resolve some compile errors
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/cluster/ClusterManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/cluster/ClusterManager.java b/modules/core/src/flex/messaging/cluster/ClusterManager.java
old mode 100755
new mode 100644
index d3a4196..0e88fe1
--- a/modules/core/src/flex/messaging/cluster/ClusterManager.java
+++ b/modules/core/src/flex/messaging/cluster/ClusterManager.java
@@ -1,673 +1,673 @@
-/*
- * 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 flex.messaging.cluster;
-
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Collections;
-import java.util.TreeSet;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import flex.messaging.Destination;
-import flex.messaging.MessageBroker;
-import flex.messaging.config.ClusterSettings;
-import flex.messaging.config.ConfigMap;
-import flex.messaging.endpoints.Endpoint;
-import flex.messaging.util.ClassUtil;
-
-/**
- * @exclude
- * The manager of all clusters defined in services-config.xml, and the broker
- * for the clusters created for clustered destinations.
- */
-public class ClusterManager
-{
- /**
- * Supported operations.
- */
- public static final String OPERATION_ADD_ENDPOINT_FOR_CHANNEL = "addEndpointForChannel";
- public static final String OPERATION_SEND_ENDPOINT_URL = "sendEndpointUrl";
- public static final String OPERATION_RECEIVE_ENDPOINT_URL = "receiveEndpointUrl";
-
- public static final String OPERATION_PUSH_MESSAGE_FROM_PEER = "pushMessageFromPeer";
- public static final String OPERATION_PEER_SYNC_AND_PUSH = "peerSyncAndPush";
- public static final String OPERATION_REQUEST_ADAPTER_STATE = "requestAdapterState";
- public static final String OPERATION_RECEIVE_ADAPTER_STATE = "receiveAdapterState";
- public static final String OPERATION_SEND_SUBSCRIPTIONS = "sendSubscriptions";
- public static final String OPERATION_RECEIVE_SUBSCRIPTIONS = "receiveSubscriptions";
- public static final String OPERATION_SUBSCRIBE_FROM_PEER = "subscribeFromPeer";
- public static final String OPERATION_PUSH_MESSAGE_FROM_PEER_TO_PEER = "pushMessageFromPeerToPeer";
- public static final String OPERATION_PEER_SYNC_AND_PUSH_ONE_TO_PEER = "peerSyncAndPushOneToPeer";
-
- /**
- * A link to the MessageBroker.
- */
- private MessageBroker broker;
-
- /**
- * A mapping between the cluster ids and the Cluster instances.
- * name=clusterId value=clusterInstance
- */
- private LinkedHashMap<String,Cluster> clusters;
-
- /**
- * A mapping between destinations and the Cluster instances.
- */
- private Map<String, Cluster> clustersForDestination;
-
- /**
- * A mapping between cluster ids and their configuration files.
- * name=clusterId value=propsFile
- */
- private Map<String, Element> clusterConfig;
-
- /**
- * A mapping between cluster ids and ClusterSettings instances.
- * name=clusterId value=ClusterSettings
- */
- private Map<String, ClusterSettings> clusterSettings;
-
- /**
- * A mapped between destinations and a boolean representing
- * whether or not the backend for the destination is shared.
- */
- private Map<String, Boolean> backendSharedForDestination;
-
- /**
- * The default cluster when the cluster id for the destination
- * is unspecified.
- */
- private Cluster defaultCluster;
-
- /**
- * The id of the default cluster.
- */
- private String defaultClusterId;
-
- /**
- * The manager of all clusters defined in services-config.xml, and the broker
- * for the clusters created for clustered destinations. This class provides
- * an entry point and abstraction to the logical cluster implementation as
- * well as the specific cluster implementation.
- * @param broker the message broker which uses the cluster manager
- */
- public ClusterManager(MessageBroker broker)
- {
- this.broker = broker;
- clusters = new LinkedHashMap<String,Cluster>();
- clusterConfig = new HashMap<String, Element>();
- clusterSettings = new HashMap<String, ClusterSettings>();
- clustersForDestination = new HashMap<String,Cluster>();
- backendSharedForDestination = new HashMap<String, Boolean>();
- }
-
- /**
- * The MessageBroker for this cluster.
- *
- * @return The defined MessageBroker.
- */
- public MessageBroker getMessageBroker()
- {
- return broker;
- }
-
- /**
- * The default cluster when the cluster id for the destination
- * is unspecified.
- * @return Cluster the default Cluster to use
- */
- public Cluster getDefaultCluster()
- {
- return defaultCluster;
- }
-
- /**
- * The id of the default cluster.
- * @return String the default cluster ID
- */
- public String getDefaultClusterId()
- {
- return defaultClusterId;
- }
-
- /**
- * Invoke an endpoint operation across the cluster.
- * <p>
- * NOTE: Endpoints don't reference a specific cluster so the default cluster is used for the broadcast.
- * If no default cluster is defined the operation is broadcast over all defined clusters.
- * </p>
- *
- * @param endpointId The id of the remote endpoint across the cluster to invoke an operation on.
- * @param operationName The name of the operation to invoke.
- * @param params The arguments to use for operation invocation.
- */
- public void invokeEndpointOperation(String endpointId, String operationName, Object[] params)
- {
- Object[] arguments = new Object[2 + params.length];
- arguments[0] = endpointId;
- arguments[1] = operationName;
- int n = params.length;
- for (int i = 2, j = 0; j < n; ++i, ++j)
- arguments[i] = params[j];
-
- if (defaultCluster != null)
- {
- defaultCluster.broadcastServiceOperation(operationName, arguments);
- }
- else
- {
- for (Cluster cluster : clusters.values())
- cluster.broadcastServiceOperation(operationName, arguments);
- }
- }
-
- /**
- * Invoke an endpoint operation on a specific peer within the cluster.
- * <p>
- * NOTE: Endpoints don't reference a specific cluster so the default cluster is used for the broadcast.
- * If no default cluster is defined the operation is broadcast over all defined clusters.
- * </p>
- *
- * @param endpointId The id of the remote endpoint across the cluster to invoke an operation on.
- * @param operationName The name of the operation to invoke.
- * @param params The arguments to use for operation invocation.
- * @param targetAddress The peer node that the operation should be invoked on.
- */
- public void invokePeerToPeerEndpointOperation(String endpointId, String operationName, Object[] params, Object targetAddress)
- {
- Object[] arguments = new Object[2 + params.length];
- arguments[0] = endpointId;
- arguments[1] = operationName;
- int n = params.length;
- for (int i = 2, j = 0; j < n; ++i, ++j)
- arguments[i] = params[j];
-
- if (defaultCluster != null)
- {
- defaultCluster.sendPointToPointServiceOperation(operationName, arguments, targetAddress);
- }
- else
- {
- for (Cluster cluster : clusters.values())
- {
- cluster.sendPointToPointServiceOperation(operationName, arguments, targetAddress);
- }
- }
- }
-
- /**
- * Invoke a service-related operation, which usually includes a Message as a method parameter. This method
- * allows a local service to process a Message and then send the Message to the services on all peer nodes
- * so that they may perform the same processing. Invoke the service operation for the cluster, identified by
- * serviceType and destinationName.
- *
- * @param serviceType The name for the service for this destination.
- * @param destinationName The name of the destination.
- * @param operationName The name of the service operation to invoke.
- * @param params Parameters needed for the service operation.
- */
- public void invokeServiceOperation(String serviceType, String destinationName,
- String operationName, Object[] params)
- {
- Cluster c = getCluster(serviceType,destinationName);
- ArrayList newParams = new ArrayList(Arrays.asList(params));
- newParams.add(0, serviceType);
- newParams.add(1, destinationName);
- c.broadcastServiceOperation(operationName, newParams.toArray());
- }
-
- /**
- * Send a service-related operation in point-to-point fashion to one and only one member of the cluster.
- * This is similar to the invokeServiceOperation except that this invocation is sent to the node,
- * identified by targetAddress.
- *
- * @param serviceType The name for the service for this destination.
- * @param destinationName The name of the destination.
- * @param operationName The name of the service operation to invoke.
- * @param params Parameters needed for the service operation.
- * @param targetAddress The node that the operation should be passed to.
- */
- public void invokePeerToPeerOperation(String serviceType, String destinationName,
- String operationName, Object[] params, Object targetAddress)
- {
- Cluster c = getCluster(serviceType,destinationName);
- ArrayList newParams = new ArrayList(Arrays.asList(params));
- newParams.add(0, serviceType);
- newParams.add(1, destinationName);
- c.sendPointToPointServiceOperation(operationName, newParams.toArray(), targetAddress);
- }
-
- /**
- * Determines whether the given destination is clustered.
- *
- * @param serviceType The name for the service for this destination.
- * @param destinationName The name of the destination.
- * @return Whether the destination is a clustered destination.
- */
- public boolean isDestinationClustered(String serviceType, String destinationName)
- {
- return getCluster(serviceType, destinationName) != null;
- }
-
- /**
- * Checks whether the give destination is configured for a shared backend.
- *
- * @param serviceType The name of the service for this destination.
- * @param destinationName The name of the destination.
- * @return Whether the destination is configured for shared backend.
- */
- public boolean isBackendShared(String serviceType, String destinationName)
- {
- String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
- Boolean shared = backendSharedForDestination.get(destKey);
- return shared != null? shared.booleanValue() : false;
- }
-
- /**
- * Retrieves a list of cluster nodes for the given cluster.
- *
- * @param serviceType The name of the service for the clustered destination.
- * @param destinationName The name of the destination.
- * @return List of cluster nodes for the given cluster.
- */
- public List getClusterMemberAddresses(String serviceType, String destinationName)
- {
- Cluster c= getCluster(serviceType, destinationName);
- return c != null? c.getMemberAddresses() : Collections.EMPTY_LIST;
- }
-
- /**
- * Used for targeted endpoint operation invocations across the cluster.
- * If a default cluster is defined, its list of member addresses is returned.
- * Otherwise, a de-duped list of all member addresses from all registered clusters is returned.
- *
- * @return The list of cluster nodes that endpoint operation invocations can be issued against.
- */
- public List getClusterMemberAddresses()
- {
- if (defaultCluster != null)
- return defaultCluster.getMemberAddresses();
-
- TreeSet uniqueAddresses = new TreeSet();
- for (Cluster cluster : clusters.values())
- uniqueAddresses.addAll(cluster.getMemberAddresses());
-
- return new ArrayList(uniqueAddresses);
- }
-
- /**
- * Find the properties file in the given cluster settings. Read the XML based
- * cluster configuration file and save the settings and configuration for the
- * given cluster for retrieval later.
- *
- * @param settings The cluster settings for a specific cluster.
- */
- public void prepareCluster(ClusterSettings settings)
- {
- String propsFileName = settings.getPropsFileName();
-
- checkForNullPropertiesFile(settings.getClusterName(), propsFileName);
-
- InputStream propsFile = resolveInternalPath(propsFileName);
-
- if( propsFile == null )
- propsFile = resolveExternalPath(propsFileName);
-
- if (propsFile == null)
- throwClusterException(10208, new Object[] {propsFileName}, null);
-
- try
- {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(false);
- factory.setValidating(false);
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(propsFile);
- if (settings.isDefault())
- defaultClusterId = settings.getClusterName();
- clusterConfig.put(settings.getClusterName(), doc.getDocumentElement());
- clusterSettings.put(settings.getClusterName(), settings);
- }
- catch (Exception ex)
- {
- throwClusterException(10213, new Object[] {propsFileName}, ex);
- }
- }
-
- /**
- * Retrieve the local address for the specified clustered destination.
- *
- * @param serviceType The service type of the clustered destination.
- * @param destinationName The name of the clustered destination.
- * @return The local address of the clustered destination.
- */
- public Object getLocalAddress(String serviceType, String destinationName)
- {
- Cluster c = getCluster(serviceType, destinationName);
- return c != null? c.getLocalAddress() : null;
- }
-
- /**
- * Retrieve the local address for the default cluster or if no default cluster is defined
- * return the local address derived from the first cluster of any defined.
- *
- * @return The local address for this cluster node, or <code>null</code> if this node
- * is not a member of any cluster.
- */
- public Object getLocalAddress()
- {
- if (defaultCluster != null)
- return defaultCluster.getLocalAddress();
-
- // Else, use first defined cluster.
- for (Entry<String,Cluster> entry : clusters.entrySet())
- return entry.getValue().getLocalAddress();
-
- return null; // No cluster defined.
- }
-
- /**
- * Find the cluster for the specified cluster id.
- *
- * @param clusterId the cluster ID
- * @return The cluster identified by the given id.
- */
- public Cluster getClusterById(String clusterId)
- {
- return clusters.get(clusterId);
- }
-
- /**
- * Find the cluster identified by the service type and destination name.
- *
- * @param serviceType The service type of the clustered destination.
- * @param destinationName The name of the clustered destination.
- * @return The cluster identified by the serviec type and destination naem.
- */
- public Cluster getCluster(String serviceType, String destinationName)
- {
- Cluster cluster = null;
- try
- {
- String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
-
- cluster = clustersForDestination.get(destKey);
-
- if (cluster == null)
- cluster = defaultCluster;
- }
- catch (NoClassDefFoundError nex)
- {
- ClusterException cx = new ClusterException();
- cx.setMessage(10202, new Object[] { destinationName });
- cx.setRootCause(nex);
- throw cx;
- }
- return cluster;
- }
-
- /**
- * Call destroy on each of the managed clusters.
- */
- public void destroyClusters()
- {
- for (Iterator<Cluster> iter=clusters.values().iterator(); iter.hasNext(); )
- {
- Cluster cluster = iter.next();
- cluster.destroy();
- iter.remove();
- }
- }
-
- /**
- * Add the specified destination to the cluster, identitied by clusterId if available. If the cluster
- * is not currently defined, create the cluster. Also, setup the load balancing urls and shared
- * backend information for this clustered destination and endpoint.
- *
- * @param clusterId The cluster id that this destination wants to be associated with.
- * @param serviceType The service type for the clustered destination.
- * @param destinationName The name of the clustered destination.
- * @param channelId The channel id that should be added to the cluster load balancing.
- * @param endpointUrl The endpoint url that should be added to the cluster load balancing.
- * @param endpointPort The endpoint port that should be added to the cluster load balancing.
- * @param sharedBackend Whether the destination has shared backend set to true or not.
- */
- public void clusterDestinationChannel(String clusterId, String serviceType, String destinationName,
- String channelId, String endpointUrl, int endpointPort, boolean sharedBackend)
- {
- Cluster cluster = getClusterById(clusterId);
- String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
- if (cluster == null)
- {
- if (!clusterConfig.containsKey(clusterId))
- {
- ClusterException cx = new ClusterException();
- cx.setMessage(10207, new Object[] { destinationName, clusterId });
- throw cx;
- }
- cluster = createCluster(clusterId, serviceType, destinationName);
- }
- else
- {
- clustersForDestination.put(destKey, cluster);
- }
- backendSharedForDestination.put(destKey, sharedBackend ? Boolean.TRUE : Boolean.FALSE);
-
- if (cluster.getURLLoadBalancing())
- cluster.addLocalEndpointForChannel(serviceType, destinationName,
- channelId, endpointUrl, endpointPort);
- }
-
- /**
- * Adds the destination to the cluster. The settings for the clustered destination are
- * available from the <code>Destination</code> object.
- *
- * @param destination The destination to be clustered.
- */
- public void clusterDestination(Destination destination)
- {
- String clusterId = destination.getNetworkSettings().getClusterId();
- if (clusterId == null)
- clusterId = getDefaultClusterId();
-
- ClusterSettings cls = clusterSettings.get(clusterId);
- if (cls == null)
- {
- ClusterException ce = new ClusterException();
- ce.setMessage(10217, new Object[] {destination.getId(), clusterId});
- throw ce;
- }
-
- for (String channelId : destination.getChannels())
- {
- Endpoint endpoint = broker.getEndpoint(channelId);
- String endpointUrl = endpoint.getUrl();
- int endpointPort = endpoint.getPort();
-
- // This is only an error if we are using client side url-based load balancing. If
- // there is a HW load balancer, then we can assume the server.name served up by the
- // SWF can be used to access the cluster members. With client side load balancing,
- // the clients need the direct URLs of all of the servers.
- if (cls.getURLLoadBalancing())
- {
- // Ensure that the endpoint URI does not contain any replacement tokens.
- int tokenStart = endpointUrl.indexOf('{');
- if (tokenStart != -1)
- {
- int tokenEnd = endpointUrl.indexOf('}', tokenStart);
- if (tokenEnd == -1)
- tokenEnd = endpointUrl.length();
- else
- tokenEnd++;
-
- ClusterException ce = new ClusterException();
- ce.setMessage(10209, new Object[] {destination.getId(), channelId, endpointUrl.substring(tokenStart, tokenEnd)});
- throw ce;
- }
- }
-
- clusterDestinationChannel(clusterId, destination.getServiceType(),
- destination.getId(), channelId, endpointUrl, endpointPort, destination.getNetworkSettings().isSharedBackend());
- }
- }
-
- /**
- * Get a list of endpoints for the destination.
- * @param serviceType the service type
- * @param destinationName destination name
- * @return List the list endpoints that the destination can use
- */
- public List getEndpointsForDestination(String serviceType, String destinationName)
- {
- Cluster c = getCluster(serviceType, destinationName);
- return c != null? c.getAllEndpoints(serviceType, destinationName) : null;
- }
-
-
- private void checkForNullPropertiesFile(String clusterName, String propsFileName)
- {
- if (propsFileName == null)
- throwClusterException(10201, new Object[] {clusterName, propsFileName}, null);
- }
-
- /**
- * Create the cluster based on the cluster settings already available. The cluster
- * is added to the cluster managers list of clusters indexed by the cluster id.
- * The cluster is also associated with the specified service type and destination
- * name. The cluster id is unique across all clusters managed by this cluster
- * manager. The cluster may be associated with more than one cluster destination.
- *
- * @param clusterId The cluster id.
- * @param serviceType The service type of the clustered destination.
- * @param destinationName The destination name for the clustered destination.
- * @return The new cluster.
- */
- private Cluster createCluster(String clusterId, String serviceType, String destinationName)
- {
- String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
- Element propsFile = clusterConfig.get(clusterId);
- ClusterSettings cls = clusterSettings.get(clusterId);
- Cluster cluster = null;
- Class clusterClass = ClassUtil.createClass(cls.getImplementationClass());
- Constructor clusterConstructor = null;
- try
- {
- clusterConstructor = clusterClass.getConstructor(new Class[] {ClusterManager.class});
- }
- catch (Exception e)
- {
- ClusterException cx = new ClusterException();
- cx.setMessage(10210);
- cx.setRootCause(e);
- throw cx;
- }
- try
- {
- cluster = (Cluster)clusterConstructor.newInstance(new Object[] {this});
- cluster.setClusterPropertiesFile(propsFile);
- cluster.setURLLoadBalancing(cls.getURLLoadBalancing());
- cluster.initialize(clusterId, cls.getProperties());
- }
- catch (Exception e)
- {
- ClusterException cx = new ClusterException();
- cx.setMessage(10211);
- cx.setRootCause(e);
- throw cx;
- }
- clustersForDestination.put(destKey, cluster);
- clusters.put(clusterId, cluster);
-
- if (defaultClusterId != null && defaultClusterId.equals(clusterId))
- defaultCluster = cluster;
-
- return cluster;
- }
-
- private InputStream resolveExternalPath(String propsFileName)
- {
- try
- {
- return broker.resolveExternalPath(propsFileName);
- }
- catch (Throwable t)
- {
- throwClusterException(10208, new Object[] {propsFileName}, t);
- }
- return null;
- }
-
- private InputStream resolveInternalPath(String propsFileName)
- {
- try
- {
- return broker.resolveInternalPath(propsFileName);
- }
- catch (Throwable t)
- {
- throwClusterException(10208, new Object[] {propsFileName}, t);
- }
- return null;
- }
-
- private void throwClusterException(int number, Object[] args, Throwable t)
- {
- ClusterException cx = new ClusterException();
- cx.setMessage(number, args);
- if (t != null)
- cx.setRootCause(t);
- throw cx;
- }
-
- /**
- * Return a {@link ConfigMap} describing the clusters that have been added to the cluster manager
- *
- * @return a ConfigMap of the clusters
- */
- public ConfigMap describeClusters()
- {
- ConfigMap result = new ConfigMap();
- for (Entry<String, Cluster> entry: clusters.entrySet())
- {
- Cluster cluster = entry.getValue();
- ConfigMap clusterMap = new ConfigMap();
- clusterMap.put("id", entry.getKey());
- ClusterSettings settings = clusterSettings.get(entry.getKey());
- clusterMap.put("properties", settings.getPropsFileName());
- if (settings.isDefault())
- {
- clusterMap.put("default", "true");
- }
- clusterMap.put("class", cluster.getClass().getCanonicalName());
-
- result.addProperty("cluster", clusterMap);
- }
- return result;
- }
+/*
+ * 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 flex.messaging.cluster;
+
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Collections;
+import java.util.TreeSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import flex.messaging.Destination;
+import flex.messaging.MessageBroker;
+import flex.messaging.config.ClusterSettings;
+import flex.messaging.config.ConfigMap;
+import flex.messaging.endpoints.Endpoint;
+import flex.messaging.util.ClassUtil;
+
+/**
+ * @exclude
+ * The manager of all clusters defined in services-config.xml, and the broker
+ * for the clusters created for clustered destinations.
+ */
+public class ClusterManager
+{
+ /**
+ * Supported operations.
+ */
+ public static final String OPERATION_ADD_ENDPOINT_FOR_CHANNEL = "addEndpointForChannel";
+ public static final String OPERATION_SEND_ENDPOINT_URL = "sendEndpointUrl";
+ public static final String OPERATION_RECEIVE_ENDPOINT_URL = "receiveEndpointUrl";
+
+ public static final String OPERATION_PUSH_MESSAGE_FROM_PEER = "pushMessageFromPeer";
+ public static final String OPERATION_PEER_SYNC_AND_PUSH = "peerSyncAndPush";
+ public static final String OPERATION_REQUEST_ADAPTER_STATE = "requestAdapterState";
+ public static final String OPERATION_RECEIVE_ADAPTER_STATE = "receiveAdapterState";
+ public static final String OPERATION_SEND_SUBSCRIPTIONS = "sendSubscriptions";
+ public static final String OPERATION_RECEIVE_SUBSCRIPTIONS = "receiveSubscriptions";
+ public static final String OPERATION_SUBSCRIBE_FROM_PEER = "subscribeFromPeer";
+ public static final String OPERATION_PUSH_MESSAGE_FROM_PEER_TO_PEER = "pushMessageFromPeerToPeer";
+ public static final String OPERATION_PEER_SYNC_AND_PUSH_ONE_TO_PEER = "peerSyncAndPushOneToPeer";
+
+ /**
+ * A link to the MessageBroker.
+ */
+ private MessageBroker broker;
+
+ /**
+ * A mapping between the cluster ids and the Cluster instances.
+ * name=clusterId value=clusterInstance
+ */
+ private LinkedHashMap<String,Cluster> clusters;
+
+ /**
+ * A mapping between destinations and the Cluster instances.
+ */
+ private Map<String, Cluster> clustersForDestination;
+
+ /**
+ * A mapping between cluster ids and their configuration files.
+ * name=clusterId value=propsFile
+ */
+ private Map<String, Element> clusterConfig;
+
+ /**
+ * A mapping between cluster ids and ClusterSettings instances.
+ * name=clusterId value=ClusterSettings
+ */
+ private Map<String, ClusterSettings> clusterSettings;
+
+ /**
+ * A mapped between destinations and a boolean representing
+ * whether or not the backend for the destination is shared.
+ */
+ private Map<String, Boolean> backendSharedForDestination;
+
+ /**
+ * The default cluster when the cluster id for the destination
+ * is unspecified.
+ */
+ private Cluster defaultCluster;
+
+ /**
+ * The id of the default cluster.
+ */
+ private String defaultClusterId;
+
+ /**
+ * The manager of all clusters defined in services-config.xml, and the broker
+ * for the clusters created for clustered destinations. This class provides
+ * an entry point and abstraction to the logical cluster implementation as
+ * well as the specific cluster implementation.
+ * @param broker the message broker which uses the cluster manager
+ */
+ public ClusterManager(MessageBroker broker)
+ {
+ this.broker = broker;
+ clusters = new LinkedHashMap<String,Cluster>();
+ clusterConfig = new HashMap<String, Element>();
+ clusterSettings = new HashMap<String, ClusterSettings>();
+ clustersForDestination = new HashMap<String,Cluster>();
+ backendSharedForDestination = new HashMap<String, Boolean>();
+ }
+
+ /**
+ * The MessageBroker for this cluster.
+ *
+ * @return The defined MessageBroker.
+ */
+ public MessageBroker getMessageBroker()
+ {
+ return broker;
+ }
+
+ /**
+ * The default cluster when the cluster id for the destination
+ * is unspecified.
+ * @return Cluster the default Cluster to use
+ */
+ public Cluster getDefaultCluster()
+ {
+ return defaultCluster;
+ }
+
+ /**
+ * The id of the default cluster.
+ * @return String the default cluster ID
+ */
+ public String getDefaultClusterId()
+ {
+ return defaultClusterId;
+ }
+
+ /**
+ * Invoke an endpoint operation across the cluster.
+ * <p>
+ * NOTE: Endpoints don't reference a specific cluster so the default cluster is used for the broadcast.
+ * If no default cluster is defined the operation is broadcast over all defined clusters.
+ * </p>
+ *
+ * @param endpointId The id of the remote endpoint across the cluster to invoke an operation on.
+ * @param operationName The name of the operation to invoke.
+ * @param params The arguments to use for operation invocation.
+ */
+ public void invokeEndpointOperation(String endpointId, String operationName, Object[] params)
+ {
+ Object[] arguments = new Object[2 + params.length];
+ arguments[0] = endpointId;
+ arguments[1] = operationName;
+ int n = params.length;
+ for (int i = 2, j = 0; j < n; ++i, ++j)
+ arguments[i] = params[j];
+
+ if (defaultCluster != null)
+ {
+ defaultCluster.broadcastServiceOperation(operationName, arguments);
+ }
+ else
+ {
+ for (Cluster cluster : clusters.values())
+ cluster.broadcastServiceOperation(operationName, arguments);
+ }
+ }
+
+ /**
+ * Invoke an endpoint operation on a specific peer within the cluster.
+ * <p>
+ * NOTE: Endpoints don't reference a specific cluster so the default cluster is used for the broadcast.
+ * If no default cluster is defined the operation is broadcast over all defined clusters.
+ * </p>
+ *
+ * @param endpointId The id of the remote endpoint across the cluster to invoke an operation on.
+ * @param operationName The name of the operation to invoke.
+ * @param params The arguments to use for operation invocation.
+ * @param targetAddress The peer node that the operation should be invoked on.
+ */
+ public void invokePeerToPeerEndpointOperation(String endpointId, String operationName, Object[] params, Object targetAddress)
+ {
+ Object[] arguments = new Object[2 + params.length];
+ arguments[0] = endpointId;
+ arguments[1] = operationName;
+ int n = params.length;
+ for (int i = 2, j = 0; j < n; ++i, ++j)
+ arguments[i] = params[j];
+
+ if (defaultCluster != null)
+ {
+ defaultCluster.sendPointToPointServiceOperation(operationName, arguments, targetAddress);
+ }
+ else
+ {
+ for (Cluster cluster : clusters.values())
+ {
+ cluster.sendPointToPointServiceOperation(operationName, arguments, targetAddress);
+ }
+ }
+ }
+
+ /**
+ * Invoke a service-related operation, which usually includes a Message as a method parameter. This method
+ * allows a local service to process a Message and then send the Message to the services on all peer nodes
+ * so that they may perform the same processing. Invoke the service operation for the cluster, identified by
+ * serviceType and destinationName.
+ *
+ * @param serviceType The name for the service for this destination.
+ * @param destinationName The name of the destination.
+ * @param operationName The name of the service operation to invoke.
+ * @param params Parameters needed for the service operation.
+ */
+ public void invokeServiceOperation(String serviceType, String destinationName,
+ String operationName, Object[] params)
+ {
+ Cluster c = getCluster(serviceType,destinationName);
+ ArrayList newParams = new ArrayList(Arrays.asList(params));
+ newParams.add(0, serviceType);
+ newParams.add(1, destinationName);
+ c.broadcastServiceOperation(operationName, newParams.toArray());
+ }
+
+ /**
+ * Send a service-related operation in point-to-point fashion to one and only one member of the cluster.
+ * This is similar to the invokeServiceOperation except that this invocation is sent to the node,
+ * identified by targetAddress.
+ *
+ * @param serviceType The name for the service for this destination.
+ * @param destinationName The name of the destination.
+ * @param operationName The name of the service operation to invoke.
+ * @param params Parameters needed for the service operation.
+ * @param targetAddress The node that the operation should be passed to.
+ */
+ public void invokePeerToPeerOperation(String serviceType, String destinationName,
+ String operationName, Object[] params, Object targetAddress)
+ {
+ Cluster c = getCluster(serviceType,destinationName);
+ ArrayList newParams = new ArrayList(Arrays.asList(params));
+ newParams.add(0, serviceType);
+ newParams.add(1, destinationName);
+ c.sendPointToPointServiceOperation(operationName, newParams.toArray(), targetAddress);
+ }
+
+ /**
+ * Determines whether the given destination is clustered.
+ *
+ * @param serviceType The name for the service for this destination.
+ * @param destinationName The name of the destination.
+ * @return Whether the destination is a clustered destination.
+ */
+ public boolean isDestinationClustered(String serviceType, String destinationName)
+ {
+ return getCluster(serviceType, destinationName) != null;
+ }
+
+ /**
+ * Checks whether the give destination is configured for a shared backend.
+ *
+ * @param serviceType The name of the service for this destination.
+ * @param destinationName The name of the destination.
+ * @return Whether the destination is configured for shared backend.
+ */
+ public boolean isBackendShared(String serviceType, String destinationName)
+ {
+ String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
+ Boolean shared = backendSharedForDestination.get(destKey);
+ return shared != null? shared.booleanValue() : false;
+ }
+
+ /**
+ * Retrieves a list of cluster nodes for the given cluster.
+ *
+ * @param serviceType The name of the service for the clustered destination.
+ * @param destinationName The name of the destination.
+ * @return List of cluster nodes for the given cluster.
+ */
+ public List getClusterMemberAddresses(String serviceType, String destinationName)
+ {
+ Cluster c= getCluster(serviceType, destinationName);
+ return c != null? c.getMemberAddresses() : Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Used for targeted endpoint operation invocations across the cluster.
+ * If a default cluster is defined, its list of member addresses is returned.
+ * Otherwise, a de-duped list of all member addresses from all registered clusters is returned.
+ *
+ * @return The list of cluster nodes that endpoint operation invocations can be issued against.
+ */
+ public List getClusterMemberAddresses()
+ {
+ if (defaultCluster != null)
+ return defaultCluster.getMemberAddresses();
+
+ TreeSet uniqueAddresses = new TreeSet();
+ for (Cluster cluster : clusters.values())
+ uniqueAddresses.addAll(cluster.getMemberAddresses());
+
+ return new ArrayList(uniqueAddresses);
+ }
+
+ /**
+ * Find the properties file in the given cluster settings. Read the XML based
+ * cluster configuration file and save the settings and configuration for the
+ * given cluster for retrieval later.
+ *
+ * @param settings The cluster settings for a specific cluster.
+ */
+ public void prepareCluster(ClusterSettings settings)
+ {
+ String propsFileName = settings.getPropsFileName();
+
+ checkForNullPropertiesFile(settings.getClusterName(), propsFileName);
+
+ InputStream propsFile = resolveInternalPath(propsFileName);
+
+ if( propsFile == null )
+ propsFile = resolveExternalPath(propsFileName);
+
+ if (propsFile == null)
+ throwClusterException(10208, new Object[] {propsFileName}, null);
+
+ try
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(false);
+ factory.setValidating(false);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(propsFile);
+ if (settings.isDefault())
+ defaultClusterId = settings.getClusterName();
+ clusterConfig.put(settings.getClusterName(), doc.getDocumentElement());
+ clusterSettings.put(settings.getClusterName(), settings);
+ }
+ catch (Exception ex)
+ {
+ throwClusterException(10213, new Object[] {propsFileName}, ex);
+ }
+ }
+
+ /**
+ * Retrieve the local address for the specified clustered destination.
+ *
+ * @param serviceType The service type of the clustered destination.
+ * @param destinationName The name of the clustered destination.
+ * @return The local address of the clustered destination.
+ */
+ public Object getLocalAddress(String serviceType, String destinationName)
+ {
+ Cluster c = getCluster(serviceType, destinationName);
+ return c != null? c.getLocalAddress() : null;
+ }
+
+ /**
+ * Retrieve the local address for the default cluster or if no default cluster is defined
+ * return the local address derived from the first cluster of any defined.
+ *
+ * @return The local address for this cluster node, or <code>null</code> if this node
+ * is not a member of any cluster.
+ */
+ public Object getLocalAddress()
+ {
+ if (defaultCluster != null)
+ return defaultCluster.getLocalAddress();
+
+ // Else, use first defined cluster.
+ for (Entry<String,Cluster> entry : clusters.entrySet())
+ return entry.getValue().getLocalAddress();
+
+ return null; // No cluster defined.
+ }
+
+ /**
+ * Find the cluster for the specified cluster id.
+ *
+ * @param clusterId the cluster ID
+ * @return The cluster identified by the given id.
+ */
+ public Cluster getClusterById(String clusterId)
+ {
+ return clusters.get(clusterId);
+ }
+
+ /**
+ * Find the cluster identified by the service type and destination name.
+ *
+ * @param serviceType The service type of the clustered destination.
+ * @param destinationName The name of the clustered destination.
+ * @return The cluster identified by the serviec type and destination naem.
+ */
+ public Cluster getCluster(String serviceType, String destinationName)
+ {
+ Cluster cluster = null;
+ try
+ {
+ String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
+
+ cluster = clustersForDestination.get(destKey);
+
+ if (cluster == null)
+ cluster = defaultCluster;
+ }
+ catch (NoClassDefFoundError nex)
+ {
+ ClusterException cx = new ClusterException();
+ cx.setMessage(10202, new Object[] { destinationName });
+ cx.setRootCause(nex);
+ throw cx;
+ }
+ return cluster;
+ }
+
+ /**
+ * Call destroy on each of the managed clusters.
+ */
+ public void destroyClusters()
+ {
+ for (Iterator<Cluster> iter=clusters.values().iterator(); iter.hasNext(); )
+ {
+ Cluster cluster = iter.next();
+ cluster.destroy();
+ iter.remove();
+ }
+ }
+
+ /**
+ * Add the specified destination to the cluster, identitied by clusterId if available. If the cluster
+ * is not currently defined, create the cluster. Also, setup the load balancing urls and shared
+ * backend information for this clustered destination and endpoint.
+ *
+ * @param clusterId The cluster id that this destination wants to be associated with.
+ * @param serviceType The service type for the clustered destination.
+ * @param destinationName The name of the clustered destination.
+ * @param channelId The channel id that should be added to the cluster load balancing.
+ * @param endpointUrl The endpoint url that should be added to the cluster load balancing.
+ * @param endpointPort The endpoint port that should be added to the cluster load balancing.
+ * @param sharedBackend Whether the destination has shared backend set to true or not.
+ */
+ public void clusterDestinationChannel(String clusterId, String serviceType, String destinationName,
+ String channelId, String endpointUrl, int endpointPort, boolean sharedBackend)
+ {
+ Cluster cluster = getClusterById(clusterId);
+ String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
+ if (cluster == null)
+ {
+ if (!clusterConfig.containsKey(clusterId))
+ {
+ ClusterException cx = new ClusterException();
+ cx.setMessage(10207, new Object[] { destinationName, clusterId });
+ throw cx;
+ }
+ cluster = createCluster(clusterId, serviceType, destinationName);
+ }
+ else
+ {
+ clustersForDestination.put(destKey, cluster);
+ }
+ backendSharedForDestination.put(destKey, sharedBackend ? Boolean.TRUE : Boolean.FALSE);
+
+ if (cluster.getURLLoadBalancing())
+ cluster.addLocalEndpointForChannel(serviceType, destinationName,
+ channelId, endpointUrl, endpointPort);
+ }
+
+ /**
+ * Adds the destination to the cluster. The settings for the clustered destination are
+ * available from the <code>Destination</code> object.
+ *
+ * @param destination The destination to be clustered.
+ */
+ public void clusterDestination(Destination destination)
+ {
+ String clusterId = destination.getNetworkSettings().getClusterId();
+ if (clusterId == null)
+ clusterId = getDefaultClusterId();
+
+ ClusterSettings cls = clusterSettings.get(clusterId);
+ if (cls == null)
+ {
+ ClusterException ce = new ClusterException();
+ ce.setMessage(10217, new Object[] {destination.getId(), clusterId});
+ throw ce;
+ }
+
+ for (String channelId : destination.getChannels())
+ {
+ Endpoint endpoint = broker.getEndpoint(channelId);
+ String endpointUrl = endpoint.getUrl();
+ int endpointPort = endpoint.getPort();
+
+ // This is only an error if we are using client side url-based load balancing. If
+ // there is a HW load balancer, then we can assume the server.name served up by the
+ // SWF can be used to access the cluster members. With client side load balancing,
+ // the clients need the direct URLs of all of the servers.
+ if (cls.getURLLoadBalancing())
+ {
+ // Ensure that the endpoint URI does not contain any replacement tokens.
+ int tokenStart = endpointUrl.indexOf('{');
+ if (tokenStart != -1)
+ {
+ int tokenEnd = endpointUrl.indexOf('}', tokenStart);
+ if (tokenEnd == -1)
+ tokenEnd = endpointUrl.length();
+ else
+ tokenEnd++;
+
+ ClusterException ce = new ClusterException();
+ ce.setMessage(10209, new Object[] {destination.getId(), channelId, endpointUrl.substring(tokenStart, tokenEnd)});
+ throw ce;
+ }
+ }
+
+ clusterDestinationChannel(clusterId, destination.getServiceType(),
+ destination.getId(), channelId, endpointUrl, endpointPort, destination.getNetworkSettings().isSharedBackend());
+ }
+ }
+
+ /**
+ * Get a list of endpoints for the destination.
+ * @param serviceType the service type
+ * @param destinationName destination name
+ * @return List the list endpoints that the destination can use
+ */
+ public List getEndpointsForDestination(String serviceType, String destinationName)
+ {
+ Cluster c = getCluster(serviceType, destinationName);
+ return c != null? c.getAllEndpoints(serviceType, destinationName) : null;
+ }
+
+
+ private void checkForNullPropertiesFile(String clusterName, String propsFileName)
+ {
+ if (propsFileName == null)
+ throwClusterException(10201, new Object[] {clusterName, propsFileName}, null);
+ }
+
+ /**
+ * Create the cluster based on the cluster settings already available. The cluster
+ * is added to the cluster managers list of clusters indexed by the cluster id.
+ * The cluster is also associated with the specified service type and destination
+ * name. The cluster id is unique across all clusters managed by this cluster
+ * manager. The cluster may be associated with more than one cluster destination.
+ *
+ * @param clusterId The cluster id.
+ * @param serviceType The service type of the clustered destination.
+ * @param destinationName The destination name for the clustered destination.
+ * @return The new cluster.
+ */
+ private Cluster createCluster(String clusterId, String serviceType, String destinationName)
+ {
+ String destKey = Cluster.getClusterDestinationKey(serviceType, destinationName);
+ Element propsFile = clusterConfig.get(clusterId);
+ ClusterSettings cls = clusterSettings.get(clusterId);
+ Cluster cluster = null;
+ Class clusterClass = ClassUtil.createClass(cls.getImplementationClass());
+ Constructor clusterConstructor = null;
+ try
+ {
+ clusterConstructor = clusterClass.getConstructor(new Class[] {ClusterManager.class});
+ }
+ catch (Exception e)
+ {
+ ClusterException cx = new ClusterException();
+ cx.setMessage(10210);
+ cx.setRootCause(e);
+ throw cx;
+ }
+ try
+ {
+ cluster = (Cluster)clusterConstructor.newInstance(new Object[] {this});
+ cluster.setClusterPropertiesFile(propsFile);
+ cluster.setURLLoadBalancing(cls.getURLLoadBalancing());
+ cluster.initialize(clusterId, cls.getProperties());
+ }
+ catch (Exception e)
+ {
+ ClusterException cx = new ClusterException();
+ cx.setMessage(10211);
+ cx.setRootCause(e);
+ throw cx;
+ }
+ clustersForDestination.put(destKey, cluster);
+ clusters.put(clusterId, cluster);
+
+ if (defaultClusterId != null && defaultClusterId.equals(clusterId))
+ defaultCluster = cluster;
+
+ return cluster;
+ }
+
+ private InputStream resolveExternalPath(String propsFileName)
+ {
+ try
+ {
+ return broker.resolveExternalPath(propsFileName);
+ }
+ catch (Throwable t)
+ {
+ throwClusterException(10208, new Object[] {propsFileName}, t);
+ }
+ return null;
+ }
+
+ private InputStream resolveInternalPath(String propsFileName)
+ {
+ try
+ {
+ return broker.resolveInternalPath(propsFileName);
+ }
+ catch (Throwable t)
+ {
+ throwClusterException(10208, new Object[] {propsFileName}, t);
+ }
+ return null;
+ }
+
+ private void throwClusterException(int number, Object[] args, Throwable t)
+ {
+ ClusterException cx = new ClusterException();
+ cx.setMessage(number, args);
+ if (t != null)
+ cx.setRootCause(t);
+ throw cx;
+ }
+
+ /**
+ * Return a {@link ConfigMap} describing the clusters that have been added to the cluster manager
+ *
+ * @return a ConfigMap of the clusters
+ */
+ public ConfigMap describeClusters()
+ {
+ ConfigMap result = new ConfigMap();
+ for (Entry<String, Cluster> entry: clusters.entrySet())
+ {
+ Cluster cluster = entry.getValue();
+ ConfigMap clusterMap = new ConfigMap();
+ clusterMap.put("id", entry.getKey());
+ ClusterSettings settings = clusterSettings.get(entry.getKey());
+ clusterMap.put("properties", settings.getPropsFileName());
+ if (settings.isDefault())
+ {
+ clusterMap.put("default", "true");
+ }
+ clusterMap.put("class", cluster.getClass().getCanonicalName());
+
+ result.addProperty("cluster", clusterMap);
+ }
+ return result;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/cluster/ClusterMembershipListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/cluster/ClusterMembershipListener.java b/modules/core/src/flex/messaging/cluster/ClusterMembershipListener.java
old mode 100755
new mode 100644
index aa38e11..fd5b70d
--- a/modules/core/src/flex/messaging/cluster/ClusterMembershipListener.java
+++ b/modules/core/src/flex/messaging/cluster/ClusterMembershipListener.java
@@ -1,138 +1,138 @@
-/*
- * 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 flex.messaging.cluster;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Vector;
-
-import org.jgroups.Address;
-import org.jgroups.MembershipListener;
-import org.jgroups.View;
-
-/**
- * @exclude
- * Clusters employ this Listener in order to respond to nodes which
- * join and abandon it. This class bridges the low-level protocol layer
- * to the more abstract logical cluster.
- */
-class ClusterMembershipListener implements MembershipListener
-{
- /**
- * The cluster implementation that owns this listener.
- */
- // TODO: The missing class JGroupsCluster seems to extend Cluster, but is missing from the repository.
-// private JGroupsCluster cluster;
-
- /**
- * The list of current cluster members as we know it.
- */
- private List<Address> members;
-
- /**
- * The list of cluster members that are not currently active.
- */
- private List<Address> zombies;
-
- /**
- * Our implementation of cluster membership listener.
- *
- * @param cluster The logical cluster implementation.
- */
- public ClusterMembershipListener(Cluster cluster)
- {
-// this.cluster = (JGroupsCluster)cluster;
- this.members = new ArrayList<Address>();
- this.zombies = new ArrayList<Address>();
- }
-
- /**
- * This method is invoked by the cluster infrastructure whenever
- * a member joins or abandons the cluster group.
- *
- * @param membershipView Snapshot of members of the cluster.
- */
- public void viewAccepted(View membershipView)
- {
- synchronized(this)
- {
- Vector<Address> currentMemberList = membershipView.getMembers();
- handleArrivingMembers(currentMemberList);
- handleDepartedMembers(membershipView, currentMemberList);
- }
- }
-
- /**
- * This method is invoked by the cluster infrastructure whenever
- * a member appears to have left the cluster, but before it has
- * been removed from the active member list. The Cluster treats
- * these addresses as zombies and will not use their channel and
- * endpoint information.
- *
- * @param zombieAddress The address of the suspect node.
- */
- public void suspect(Address zombieAddress)
- {
- synchronized(this)
- {
- zombies.add(zombieAddress);
- }
- }
-
- /**
- * This method from the core MembershipListener is a no-op for
- * the Flex destination Cluster.
- */
- public void block()
- {
- // No-op.
- }
-
- /**
- * Allow the Cluster to determine whether a given physical address
- * is a zombie.
- *
- * @param address The node to check.
- * @return True, if the given address is a zombie.
- */
- public boolean isZombie(Address address)
- {
- return zombies.contains(address);
- }
-
- private void handleDepartedMembers(View membershipView, Vector<Address> currentMemberList)
- {
- for (Address member : members)
- {
- if (!membershipView.containsMember(member))
- {
-// cluster.removeClusterNode(member);
- zombies.remove(member);
- }
- }
- members = currentMemberList;
- }
-
- private void handleArrivingMembers(Vector<Address> currentMemberList)
- {
- for (Address member : currentMemberList)
- {
-/* if (!cluster.getLocalAddress().equals(member) && !members.contains(member))
- cluster.addClusterNode(member);*/
- }
- }
+/*
+ * 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 flex.messaging.cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.jgroups.Address;
+import org.jgroups.MembershipListener;
+import org.jgroups.View;
+
+/**
+ * @exclude
+ * Clusters employ this Listener in order to respond to nodes which
+ * join and abandon it. This class bridges the low-level protocol layer
+ * to the more abstract logical cluster.
+ */
+class ClusterMembershipListener implements MembershipListener
+{
+ /**
+ * The cluster implementation that owns this listener.
+ */
+ // TODO: The missing class JGroupsCluster seems to extend Cluster, but is missing from the repository.
+// private JGroupsCluster cluster;
+
+ /**
+ * The list of current cluster members as we know it.
+ */
+ private List<Address> members;
+
+ /**
+ * The list of cluster members that are not currently active.
+ */
+ private List<Address> zombies;
+
+ /**
+ * Our implementation of cluster membership listener.
+ *
+ * @param cluster The logical cluster implementation.
+ */
+ public ClusterMembershipListener(Cluster cluster)
+ {
+// this.cluster = (JGroupsCluster)cluster;
+ this.members = new ArrayList<Address>();
+ this.zombies = new ArrayList<Address>();
+ }
+
+ /**
+ * This method is invoked by the cluster infrastructure whenever
+ * a member joins or abandons the cluster group.
+ *
+ * @param membershipView Snapshot of members of the cluster.
+ */
+ public void viewAccepted(View membershipView)
+ {
+ synchronized(this)
+ {
+ Vector<Address> currentMemberList = membershipView.getMembers();
+ handleArrivingMembers(currentMemberList);
+ handleDepartedMembers(membershipView, currentMemberList);
+ }
+ }
+
+ /**
+ * This method is invoked by the cluster infrastructure whenever
+ * a member appears to have left the cluster, but before it has
+ * been removed from the active member list. The Cluster treats
+ * these addresses as zombies and will not use their channel and
+ * endpoint information.
+ *
+ * @param zombieAddress The address of the suspect node.
+ */
+ public void suspect(Address zombieAddress)
+ {
+ synchronized(this)
+ {
+ zombies.add(zombieAddress);
+ }
+ }
+
+ /**
+ * This method from the core MembershipListener is a no-op for
+ * the Flex destination Cluster.
+ */
+ public void block()
+ {
+ // No-op.
+ }
+
+ /**
+ * Allow the Cluster to determine whether a given physical address
+ * is a zombie.
+ *
+ * @param address The node to check.
+ * @return True, if the given address is a zombie.
+ */
+ public boolean isZombie(Address address)
+ {
+ return zombies.contains(address);
+ }
+
+ private void handleDepartedMembers(View membershipView, Vector<Address> currentMemberList)
+ {
+ for (Address member : members)
+ {
+ if (!membershipView.containsMember(member))
+ {
+// cluster.removeClusterNode(member);
+ zombies.remove(member);
+ }
+ }
+ members = currentMemberList;
+ }
+
+ private void handleArrivingMembers(Vector<Address> currentMemberList)
+ {
+ for (Address member : currentMemberList)
+ {
+/* if (!cluster.getLocalAddress().equals(member) && !members.contains(member))
+ cluster.addClusterNode(member);*/
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/cluster/ClusterNode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/cluster/ClusterNode.java b/modules/core/src/flex/messaging/cluster/ClusterNode.java
old mode 100755
new mode 100644
index 945867a..6fdd67e
--- a/modules/core/src/flex/messaging/cluster/ClusterNode.java
+++ b/modules/core/src/flex/messaging/cluster/ClusterNode.java
@@ -1,172 +1,172 @@
-/*
- * 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 flex.messaging.cluster;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * @exclude
- * ClusterNode is an encapsulation for pairing a physical host and a logical
- * software group, which is in effect a mapping between a physical address used
- * by the cluster infrastructure and a service destination used by the message
- * infrastructure.
- *
- * This class is specific to the <code>JGroupsCluster</code> implementation.
- */
-public class ClusterNode
-{
- /**
- * The name of the host for this cluster node.
- */
- private final String host;
-
- /**
- * Mapping between clustered destinations and the
- * clustered endpoint.
- * key = destination key (String)
- * value = Map of channel-id to endpoint-url mappings.
- */
- private final Map<String,Map<String,String>> destKeyToChannelMap;
-
- /**
- * Constructor.
- */
- ClusterNode(String host)
- {
- this.host = host;
- destKeyToChannelMap = new HashMap<String,Map<String,String>>();
- }
-
- /**
- * Returns the name of the host for this cluster node.
- *
- * @return The name of the host.
- */
- String getHost()
- {
- return host;
- }
-
- /**
- * Returns a map of clustered destination to clustered
- * endpoint mappings.
- *
- * @return Map of clustered destination to clustered
- * endpoint mappings.
- */
- Map<String,Map<String,String>> getDestKeyToChannelMap()
- {
- return destKeyToChannelMap;
- }
-
- /**
- * Returns a map of clustered endpoints for the specified
- * clustered destination. If there is not currently a
- * map for the destination, an empty mapping is created
- * and returned.
- *
- * The endpoint map is indexed by channel id.
- * The endpoint map contains endpoint urls.
- *
- * @param serviceType The service type of the clustered destination.
- * @param destName The destination name of the clustered destination.
- * @return Map of clustered endpoints.
- */
- Map<String,String> getEndpoints(String serviceType, String destName)
- {
- String destKey = serviceType + ":" + destName;
- synchronized (destKeyToChannelMap)
- {
- Map<String,String> channelEndpoints = destKeyToChannelMap.get(destKey);
- if (channelEndpoints == null)
- {
- channelEndpoints = new HashMap<String,String>();
- destKeyToChannelMap.put(destKey, channelEndpoints);
- }
- return channelEndpoints;
- }
- }
-
- /**
- * This method adds an endpoint to the list of endpoints for the clustered
- * destination, identified by service type and destination name.
- *
- * @param serviceType The service type of the clustered destination.
- * @param destName The destination name of the clustered destination.
- * @param channelId The channel id to be added to the channel endpoint mapping.
- * @param endpointUrl The endpoint url to be added to the endpoint url mapping.
- */
- void addEndpoint(String serviceType, String destName, String channelId, String endpointUrl)
- {
- synchronized (destKeyToChannelMap)
- {
- Map<String,String> channelEndpoints = getEndpoints(serviceType, destName);
- channelEndpoints.put(channelId, endpointUrl);
- }
- }
-
- /**
- * Returns whether the endpoint, specified by channel id and endpoint url,
- * is included in the list of endpoints in the clustered destination.
- *
- * @param serviceType The service type of the clustered destination.
- * @param destName The destination name of the clustered destination.
- * @param channelId The channel id to find in the list of endpoints.
- * @param endpointUrl The endpoint url to find in the list of endpoints.
- * @return Whether the endpoint is included in the list for the clustered destination.
- */
- boolean containsEndpoint(String serviceType, String destName, String channelId, String endpointUrl)
- {
- Map<String,String> channelEndpoints = getEndpoints(serviceType, destName);
- return channelEndpoints.containsKey(channelId) && channelEndpoints.get(channelId).equals(endpointUrl);
- }
-
- /**
- * Returns a description of the clustered node including details
- * on the mapping between the clustered destinations on this node
- * and their endpoint mappings.
- *
- * @return Description of the clustered node.
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer("ClusterNode[");
- synchronized (destKeyToChannelMap)
- {
- for (Map.Entry<String,Map<String,String>> entry : destKeyToChannelMap.entrySet())
- {
- sb.append(" channels for ");
- sb.append(entry.getKey());
- sb.append('(');
- for (Iterator<Map.Entry<String,String>> iter = entry.getValue().entrySet().iterator(); iter.hasNext();)
- {
- Map.Entry<String,String> channelMapEntry = iter.next();
- sb.append(channelMapEntry.getKey());
- sb.append('=');
- sb.append(channelMapEntry.getValue());
- if (iter.hasNext())
- sb.append(", ");
- }
- sb.append(')');
- }
- }
- sb.append(" ]");
- return sb.toString();
- }
-}
+/*
+ * 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 flex.messaging.cluster;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @exclude
+ * ClusterNode is an encapsulation for pairing a physical host and a logical
+ * software group, which is in effect a mapping between a physical address used
+ * by the cluster infrastructure and a service destination used by the message
+ * infrastructure.
+ *
+ * This class is specific to the <code>JGroupsCluster</code> implementation.
+ */
+public class ClusterNode
+{
+ /**
+ * The name of the host for this cluster node.
+ */
+ private final String host;
+
+ /**
+ * Mapping between clustered destinations and the
+ * clustered endpoint.
+ * key = destination key (String)
+ * value = Map of channel-id to endpoint-url mappings.
+ */
+ private final Map<String,Map<String,String>> destKeyToChannelMap;
+
+ /**
+ * Constructor.
+ */
+ ClusterNode(String host)
+ {
+ this.host = host;
+ destKeyToChannelMap = new HashMap<String,Map<String,String>>();
+ }
+
+ /**
+ * Returns the name of the host for this cluster node.
+ *
+ * @return The name of the host.
+ */
+ String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Returns a map of clustered destination to clustered
+ * endpoint mappings.
+ *
+ * @return Map of clustered destination to clustered
+ * endpoint mappings.
+ */
+ Map<String,Map<String,String>> getDestKeyToChannelMap()
+ {
+ return destKeyToChannelMap;
+ }
+
+ /**
+ * Returns a map of clustered endpoints for the specified
+ * clustered destination. If there is not currently a
+ * map for the destination, an empty mapping is created
+ * and returned.
+ *
+ * The endpoint map is indexed by channel id.
+ * The endpoint map contains endpoint urls.
+ *
+ * @param serviceType The service type of the clustered destination.
+ * @param destName The destination name of the clustered destination.
+ * @return Map of clustered endpoints.
+ */
+ Map<String,String> getEndpoints(String serviceType, String destName)
+ {
+ String destKey = serviceType + ":" + destName;
+ synchronized (destKeyToChannelMap)
+ {
+ Map<String,String> channelEndpoints = destKeyToChannelMap.get(destKey);
+ if (channelEndpoints == null)
+ {
+ channelEndpoints = new HashMap<String,String>();
+ destKeyToChannelMap.put(destKey, channelEndpoints);
+ }
+ return channelEndpoints;
+ }
+ }
+
+ /**
+ * This method adds an endpoint to the list of endpoints for the clustered
+ * destination, identified by service type and destination name.
+ *
+ * @param serviceType The service type of the clustered destination.
+ * @param destName The destination name of the clustered destination.
+ * @param channelId The channel id to be added to the channel endpoint mapping.
+ * @param endpointUrl The endpoint url to be added to the endpoint url mapping.
+ */
+ void addEndpoint(String serviceType, String destName, String channelId, String endpointUrl)
+ {
+ synchronized (destKeyToChannelMap)
+ {
+ Map<String,String> channelEndpoints = getEndpoints(serviceType, destName);
+ channelEndpoints.put(channelId, endpointUrl);
+ }
+ }
+
+ /**
+ * Returns whether the endpoint, specified by channel id and endpoint url,
+ * is included in the list of endpoints in the clustered destination.
+ *
+ * @param serviceType The service type of the clustered destination.
+ * @param destName The destination name of the clustered destination.
+ * @param channelId The channel id to find in the list of endpoints.
+ * @param endpointUrl The endpoint url to find in the list of endpoints.
+ * @return Whether the endpoint is included in the list for the clustered destination.
+ */
+ boolean containsEndpoint(String serviceType, String destName, String channelId, String endpointUrl)
+ {
+ Map<String,String> channelEndpoints = getEndpoints(serviceType, destName);
+ return channelEndpoints.containsKey(channelId) && channelEndpoints.get(channelId).equals(endpointUrl);
+ }
+
+ /**
+ * Returns a description of the clustered node including details
+ * on the mapping between the clustered destinations on this node
+ * and their endpoint mappings.
+ *
+ * @return Description of the clustered node.
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("ClusterNode[");
+ synchronized (destKeyToChannelMap)
+ {
+ for (Map.Entry<String,Map<String,String>> entry : destKeyToChannelMap.entrySet())
+ {
+ sb.append(" channels for ");
+ sb.append(entry.getKey());
+ sb.append('(');
+ for (Iterator<Map.Entry<String,String>> iter = entry.getValue().entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry<String,String> channelMapEntry = iter.next();
+ sb.append(channelMapEntry.getKey());
+ sb.append('=');
+ sb.append(channelMapEntry.getValue());
+ if (iter.hasNext())
+ sb.append(", ");
+ }
+ sb.append(')');
+ }
+ }
+ sb.append(" ]");
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/cluster/RemoveNodeListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/cluster/RemoveNodeListener.java b/modules/core/src/flex/messaging/cluster/RemoveNodeListener.java
old mode 100755
new mode 100644
index 5d23721..fd8778d
--- a/modules/core/src/flex/messaging/cluster/RemoveNodeListener.java
+++ b/modules/core/src/flex/messaging/cluster/RemoveNodeListener.java
@@ -1,35 +1,35 @@
-/*
- * 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 flex.messaging.cluster;
-
-
-/**
- * @exclude
- * Called when a node leaves the cluster. Note that for JGroups at least, this
- * callback should not execute any "long running" operations. This is indirectly
- * called from the MembershipListener interface in JGroups.
- */
-public interface RemoveNodeListener
-{
- /**
- * Callback that the clustering subsystem uses to notify that a
- * node has been removed from the cluster.
- *
- * @address The node that was removed from the cluster.
- */
- void removeClusterNode(Object address);
-}
+/*
+ * 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 flex.messaging.cluster;
+
+
+/**
+ * @exclude
+ * Called when a node leaves the cluster. Note that for JGroups at least, this
+ * callback should not execute any "long running" operations. This is indirectly
+ * called from the MembershipListener interface in JGroups.
+ */
+public interface RemoveNodeListener
+{
+ /**
+ * Callback that the clustering subsystem uses to notify that a
+ * node has been removed from the cluster.
+ *
+ * @address The node that was removed from the cluster.
+ */
+ void removeClusterNode(Object address);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/cluster/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/cluster/package-info.java b/modules/core/src/flex/messaging/cluster/package-info.java
old mode 100755
new mode 100644
index 5ff0444..0bbec3a
--- a/modules/core/src/flex/messaging/cluster/package-info.java
+++ b/modules/core/src/flex/messaging/cluster/package-info.java
@@ -1,19 +1,19 @@
-/*
- * 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.
- */
-
-
+/*
+ * 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 flex.messaging.cluster;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/config/ApacheXPathServerConfigurationParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/config/ApacheXPathServerConfigurationParser.java b/modules/core/src/flex/messaging/config/ApacheXPathServerConfigurationParser.java
old mode 100755
new mode 100644
index 2eeac88..1eae53e
--- a/modules/core/src/flex/messaging/config/ApacheXPathServerConfigurationParser.java
+++ b/modules/core/src/flex/messaging/config/ApacheXPathServerConfigurationParser.java
@@ -1,89 +1,89 @@
-/*
- * 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 flex.messaging.config;
-
-import org.apache.xpath.CachedXPathAPI;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import javax.xml.transform.TransformerException;
-
-/**
- * Uses Apache XPath on a DOM representation of a messaging configuration
- * file.
- * <p>
- * Note: Since reference ids are used between elements, certain
- * sections of the document need to be parsed first.
- * </p>
- *
- * @author Peter Farland
- * @exclude
- */
-public class ApacheXPathServerConfigurationParser extends ServerConfigurationParser
-{
- private CachedXPathAPI xpath;
-
- protected void initializeExpressionQuery()
- {
- this.xpath = new CachedXPathAPI();
- }
-
- protected Node selectSingleNode(Node source, String expression)
- {
- try
- {
- return xpath.selectSingleNode(source, expression);
- }
- catch (TransformerException transformerException)
- {
- throw wrapException(transformerException);
- }
- }
-
- protected NodeList selectNodeList(Node source, String expression)
- {
- try
- {
- return xpath.selectNodeList(source, expression);
- }
- catch (TransformerException transformerException)
- {
- throw wrapException(transformerException);
- }
- }
-
- protected Object evaluateExpression(Node source, String expression)
- {
- try
- {
- return xpath.eval(source, expression);
- }
- catch (TransformerException transformerException)
- {
- throw wrapException(transformerException);
- }
- }
-
- private ConfigurationException wrapException(TransformerException exception)
- {
- ConfigurationException result = new ConfigurationException();
- result.setDetails(PARSER_INTERNAL_ERROR);
- result.setRootCause(exception);
- return result;
- }
-
-
-}
+/*
+ * 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 flex.messaging.config;
+
+import org.apache.xpath.CachedXPathAPI;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import javax.xml.transform.TransformerException;
+
+/**
+ * Uses Apache XPath on a DOM representation of a messaging configuration
+ * file.
+ * <p>
+ * Note: Since reference ids are used between elements, certain
+ * sections of the document need to be parsed first.
+ * </p>
+ *
+ * @author Peter Farland
+ * @exclude
+ */
+public class ApacheXPathServerConfigurationParser extends ServerConfigurationParser
+{
+ private CachedXPathAPI xpath;
+
+ protected void initializeExpressionQuery()
+ {
+ this.xpath = new CachedXPathAPI();
+ }
+
+ protected Node selectSingleNode(Node source, String expression)
+ {
+ try
+ {
+ return xpath.selectSingleNode(source, expression);
+ }
+ catch (TransformerException transformerException)
+ {
+ throw wrapException(transformerException);
+ }
+ }
+
+ protected NodeList selectNodeList(Node source, String expression)
+ {
+ try
+ {
+ return xpath.selectNodeList(source, expression);
+ }
+ catch (TransformerException transformerException)
+ {
+ throw wrapException(transformerException);
+ }
+ }
+
+ protected Object evaluateExpression(Node source, String expression)
+ {
+ try
+ {
+ return xpath.eval(source, expression);
+ }
+ catch (TransformerException transformerException)
+ {
+ throw wrapException(transformerException);
+ }
+ }
+
+ private ConfigurationException wrapException(TransformerException exception)
+ {
+ ConfigurationException result = new ConfigurationException();
+ result.setDetails(PARSER_INTERNAL_ERROR);
+ result.setRootCause(exception);
+ return result;
+ }
+
+
+}