| /* |
| * 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.services; |
| |
| import flex.management.ManageableComponent; |
| import flex.management.runtime.messaging.DestinationControl; |
| import flex.messaging.Destination; |
| import flex.messaging.log.Log; |
| import flex.messaging.messages.AcknowledgeMessage; |
| import flex.messaging.messages.CommandMessage; |
| import flex.messaging.messages.Message; |
| |
| /** |
| * The ServiceAdapter class is the base definition of a service adapter. |
| */ |
| public abstract class ServiceAdapter extends ManageableComponent { |
| /** |
| * Log category for <code>ServiceAdapter</code>. |
| */ |
| public static final String LOG_CATEGORY = Destination.LOG_CATEGORY; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructs an unmanaged <code>ServiceAdapter</code> instance. |
| */ |
| public ServiceAdapter() { |
| this(false); |
| } |
| |
| /** |
| * Constructs a <code>ServiceAdapter</code> instance. |
| * |
| * @param enableManagement <code>true</code> if the <code>ServiceAdapter</code> has a |
| * corresponding MBean control for management; otherwise <code>false</code>. |
| */ |
| public ServiceAdapter(boolean enableManagement) { |
| super(enableManagement); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Initialize, validate, start, and stop methods. |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Verifies that the <code>ServiceAdapter</code> is in valid state before |
| * it is started. If subclasses override, they must call <code>super.validate()</code>. |
| */ |
| protected void validate() { |
| if (isValid()) |
| return; |
| |
| super.validate(); |
| } |
| |
| /** |
| * Starts the adapter if its associated <code>Destination</code> is started |
| * and if the adapter is not already running. If subclasses override, they |
| * must call <code>super.start()</code>. |
| */ |
| public void start() { |
| if (isStarted()) { |
| return; |
| } |
| |
| // Check if the Destination is started |
| Destination destination = getDestination(); |
| if (!destination.isStarted()) { |
| if (Log.isWarn()) { |
| Log.getLogger(getLogCategory()).warn("Adapter with id '{0}' cannot be started" + |
| " when its Destination with id '{1}' is not started.", |
| new Object[]{getId(), destination.getId()}); |
| } |
| return; |
| } |
| |
| // Set up management |
| if (isManaged() && destination.isManaged()) { |
| setupAdapterControl(destination); |
| DestinationControl controller = (DestinationControl) destination.getControl(); |
| if (getControl() != null) |
| controller.setAdapter(getControl().getObjectName()); |
| |
| } |
| |
| super.start(); |
| } |
| |
| /** |
| * Stops the <code>ServiceAdapter</code>. |
| * If subclasses override, they must call <code>super.start()</code>. |
| */ |
| public void stop() { |
| if (!isStarted()) { |
| return; |
| } |
| |
| super.stop(); |
| |
| // Remove management |
| if (isManaged() && getDestination().isManaged()) { |
| if (getControl() != null) { |
| getControl().unregister(); |
| setControl(null); |
| } |
| setManaged(false); |
| } |
| |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Public Getters and Setters for AbstractService properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns the <code>Destination</code> of the <code>ServiceAdapter</code>. |
| * |
| * @return The <code>Destination</code> of the <code>ServiceAdapter</code>. |
| */ |
| public Destination getDestination() { |
| return (Destination) getParent(); |
| } |
| |
| /** |
| * Sets the <code>Destination</code> of the <code>ServiceAdapter</code>. |
| * Also sets the <code>ServiceAdapter</code> of the <code>Destination</code> |
| * if needed. |
| * |
| * @param destination The <code>Destination</code> of the <code>ServiceAdapter</code>. |
| */ |
| public void setDestination(Destination destination) { |
| Destination oldDestination = getDestination(); |
| |
| setParent(destination); |
| |
| if (oldDestination != null) |
| oldDestination.setAdapter(null); |
| |
| // Set destination's adapter if needed |
| if (destination.getAdapter() != this) { |
| destination.setAdapter(this); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Other Public APIs |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Handle a data message intended for this adapter. This method is responsible |
| * for handling the message and returning a result (if any). The return value |
| * of this message is used as the body of the acknowledge message returned to |
| * the client. It may be null if there is no data being returned for this message. |
| * <p> |
| * Typically the data content for the message is stored in the body property |
| * of the message. The headers of the message are used to store fields which relate |
| * to the transport of the message. The type of operation is stored as the |
| * operation property of the message. |
| * </p> |
| * |
| * @param message the message as sent by the client intended for this adapter |
| * @return the body of the acknowledge message (or null if there is no body) |
| * @see flex.messaging.messages.Message |
| * @see flex.messaging.messages.AsyncMessage |
| */ |
| public abstract Object invoke(Message message); |
| |
| |
| /** |
| * Accept a command from the adapter's service and perform some |
| * internal action based upon it. CommandMessages are used for messages |
| * which control the state of the connection between the client and |
| * the server. For example, this lets the adapter perform processing with |
| * subscribe, unsubscribe, and poll operations. For subscribe and unsubscribe, |
| * this method is only called if handlesSubscriptions returns true. |
| * <p> |
| * The service will perform some processing on the message before and after it |
| * calls this method. For subscribe messages the MessageService |
| * will register a subscription after this method returns successfully. |
| * For unsubscribe messages, the MessageService will unsubscribe after this |
| * method returns successfully. For both of these messages, this method |
| * can return null or it can return the AcknowledgeMessage to send to the client |
| * for the reply to this operation. If a MultiTopicConsumer is used on the |
| * client, this method will receive a MULTI_SUBSCRIBE message. |
| * </p><p> |
| * For POLL operations, this method can return a list of messages to be |
| * added to the set returned to the client for this poll. If it returns |
| * null, it means no messages are to be added to the set already queued |
| * up for this client. |
| * </p> |
| * |
| * @param commandMessage The command message to manage. |
| * @return The result of manage. The default implementation returns null. |
| * @see flex.messaging.messages.CommandMessage |
| * @see flex.messaging.messages.AsyncMessage |
| */ |
| public Object manage(CommandMessage commandMessage) { |
| return null; |
| } |
| |
| /** |
| * Return an object, usually a Collection, representing any |
| * shared state for the adapter. If adapters have shared state, |
| * they should override this method, as the default implementation |
| * throws an UnsupportedOperationException. |
| * |
| * @return The state of the adapter. The default implementations throws |
| * <code>UnsupportedOperationException</code>. |
| */ |
| public Object getAdapterState() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Set an object, usually a Collection, to represent shared |
| * state for the adapter. If adapters have shared state, |
| * they should override this method, as the default implementation |
| * throws an UnsupportedOperationException. |
| * |
| * @param adapterState The object representing the adapter state. |
| */ |
| public void setAdapterState(Object adapterState) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Returns <code>true</code> if the adapter performs custom subscription management. |
| * The default return value is <code>false</code>, and subclasses should override this |
| * method as necessary. |
| * |
| * @return <code>true</code> if the adapter performs custom subscription management. |
| * The default return value is <code>false</code>. |
| */ |
| public boolean handlesSubscriptions() { |
| return false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Protected/private APIs |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns the log category of the <code>ServiceAdapter</code>. Subclasses |
| * can override to provide a more specific logging category. |
| * |
| * @return The log category. |
| */ |
| protected String getLogCategory() { |
| return LOG_CATEGORY; |
| } |
| |
| /** |
| * Managed subclasses should override this method to setup and |
| * register their corresponding MBean control. |
| * |
| * @param destination The associated <code>Destination</code> for the adapter. |
| */ |
| protected void setupAdapterControl(Destination destination) { |
| setManaged(false); |
| } |
| |
| } |