001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.server.backends.pluggable; 028 029import org.forgerock.opendj.ldap.ByteSequence; 030import org.forgerock.opendj.ldap.ByteString; 031import org.forgerock.opendj.ldap.ByteStringBuilder; 032import org.opends.server.types.DN; 033 034/** 035 * Handles the disk representation of LDAP data. 036 */ 037public class DnKeyFormat 038{ 039 040 /** The format version used by this class to encode and decode a ByteString. */ 041 static final byte FORMAT_VERSION = 0x01; 042 043 /** 044 * Find the length of bytes that represents the superior DN of the given DN 045 * key. The superior DN is represented by the initial bytes of the DN key. 046 * 047 * @param dnKey 048 * The key value of the DN. 049 * @return The length of the superior DN or -1 if the given dn is the root DN 050 * or 0 if the superior DN is removed. 051 */ 052 static int findDNKeyParent(ByteSequence dnKey) 053 { 054 if (dnKey.length() == 0) 055 { 056 // This is the root or base DN 057 return -1; 058 } 059 060 // We will walk backwards through the buffer 061 // and find the first unescaped NORMALIZED_RDN_SEPARATOR 062 for (int i = dnKey.length() - 1; i >= 0; i--) 063 { 064 if (dnKey.byteAt(i) == DN.NORMALIZED_RDN_SEPARATOR && i - 1 >= 0 && dnKey.byteAt(i - 1) != DN.NORMALIZED_ESC_BYTE) 065 { 066 return i; 067 } 068 } 069 return 0; 070 } 071 072 /** 073 * Create a DN key from an entry DN. 074 * 075 * @param dn The entry DN. 076 * @param prefixRDNs The number of prefix RDNs to remove from the encoded 077 * representation. 078 * @return A ByteString containing the key. 079 */ 080 static ByteString dnToDNKey(DN dn, int prefixRDNs) 081 { 082 final ByteStringBuilder builder = new ByteStringBuilder(128); 083 final int startSize = dn.size() - prefixRDNs - 1; 084 for (int i = startSize; i >= 0; i--) 085 { 086 builder.append(DN.NORMALIZED_RDN_SEPARATOR); 087 dn.getRDN(i).toNormalizedByteString(builder); 088 } 089 return builder.toByteString(); 090 } 091 092 static ByteStringBuilder beforeKey(final ByteSequence key) 093 { 094 final ByteStringBuilder beforeKey = new ByteStringBuilder(key.length() + 1); 095 beforeKey.append(key); 096 beforeKey.append((byte) 0x00); 097 return beforeKey; 098 } 099 100 static ByteStringBuilder afterKey(final ByteSequence key) 101 { 102 final ByteStringBuilder afterKey = new ByteStringBuilder(key.length() + 1); 103 afterKey.append(key); 104 afterKey.append((byte) 0x01); 105 return afterKey; 106 } 107}