blob: 00be9e0b2e011b6d42b6b482754c171cd8a33e6d [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.server.core.entry;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.naming.NamingException;
//import javax.naming.directory.DirContext;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.entry.Modification;
import org.apache.directory.shared.ldap.entry.ModificationOperation;
import org.apache.directory.shared.ldap.entry.client.ClientModification;
import org.apache.directory.shared.ldap.schema.AttributeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An internal implementation for a ModificationItem. The name has been
* chosen so that it does not conflict with @see ModificationItem
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class ServerModification implements Modification
{
public static final long serialVersionUID = 1L;
/** logger for reporting errors that might not be handled properly upstream */
private static final Logger LOG = LoggerFactory.getLogger( ServerModification.class );
/** The modification operation */
private ModificationOperation operation;
/** The attribute which contains the modification */
private EntryAttribute attribute;
//-------------------------------------------------------------------------
// Constructors
//-------------------------------------------------------------------------
/**
* Create a new instance of a ServerModification.
*/
public ServerModification()
{
}
/**
* Create a new instance of a ServerModification.
*
* @param operation the Modification operation (one of add, replace or remove)
* @param attribute the modified attribute
*/
public ServerModification( ModificationOperation operation, EntryAttribute attribute )
{
this.operation = operation;
this.attribute = attribute;
}
public ServerModification( Registries registries, Modification modification )
{
operation = modification.getOperation();
EntryAttribute modAttribute = modification.getAttribute();
try
{
AttributeType at = null;
if ( modAttribute instanceof ServerAttribute )
{
at = ((ServerAttribute)modAttribute).getAttributeType();
}
else
{
at = registries.getAttributeTypeRegistry().lookup( modAttribute.getId() );
}
attribute = new DefaultServerAttribute( at, modAttribute );
}
catch ( NamingException ne )
{
// The attributeType is incorrect. Log, but do nothing otherwise.
LOG.error( "The attribute '" + modAttribute.getId() + "' is incorrect" );
}
}
//-------------------------------------------------------------------------
// API
//-------------------------------------------------------------------------
/**
* @return the operation
*/
public ModificationOperation getOperation()
{
return operation;
}
/**
* Store the modification operation
*
* @param operation The DirContext value to assign
*/
public void setOperation( int operation )
{
this.operation = ModificationOperation.getOperation( operation );
}
/**
* Store the modification operation
*
* @param operation The DirContext value to assign
*/
public void setOperation( ModificationOperation operation )
{
this.operation = operation;
}
/**
* @return the attribute containing the modifications
*/
public EntryAttribute getAttribute()
{
return attribute;
}
/**
* Set the attribute's modification
*
* @param attribute The modified attribute
*/
public void setAttribute( EntryAttribute attribute )
{
this.attribute = (ServerAttribute)attribute;
}
/**
* Convert the current ServerModification to a ClientModification instance
*
* @return a new ClientModification instance
*/
public Modification toClientModification()
{
ModificationOperation newOperation = operation;
EntryAttribute newAttribute = ((ServerAttribute)attribute).toClientAttribute();
Modification newModification = new ClientModification( newOperation, newAttribute );
return newModification;
}
//-------------------------------------------------------------------------
// Overloaded Object class methods
//-------------------------------------------------------------------------
/**
* Compute the modification @see Object#hashCode
* @return the instance's hash code
*/
public int hashCode()
{
int h = 37;
h += h*17 + operation.getValue();
h += h*17 + attribute.hashCode();
return h;
}
/**
* @see Object#equals(Object)
*/
public boolean equals( Object that )
{
// Shortcut
if ( this == that )
{
return true;
}
if ( ! ( that instanceof ServerModification ) )
{
return false;
}
ServerModification modification = (ServerModification)that;
if ( operation != modification.getOperation() )
{
return false;
}
if ( attribute == null )
{
return modification.getAttribute() == null;
}
return attribute.equals( modification.getAttribute() );
}
/**
* Create a clone instance
*/
public ServerModification clone()
{
try
{
ServerModification clone = (ServerModification)super.clone();
clone.attribute = (ServerAttribute)this.attribute.clone();
return clone;
}
catch ( CloneNotSupportedException cnse )
{
return null;
}
}
/**
* @see java.io.Externalizable#writeExternal(ObjectOutput)
*
* We can't use this method for a ServerModification.
*/
public void writeExternal( ObjectOutput out ) throws IOException
{
throw new IllegalStateException( "Cannot use standard serialization for a ServerEntry" );
}
/**
* @see java.io.Externalizable#readExternal(ObjectInput)
*
* We can't use this method for a ServerModification.
*/
public void readExternal( ObjectInput in ) throws IOException
{
throw new IllegalStateException( "Cannot use standard serialization for a ServerEntry" );
}
/**
* Deserialize a ServerModification
*
* @param in The buffer containing the serialized value
* @param atRegistry The AttributeType registry
* @throws IOException If we weren't able to deserialize the data
* @throws ClassNotFoundException if we weren't able to construct a Modification instance
* @throws NamingException If we didn't found the AttributeType in the registries
*/
public void deserialize( ObjectInput in, AttributeTypeRegistry atRegistry ) throws IOException, ClassNotFoundException, NamingException
{
// Read the operation
int op = in.readInt();
operation = ModificationOperation.getOperation( op );
// Read the attribute OID
String oid = in.readUTF();
// Lookup for tha associated AttributeType
AttributeType attributeType = atRegistry.lookup( oid );
attribute = new DefaultServerAttribute( attributeType );
// Read the attribute
((DefaultServerAttribute)attribute).deserialize( in );
}
/**
* Serialize a ServerModification.
*/
public void serialize( ObjectOutput out ) throws IOException
{
if ( attribute == null )
{
throw new IOException( "Cannot serialize a Modification with no attribute" );
}
// Write the operation
out.writeInt( operation.getValue() );
AttributeType at = ((DefaultServerAttribute)attribute).getAttributeType();
// Write the attribute's oid
out.writeUTF( at.getOid() );
// Write the attribute
((DefaultServerAttribute)attribute).serialize( out );
}
/**
* @see Object#toString()
*/
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "Modification: " ).
append( operation ).
append( "\n" ).
append( ", attribute : " ).
append( attribute );
return sb.toString();
}
}