| /* |
| * 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.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import flex.management.ManageableComponent; |
| import flex.management.runtime.messaging.services.ServiceControl; |
| import flex.messaging.log.LogCategories; |
| import flex.messaging.log.Log; |
| import flex.messaging.services.Service; |
| import flex.messaging.services.ServiceAdapter; |
| import flex.messaging.util.ClassUtil; |
| import flex.messaging.cluster.ClusterManager; |
| import flex.messaging.config.ClusterSettings; |
| import flex.messaging.config.ConfigMap; |
| import flex.messaging.config.ConfigurationConstants; |
| import flex.messaging.config.ConfigurationException; |
| import flex.messaging.config.NetworkSettings; |
| import flex.messaging.config.SecurityConstraint; |
| /** |
| * The <code>Destination</code> class is a source and sink for messages sent through |
| * a service destination and uses an adapter to process messages. |
| */ |
| public class Destination extends ManageableComponent implements java.io.Serializable |
| { |
| static final long serialVersionUID = -977001797620881435L; |
| |
| /** Default log category for <code>Destination</code>. */ |
| public static final String LOG_CATEGORY = LogCategories.SERVICE_GENERAL; |
| |
| /** Hard coded id for the push destination */ |
| public static final String PUSH_DESTINATION_ID = "_DS_PUSH_"; |
| |
| // Errors |
| private static final int NO_SERVICE = 11117; |
| |
| // Destination's properties |
| protected ServiceAdapter adapter; |
| protected List<String> channelIds; |
| protected NetworkSettings networkSettings; |
| protected SecurityConstraint securityConstraint; |
| protected String securityConstraintRef; |
| protected HashMap<String, Object> extraProperties; |
| protected boolean initialized; |
| protected boolean clustered; |
| protected boolean clusteredCalculated; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructs an unmanaged <code>Destination</code> instance. |
| */ |
| public Destination() |
| { |
| this(false); |
| } |
| |
| /** |
| * Constructs a <code>Destination</code> with the indicated management. |
| * |
| * @param enableManagement <code>true</code> if the <code>Destination</code> |
| * is manageable; otherwise <code>false</code>. |
| */ |
| public Destination(boolean enableManagement) |
| { |
| super(enableManagement); |
| |
| networkSettings = new NetworkSettings(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Initialize, validate, start, and stop methods. |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Initializes the <code>Destination</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 destination. |
| */ |
| @Override |
| public void initialize(String id, ConfigMap properties) |
| { |
| super.initialize(id, properties); |
| |
| if (properties == null || properties.size() == 0) |
| { |
| initialized = true; |
| return; |
| } |
| |
| ConfigMap network = properties.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null); |
| |
| if (network != null) |
| { |
| networkSettings.setReliable(network.getPropertyAsBoolean(NetworkSettings.RELIABLE_ELEMENT, false)); |
| |
| ConfigMap clusterInfo = network.getPropertyAsMap(ClusterSettings.CLUSTER_ELEMENT, null); |
| if (clusterInfo != null) |
| { |
| // Mark these as used so we do not get warnings about them. |
| network.allowProperty(ClusterSettings.CLUSTER_ELEMENT); |
| clusterInfo.allowProperty(ClusterSettings.REF_ATTR); |
| clusterInfo.allowProperty(ClusterSettings.SHARED_BACKEND_ATTR); |
| |
| String clusterId = clusterInfo.getPropertyAsString(ClusterSettings.REF_ATTR, null); |
| String coordinatorPolicy = clusterInfo.getPropertyAsString(ClusterSettings.SHARED_BACKEND_ATTR, null); |
| if (coordinatorPolicy != null) |
| networkSettings.setSharedBackend(Boolean.valueOf(coordinatorPolicy)); |
| |
| networkSettings.setClusterId(clusterId); |
| } |
| } |
| |
| initialized = true; |
| } |
| |
| /** |
| * Returns whether or not the destination has been initialized. |
| * |
| * @return True, if the destination has been initialized. |
| */ |
| public boolean isInitialized() |
| { |
| return initialized; |
| } |
| |
| /** |
| * Verifies that the <code>Destination</code> is in valid state before |
| * it is started. If subclasses override, they must call <code>super.validate()</code>. |
| */ |
| @Override |
| protected void validate() |
| { |
| if (isValid()) |
| return; |
| |
| super.validate(); |
| |
| if (getAdapter() == null) |
| { |
| String defaultAdapterId = getService().getDefaultAdapter(); |
| if (defaultAdapterId != null) |
| { |
| createAdapter(defaultAdapterId); |
| } |
| else |
| { |
| invalidate(); |
| // Destination '{id}' must specify at least one adapter. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(ConfigurationConstants.DEST_NEEDS_ADAPTER, new Object[]{getId()}); |
| throw ex; |
| } |
| } |
| |
| if (channelIds != null) |
| { |
| List<String> brokerChannelIds = getService().getMessageBroker().getChannelIds(); |
| for (Iterator<String> iter = channelIds.iterator(); iter.hasNext();) |
| { |
| String id = iter.next(); |
| if (brokerChannelIds == null || !brokerChannelIds.contains(id)) |
| { |
| iter.remove(); |
| if (Log.isWarn()) |
| { |
| Log.getLogger(getLogCategory()).warn("No channel with id '{0}' is known by the MessageBroker." + |
| " Removing the channel.", |
| new Object[]{id}); |
| } |
| } |
| } |
| } |
| |
| // Set the default channels if needed |
| if (channelIds == null) |
| { |
| List<String> defaultChannelIds = getService().getDefaultChannels(); |
| if (defaultChannelIds != null && defaultChannelIds.size() > 0) |
| { |
| setChannels(defaultChannelIds); |
| } |
| else |
| { |
| invalidate(); |
| // Destination '{id}' must specify at least one channel. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(ConfigurationConstants.DEST_NEEDS_CHANNEL, new Object[]{getId()}); |
| throw ex; |
| } |
| } |
| |
| MessageBroker broker = getService().getMessageBroker(); |
| |
| // Validate the security constraint |
| if (securityConstraint == null && securityConstraintRef != null) |
| { |
| securityConstraint = broker.getSecurityConstraint(securityConstraintRef); |
| // No need to throw an error as MessageBroker automatically throws |
| // an error if no such constraint exists |
| } |
| |
| ClusterManager cm = broker.getClusterManager(); |
| |
| // Set clustering if needed |
| if (getNetworkSettings().getClusterId() != null || cm.getDefaultClusterId() != null) |
| { |
| cm.clusterDestination(this); |
| } |
| } |
| |
| /** |
| * Starts the destination if its associated <code>Service</code> is started |
| * and if the destination is not already running. The default implementation |
| * of this method starts the adapter of the destination. If subclasses |
| * override, they must call <code>super.start()</code>. |
| */ |
| @Override |
| public void start() |
| { |
| if (isStarted()) |
| { |
| // Needed for adapters added after startup. |
| getAdapter().start(); |
| return; |
| } |
| |
| // Check if the Service is started |
| Service service = getService(); |
| if (!service.isStarted()) |
| { |
| if (Log.isWarn()) |
| { |
| Log.getLogger(getLogCategory()).warn("Destination with id '{0}' cannot be started" + |
| " when its Service with id '{1}' is not started.", |
| new Object[]{getId(), service.getId()}); |
| } |
| return; |
| } |
| |
| // Set up management |
| if (isManaged() && service.isManaged()) |
| { |
| setupDestinationControl(service); |
| ServiceControl controller = (ServiceControl)service.getControl(); |
| if (getControl() != null) |
| controller.addDestination(getControl().getObjectName()); |
| } |
| |
| super.start(); |
| |
| getAdapter().start(); |
| } |
| |
| /** |
| * The default implementation of this method stops all of the adapters |
| * of the destination. |
| * If subclasses override, they must call <code>super.stop()</code>. |
| * |
| */ |
| @Override |
| public void stop() |
| { |
| if (!isStarted()) |
| return; |
| |
| getAdapter().stop(); |
| |
| super.stop(); |
| |
| // Remove management |
| if (isManaged() && getService().isManaged()) |
| { |
| if (getControl() != null) |
| { |
| getControl().unregister(); |
| setControl(null); |
| } |
| setManaged(false); |
| } |
| |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Public Getters and Setters for Destination properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns the <code>ServiceAdapter</code> for the <code>Destination</code>. |
| * |
| * @return The <code>ServiceAdapter</code> for the <code>Destination</code>. |
| */ |
| public ServiceAdapter getAdapter() |
| { |
| return adapter; |
| } |
| |
| /** |
| * Creates a <code>ServiceAdapter</code> instance, sets its id, sets it manageable |
| * if the <code>Destination</code> that created it is manageable, |
| * and set its <code>Destination</code> to the <code>Destination</code> that |
| * created it. |
| * |
| * In order to use this method, <code>Destination</code> should have an assigned |
| * <code>Service</code> and the id provided for the adapter should already |
| * be registered with the <code>Service</code>. |
| * |
| * @param id The id of the <code>ServiceAdapter</code>. |
| * @return The <code>ServiceAdapter</code> instanced created. |
| */ |
| public ServiceAdapter createAdapter(String id) |
| { |
| if (getService() == null) |
| { |
| // Destination cannot create adapter '{0}' without its Service set. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(NO_SERVICE, new Object[]{id}); |
| throw ex; |
| } |
| Map<String, String> adapterClasses = getService().getRegisteredAdapters(); |
| if (!adapterClasses.containsKey(id)) |
| { |
| // No adapter with id '{0}' is registered with the service '{1}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(ConfigurationConstants.UNREGISTERED_ADAPTER, new Object[]{id, getService().getId()}); |
| throw ex; |
| } |
| |
| String adapterClassName = adapterClasses.get(id); |
| Class<?> adapterClass = ClassUtil.createClass(adapterClassName, |
| FlexContext.getMessageBroker() == null ? |
| null : FlexContext.getMessageBroker().getClassLoader()); |
| |
| ServiceAdapter adapter = (ServiceAdapter)ClassUtil.createDefaultInstance(adapterClass, ServiceAdapter.class); |
| adapter.setId(id); |
| adapter.setManaged(isManaged()); |
| adapter.setDestination(this); |
| |
| return adapter; |
| } |
| |
| /** |
| * Sets the <code>ServiceAdapter</code> of the <code>Destination</code>. |
| * |
| * <code>ServiceAdapter</code> needs to be started if the <code>Destination</code> |
| * is already running. |
| * |
| * @param adapter The adapter for the destination. |
| */ |
| public void setAdapter(ServiceAdapter adapter) |
| { |
| if (getAdapter() == adapter) // No need to reset the adapter. |
| return; |
| |
| if (adapter == null) |
| { |
| removeAdapter(); |
| return; |
| } |
| |
| addAdapter(adapter); |
| } |
| |
| /** |
| * Used by setAdapter and it removes the old adapter of the destination |
| * and adds the new adapter. |
| * |
| * @param adapter The adapter for the destination. |
| */ |
| private void addAdapter(ServiceAdapter adapter) |
| { |
| removeAdapter(); |
| |
| this.adapter = adapter; |
| |
| if (adapter.getDestination() == null || adapter.getDestination() != this) |
| adapter.setDestination(this); |
| } |
| |
| /** |
| * Used by setAdapter and addAdapter. It removes the current adapter |
| * of the destination |
| */ |
| private void removeAdapter() |
| { |
| ServiceAdapter adapter = getAdapter(); |
| if (adapter != null) |
| { |
| adapter.stop(); |
| } |
| this.adapter = null; |
| } |
| |
| |
| /** |
| * The destination may be not clustered at all, may be clustered for channel failover and |
| * destination sharing, or it may be clustered for channel failover and also have a |
| * common backend, such as a common database or backend clustered JMS topic. |
| * If the destination is clustered and has a common backend to coordinate the cluster, |
| * this method returns true; otherwise it return false. Note that this method returns |
| * <code>false</code> if the <code>Destination</code> is not runnning. |
| * |
| * @return <code>true</code> if the clustered <code>Destination</code> shares a common backend; |
| * otherwise <code>false</code>. |
| */ |
| public boolean isBackendShared() |
| { |
| if (!isStarted()) |
| return false; |
| |
| ClusterManager clm = getService().getMessageBroker().getClusterManager(); |
| return clm.isBackendShared(getService().getClass().getName(), getId()); |
| } |
| |
| /** |
| * Returns the list of channel ids of the <code>Destination</code>. |
| * |
| * @return The list of channel ids of the <code>Destination</code>. |
| */ |
| public List<String> getChannels() |
| { |
| return channelIds; |
| } |
| |
| /** |
| * Adds a channel to the list of channels known by the <code>Destination</code>. |
| * <code>MessageBroker</code> has to know the channel. Otherwise, the channel |
| * is not added to the list. |
| * |
| * @param id The id of the channel. |
| */ |
| public void addChannel(String id) |
| { |
| if (channelIds == null) |
| channelIds = new ArrayList<String>(); |
| else if (channelIds.contains(id)) |
| return; |
| |
| if (isStarted()) |
| { |
| List<String> brokerChannelIds = getService().getMessageBroker().getChannelIds(); |
| if (brokerChannelIds == null || !brokerChannelIds.contains(id)) |
| { |
| if (Log.isWarn()) |
| { |
| Log.getLogger(getLogCategory()).warn("No channel with id '{0}' is known by the MessageBroker." + |
| " Not adding the channel.", |
| new Object[]{id}); |
| } |
| return; |
| } |
| } |
| // Either message broker knows about the channel, or destination is not |
| // running and channel will be checked before startup during validate |
| channelIds.add(id); |
| } |
| |
| /** |
| * Removes the channel from the list of channels for the <code>Destination</code>. |
| * |
| * @param id The id of the channel. |
| * @return <code>true</code> if the list contained the channel id. |
| */ |
| public boolean removeChannel(String id) |
| { |
| return channelIds != null && channelIds.remove(id); |
| } |
| |
| /** |
| * Sets the channel list of the <code>Destination</code>. |
| * <code>MessageBroker</code> has to know the channels, otherwise they |
| * are not added to the list. |
| * |
| * @param ids List of channel ids. |
| */ |
| public void setChannels(List<String> ids) |
| { |
| if (ids != null && isStarted()) |
| { |
| List<String> brokerChannelIds = getService().getMessageBroker().getChannelIds(); |
| for (Iterator<String> iter = ids.iterator(); iter.hasNext();) |
| { |
| String id = iter.next(); |
| if (brokerChannelIds == null || !brokerChannelIds.contains(id)) |
| { |
| iter.remove(); |
| if (Log.isWarn()) |
| { |
| Log.getLogger(getLogCategory()).warn("No channel with id '{0}' is known by the MessageBroker." + |
| " Not adding the channel.", |
| new Object[]{id}); |
| } |
| } |
| } |
| } |
| // Otherwise, channels will be checked before startup during validate |
| channelIds = ids; |
| } |
| |
| /** |
| * The destination may be not clustered at all, may be clustered for channel failover |
| * only, or it may be clustered for channel failover and also have shared back ends. |
| * If the destination is clustered, regardless of whether or not it relies on a shared |
| * back end for cluster configuration, this method returns true. Note that this method |
| * returns <code>false</code> if the <code>Destination</code> is not runnning. |
| * |
| * @return <code>true</code> if the <code>Destination</code> is clustered; otherwise <code>false</code>. |
| */ |
| public boolean isClustered() |
| { |
| if (!isStarted()) |
| return false; |
| |
| if (!clusteredCalculated) |
| { |
| ClusterManager clm = getService().getMessageBroker().getClusterManager(); |
| clustered = clm.isDestinationClustered(getService().getClass().getName(), getId()); |
| clusteredCalculated = true; |
| } |
| return clustered; |
| } |
| |
| /** |
| * Sets the id of the <code>Destination</code>. If the <code>Destination</code> |
| * has a <code>Service</code> assigned, it also updates the id in the |
| * <code>Service</code>. |
| * |
| * @param id The id of the <code>Destination</code>. |
| */ |
| @Override |
| public void setId(String id) |
| { |
| String oldId = getId(); |
| |
| super.setId(id); |
| |
| // Update the destination id in the service and MessageBroker |
| Service service = getService(); |
| if (service != null) |
| { |
| service.removeDestination(oldId); |
| service.addDestination(this); |
| } |
| } |
| |
| /** |
| * Get the <code>NetworkSettings</code> of the <code>Destination</code>. |
| * |
| * @return The <code>NetworkSettings</code> of the <code>Destination</code>. |
| */ |
| public NetworkSettings getNetworkSettings() |
| { |
| return networkSettings; |
| } |
| |
| /** |
| * Set the <code>NetworkSettings</code> of the <code>Destination</code>. |
| * |
| * @param networkSettings The <code>NetworkSettings</code> of the <code>Destination</code>. |
| */ |
| public void setNetworkSettings(NetworkSettings networkSettings) |
| { |
| this.networkSettings = networkSettings; |
| } |
| |
| /** |
| * Returns the <code>Service</code> managing this <code>Destination</code>. |
| * |
| * @return The <code>Service</code> managing this <code>Destination</code>. |
| */ |
| public Service getService() |
| { |
| return (Service)getParent(); |
| } |
| |
| /** |
| * Sets the <code>Service</code> managing this <code>Destination</code>. |
| * Removes the <code>Destination</code> from the old service |
| * (if there was one) and adds to the list of destination in the new service. |
| * |
| * @param service The <code>Service</code> managing this <code>Destination</code>. |
| */ |
| public void setService(Service service) |
| { |
| Service oldService = getService(); |
| |
| setParent(service); |
| |
| if (oldService != null) |
| oldService.removeDestination(getId()); |
| |
| // Add the destination to the service if needed |
| if (service.getDestination(getId()) != this) |
| service.addDestination(this); |
| } |
| |
| /** |
| * Returns the Java class name for the <code>Service</code> managing this |
| * <code>Destination</code>. Returns null if there is no <code>Service</code> |
| * assigned to the <code>Destination</code> yet. |
| * |
| * @return The Java class name for the <code>Service</code> manageing this <code>Destination</code>. |
| */ |
| public String getServiceType() |
| { |
| Service service = getService(); |
| return service != null? service.getClass().getName() : null; |
| } |
| |
| /** |
| * Returns the <code>SecurityConstraint</code> of the <code>Destination</code>. |
| * <code>SecurityConstraint</code> is constructed as the <code>Destination</code> |
| * starts up. Therefore, this could return null even if the <code>SecurityConstraint</code> |
| * reference is set but <code>Destination</code> is not started yet. |
| * |
| * @return The <code>SecurityConstraint</code> of the <code>Destination</code>. |
| */ |
| public SecurityConstraint getSecurityConstraint() |
| { |
| return securityConstraint; |
| } |
| |
| /** |
| * Sets the <code>SecurityConstraint</code> of the <code>Destination</code>. |
| * |
| * @param securityConstraint The <code>SecurityConstraint</code> of the <code>Destination</code>. |
| */ |
| public void setSecurityConstraint(SecurityConstraint securityConstraint) |
| { |
| this.securityConstraint = securityConstraint; |
| } |
| |
| /** |
| * Sets the <code>SecurityConstraint</code> reference of the <code>Destination</code>. |
| * <code>MessageBroker</code> has to know the <code>SecurityConstraint</code> |
| * reference. Note that <code>getSecurityConstraint</code> can return null |
| * if the reference is set but the <code>Destination</code> is not started yet. |
| * |
| * @param ref <code>SecurityConstraint</code> reference. |
| */ |
| public void setSecurityConstraint(String ref) |
| { |
| if (isStarted()) |
| { |
| MessageBroker msgBroker = getService().getMessageBroker(); |
| securityConstraint = msgBroker.getSecurityConstraint(ref); |
| // No need to throw an error as MessageBroker automatically throws |
| // an error if no such constraint exists |
| } |
| securityConstraintRef = ref; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Other public APIs |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Calls {@link Destination#describeDestination(boolean)} with true boolean value. |
| * |
| * @return A <tt>ConfigMap</tt> of destination properties that the client needs. |
| * @see flex.messaging.Destination#describeDestination(boolean) |
| */ |
| public ConfigMap describeDestination() |
| { |
| return describeDestination(true); |
| } |
| |
| /** |
| * Returns a <tt>ConfigMap</tt> of destination properties that the client |
| * needs. Subclasses can add additional properties to <tt>super.describeDestination(boolean)</tt>, |
| * or return null if they don't want their properties to be sent to the client. |
| * |
| * @param onlyReliable Determines whether only reliable destination configuration should be returned. |
| * @return A <tt>ConfigMap</tt> of destination properties that the client needs. |
| */ |
| public ConfigMap describeDestination(boolean onlyReliable) |
| { |
| boolean reliable = networkSettings != null && networkSettings.isReliable(); |
| if (onlyReliable && !reliable) |
| return null; |
| |
| ConfigMap destinationConfig = new ConfigMap(); |
| destinationConfig.addProperty(ConfigurationConstants.ID_ATTR, getId()); |
| |
| // Include network settings if reliability for the destination is enabled. |
| if (reliable) |
| { |
| ConfigMap properties = new ConfigMap(); |
| ConfigMap network = new ConfigMap(); |
| |
| ConfigMap reliableMap = new ConfigMap(); |
| // Adding as a value rather than attribute to the parent |
| reliableMap.addProperty(ConfigurationConstants.EMPTY_STRING, Boolean.toString(networkSettings.isReliable())); |
| |
| network.addProperty(NetworkSettings.RELIABLE_ELEMENT, reliableMap); |
| properties.addProperty(NetworkSettings.NETWORK_ELEMENT, network); |
| |
| destinationConfig.addProperty(ConfigurationConstants.PROPERTIES_ELEMENT, properties); |
| } |
| |
| ConfigMap channelsConfig = new ConfigMap(); |
| for (String id : channelIds) |
| { |
| ConfigMap channelConfig = new ConfigMap(); |
| channelConfig.addProperty(ConfigurationConstants.REF_ATTR, id); |
| channelsConfig.addProperty(ConfigurationConstants.CHANNEL_ELEMENT, channelConfig); |
| } |
| |
| if (channelsConfig.size() > 0) |
| destinationConfig.addProperty(ConfigurationConstants.CHANNELS_ELEMENT, channelsConfig); |
| |
| return destinationConfig; |
| } |
| |
| /** |
| * Method for setting an extra property for the destination at runtime. |
| * |
| * @param name The name of the property. |
| * @param value The value of the property. |
| */ |
| public void addExtraProperty(String name, Object value) |
| { |
| if (extraProperties == null) |
| { |
| extraProperties = new HashMap<String, Object>(); |
| } |
| |
| extraProperties.put(name, value); |
| } |
| |
| /** |
| * Method for getting an extra property at runtime. |
| * |
| * @param name The name of the property. |
| * @return The value of the property or null if the property does not exist. |
| */ |
| public Object getExtraProperty(String name) |
| { |
| return extraProperties != null? extraProperties.get(name) : null; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Protected/private APIs |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns the log category of the <code>Destination</code>. Subclasses |
| * can override to provide a more specific log category. |
| * |
| * @return The log category. |
| */ |
| @Override |
| protected String getLogCategory() |
| { |
| return LOG_CATEGORY; |
| } |
| |
| /** |
| * Invoked automatically to allow the <code>Destination</code> to setup its corresponding |
| * MBean control. Subclasses should override to setup and register their MBean control. |
| * |
| * @param service The <code>Service</code> that manages this <code>Destination</code>. |
| */ |
| protected void setupDestinationControl(Service service) |
| { |
| // Manageable subclasses should override this template method. |
| setManaged(false); |
| } |
| } |