| /* |
| * 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.shared.ldap.model.message; |
| |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.directory.shared.ldap.model.exception.MessageException; |
| |
| |
| /** |
| * Abstract message base class. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public abstract class AbstractMessage implements Message |
| { |
| private static final long serialVersionUID = 7601738291101182094L; |
| |
| /** 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 ) throws MessageException |
| { |
| controls.put( control.getOid(), control ); |
| |
| return this; |
| } |
| |
| |
| /** |
| * Deletes a control removing it from this Message. |
| * |
| * @param control the control to remove. |
| * @throws MessageException if controls cannot be added to this Message or the control is |
| * not known etc. |
| */ |
| public Message removeControl( Control control ) throws MessageException |
| { |
| 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> controls = msg.getControls(); |
| |
| if ( controls.size() != this.controls.size() ) |
| { |
| return false; |
| } |
| |
| for ( String key : this.controls.keySet() ) |
| { |
| if ( ! controls.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 ) throws MessageException |
| { |
| 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(); |
| } |
| } |