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:38 UTC
[24/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/MessageClientListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageClientListener.java b/modules/core/src/flex/messaging/MessageClientListener.java
old mode 100755
new mode 100644
index e77b31d..7cfdb90
--- a/modules/core/src/flex/messaging/MessageClientListener.java
+++ b/modules/core/src/flex/messaging/MessageClientListener.java
@@ -1,40 +1,40 @@
-/*
- * 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;
-
-/**
- * Interface to be notified when a MessageClient is created or destroyed. Implementations of this interface
- * may add themselves as listeners statically via <code>MessageClient.addMessageClientCreatedListener()</code>.
- * To listen for MessageClient destruction, the implementation class instance must add itself as a listener to
- * a specific MessageClient instance via the <code>addMessageClientDestroyedListener()</code> method.
- */
-public interface MessageClientListener
-{
- /**
- * Notification that a MessageClient was created.
- *
- * @param messageClient The MessageClient that was created.
- */
- void messageClientCreated(MessageClient messageClient);
-
- /**
- * Notification that a MessageClient is about to be destroyed.
- *
- * @param messageClient The MessageClient that will be destroyed.
- */
- void messageClientDestroyed(MessageClient messageClient);
-}
+/*
+ * 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;
+
+/**
+ * Interface to be notified when a MessageClient is created or destroyed. Implementations of this interface
+ * may add themselves as listeners statically via <code>MessageClient.addMessageClientCreatedListener()</code>.
+ * To listen for MessageClient destruction, the implementation class instance must add itself as a listener to
+ * a specific MessageClient instance via the <code>addMessageClientDestroyedListener()</code> method.
+ */
+public interface MessageClientListener
+{
+ /**
+ * Notification that a MessageClient was created.
+ *
+ * @param messageClient The MessageClient that was created.
+ */
+ void messageClientCreated(MessageClient messageClient);
+
+ /**
+ * Notification that a MessageClient is about to be destroyed.
+ *
+ * @param messageClient The MessageClient that will be destroyed.
+ */
+ void messageClientDestroyed(MessageClient messageClient);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/MessageDestination.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageDestination.java b/modules/core/src/flex/messaging/MessageDestination.java
old mode 100755
new mode 100644
index 5552b7a..bd80b41
--- a/modules/core/src/flex/messaging/MessageDestination.java
+++ b/modules/core/src/flex/messaging/MessageDestination.java
@@ -1,491 +1,491 @@
-/*
- * 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;
-
-import flex.management.runtime.messaging.MessageDestinationControl;
-import flex.management.runtime.messaging.services.messaging.SubscriptionManagerControl;
-import flex.management.runtime.messaging.services.messaging.ThrottleManagerControl;
-import flex.messaging.config.ConfigurationConstants;
-import flex.messaging.config.ConfigurationException;
-import flex.messaging.config.DestinationSettings;
-import flex.messaging.config.ThrottleSettings;
-import flex.messaging.config.ConfigMap;
-import flex.messaging.config.NetworkSettings;
-import flex.messaging.config.ServerSettings;
-import flex.messaging.config.ThrottleSettings.Policy;
-import flex.messaging.log.LogCategories;
-import flex.messaging.services.MessageService;
-import flex.messaging.services.Service;
-import flex.messaging.services.messaging.SubscriptionManager;
-import flex.messaging.services.messaging.RemoteSubscriptionManager;
-import flex.messaging.services.messaging.ThrottleManager;
-import flex.messaging.services.messaging.MessagingConstants;
-import flex.messaging.util.ClassUtil;
-
-/**
- * A logical reference to a MessageDestination.
- */
-public class MessageDestination extends FactoryDestination
-{
- static final long serialVersionUID = -2016911808141319012L;
-
- /** Log category for <code>MessageDestination</code>.*/
- public static final String LOG_CATEGORY = LogCategories.SERVICE_MESSAGE;
-
- // Errors
- private static final int UNSUPPORTED_POLICY = 10124;
-
- // Destination properties
- private transient ServerSettings serverSettings;
-
- // Destination internal
- private transient SubscriptionManager subscriptionManager;
- private transient RemoteSubscriptionManager remoteSubscriptionManager;
- private transient ThrottleManager throttleManager;
-
- private transient MessageDestinationControl controller;
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructs an unmanaged <code>MessageDestination</code> instance.
- */
- public MessageDestination()
- {
- this(false);
- }
-
- /**
- * Constructs a <code>MessageDestination</code> with the indicated management.
- *
- * @param enableManagement <code>true</code> if the <code>MessageDestination</code>
- * is manageable; otherwise <code>false</code>.
- */
- public MessageDestination(boolean enableManagement)
- {
- super(enableManagement);
-
- serverSettings = new ServerSettings();
-
- // Managers
- subscriptionManager = new SubscriptionManager(this);
- remoteSubscriptionManager = new RemoteSubscriptionManager(this);
- }
-
- //--------------------------------------------------------------------------
- //
- // Initialize, validate, start, and stop methods.
- //
- //--------------------------------------------------------------------------
-
- /**
- * Initializes the <code>MessageDestination</code> with the properties.
- * If subclasses override, they must call <code>super.initialize()</code>.
- *
- * @param id The id of the destination.
- * @param properties Properties for the <code>MessageDestination</code>.
- */
- @Override
- public void initialize(String id, ConfigMap properties)
- {
- super.initialize(id, properties);
-
- if (properties == null || properties.size() == 0)
- return;
-
- // Network properties
- network(properties);
-
- // Server properties
- server(properties);
- }
-
- /**
- * Sets up the throttle manager before it starts.
- */
- @Override
- public void start()
- {
- // Create the throttle manager, only if needed.
- if (networkSettings.getThrottleSettings() != null)
- {
- ThrottleSettings settings = networkSettings.getThrottleSettings();
- if (settings.isClientThrottleEnabled() || settings.isDestinationThrottleEnabled())
- {
- settings.setDestinationName(getId());
- throttleManager = createThrottleManager();
- throttleManager.setThrottleSettings(settings);
- throttleManager.start();
- }
- }
- super.start();
- }
-
- /**
- * Stops the subscription, remote subscription, and throttle managers and
- * then calls super class's stop.
- */
- @Override
- public void stop()
- {
- if (isStarted())
- {
- subscriptionManager.stop();
- remoteSubscriptionManager.stop();
- if (throttleManager != null)
- throttleManager.stop();
- }
- super.stop();
- }
-
- //--------------------------------------------------------------------------
- //
- // Public Getters and Setters for Destination properties
- //
- //--------------------------------------------------------------------------
-
- /**
- * Sets the <code>NetworkSettings</code> of the <code>MessageDestination</code>.
- *
- * @param networkSettings The <code>NetworkSettings</code> of the <code>MessageDestination</code>
- */
- @Override
- public void setNetworkSettings(NetworkSettings networkSettings)
- {
- super.setNetworkSettings(networkSettings);
-
- // Set the subscription manager settings if needed.
- if (networkSettings.getSubscriptionTimeoutMinutes() > 0)
- {
- long subscriptionTimeoutMillis = networkSettings.getSubscriptionTimeoutMinutes() * 60L * 1000L; // Convert to millis.
- subscriptionManager.setSubscriptionTimeoutMillis(subscriptionTimeoutMillis);
- }
- }
-
- /**
- * Returns the <code>ServerSettings</code> of the <code>MessageDestination</code>.
- *
- * @return The <code>ServerSettings</code> of the <code>MessageDestination</code>.
- */
- public ServerSettings getServerSettings()
- {
- return serverSettings;
- }
-
- /**
- * Sets the <code>ServerSettings</code> of the <code>MessageDestination</code>.
- *
- * @param serverSettings The <code>ServerSettings</code> of the <code>MessageDestination</code>
- */
- public void setServerSettings(ServerSettings serverSettings)
- {
- this.serverSettings = serverSettings;
- }
-
- /**
- * Casts the <code>Service</code> into <code>MessageService</code>
- * and calls super.setService.
- *
- * @param service The <code>Service</code> managing this <code>Destination</code>.
- */
- @Override
- public void setService(Service service)
- {
- MessageService messageService = (MessageService)service;
- super.setService(messageService);
- }
-
- //--------------------------------------------------------------------------
- //
- // Other Public Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @exclude
- * Returns a <tt>ConfigMap</tt> of destination properties that the client
- * needs. This includes properties from <code>super{@link #describeDestination(boolean)}</code>
- * and it also includes outbound throttling policy that the edge server might need.
- *
- * @param onlyReliable Determines whether only reliable destination configuration should be returned.
- * @return A <tt>ConfigMap</tt> of destination properties that the client needs.
- */
- @Override
- public ConfigMap describeDestination(boolean onlyReliable)
- {
- ConfigMap destinationConfig = super.describeDestination(onlyReliable);
- if (destinationConfig == null)
- return null;
-
- if (throttleManager == null)
- return destinationConfig;
-
- Policy outboundPolicy = throttleManager.getOutboundPolicy();
- if (outboundPolicy == null || outboundPolicy == Policy.NONE)
- return destinationConfig;
-
- // Add the outbound throttle policy to network properties section as appropriate.
- ConfigMap properties = destinationConfig.getPropertyAsMap(ConfigurationConstants.PROPERTIES_ELEMENT, null);
- if (properties == null)
- {
- properties = new ConfigMap();
- destinationConfig.addProperty(ConfigurationConstants.PROPERTIES_ELEMENT, properties);
- }
-
- ConfigMap network = properties.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null);
- if (network == null)
- {
- network = new ConfigMap();
- properties.addProperty(NetworkSettings.NETWORK_ELEMENT, network);
- }
-
- ConfigMap throttleOutbound = new ConfigMap();
- throttleOutbound.addProperty(ThrottleSettings.ELEMENT_POLICY, throttleManager.getOutboundPolicy().toString());
- network.addProperty(ThrottleSettings.ELEMENT_OUTBOUND, throttleOutbound);
-
- return destinationConfig;
- }
-
- /** @exclude */
- public SubscriptionManager getSubscriptionManager()
- {
- return subscriptionManager;
- }
-
- /** @exclude */
- public RemoteSubscriptionManager getRemoteSubscriptionManager()
- {
- return remoteSubscriptionManager;
- }
-
- /** @exclude */
- public ThrottleManager getThrottleManager()
- {
- return throttleManager;
- }
-
- /** @exclude **/
- @Override
- public boolean equals(Object o)
- {
- if (o instanceof Destination)
- {
- Destination d = (Destination)o;
- String serviceType1 = d.getServiceType();
- String serviceType2 = getServiceType();
- if ((serviceType1 == null && serviceType2 == null) || (serviceType1 != null && serviceType1.equals(serviceType2)))
- {
- String id1 = d.getId();
- String id2 = getId();
- if ((id1 == null && id2 == null) || (id1 != null && id1.equals(id2)))
- return true;
- }
- }
- return false;
- }
-
- /** @exclude **/
- @Override
- public int hashCode()
- {
- return (getServiceType() == null ? 0 : getServiceType().hashCode()) * 100003 +
- (getId() == null ? 0 : getId().hashCode());
- }
-
- /** @exclude **/
- @Override
- public String toString()
- {
- return getServiceType() + "#" + getId();
- }
-
- //--------------------------------------------------------------------------
- //
- // Protected/Private Methods
- //
- //--------------------------------------------------------------------------
-
- protected ThrottleManager createThrottleManager()
- {
- Service service = getService();
- if (service == null || service.getMessageBroker() == null)
- return new ThrottleManager(); // Return the default.
-
- try
- {
- Class<? extends ThrottleManager> throttleManagerClass = service.getMessageBroker().getThrottleManagerClass();
- Object instance = ClassUtil.createDefaultInstance(throttleManagerClass, null);
- if (instance instanceof ThrottleManager)
- return (ThrottleManager)instance;
- }
- catch (Throwable t)
- {
- // NOWARN
- }
-
- return new ThrottleManager(); // Return the default.
- }
-
- protected void network(ConfigMap properties)
- {
- ConfigMap network = properties.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null);
- if (network == null)
- return;
-
- // Get implementation specific network settings, including subclasses!
- NetworkSettings ns = getNetworkSettings();
-
- // Subscriber timeout; first check for subscription-timeout-minutes and fallback to legacy session-timeout.
- int useLegacyPropertyToken = -999999;
- int subscriptionTimeoutMinutes = network.getPropertyAsInt(NetworkSettings.SUBSCRIPTION_TIMEOUT_MINUTES, useLegacyPropertyToken);
- if (subscriptionTimeoutMinutes == useLegacyPropertyToken)
- subscriptionTimeoutMinutes = network.getPropertyAsInt(NetworkSettings.SESSION_TIMEOUT, NetworkSettings.DEFAULT_TIMEOUT);
- ns.setSubscriptionTimeoutMinutes(subscriptionTimeoutMinutes);
-
- // Throttle Settings
- ThrottleSettings ts = ns.getThrottleSettings();
- ts.setDestinationName(getId());
- throttle(ts, network);
-
- setNetworkSettings(ns);
- }
-
- protected void throttle(ThrottleSettings ts, ConfigMap network)
- {
- ConfigMap inbound = network.getPropertyAsMap(ThrottleSettings.ELEMENT_INBOUND, null);
- if (inbound != null)
- {
- ThrottleSettings.Policy policy = getPolicyFromThrottleSettings(inbound);
- ts.setInboundPolicy(policy);
- int destFreq = inbound.getPropertyAsInt(ThrottleSettings.ELEMENT_DEST_FREQ, 0);
- ts.setIncomingDestinationFrequency(destFreq);
- int clientFreq = inbound.getPropertyAsInt(ThrottleSettings.ELEMENT_CLIENT_FREQ, 0);
- ts.setIncomingClientFrequency(clientFreq);
- }
-
- ConfigMap outbound = network.getPropertyAsMap(ThrottleSettings.ELEMENT_OUTBOUND, null);
- if (outbound != null)
- {
- ThrottleSettings.Policy policy = getPolicyFromThrottleSettings(outbound);
- ts.setOutboundPolicy(policy);
- int destFreq = outbound.getPropertyAsInt(ThrottleSettings.ELEMENT_DEST_FREQ, 0);
- ts.setOutgoingDestinationFrequency(destFreq);
- int clientFreq = outbound.getPropertyAsInt(ThrottleSettings.ELEMENT_CLIENT_FREQ, 0);
- ts.setOutgoingClientFrequency(clientFreq);
- }
- }
-
- private ThrottleSettings.Policy getPolicyFromThrottleSettings(ConfigMap settings)
- {
- String policyString = settings.getPropertyAsString(ThrottleSettings.ELEMENT_POLICY, null);
- ThrottleSettings.Policy policy = ThrottleSettings.Policy.NONE;
- if (policyString == null)
- return policy;
- try
- {
- policy = ThrottleSettings.parsePolicy(policyString);
- }
- catch (ConfigurationException exception)
- {
- ConfigurationException ce = new ConfigurationException();
- ce.setMessage(UNSUPPORTED_POLICY, new Object[] {getId(), policyString});
- throw ce;
- }
- return policy;
- }
-
- protected void server(ConfigMap properties)
- {
- ConfigMap server = properties.getPropertyAsMap(DestinationSettings.SERVER_ELEMENT, null);
- if (server == null)
- return;
-
- long ttl = server.getPropertyAsLong(MessagingConstants.TIME_TO_LIVE_ELEMENT, -1);
- serverSettings.setMessageTTL(ttl);
-
- boolean durable = server.getPropertyAsBoolean(MessagingConstants.IS_DURABLE_ELEMENT, false);
- serverSettings.setDurable(durable);
-
- boolean allowSubtopics = server.getPropertyAsBoolean(MessagingConstants.ALLOW_SUBTOPICS_ELEMENT, false);
- serverSettings.setAllowSubtopics(allowSubtopics);
-
- boolean disallowWildcardSubtopics = server.getPropertyAsBoolean(MessagingConstants.DISALLOW_WILDCARD_SUBTOPICS_ELEMENT, false);
- serverSettings.setDisallowWildcardSubtopics(disallowWildcardSubtopics);
-
- int priority = server.getPropertyAsInt(MessagingConstants.MESSAGE_PRIORITY, -1);
- if (priority != -1)
- serverSettings.setPriority(priority);
-
- String subtopicSeparator = server.getPropertyAsString(MessagingConstants.SUBTOPIC_SEPARATOR_ELEMENT, MessagingConstants.DEFAULT_SUBTOPIC_SEPARATOR);
- serverSettings.setSubtopicSeparator(subtopicSeparator);
-
- String routingMode = server.getPropertyAsString(MessagingConstants.CLUSTER_MESSAGE_ROUTING, "server-to-server");
- serverSettings.setBroadcastRoutingMode(routingMode);
- }
-
- /**
- * Returns the log category of the <code>MessageDestination</code>.
- *
- * @return The log category of the component.
- */
- @Override
- protected String getLogCategory()
- {
- return LOG_CATEGORY;
- }
-
- /**
- * Invoked automatically to allow the <code>MessageDestination</code> to setup its corresponding
- * MBean control.
- *
- * @param service The <code>Service</code> that manages this <code>MessageDestination</code>.
- */
- @Override
- protected void setupDestinationControl(Service service)
- {
- controller = new MessageDestinationControl(this, service.getControl());
- controller.register();
- setControl(controller);
- setupThrottleManagerControl(controller);
- setupSubscriptionManagerControl(controller);
- }
-
- protected void setupThrottleManagerControl(MessageDestinationControl destinationControl)
- {
- if (throttleManager != null)
- {
- ThrottleManagerControl throttleManagerControl = new ThrottleManagerControl(throttleManager, destinationControl);
- throttleManagerControl.register();
- throttleManager.setControl(throttleManagerControl);
- throttleManager.setManaged(true);
- destinationControl.setThrottleManager(throttleManagerControl.getObjectName());
- }
- }
-
- private void setupSubscriptionManagerControl(MessageDestinationControl destinationControl)
- {
- SubscriptionManagerControl subscriptionManagerControl = new SubscriptionManagerControl(getSubscriptionManager(), destinationControl);
- subscriptionManagerControl.register();
- getSubscriptionManager().setControl(subscriptionManagerControl);
- getSubscriptionManager().setManaged(true);
- destinationControl.setSubscriptionManager(subscriptionManagerControl.getObjectName());
- }
-}
+/*
+ * 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;
+
+import flex.management.runtime.messaging.MessageDestinationControl;
+import flex.management.runtime.messaging.services.messaging.SubscriptionManagerControl;
+import flex.management.runtime.messaging.services.messaging.ThrottleManagerControl;
+import flex.messaging.config.ConfigurationConstants;
+import flex.messaging.config.ConfigurationException;
+import flex.messaging.config.DestinationSettings;
+import flex.messaging.config.ThrottleSettings;
+import flex.messaging.config.ConfigMap;
+import flex.messaging.config.NetworkSettings;
+import flex.messaging.config.ServerSettings;
+import flex.messaging.config.ThrottleSettings.Policy;
+import flex.messaging.log.LogCategories;
+import flex.messaging.services.MessageService;
+import flex.messaging.services.Service;
+import flex.messaging.services.messaging.SubscriptionManager;
+import flex.messaging.services.messaging.RemoteSubscriptionManager;
+import flex.messaging.services.messaging.ThrottleManager;
+import flex.messaging.services.messaging.MessagingConstants;
+import flex.messaging.util.ClassUtil;
+
+/**
+ * A logical reference to a MessageDestination.
+ */
+public class MessageDestination extends FactoryDestination
+{
+ static final long serialVersionUID = -2016911808141319012L;
+
+ /** Log category for <code>MessageDestination</code>.*/
+ public static final String LOG_CATEGORY = LogCategories.SERVICE_MESSAGE;
+
+ // Errors
+ private static final int UNSUPPORTED_POLICY = 10124;
+
+ // Destination properties
+ private transient ServerSettings serverSettings;
+
+ // Destination internal
+ private transient SubscriptionManager subscriptionManager;
+ private transient RemoteSubscriptionManager remoteSubscriptionManager;
+ private transient ThrottleManager throttleManager;
+
+ private transient MessageDestinationControl controller;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructs an unmanaged <code>MessageDestination</code> instance.
+ */
+ public MessageDestination()
+ {
+ this(false);
+ }
+
+ /**
+ * Constructs a <code>MessageDestination</code> with the indicated management.
+ *
+ * @param enableManagement <code>true</code> if the <code>MessageDestination</code>
+ * is manageable; otherwise <code>false</code>.
+ */
+ public MessageDestination(boolean enableManagement)
+ {
+ super(enableManagement);
+
+ serverSettings = new ServerSettings();
+
+ // Managers
+ subscriptionManager = new SubscriptionManager(this);
+ remoteSubscriptionManager = new RemoteSubscriptionManager(this);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Initialize, validate, start, and stop methods.
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Initializes the <code>MessageDestination</code> with the properties.
+ * If subclasses override, they must call <code>super.initialize()</code>.
+ *
+ * @param id The id of the destination.
+ * @param properties Properties for the <code>MessageDestination</code>.
+ */
+ @Override
+ public void initialize(String id, ConfigMap properties)
+ {
+ super.initialize(id, properties);
+
+ if (properties == null || properties.size() == 0)
+ return;
+
+ // Network properties
+ network(properties);
+
+ // Server properties
+ server(properties);
+ }
+
+ /**
+ * Sets up the throttle manager before it starts.
+ */
+ @Override
+ public void start()
+ {
+ // Create the throttle manager, only if needed.
+ if (networkSettings.getThrottleSettings() != null)
+ {
+ ThrottleSettings settings = networkSettings.getThrottleSettings();
+ if (settings.isClientThrottleEnabled() || settings.isDestinationThrottleEnabled())
+ {
+ settings.setDestinationName(getId());
+ throttleManager = createThrottleManager();
+ throttleManager.setThrottleSettings(settings);
+ throttleManager.start();
+ }
+ }
+ super.start();
+ }
+
+ /**
+ * Stops the subscription, remote subscription, and throttle managers and
+ * then calls super class's stop.
+ */
+ @Override
+ public void stop()
+ {
+ if (isStarted())
+ {
+ subscriptionManager.stop();
+ remoteSubscriptionManager.stop();
+ if (throttleManager != null)
+ throttleManager.stop();
+ }
+ super.stop();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Public Getters and Setters for Destination properties
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Sets the <code>NetworkSettings</code> of the <code>MessageDestination</code>.
+ *
+ * @param networkSettings The <code>NetworkSettings</code> of the <code>MessageDestination</code>
+ */
+ @Override
+ public void setNetworkSettings(NetworkSettings networkSettings)
+ {
+ super.setNetworkSettings(networkSettings);
+
+ // Set the subscription manager settings if needed.
+ if (networkSettings.getSubscriptionTimeoutMinutes() > 0)
+ {
+ long subscriptionTimeoutMillis = networkSettings.getSubscriptionTimeoutMinutes() * 60L * 1000L; // Convert to millis.
+ subscriptionManager.setSubscriptionTimeoutMillis(subscriptionTimeoutMillis);
+ }
+ }
+
+ /**
+ * Returns the <code>ServerSettings</code> of the <code>MessageDestination</code>.
+ *
+ * @return The <code>ServerSettings</code> of the <code>MessageDestination</code>.
+ */
+ public ServerSettings getServerSettings()
+ {
+ return serverSettings;
+ }
+
+ /**
+ * Sets the <code>ServerSettings</code> of the <code>MessageDestination</code>.
+ *
+ * @param serverSettings The <code>ServerSettings</code> of the <code>MessageDestination</code>
+ */
+ public void setServerSettings(ServerSettings serverSettings)
+ {
+ this.serverSettings = serverSettings;
+ }
+
+ /**
+ * Casts the <code>Service</code> into <code>MessageService</code>
+ * and calls super.setService.
+ *
+ * @param service The <code>Service</code> managing this <code>Destination</code>.
+ */
+ @Override
+ public void setService(Service service)
+ {
+ MessageService messageService = (MessageService)service;
+ super.setService(messageService);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Other Public Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @exclude
+ * Returns a <tt>ConfigMap</tt> of destination properties that the client
+ * needs. This includes properties from <code>super{@link #describeDestination(boolean)}</code>
+ * and it also includes outbound throttling policy that the edge server might need.
+ *
+ * @param onlyReliable Determines whether only reliable destination configuration should be returned.
+ * @return A <tt>ConfigMap</tt> of destination properties that the client needs.
+ */
+ @Override
+ public ConfigMap describeDestination(boolean onlyReliable)
+ {
+ ConfigMap destinationConfig = super.describeDestination(onlyReliable);
+ if (destinationConfig == null)
+ return null;
+
+ if (throttleManager == null)
+ return destinationConfig;
+
+ Policy outboundPolicy = throttleManager.getOutboundPolicy();
+ if (outboundPolicy == null || outboundPolicy == Policy.NONE)
+ return destinationConfig;
+
+ // Add the outbound throttle policy to network properties section as appropriate.
+ ConfigMap properties = destinationConfig.getPropertyAsMap(ConfigurationConstants.PROPERTIES_ELEMENT, null);
+ if (properties == null)
+ {
+ properties = new ConfigMap();
+ destinationConfig.addProperty(ConfigurationConstants.PROPERTIES_ELEMENT, properties);
+ }
+
+ ConfigMap network = properties.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null);
+ if (network == null)
+ {
+ network = new ConfigMap();
+ properties.addProperty(NetworkSettings.NETWORK_ELEMENT, network);
+ }
+
+ ConfigMap throttleOutbound = new ConfigMap();
+ throttleOutbound.addProperty(ThrottleSettings.ELEMENT_POLICY, throttleManager.getOutboundPolicy().toString());
+ network.addProperty(ThrottleSettings.ELEMENT_OUTBOUND, throttleOutbound);
+
+ return destinationConfig;
+ }
+
+ /** @exclude */
+ public SubscriptionManager getSubscriptionManager()
+ {
+ return subscriptionManager;
+ }
+
+ /** @exclude */
+ public RemoteSubscriptionManager getRemoteSubscriptionManager()
+ {
+ return remoteSubscriptionManager;
+ }
+
+ /** @exclude */
+ public ThrottleManager getThrottleManager()
+ {
+ return throttleManager;
+ }
+
+ /** @exclude **/
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o instanceof Destination)
+ {
+ Destination d = (Destination)o;
+ String serviceType1 = d.getServiceType();
+ String serviceType2 = getServiceType();
+ if ((serviceType1 == null && serviceType2 == null) || (serviceType1 != null && serviceType1.equals(serviceType2)))
+ {
+ String id1 = d.getId();
+ String id2 = getId();
+ if ((id1 == null && id2 == null) || (id1 != null && id1.equals(id2)))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** @exclude **/
+ @Override
+ public int hashCode()
+ {
+ return (getServiceType() == null ? 0 : getServiceType().hashCode()) * 100003 +
+ (getId() == null ? 0 : getId().hashCode());
+ }
+
+ /** @exclude **/
+ @Override
+ public String toString()
+ {
+ return getServiceType() + "#" + getId();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Protected/Private Methods
+ //
+ //--------------------------------------------------------------------------
+
+ protected ThrottleManager createThrottleManager()
+ {
+ Service service = getService();
+ if (service == null || service.getMessageBroker() == null)
+ return new ThrottleManager(); // Return the default.
+
+ try
+ {
+ Class<? extends ThrottleManager> throttleManagerClass = service.getMessageBroker().getThrottleManagerClass();
+ Object instance = ClassUtil.createDefaultInstance(throttleManagerClass, null);
+ if (instance instanceof ThrottleManager)
+ return (ThrottleManager)instance;
+ }
+ catch (Throwable t)
+ {
+ // NOWARN
+ }
+
+ return new ThrottleManager(); // Return the default.
+ }
+
+ protected void network(ConfigMap properties)
+ {
+ ConfigMap network = properties.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null);
+ if (network == null)
+ return;
+
+ // Get implementation specific network settings, including subclasses!
+ NetworkSettings ns = getNetworkSettings();
+
+ // Subscriber timeout; first check for subscription-timeout-minutes and fallback to legacy session-timeout.
+ int useLegacyPropertyToken = -999999;
+ int subscriptionTimeoutMinutes = network.getPropertyAsInt(NetworkSettings.SUBSCRIPTION_TIMEOUT_MINUTES, useLegacyPropertyToken);
+ if (subscriptionTimeoutMinutes == useLegacyPropertyToken)
+ subscriptionTimeoutMinutes = network.getPropertyAsInt(NetworkSettings.SESSION_TIMEOUT, NetworkSettings.DEFAULT_TIMEOUT);
+ ns.setSubscriptionTimeoutMinutes(subscriptionTimeoutMinutes);
+
+ // Throttle Settings
+ ThrottleSettings ts = ns.getThrottleSettings();
+ ts.setDestinationName(getId());
+ throttle(ts, network);
+
+ setNetworkSettings(ns);
+ }
+
+ protected void throttle(ThrottleSettings ts, ConfigMap network)
+ {
+ ConfigMap inbound = network.getPropertyAsMap(ThrottleSettings.ELEMENT_INBOUND, null);
+ if (inbound != null)
+ {
+ ThrottleSettings.Policy policy = getPolicyFromThrottleSettings(inbound);
+ ts.setInboundPolicy(policy);
+ int destFreq = inbound.getPropertyAsInt(ThrottleSettings.ELEMENT_DEST_FREQ, 0);
+ ts.setIncomingDestinationFrequency(destFreq);
+ int clientFreq = inbound.getPropertyAsInt(ThrottleSettings.ELEMENT_CLIENT_FREQ, 0);
+ ts.setIncomingClientFrequency(clientFreq);
+ }
+
+ ConfigMap outbound = network.getPropertyAsMap(ThrottleSettings.ELEMENT_OUTBOUND, null);
+ if (outbound != null)
+ {
+ ThrottleSettings.Policy policy = getPolicyFromThrottleSettings(outbound);
+ ts.setOutboundPolicy(policy);
+ int destFreq = outbound.getPropertyAsInt(ThrottleSettings.ELEMENT_DEST_FREQ, 0);
+ ts.setOutgoingDestinationFrequency(destFreq);
+ int clientFreq = outbound.getPropertyAsInt(ThrottleSettings.ELEMENT_CLIENT_FREQ, 0);
+ ts.setOutgoingClientFrequency(clientFreq);
+ }
+ }
+
+ private ThrottleSettings.Policy getPolicyFromThrottleSettings(ConfigMap settings)
+ {
+ String policyString = settings.getPropertyAsString(ThrottleSettings.ELEMENT_POLICY, null);
+ ThrottleSettings.Policy policy = ThrottleSettings.Policy.NONE;
+ if (policyString == null)
+ return policy;
+ try
+ {
+ policy = ThrottleSettings.parsePolicy(policyString);
+ }
+ catch (ConfigurationException exception)
+ {
+ ConfigurationException ce = new ConfigurationException();
+ ce.setMessage(UNSUPPORTED_POLICY, new Object[] {getId(), policyString});
+ throw ce;
+ }
+ return policy;
+ }
+
+ protected void server(ConfigMap properties)
+ {
+ ConfigMap server = properties.getPropertyAsMap(DestinationSettings.SERVER_ELEMENT, null);
+ if (server == null)
+ return;
+
+ long ttl = server.getPropertyAsLong(MessagingConstants.TIME_TO_LIVE_ELEMENT, -1);
+ serverSettings.setMessageTTL(ttl);
+
+ boolean durable = server.getPropertyAsBoolean(MessagingConstants.IS_DURABLE_ELEMENT, false);
+ serverSettings.setDurable(durable);
+
+ boolean allowSubtopics = server.getPropertyAsBoolean(MessagingConstants.ALLOW_SUBTOPICS_ELEMENT, false);
+ serverSettings.setAllowSubtopics(allowSubtopics);
+
+ boolean disallowWildcardSubtopics = server.getPropertyAsBoolean(MessagingConstants.DISALLOW_WILDCARD_SUBTOPICS_ELEMENT, false);
+ serverSettings.setDisallowWildcardSubtopics(disallowWildcardSubtopics);
+
+ int priority = server.getPropertyAsInt(MessagingConstants.MESSAGE_PRIORITY, -1);
+ if (priority != -1)
+ serverSettings.setPriority(priority);
+
+ String subtopicSeparator = server.getPropertyAsString(MessagingConstants.SUBTOPIC_SEPARATOR_ELEMENT, MessagingConstants.DEFAULT_SUBTOPIC_SEPARATOR);
+ serverSettings.setSubtopicSeparator(subtopicSeparator);
+
+ String routingMode = server.getPropertyAsString(MessagingConstants.CLUSTER_MESSAGE_ROUTING, "server-to-server");
+ serverSettings.setBroadcastRoutingMode(routingMode);
+ }
+
+ /**
+ * Returns the log category of the <code>MessageDestination</code>.
+ *
+ * @return The log category of the component.
+ */
+ @Override
+ protected String getLogCategory()
+ {
+ return LOG_CATEGORY;
+ }
+
+ /**
+ * Invoked automatically to allow the <code>MessageDestination</code> to setup its corresponding
+ * MBean control.
+ *
+ * @param service The <code>Service</code> that manages this <code>MessageDestination</code>.
+ */
+ @Override
+ protected void setupDestinationControl(Service service)
+ {
+ controller = new MessageDestinationControl(this, service.getControl());
+ controller.register();
+ setControl(controller);
+ setupThrottleManagerControl(controller);
+ setupSubscriptionManagerControl(controller);
+ }
+
+ protected void setupThrottleManagerControl(MessageDestinationControl destinationControl)
+ {
+ if (throttleManager != null)
+ {
+ ThrottleManagerControl throttleManagerControl = new ThrottleManagerControl(throttleManager, destinationControl);
+ throttleManagerControl.register();
+ throttleManager.setControl(throttleManagerControl);
+ throttleManager.setManaged(true);
+ destinationControl.setThrottleManager(throttleManagerControl.getObjectName());
+ }
+ }
+
+ private void setupSubscriptionManagerControl(MessageDestinationControl destinationControl)
+ {
+ SubscriptionManagerControl subscriptionManagerControl = new SubscriptionManagerControl(getSubscriptionManager(), destinationControl);
+ subscriptionManagerControl.register();
+ getSubscriptionManager().setControl(subscriptionManagerControl);
+ getSubscriptionManager().setManaged(true);
+ destinationControl.setSubscriptionManager(subscriptionManagerControl.getObjectName());
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/MessageException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageException.java b/modules/core/src/flex/messaging/MessageException.java
old mode 100755
new mode 100644
index f11c59a..9ebf0c2
--- a/modules/core/src/flex/messaging/MessageException.java
+++ b/modules/core/src/flex/messaging/MessageException.java
@@ -1,443 +1,443 @@
-/*
- * 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;
-
-import java.util.Map;
-
-import flex.messaging.log.Log;
-import flex.messaging.log.LogCategories;
-import flex.messaging.log.LogEvent;
-import flex.messaging.messages.ErrorMessage;
-import flex.messaging.messages.Message;
-import flex.messaging.util.ExceptionUtil;
-import flex.messaging.util.PropertyStringResourceLoader;
-import flex.messaging.util.ResourceLoader;
-import flex.messaging.util.StringUtils;
-
-/**
- * The MessageException class is the basic exception type used throughout
- * the server. This class is extended to support more specific exception types.
- */
-public class MessageException extends LocalizedException
-{
- //--------------------------------------------------------------------------
- //
- // Static Constants
- //
- //--------------------------------------------------------------------------
-
- // Message exception code strings.
- public static final String CODE_SERVER_RESOURCE_UNAVAILABLE = "Server.ResourceUnavailable";
-
- /** @exclude **/
- static final long serialVersionUID = 3310842114461162689L;
-
- //--------------------------------------------------------------------------
- //
- // Constructors
- //
- //--------------------------------------------------------------------------
-
- /**
- * Default constructor.
- */
- public MessageException()
- {
- }
-
- /**
- * Construct a message specifying a ResourceLoader to be used to load localized strings.
- *
- * @param loader
- */
- public MessageException(ResourceLoader loader)
- {
- super(loader);
- }
-
- /**
- * Constructor with a message.
- *
- * @param message The detailed message for the exception.
- */
- public MessageException(String message)
- {
- setMessage(message);
- }
-
- /**
- * Constructs a new exception with the specified message and the <code>Throwable</code> as the root cause.
- *
- * @param message The detailed message for the exception.
- * @param t The root cause of the exception.
- */
- public MessageException(String message, Throwable t)
- {
- setMessage(message);
- setRootCause(t);
- }
-
- /**
- * Constructs a new exception with the specified <code>Throwable</code> as the root cause.
- *
- * @param t The root cause of the exception.
- */
- public MessageException(Throwable t)
- {
- String rootMessage = t.getMessage();
- if (rootMessage == null)
- rootMessage = t.toString();
- setMessage(rootMessage);
- setRootCause(t);
- }
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // code
- //----------------------------------
-
- /** @exclude **/
- protected String code;
-
- /**
- * Returns the code of the exception.
- *
- * @return Code of the exception.
- */
- public String getCode()
- {
- return code;
- }
-
- /**
- * Sets the code of the exception.
- *
- * @param code Code of the exception.
- */
- public void setCode(String code)
- {
- this.code = code;
- }
-
- //----------------------------------
- // defaultLogMessageIntro
- //----------------------------------
-
- /**
- * Returns the default initial text for use in the log output generated by <code>logAtHingePoint()</code>.
- */
- public String getDefaultLogMessageIntro()
- {
- return "Error handling message: ";
- }
-
- //----------------------------------
- // extendedData
- //----------------------------------
-
- /** @exclude **/
- protected Map extendedData;
-
- /**
- * Returns the extended data of the exception.
- *
- * @return The extended data of the exception.
- */
- public Map getExtendedData()
- {
- return extendedData;
- }
-
- /**
- * Sets the extended data of the exception.
- *
- * @param extendedData The extended data of the exception.
- */
- public void setExtendedData(Map extendedData)
- {
- this.extendedData = extendedData;
- }
-
- //----------------------------------
- // errorMessage
- //----------------------------------
-
- /** @exclude **/
- protected ErrorMessage errorMessage;
-
- /**
- * Returns the error message of the exception.
- *
- * @return The error message of the exception.
- */
- public ErrorMessage getErrorMessage()
- {
- if (errorMessage == null)
- {
- errorMessage = createErrorMessage();
- }
- return errorMessage;
- }
-
- /**
- * Sets the error message of the exception.
- *
- * @param errorMessage The error message of the exception.
- */
- public void setErrorMessage(ErrorMessage errorMessage)
- {
- this.errorMessage = errorMessage;
- }
-
- //----------------------------------
- // logStackTraceEnabled
- //----------------------------------
-
- /**
- * Indicates whether logging of this exception should include a full stack trace or not.
- * Default is true.
- *
- * @see #logAtHingePoint(Message, ErrorMessage, String)
- */
- public boolean isLogStackTraceEnabled()
- {
- return true;
- }
-
- //----------------------------------
- // logged
- //----------------------------------
-
- protected boolean logged;
-
- /**
- * Indicates whether this exception has already been logged
- * by a call to <code>logAtHingPoint()</code>.
- * Manual logging for an exception can use <code>setLogged(true)</code>
- * to suppress any further automatic logging of the exception.
- *
- * @return true if the exception has been logged; otherwise false.
- */
- public boolean isLogged()
- {
- return logged;
- }
-
- /**
- * Records whether this exception has been logged.
- *
- * @param value true if the exception has been logged; otherwise false.
- */
- public void setLogged(boolean value)
- {
- logged = value;
- }
-
- //----------------------------------
- // peferredLogLevel
- //----------------------------------
-
- /**
- * Returns the preferred log level for this exception instance.
- * The default value is <code>LogEvent.ERROR</code>.
- *
- * @see #logAtHingePoint(Message, ErrorMessage, String)
- */
- public short getPreferredLogLevel()
- {
- return LogEvent.ERROR;
- }
-
- //----------------------------------
- // resourceLoader
- //----------------------------------
-
- /**
- * Returns the <code>ResourceLoader</code> used to load localized strings.
- *
- * @return The <code>ResourceLoader</code> used to load localized strings.
- */
- @Override protected ResourceLoader getResourceLoader()
- {
- if (resourceLoader == null)
- {
- try
- {
- MessageBroker broker = FlexContext.getMessageBroker();
- resourceLoader = broker != null? broker.getSystemSettings().getResourceLoader()
- : new PropertyStringResourceLoader();
- }
- catch (NoClassDefFoundError exception) // Could happen in client mode.
- {
- return new PropertyStringResourceLoader();
- }
- }
-
- return resourceLoader;
- }
-
- //----------------------------------
- // rootCauseErrorMessage
- //----------------------------------
-
- /** @exclude **/
- public Object getRootCauseErrorMessage()
- {
- if (rootCause == null)
- return null;
-
- // FIXME: serialize number field.
- return rootCause instanceof MessageException?
- ((MessageException)rootCause).createErrorMessage() : rootCause;
- }
-
- //----------------------------------
- // statusCode
- //----------------------------------
-
- protected int statusCode;
-
- /**
- * Returns the HTTP status code of the exception.
- *
- * @return The HTTP status code of the exception.
- */
- public int getStatusCode()
- {
- return statusCode;
- }
-
- /**
- * Sets the HTTP status code of the exception.
- *
- * @param statusCode The HTTP status code of the exception.
- */
- public void setStatusCode(int statusCode)
- {
- this.statusCode = statusCode;
- }
-
- //--------------------------------------------------------------------------
- //
- // Public Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * Creates an error message from the exception.
- *
- * @return The error message.
- */
- public ErrorMessage createErrorMessage()
- {
- ErrorMessage msg = new ErrorMessage();
- msg.faultCode = code != null? code : "Server.Processing";
- msg.faultString = message;
- msg.faultDetail = details;
- msg.rootCause = getRootCauseErrorMessage();
- if (extendedData != null)
- msg.extendedData = extendedData;
- if (statusCode != 0)
- msg.setHeader(Message.STATUS_CODE_HEADER, statusCode);
- return msg;
- }
-
- /**
- * Invoked at hinge-points in server processing where catch-all exception logging is performed.
- * This method uses <code>isLogged()</code> and <code>setLogged()</code> to avoid repeat logging
- * of the same exception and uses <code>getPreferredLogLevel()</code> which may be
- * overridden in subclasses to control the log level that the logging is output at.
- * The underlying exception stack traces are also conditionally included in log output
- * if the exception class allows it and this is determined by invoking <code>isLogStackTraceEnabled()</code>
- *
- * @param inboundMessage The inbound message that triggered an exception during processing.
- * @param outboundMessage The outbound <code>ErrorMessage</code>, which may be null depending on whether it has been generated
- * or not at the point this method is invoked.
- * @param logMessageIntro The beginning text for the log message, which may be null; default value is returned by <code>getDefaultLogMessageIntro()</code>.
- */
- public void logAtHingePoint(Message inboundMessage, ErrorMessage outboundMessage, String logMessageIntro)
- {
- if (!isLogged())
- {
- setLogged(true);
-
- short preferredLevel = getPreferredLogLevel();
- // If the preferred level is less than the current Log level; return early.
- if (preferredLevel < Log.getTargetLevel())
- return;
-
- // Construct core log output.
- StringBuffer output = new StringBuffer();
- output.append((logMessageIntro != null) ? logMessageIntro : getDefaultLogMessageIntro());
- output.append(this.toString());
- output.append(StringUtils.NEWLINE);
- output.append(" incomingMessage: ");
- output.append(inboundMessage);
- output.append(StringUtils.NEWLINE);
- if (outboundMessage != null)
- {
- output.append(" errorReply: ");
- output.append(outboundMessage);
- output.append(StringUtils.NEWLINE);
- }
- if (isLogStackTraceEnabled())
- {
- output.append(ExceptionUtil.exceptionFollowedByRootCausesToString(this));
- output.append(StringUtils.NEWLINE);
- }
-
- switch (preferredLevel)
- {
- case LogEvent.FATAL:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).fatal(output.toString());
- break;
- }
- case LogEvent.ERROR:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).error(output.toString());
- break;
- }
- case LogEvent.WARN:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).warn(output.toString());
- break;
- }
- case LogEvent.INFO:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).info(output.toString());
- break;
- }
- case LogEvent.DEBUG:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).debug(output.toString());
- break;
- }
- default:
- {
- Log.getLogger(LogCategories.MESSAGE_GENERAL).fatal("Failed to log exception for handling message due to an invalid preferred log level: " + preferredLevel);
- break;
- }
- }
- }
- }
-}
+/*
+ * 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;
+
+import java.util.Map;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.LogCategories;
+import flex.messaging.log.LogEvent;
+import flex.messaging.messages.ErrorMessage;
+import flex.messaging.messages.Message;
+import flex.messaging.util.ExceptionUtil;
+import flex.messaging.util.PropertyStringResourceLoader;
+import flex.messaging.util.ResourceLoader;
+import flex.messaging.util.StringUtils;
+
+/**
+ * The MessageException class is the basic exception type used throughout
+ * the server. This class is extended to support more specific exception types.
+ */
+public class MessageException extends LocalizedException
+{
+ //--------------------------------------------------------------------------
+ //
+ // Static Constants
+ //
+ //--------------------------------------------------------------------------
+
+ // Message exception code strings.
+ public static final String CODE_SERVER_RESOURCE_UNAVAILABLE = "Server.ResourceUnavailable";
+
+ /** @exclude **/
+ static final long serialVersionUID = 3310842114461162689L;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructors
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Default constructor.
+ */
+ public MessageException()
+ {
+ }
+
+ /**
+ * Construct a message specifying a ResourceLoader to be used to load localized strings.
+ *
+ * @param loader
+ */
+ public MessageException(ResourceLoader loader)
+ {
+ super(loader);
+ }
+
+ /**
+ * Constructor with a message.
+ *
+ * @param message The detailed message for the exception.
+ */
+ public MessageException(String message)
+ {
+ setMessage(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified message and the <code>Throwable</code> as the root cause.
+ *
+ * @param message The detailed message for the exception.
+ * @param t The root cause of the exception.
+ */
+ public MessageException(String message, Throwable t)
+ {
+ setMessage(message);
+ setRootCause(t);
+ }
+
+ /**
+ * Constructs a new exception with the specified <code>Throwable</code> as the root cause.
+ *
+ * @param t The root cause of the exception.
+ */
+ public MessageException(Throwable t)
+ {
+ String rootMessage = t.getMessage();
+ if (rootMessage == null)
+ rootMessage = t.toString();
+ setMessage(rootMessage);
+ setRootCause(t);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // code
+ //----------------------------------
+
+ /** @exclude **/
+ protected String code;
+
+ /**
+ * Returns the code of the exception.
+ *
+ * @return Code of the exception.
+ */
+ public String getCode()
+ {
+ return code;
+ }
+
+ /**
+ * Sets the code of the exception.
+ *
+ * @param code Code of the exception.
+ */
+ public void setCode(String code)
+ {
+ this.code = code;
+ }
+
+ //----------------------------------
+ // defaultLogMessageIntro
+ //----------------------------------
+
+ /**
+ * Returns the default initial text for use in the log output generated by <code>logAtHingePoint()</code>.
+ */
+ public String getDefaultLogMessageIntro()
+ {
+ return "Error handling message: ";
+ }
+
+ //----------------------------------
+ // extendedData
+ //----------------------------------
+
+ /** @exclude **/
+ protected Map extendedData;
+
+ /**
+ * Returns the extended data of the exception.
+ *
+ * @return The extended data of the exception.
+ */
+ public Map getExtendedData()
+ {
+ return extendedData;
+ }
+
+ /**
+ * Sets the extended data of the exception.
+ *
+ * @param extendedData The extended data of the exception.
+ */
+ public void setExtendedData(Map extendedData)
+ {
+ this.extendedData = extendedData;
+ }
+
+ //----------------------------------
+ // errorMessage
+ //----------------------------------
+
+ /** @exclude **/
+ protected ErrorMessage errorMessage;
+
+ /**
+ * Returns the error message of the exception.
+ *
+ * @return The error message of the exception.
+ */
+ public ErrorMessage getErrorMessage()
+ {
+ if (errorMessage == null)
+ {
+ errorMessage = createErrorMessage();
+ }
+ return errorMessage;
+ }
+
+ /**
+ * Sets the error message of the exception.
+ *
+ * @param errorMessage The error message of the exception.
+ */
+ public void setErrorMessage(ErrorMessage errorMessage)
+ {
+ this.errorMessage = errorMessage;
+ }
+
+ //----------------------------------
+ // logStackTraceEnabled
+ //----------------------------------
+
+ /**
+ * Indicates whether logging of this exception should include a full stack trace or not.
+ * Default is true.
+ *
+ * @see #logAtHingePoint(Message, ErrorMessage, String)
+ */
+ public boolean isLogStackTraceEnabled()
+ {
+ return true;
+ }
+
+ //----------------------------------
+ // logged
+ //----------------------------------
+
+ protected boolean logged;
+
+ /**
+ * Indicates whether this exception has already been logged
+ * by a call to <code>logAtHingPoint()</code>.
+ * Manual logging for an exception can use <code>setLogged(true)</code>
+ * to suppress any further automatic logging of the exception.
+ *
+ * @return true if the exception has been logged; otherwise false.
+ */
+ public boolean isLogged()
+ {
+ return logged;
+ }
+
+ /**
+ * Records whether this exception has been logged.
+ *
+ * @param value true if the exception has been logged; otherwise false.
+ */
+ public void setLogged(boolean value)
+ {
+ logged = value;
+ }
+
+ //----------------------------------
+ // peferredLogLevel
+ //----------------------------------
+
+ /**
+ * Returns the preferred log level for this exception instance.
+ * The default value is <code>LogEvent.ERROR</code>.
+ *
+ * @see #logAtHingePoint(Message, ErrorMessage, String)
+ */
+ public short getPreferredLogLevel()
+ {
+ return LogEvent.ERROR;
+ }
+
+ //----------------------------------
+ // resourceLoader
+ //----------------------------------
+
+ /**
+ * Returns the <code>ResourceLoader</code> used to load localized strings.
+ *
+ * @return The <code>ResourceLoader</code> used to load localized strings.
+ */
+ @Override protected ResourceLoader getResourceLoader()
+ {
+ if (resourceLoader == null)
+ {
+ try
+ {
+ MessageBroker broker = FlexContext.getMessageBroker();
+ resourceLoader = broker != null? broker.getSystemSettings().getResourceLoader()
+ : new PropertyStringResourceLoader();
+ }
+ catch (NoClassDefFoundError exception) // Could happen in client mode.
+ {
+ return new PropertyStringResourceLoader();
+ }
+ }
+
+ return resourceLoader;
+ }
+
+ //----------------------------------
+ // rootCauseErrorMessage
+ //----------------------------------
+
+ /** @exclude **/
+ public Object getRootCauseErrorMessage()
+ {
+ if (rootCause == null)
+ return null;
+
+ // FIXME: serialize number field.
+ return rootCause instanceof MessageException?
+ ((MessageException)rootCause).createErrorMessage() : rootCause;
+ }
+
+ //----------------------------------
+ // statusCode
+ //----------------------------------
+
+ protected int statusCode;
+
+ /**
+ * Returns the HTTP status code of the exception.
+ *
+ * @return The HTTP status code of the exception.
+ */
+ public int getStatusCode()
+ {
+ return statusCode;
+ }
+
+ /**
+ * Sets the HTTP status code of the exception.
+ *
+ * @param statusCode The HTTP status code of the exception.
+ */
+ public void setStatusCode(int statusCode)
+ {
+ this.statusCode = statusCode;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Public Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Creates an error message from the exception.
+ *
+ * @return The error message.
+ */
+ public ErrorMessage createErrorMessage()
+ {
+ ErrorMessage msg = new ErrorMessage();
+ msg.faultCode = code != null? code : "Server.Processing";
+ msg.faultString = message;
+ msg.faultDetail = details;
+ msg.rootCause = getRootCauseErrorMessage();
+ if (extendedData != null)
+ msg.extendedData = extendedData;
+ if (statusCode != 0)
+ msg.setHeader(Message.STATUS_CODE_HEADER, statusCode);
+ return msg;
+ }
+
+ /**
+ * Invoked at hinge-points in server processing where catch-all exception logging is performed.
+ * This method uses <code>isLogged()</code> and <code>setLogged()</code> to avoid repeat logging
+ * of the same exception and uses <code>getPreferredLogLevel()</code> which may be
+ * overridden in subclasses to control the log level that the logging is output at.
+ * The underlying exception stack traces are also conditionally included in log output
+ * if the exception class allows it and this is determined by invoking <code>isLogStackTraceEnabled()</code>
+ *
+ * @param inboundMessage The inbound message that triggered an exception during processing.
+ * @param outboundMessage The outbound <code>ErrorMessage</code>, which may be null depending on whether it has been generated
+ * or not at the point this method is invoked.
+ * @param logMessageIntro The beginning text for the log message, which may be null; default value is returned by <code>getDefaultLogMessageIntro()</code>.
+ */
+ public void logAtHingePoint(Message inboundMessage, ErrorMessage outboundMessage, String logMessageIntro)
+ {
+ if (!isLogged())
+ {
+ setLogged(true);
+
+ short preferredLevel = getPreferredLogLevel();
+ // If the preferred level is less than the current Log level; return early.
+ if (preferredLevel < Log.getTargetLevel())
+ return;
+
+ // Construct core log output.
+ StringBuffer output = new StringBuffer();
+ output.append((logMessageIntro != null) ? logMessageIntro : getDefaultLogMessageIntro());
+ output.append(this.toString());
+ output.append(StringUtils.NEWLINE);
+ output.append(" incomingMessage: ");
+ output.append(inboundMessage);
+ output.append(StringUtils.NEWLINE);
+ if (outboundMessage != null)
+ {
+ output.append(" errorReply: ");
+ output.append(outboundMessage);
+ output.append(StringUtils.NEWLINE);
+ }
+ if (isLogStackTraceEnabled())
+ {
+ output.append(ExceptionUtil.exceptionFollowedByRootCausesToString(this));
+ output.append(StringUtils.NEWLINE);
+ }
+
+ switch (preferredLevel)
+ {
+ case LogEvent.FATAL:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).fatal(output.toString());
+ break;
+ }
+ case LogEvent.ERROR:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).error(output.toString());
+ break;
+ }
+ case LogEvent.WARN:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).warn(output.toString());
+ break;
+ }
+ case LogEvent.INFO:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).info(output.toString());
+ break;
+ }
+ case LogEvent.DEBUG:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).debug(output.toString());
+ break;
+ }
+ default:
+ {
+ Log.getLogger(LogCategories.MESSAGE_GENERAL).fatal("Failed to log exception for handling message due to an invalid preferred log level: " + preferredLevel);
+ break;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/MessageRoutedEvent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageRoutedEvent.java b/modules/core/src/flex/messaging/MessageRoutedEvent.java
old mode 100755
new mode 100644
index 2cf0628..cc31778
--- a/modules/core/src/flex/messaging/MessageRoutedEvent.java
+++ b/modules/core/src/flex/messaging/MessageRoutedEvent.java
@@ -1,54 +1,54 @@
-/*
- * 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;
-
-import flex.messaging.messages.Message;
-
-import java.util.EventObject;
-
-/**
- * @exclude
- * This event indicates that the source message has been routed to the outbound message queues
- * for all target clients.
- * This can be used as the trigger for performing optimized IO to flush these queued messages to
- * remote hosts over the network.
- */
-public class MessageRoutedEvent extends EventObject
-{
- /**
- * @exclude
- */
- private static final long serialVersionUID = -3063794416424805005L;
-
- /**
- * Constructs a new <tt>MessageRoutedEvent</tt> using the supplied source <tt>Message</tt>.
- *
- * @param message The message that has been routed.
- */
- public MessageRoutedEvent(Message message)
- {
- super(message);
- }
-
- /**
- * Returns the message that has been routed.
- */
- public Message getMessage()
- {
- return (Message)getSource();
- }
-}
+/*
+ * 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;
+
+import flex.messaging.messages.Message;
+
+import java.util.EventObject;
+
+/**
+ * @exclude
+ * This event indicates that the source message has been routed to the outbound message queues
+ * for all target clients.
+ * This can be used as the trigger for performing optimized IO to flush these queued messages to
+ * remote hosts over the network.
+ */
+public class MessageRoutedEvent extends EventObject
+{
+ /**
+ * @exclude
+ */
+ private static final long serialVersionUID = -3063794416424805005L;
+
+ /**
+ * Constructs a new <tt>MessageRoutedEvent</tt> using the supplied source <tt>Message</tt>.
+ *
+ * @param message The message that has been routed.
+ */
+ public MessageRoutedEvent(Message message)
+ {
+ super(message);
+ }
+
+ /**
+ * Returns the message that has been routed.
+ */
+ public Message getMessage()
+ {
+ return (Message)getSource();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/MessageRoutedListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageRoutedListener.java b/modules/core/src/flex/messaging/MessageRoutedListener.java
old mode 100755
new mode 100644
index 4a04267..223cd3c
--- a/modules/core/src/flex/messaging/MessageRoutedListener.java
+++ b/modules/core/src/flex/messaging/MessageRoutedListener.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;
-
-import java.util.EventListener;
-
-/**
- * @exclude
- * Provides notification for multicast message routing events to support optimized
- * asynchronous IO to the target remote hosts.
- */
-public interface MessageRoutedListener extends EventListener
-{
- /**
- * Invoked when a message has been routed to the outbound queues for all target
- * clients.
- *
- * @param event The event containing the source message.
- */
- void messageRouted(MessageRoutedEvent event);
-}
+/*
+ * 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;
+
+import java.util.EventListener;
+
+/**
+ * @exclude
+ * Provides notification for multicast message routing events to support optimized
+ * asynchronous IO to the target remote hosts.
+ */
+public interface MessageRoutedListener extends EventListener
+{
+ /**
+ * Invoked when a message has been routed to the outbound queues for all target
+ * clients.
+ *
+ * @param event The event containing the source message.
+ */
+ void messageRouted(MessageRoutedEvent event);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/4f6a3052/modules/core/src/flex/messaging/MessageRoutedNotifier.java
----------------------------------------------------------------------
diff --git a/modules/core/src/flex/messaging/MessageRoutedNotifier.java b/modules/core/src/flex/messaging/MessageRoutedNotifier.java
old mode 100755
new mode 100644
index c2107ba..ef27b32
--- a/modules/core/src/flex/messaging/MessageRoutedNotifier.java
+++ b/modules/core/src/flex/messaging/MessageRoutedNotifier.java
@@ -1,120 +1,120 @@
-/*
- * 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;
-
-import flex.messaging.messages.Message;
-
-import java.util.ArrayList;
-
-/**
- * @exclude
- * Supports registration and notification of <tt>MessageRoutedListener</tt>s.
- * An instance of this class is exposed by <tt>FlexContext</tt> while a message is
- * being routed, and once routing of the message to the outbound messages queues for
- * target clients and registered listeners are notified.
- * This class performs no synchronization because it is only used within the context
- * of a single Thread, and only during the routing of a single message.
- */
-public class MessageRoutedNotifier
-{
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructs a <tt>MessageRoutedNotifier</tt> for the supplied source message.
- *
- * @param The source message being routed.
- */
- public MessageRoutedNotifier(Message message)
- {
- this.message = message;
- }
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * The source message being routed.
- */
- private final Message message;
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // messageRoutedListeners
- //----------------------------------
-
- private ArrayList listeners;
-
- /**
- * Adds a <tt>MessageRoutedListener</tt>.
- */
- public void addMessageRoutedListener(MessageRoutedListener listener)
- {
- if (listener != null)
- {
- // Lazy-init only if necessary.
- if (listeners == null)
- listeners = new ArrayList();
-
- // Add if absent.
- if (!listeners.contains(listener))
- listeners.add(listener);
- }
- }
-
- /**
- * Removes a <tt>MessageRoutedListener</tt>.
- */
- public void removeMessageRoutedListener(MessageRoutedListener listener)
- {
- if ((listener != null) && (listeners != null))
- listeners.remove(listener);
- }
-
- //--------------------------------------------------------------------------
- //
- // Public Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * Notifies registered listeners of a routed message.
- *
- * @param message The message that has been routed.
- */
- public void notifyMessageRouted()
- {
- if ((listeners != null) && !listeners.isEmpty())
- {
- MessageRoutedEvent event = new MessageRoutedEvent(message);
- int n = listeners.size();
- for (int i = 0; i < n; ++i)
- ((MessageRoutedListener)listeners.get(i)).messageRouted(event);
- }
- }
-}
+/*
+ * 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;
+
+import flex.messaging.messages.Message;
+
+import java.util.ArrayList;
+
+/**
+ * @exclude
+ * Supports registration and notification of <tt>MessageRoutedListener</tt>s.
+ * An instance of this class is exposed by <tt>FlexContext</tt> while a message is
+ * being routed, and once routing of the message to the outbound messages queues for
+ * target clients and registered listeners are notified.
+ * This class performs no synchronization because it is only used within the context
+ * of a single Thread, and only during the routing of a single message.
+ */
+public class MessageRoutedNotifier
+{
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructs a <tt>MessageRoutedNotifier</tt> for the supplied source message.
+ *
+ * @param The source message being routed.
+ */
+ public MessageRoutedNotifier(Message message)
+ {
+ this.message = message;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * The source message being routed.
+ */
+ private final Message message;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // messageRoutedListeners
+ //----------------------------------
+
+ private ArrayList listeners;
+
+ /**
+ * Adds a <tt>MessageRoutedListener</tt>.
+ */
+ public void addMessageRoutedListener(MessageRoutedListener listener)
+ {
+ if (listener != null)
+ {
+ // Lazy-init only if necessary.
+ if (listeners == null)
+ listeners = new ArrayList();
+
+ // Add if absent.
+ if (!listeners.contains(listener))
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a <tt>MessageRoutedListener</tt>.
+ */
+ public void removeMessageRoutedListener(MessageRoutedListener listener)
+ {
+ if ((listener != null) && (listeners != null))
+ listeners.remove(listener);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Public Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Notifies registered listeners of a routed message.
+ *
+ * @param message The message that has been routed.
+ */
+ public void notifyMessageRouted()
+ {
+ if ((listeners != null) && !listeners.isEmpty())
+ {
+ MessageRoutedEvent event = new MessageRoutedEvent(message);
+ int n = listeners.size();
+ for (int i = 0; i < n; ++i)
+ ((MessageRoutedListener)listeners.get(i)).messageRouted(event);
+ }
+ }
+}