blob: b6191e548ba6ec3fd102c2db4036de60ca36b792 [file] [log] [blame]
/*
* 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 org.apache.directory.api.ldap.model.message;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Abstract message base class.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public abstract class AbstractMessage implements Message
{
/** Map of message controls using OID Strings for keys and Control values */
protected final Map<String, Control> controls;
/** The session unique message sequence identifier */
private int id;
/** The message type enumeration */
private final MessageTypeEnum type;
/** Transient Message Parameter Hash */
private final Map<Object, Object> parameters;
/**
* Completes the instantiation of a Message.
*
* @param id the seq id of the message
* @param type the type of the message
*/
protected AbstractMessage( final int id, final MessageTypeEnum type )
{
this.id = id;
this.type = type;
controls = new HashMap<String, Control>();
parameters = new HashMap<Object, Object>();
}
/**
* Gets the session unique message sequence id for this message. Requests
* and their responses if any have the same message id. Clients at the
* initialization of a session start with the first message's id set to 1
* and increment it with each transaction.
*
* @return the session unique message id.
*/
public int getMessageId()
{
return id;
}
/**
* {@inheritDoc}
*/
public Message setMessageId( int id )
{
this.id = id;
return this;
}
/**
* {@inheritDoc}
*/
public Map<String, Control> getControls()
{
return Collections.unmodifiableMap( controls );
}
/**
* {@inheritDoc}
*/
public Control getControl( String oid )
{
return controls.get( oid );
}
/**
* {@inheritDoc}
*/
public boolean hasControl( String oid )
{
return controls.containsKey( oid );
}
/**
* {@inheritDoc}
*/
public Message addControl( Control control )
{
controls.put( control.getOid(), control );
return this;
}
/**
* Deletes a control removing it from this Message.
*
* @param control the control to remove.
*/
public Message removeControl( Control control )
{
controls.remove( control.getOid() );
return this;
}
/**
* Gets the LDAP message type code associated with this Message. Each
* request and response type has a unique message type code defined by the
* protocol in <a href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a>.
*
* @return the message type code.
*/
public MessageTypeEnum getType()
{
return type;
}
/**
* Gets a message scope parameter. Message scope parameters are temporary
* variables associated with a message and are set locally to be used to
* associate housekeeping information with a request or its processing.
* These parameters are never transmitted nor received, think of them as
* transient data associated with the message or its processing. These
* transient parameters are not locked down so modifications can occur
* without firing LockExceptions even when this Lockable is in the locked
* state.
*
* @param key the key used to access a message parameter.
* @return the transient message parameter value.
*/
public Object get( Object key )
{
return parameters.get( key );
}
/**
* Sets a message scope parameter. These transient parameters are not locked
* down so modifications can occur without firing LockExceptions even when
* this Lockable is in the locked state.
*
* @param key the parameter key
* @param value the parameter value
* @return the old value or null
*/
public Object put( Object key, Object value )
{
return parameters.put( key, value );
}
/**
* Checks to see if two messages are equivalent. Messages equivalence does
* not factor in parameters accessible through the get() and put()
* operations, nor do they factor in the Lockable properties of the Message.
* Only the type, controls, and the messageId are evaluated for equality.
*
* @param obj the object to compare this Message to for equality
*/
public boolean equals( Object obj )
{
if ( obj == this )
{
return true;
}
if ( ( obj == null ) || !( obj instanceof Message ) )
{
return false;
}
Message msg = ( Message ) obj;
if ( msg.getMessageId() != id )
{
return false;
}
if ( msg.getType() != type )
{
return false;
}
Map<String, Control> controlMap = msg.getControls();
if ( controlMap.size() != controls.size() )
{
return false;
}
for ( String key : controls.keySet() )
{
if ( !controlMap.containsKey( key ) )
{
return false;
}
}
return true;
}
/**
* @see Object#hashCode()
* @return the instance's hash code
*/
public int hashCode()
{
int hash = 37;
hash = hash * 17 + id;
hash = hash * 17 + ( type == null ? 0 : type.hashCode() );
hash = hash * 17 + ( parameters == null ? 0 : parameters.hashCode() );
hash = hash * 17 + ( controls == null ? 0 : controls.hashCode() );
return hash;
}
/**
* {@inheritDoc}
*/
public Message addAllControls( Control[] controls )
{
for ( Control c : controls )
{
this.controls.put( c.getOid(), c );
}
return this;
}
/**
* Get a String representation of a LdapMessage
*
* @return A LdapMessage String
*/
public String toString( String message )
{
StringBuilder sb = new StringBuilder();
sb.append( "MessageType : " ).append( type ).append( '\n' );
sb.append( "Message ID : " ).append( id ).append( '\n' );
sb.append( message );
if ( controls != null )
{
for ( Control control : controls.values() )
{
sb.append( control );
}
}
return sb.toString();
}
}