flex.messaging.services.ServiceAdapter Maven / Gradle / Ivy
/*
* 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 ServiceAdapter
. */
public static final String LOG_CATEGORY = Destination.LOG_CATEGORY;
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructs an unmanaged ServiceAdapter
instance.
*/
public ServiceAdapter()
{
this(false);
}
/**
* Constructs a ServiceAdapter
instance.
*
* @param enableManagement true
if the ServiceAdapter
has a
* corresponding MBean control for management; otherwise false
.
*/
public ServiceAdapter(boolean enableManagement)
{
super(enableManagement);
}
//--------------------------------------------------------------------------
//
// Initialize, validate, start, and stop methods.
//
//--------------------------------------------------------------------------
/**
* Verifies that the ServiceAdapter
is in valid state before
* it is started. If subclasses override, they must call super.validate()
.
*
*/
protected void validate()
{
if (isValid())
return;
super.validate();
}
/**
* Starts the adapter if its associated Destination
is started
* and if the adapter is not already running. If subclasses override, they
* must call super.start()
.
*/
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 ServiceAdapter
.
* If subclasses override, they must call super.start()
.
*
*/
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 Destination
of the ServiceAdapter
.
*
* @return The Destination
of the ServiceAdapter
.
*/
public Destination getDestination()
{
return (Destination)getParent();
}
/**
* Sets the Destination
of the ServiceAdapter
.
* Also sets the ServiceAdapter
of the Destination
* if needed.
*
* @param destination The Destination
of the ServiceAdapter
.
*/
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.
*
* 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.
*
*
* @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.
*
* 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.
*
* 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.
*
*
* @see flex.messaging.messages.CommandMessage
* @see flex.messaging.messages.AsyncMessage
*
* @param commandMessage The command message to manage.
* @return The result of manage. The default implementation returns null.
*/
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
* UnsupportedOperationException
.
*/
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 true
if the adapter performs custom subscription management.
* The default return value is false
, and subclasses should override this
* method as necessary.
*
* @return true
if the adapter performs custom subscription management.
* The default return value is false
.
*/
public boolean handlesSubscriptions()
{
return false;
}
//--------------------------------------------------------------------------
//
// Protected/private APIs
//
//--------------------------------------------------------------------------
/**
* Returns the log category of the ServiceAdapter
. 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 Destination
for the adapter.
*/
protected void setupAdapterControl(Destination destination)
{
setManaged(false);
}
}