blob: 58cf0db4e01b957d7ed13211c6962d11a4ac3a3e [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.partition.impl.btree.jdbm;
import javax.naming.NamingException;
import jdbm.RecordManager;
import jdbm.helper.LongSerializer;
import jdbm.helper.StringComparator;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.entry.ServerEntrySerializer;
import org.apache.directory.server.core.partition.impl.btree.MasterTable;
import org.apache.directory.server.schema.SerializableComparator;
import org.apache.directory.server.schema.registries.Registries;
/**
* The master table used to store the Attributes of entries.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class JdbmMasterTable extends JdbmTable implements MasterTable
{
private static final StringComparator STRCOMP = new StringComparator();
private static final SerializableComparator LONG_COMPARATOR = new SerializableComparator( "1.3.6.1.4.1.18060.0.4.1.1.2" )
{
private static final long serialVersionUID = 4048791282048841016L;
public int compare( Object o1, Object o2 )
{
if ( o1 == null )
{
throw new IllegalArgumentException( "Argument 'obj1' is null" );
}
else if ( o2 == null )
{
throw new IllegalArgumentException( "Argument 'obj2' is null" );
}
long thisVal = ( Long ) o1;
long anotherVal = ( Long ) o2;
if ( thisVal == anotherVal )
{
return 0;
}
if ( thisVal == anotherVal )
{
return 0;
}
if ( thisVal >= 0 )
{
if ( anotherVal >= 0 )
{
return ( thisVal > anotherVal ) ? 1 : -1;
}
else
{
return -1;
}
}
else if ( anotherVal >= 0 )
{
return 1;
}
else
{
return ( thisVal < anotherVal ) ? -1 : 1;
}
}
};
private static final SerializableComparator STRING_COMPARATOR = new SerializableComparator( "1.3.6.1.4.1.18060.0.4.1.1.3" )
{
private static final long serialVersionUID = 3258689922792961845L;
public int compare( Object o1, Object o2 )
{
return STRCOMP.compare( o1, o2 );
}
};
private final JdbmTable adminTbl;
/**
* Creates the master entry table using a Berkeley Db for the backing store.
*
* @param recMan the jdbm record manager
* @throws NamingException if there is an error opening the Db file.
*/
public JdbmMasterTable( RecordManager recMan, Registries registries ) throws NamingException
{
super( DBF, recMan, LONG_COMPARATOR, LongSerializer.INSTANCE, new ServerEntrySerializer( registries ) );
adminTbl = new JdbmTable( "admin", recMan, STRING_COMPARATOR, null, null );
String seqValue = ( String ) adminTbl.get( SEQPROP_KEY );
if ( null == seqValue )
{
adminTbl.put( SEQPROP_KEY, "0" );
}
}
/**
* Gets the ServerEntry from this MasterTable.
*
* @param id the Long id of the entry to retrieve.
* @return the ServerEntry with operational attributes and all.
* @throws NamingException if there is a read error on the underlying Db.
*/
public ServerEntry get( Object id ) throws NamingException
{
return ( ServerEntry ) super.get( id );
}
/**
* Puts the ServerEntry into this master table at an index
* specified by id. Used both to create new entries and update existing
* ones.
*
* @param entry the ServerEntry w/ operational attributes
* @param id the Long id of the entry to put
* @return the ServerEntry put
* @throws NamingException if there is a write error on the underlying Db.
*/
public ServerEntry put( ServerEntry entry, Object id ) throws NamingException
{
return ( ServerEntry ) super.put( id, entry );
}
/**
* Deletes a ServerEntry from the master table at an index specified by id.
*
* @param id the Long id of the entry to delete
* @return the Attributes of the deleted entry
* @throws NamingException if there is a write error on the underlying Db
*/
public ServerEntry delete( Object id ) throws NamingException
{
return ( ServerEntry ) super.remove( id );
}
/**
* Get's the current id value from this master database's sequence without
* affecting the seq.
*
* @return the current value.
* @throws NamingException if the admin table storing sequences cannot be
* read.
*/
public Long getCurrentId() throws NamingException
{
Long id;
synchronized ( adminTbl )
{
id = new Long( ( String ) adminTbl.get( SEQPROP_KEY ) );
//noinspection ConstantConditions
if ( null == id )
{
adminTbl.put( SEQPROP_KEY, "0" );
id = 0L;
}
}
return id;
}
/**
* Get's the next value from this SequenceBDb. This has the side-effect of
* changing the current sequence values permanently in memory and on disk.
* Master table sequence begins at BigInteger.ONE. The BigInteger.ZERO is
* used for the fictitious parent of the suffix root entry.
*
* @return the current value incremented by one.
* @throws NamingException if the admin table storing sequences cannot be
* read and written to.
*/
public Long getNextId() throws NamingException
{
Long lastVal;
Long nextVal;
synchronized ( adminTbl )
{
lastVal = new Long( ( String ) adminTbl.get( SEQPROP_KEY ) );
//noinspection ConstantConditions
if ( null == lastVal )
{
adminTbl.put( SEQPROP_KEY, "1" );
return 1L;
} else
{
nextVal = lastVal + 1L;
adminTbl.put( SEQPROP_KEY, nextVal.toString() );
}
}
return nextVal;
}
/**
* Gets a persistent property stored in the admin table of this MasterTable.
*
* @param property the key of the property to get the value of
* @return the value of the property
* @throws NamingException when the underlying admin table cannot be read
*/
public String getProperty( String property ) throws NamingException
{
synchronized ( adminTbl )
{
return ( String ) adminTbl.get( property );
}
}
/**
* Sets a persistent property stored in the admin table of this MasterTable.
*
* @param property the key of the property to set the value of
* @param value the value of the property
* @throws NamingException when the underlying admin table cannot be writen
*/
public void setProperty( String property, String value ) throws NamingException
{
synchronized ( adminTbl )
{
adminTbl.put( property, value );
}
}
}