/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2009 Sun Microsystems, Inc.
* Portions Copyright 2013-2015 ForgeRock AS.
*/
/**
* This class provides a utility for interacting with compressed representations
* of schema elements. The default implementation does not persist encoded
* attributes and object classes.
*/
mayInstantiate = false,
mayExtend = true,
mayInvoke = false)
public class CompressedSchema
{
/** Maps attribute description to ID. */
/** Maps ID to attribute description. */
private final Map<Entry<AttributeType, Set<String>>, Integer> adEncodeMap = new ConcurrentHashMap<>();
/** The map between encoded representations and object class sets. */
/** The map between object class sets and encoded representations. */
/**
* Decodes the contents of the provided array as an attribute at the current
* position.
*
* @param reader
* The byte string reader containing the encoded entry.
* @return The decoded attribute.
* @throws DirectoryException
* If the attribute could not be decoded properly for some reason.
*/
throws DirectoryException
{
// First decode the encoded attribute description id.
// Look up the attribute description.
{
}
// Before returning the attribute, make sure that the attribute type is not
// stale.
{
}
// Determine the number of values for the attribute.
// For the common case of a single value with no options, generate
// less garbage.
{
}
else
{
// Read the appropriate number of values.
for (int i = 0; i < numValues; i++)
{
}
return builder.toAttribute();
}
}
/**
* Decodes an object class set from the provided byte string.
*
* @param reader
* The byte string reader containing the object class set identifier.
* @return The decoded object class set.
* @throws DirectoryException
* If the provided byte string reader cannot be decoded as an object
* class set.
*/
{
// First decode the encoded object class id.
// Look up the object classes.
{
// Before returning the object classes, make sure that none of them are
// stale.
{
{
// Found at least one object class which is dirty so refresh them.
}
}
return ocMap;
}
else
{
}
}
/**
* Encodes the information in the provided attribute to a byte array.
*
* @param builder
* The buffer to encode the attribute to.
* @param attribute
* The attribute to be encoded.
* @throws DirectoryException
* If a problem occurs while attempting to determine the appropriate
* identifier.
*/
{
// Re-use or allocate a new ID.
// Use double checked locking to avoid lazy registration races.
{
synchronized (adEncodeMap)
{
{
}
}
}
// Encode the attribute.
for (final ByteString v : attribute)
{
builder.appendBytes(v);
}
}
/**
* Encodes the provided set of object classes to a byte array. If the same set
* had been previously encoded, then the cached value will be used. Otherwise,
* a new value will be created.
*
* @param builder
* The buffer to encode the object classes to.
* @param objectClasses
* The set of object classes for which to retrieve the corresponding
* byte array token.
* @throws DirectoryException
* If a problem occurs while attempting to determine the appropriate
* identifier.
*/
{
// Re-use or allocate a new ID.
// Use double checked locking to avoid lazy registration races.
{
synchronized (ocEncodeMap)
{
{
}
}
}
// Encode the object classes.
}
/**
* Returns a view of the encoded attributes in this compressed schema which
* can be used for saving the entire content to disk. The iterator returned by
* this method is not thread safe.
*
* @return A view of the encoded attributes in this compressed schema.
*/
{
{
{
{
private int id = 0;
public boolean hasNext()
{
}
{
return new SimpleImmutableEntry<byte[],
}
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
};
}
/**
* Returns a view of the encoded object classes in this compressed schema
* which can be used for saving the entire content to disk. The iterator
* returned by this method is not thread safe.
*
* @return A view of the encoded object classes in this compressed schema.
*/
{
{
{
{
private int id = 0;
public boolean hasNext()
{
}
{
}
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
};
}
/**
* Loads an encoded attribute into this compressed schema. This method may
* called by implementations during initialization when loading content from
* disk.
*
* @param encodedAttribute
* The encoded attribute description.
* @param attributeName
* The user provided attribute type name.
* @param attributeOptions
* The non-null but possibly empty set of attribute options.
* @return The attribute type description.
*/
{
synchronized (adEncodeMap)
{
{
}
else
{
// Grow the decode array.
{
}
}
}
return ad;
}
{
switch (attributeOptions.size())
{
case 0:
return Collections.emptySet();
case 1:
default:
return new LinkedHashSet<>(attributeOptions);
}
}
/**
* Loads an encoded object class into this compressed schema. This method may
* called by implementations during initialization when loading content from
* disk.
*
* @param encodedObjectClasses
* The encoded object classes.
* @param objectClassNames
* The user provided set of object class names.
* @return The object class set.
*/
final byte[] encodedObjectClasses,
{
{
}
synchronized (ocEncodeMap)
{
{
}
else
{
// Grow the decode array.
{
}
}
}
return ocMap;
}
/**
* Persists the provided encoded attribute. The default implementation is to
* do nothing. Calls to this method are synchronized, so implementations can
* assume that this method is not being called by other threads. Note that
* this method is not thread-safe with respect to
* {@link #storeObjectClasses(byte[], Collection)}.
*
* @param encodedAttribute
* The encoded attribute description.
* @param attributeName
* The user provided attribute type name.
* @param attributeOptions
* The non-null but possibly empty set of attribute options.
* @throws DirectoryException
* If an error occurred while persisting the encoded attribute.
*/
throws DirectoryException
{
// Do nothing by default.
}
/**
* Persists the provided encoded object classes. The default implementation is
* to do nothing. Calls to this method are synchronized, so implementations
* can assume that this method is not being called by other threads. Note that
* this method is not thread-safe with respect to
* {@link #storeAttribute(byte[], String, Collection)}.
*
* @param encodedObjectClasses
* The encoded object classes.
* @param objectClassNames
* The user provided set of object class names.
* @throws DirectoryException
* If an error occurred while persisting the encoded object classes.
*/
{
// Do nothing by default.
}
/**
* Decodes the provided encoded schema element ID.
*
* @param idBytes
* The encoded schema element ID.
* @return The schema element ID.
*/
{
int id = 0;
for (final byte b : idBytes)
{
id <<= 8;
id |= b & 0xFF;
}
}
/**
* Encodes the provided schema element ID.
*
* @param id
* The schema element ID.
* @return The encoded schema element ID.
*/
{
final byte[] idBytes;
if (value <= 0xFF)
{
idBytes = new byte[1];
}
else if (value <= 0xFFFF)
{
idBytes = new byte[2];
}
else if (value <= 0xFFFFFF)
{
idBytes = new byte[3];
}
else
{
idBytes = new byte[4];
}
return idBytes;
}
}