| /* |
| * 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 |
| * |
| * https://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.api.ldap.model.entry; |
| |
| |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotSame; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| import static org.junit.jupiter.api.Assertions.fail; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.util.Arrays; |
| |
| import org.apache.directory.api.ldap.model.exception.LdapException; |
| import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; |
| import org.apache.directory.api.ldap.model.schema.AttributeType; |
| import org.apache.directory.api.ldap.model.schema.LdapSyntax; |
| import org.apache.directory.api.ldap.model.schema.MatchingRule; |
| import org.apache.directory.api.ldap.model.schema.Normalizer; |
| import org.apache.directory.api.ldap.model.schema.PrepareString; |
| import org.apache.directory.api.ldap.model.schema.comparators.ByteArrayComparator; |
| import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OctetStringSyntaxChecker; |
| import org.apache.directory.api.util.Strings; |
| |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.Test; |
| import org.junit.jupiter.api.parallel.Execution; |
| import org.junit.jupiter.api.parallel.ExecutionMode; |
| |
| |
| /** |
| * Tests that the Value class works properly as expected. |
| * |
| * Some notes while conducting tests: |
| * |
| * <ul> |
| * <li>comparing values with different types - how does this behave</li> |
| * <li>exposing access to at from value or to a comparator?</li> |
| * </ul> |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| @Execution(ExecutionMode.CONCURRENT) |
| public class BinaryValueAttributeTypeTest |
| { |
| private LdapSyntax s; |
| private AttributeType at; |
| private MatchingRule mr; |
| |
| private static final byte[] BYTES1 = new byte[] |
| { 0x01, 0x02, 0x03, 0x04 }; |
| private static final byte[] BYTES2 = new byte[] |
| { ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83, ( byte ) 0x84 }; |
| |
| |
| /** |
| * Initialize an AttributeType and the associated MatchingRule |
| * and Syntax |
| */ |
| @BeforeEach |
| public void initAT() |
| { |
| s = EntryUtils.syntaxFactory( "1.1.1.1", false ); |
| s.setSyntaxChecker( OctetStringSyntaxChecker.INSTANCE ); |
| mr = EntryUtils.matchingRuleFactory( "1.1.2.1" ); |
| mr.setSyntax( s ); |
| |
| mr.setLdapComparator( new ByteArrayComparator( "1.1.1" ) ); |
| mr.setNormalizer( new Normalizer( "1.1.1" ) |
| { |
| public static final long serialVersionUID = 1L; |
| |
| public String normalize( String value ) throws LdapException |
| { |
| return normalize( value, PrepareString.AssertionType.ATTRIBUTE_VALUE ); |
| } |
| |
| |
| public String normalize( String value, PrepareString.AssertionType assertionType ) throws LdapException |
| { |
| byte[] val = Strings.getBytesUtf8( value ); |
| // each byte will be changed to be > 0, and spaces will be trimmed |
| byte[] newVal = new byte[val.length]; |
| int i = 0; |
| |
| for ( byte b : val ) |
| { |
| newVal[i++] = ( byte ) ( b & 0x007F ); |
| } |
| |
| return Strings.utf8ToString( Strings.trim( newVal ) ); |
| } |
| } ); |
| |
| at = new AttributeType( "1.1.3.1" ); |
| at.setEquality( mr ); |
| at.setOrdering( mr ); |
| at.setSubstring( mr ); |
| at.setSyntax( s ); |
| } |
| |
| |
| /** |
| * Serialize a Value |
| */ |
| private ByteArrayOutputStream serializeValue( Value value ) throws IOException |
| { |
| ObjectOutputStream oOut = null; |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| |
| try |
| { |
| oOut = new ObjectOutputStream( out ); |
| value.writeExternal( oOut ); |
| } |
| catch ( IOException ioe ) |
| { |
| throw ioe; |
| } |
| finally |
| { |
| try |
| { |
| if ( oOut != null ) |
| { |
| oOut.flush(); |
| oOut.close(); |
| } |
| } |
| catch ( IOException ioe ) |
| { |
| throw ioe; |
| } |
| } |
| |
| return out; |
| } |
| |
| |
| /** |
| * Deserialize a Value |
| */ |
| private Value deserializeValue( ByteArrayOutputStream out, AttributeType at ) throws IOException, |
| ClassNotFoundException |
| { |
| ObjectInputStream oIn = null; |
| ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() ); |
| |
| try |
| { |
| oIn = new ObjectInputStream( in ); |
| |
| Value value = Value.createValue( ( AttributeType ) null ); |
| value.readExternal( oIn ); |
| |
| return value; |
| } |
| finally |
| { |
| try |
| { |
| if ( oIn != null ) |
| { |
| oIn.close(); |
| } |
| } |
| catch ( IOException ioe ) |
| { |
| throw ioe; |
| } |
| } |
| } |
| |
| |
| /** |
| * Test the constructor with bad AttributeType |
| * @throws LdapInvalidAttributeValueException |
| */ |
| @Test |
| public void testBadConstructor() |
| { |
| // create a AT with no syntax |
| AttributeType attribute = new AttributeType( "1.1.3.1" ); |
| |
| Value value = Value.createValue( attribute ); |
| assertTrue( value.isHumanReadable() ); |
| } |
| |
| |
| /** |
| * Test the constructor with a null value |
| */ |
| @Test |
| public void testServerBinaryValueNullValue() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| Value value = new Value( attribute, ( byte[] ) null ); |
| |
| assertNull( value.getBytes() ); |
| assertTrue( value.isNull() ); |
| } |
| |
| |
| /** |
| * Test the constructor with an empty value |
| */ |
| @Test |
| public void testServerBinaryValueEmptyValue() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| Value value = new Value( attribute, Strings.EMPTY_BYTES ); |
| |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) ); |
| assertFalse( value.isNull() ); |
| } |
| |
| |
| /** |
| * Test the constructor with a value |
| * @throws LdapInvalidAttributeValueException |
| */ |
| @Test |
| public void testServerBinaryValueNoValue() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| byte[] val = new byte[] |
| { 0x01 }; |
| Value bv = new Value( attribute, val ); |
| assertTrue( Arrays.equals( val, bv.getBytes() ) ); |
| assertFalse( bv.isNull() ); |
| } |
| |
| |
| /** |
| * Test the constructor with a value |
| */ |
| @Test |
| public void testServerBinaryValue() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| byte[] val = new byte[] |
| { 0x01 }; |
| Value value = new Value( attribute, val ); |
| |
| assertTrue( Arrays.equals( val, value.getBytes() ) ); |
| assertFalse( value.isNull() ); |
| assertTrue( Arrays.equals( val, value.getBytes() ) ); |
| } |
| |
| |
| /** |
| * Test the clone method |
| */ |
| @Test |
| public void testClone() throws LdapException |
| { |
| AttributeType at1 = EntryUtils.getBytesAttributeType(); |
| Value bv = new Value( at1, ( byte[] ) null ); |
| Value bv1 = bv.clone(); |
| |
| assertEquals( bv, bv1 ); |
| |
| bv = new Value( Strings.EMPTY_BYTES ); |
| |
| assertNotSame( bv, bv1 ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) ); |
| |
| bv = new Value( at, BYTES2 ); |
| bv1 = bv.clone(); |
| |
| assertEquals( bv, bv1 ); |
| } |
| |
| |
| /** |
| * Test the equals method |
| */ |
| @Test |
| public void testEquals() throws LdapInvalidAttributeValueException |
| { |
| AttributeType at1 = EntryUtils.getBytesAttributeType(); |
| |
| Value value1 = new Value( at1, new byte[] |
| { 0x01, ( byte ) 0x02 } ); |
| Value value2 = new Value( at1, new byte[] |
| { 0x01, ( byte ) 0x02 } ); |
| Value value3 = new Value( at1, new byte[] |
| { 0x01, ( byte ) 0x82 } ); |
| Value value4 = new Value( at1, new byte[] |
| { 0x01 } ); |
| Value value5 = new Value( at1, ( byte[] ) null ); |
| Value value6 = new Value( at, new byte[] |
| { 0x01, 0x02 } ); |
| Value value7 = new Value( EntryUtils.getIA5StringAttributeType(), |
| "test" ); |
| |
| assertTrue( value1.equals( value1 ) ); |
| assertTrue( value1.equals( value2 ) ); |
| assertFalse( value1.equals( value3 ) ); |
| assertFalse( value1.equals( value4 ) ); |
| assertFalse( value1.equals( value5 ) ); |
| assertFalse( value1.equals( "test" ) ); |
| assertFalse( value1.equals( null ) ); |
| |
| assertTrue( value1.equals( value6 ) ); |
| assertFalse( value1.equals( value7 ) ); |
| } |
| |
| |
| /** |
| * Test the getNormValue method |
| */ |
| @Test |
| public void testGetNormalizedValue() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| Value value = new Value( attribute, ( byte[] ) null ); |
| assertNull( value.getBytes() ); |
| |
| value = new Value( attribute, Strings.EMPTY_BYTES ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) ); |
| |
| value = new Value( attribute, BYTES2 ); |
| assertTrue( Arrays.equals( BYTES2, value.getBytes() ) ); |
| } |
| |
| |
| /** |
| * Test the getNormValue method |
| */ |
| @Test |
| public void testGetNormalizedValueCopy() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| Value value = new Value( attribute, ( byte[] ) null ); |
| assertNull( value.getBytes() ); |
| |
| value = new Value( attribute, Strings.EMPTY_BYTES ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) ); |
| |
| value = new Value( attribute, BYTES2 ); |
| assertTrue( Arrays.equals( BYTES2, value.getBytes() ) ); |
| } |
| |
| |
| /** |
| * Test the getNormValue method |
| */ |
| @Test |
| public void testGetNormalizedValueReference() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| Value value = new Value( attribute, ( byte[] ) null ); |
| assertNull( value.getBytes() ); |
| |
| value = new Value( attribute, Strings.EMPTY_BYTES ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, value.getBytes() ) ); |
| |
| value = new Value( attribute, BYTES2 ); |
| assertTrue( Arrays.equals( BYTES2, value.getBytes() ) ); |
| } |
| |
| |
| /** |
| * Test the getAttributeType method |
| * @throws LdapInvalidAttributeValueException |
| */ |
| @Test |
| public void testgetAttributeType() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| Value sbv = Value.createValue( attribute ); |
| |
| assertEquals( attribute, sbv.getAttributeType() ); |
| } |
| |
| |
| /** |
| * Test the isValid method |
| * |
| * The SyntaxChecker does not accept values longer than 5 chars. |
| */ |
| @Test |
| public void testIsValid() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| |
| new Value( attribute, ( byte[] ) null ); |
| new Value( attribute, Strings.EMPTY_BYTES ); |
| new Value( attribute, new byte[] |
| { 0x01, 0x02 } ); |
| |
| try |
| { |
| new Value( attribute, new byte[] |
| { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 } ); |
| fail(); |
| } |
| catch ( LdapInvalidAttributeValueException liave ) |
| { |
| assertTrue( true ); |
| } |
| } |
| |
| |
| /** |
| * Tests to make sure the hashCode method is working properly. |
| * @throws Exception on errors |
| */ |
| @Test |
| public void testHashCode() throws LdapInvalidAttributeValueException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| Value v0 = new Value( attribute, new byte[] |
| { 0x01, 0x02 } ); |
| Value v1 = new Value( attribute, new byte[] |
| { ( byte ) 0x81, ( byte ) 0x82 } ); |
| Value v2 = new Value( attribute, new byte[] |
| { 0x01, 0x02 } ); |
| assertNotSame( v0.hashCode(), v1.hashCode() ); |
| assertNotSame( v1.hashCode(), v2.hashCode() ); |
| assertEquals( v0.hashCode(), v2.hashCode() ); |
| assertNotSame( v0, v1 ); |
| assertEquals( v0, v2 ); |
| assertNotSame( v1, v2 ); |
| |
| Value v3 = new Value( attribute, new byte[] |
| { 0x01, 0x03 } ); |
| assertFalse( v3.equals( v0 ) ); |
| assertFalse( v3.equals( v1 ) ); |
| assertFalse( v3.equals( v2 ) ); |
| } |
| |
| |
| /** |
| * Test the instanceOf method |
| */ |
| @Test |
| public void testInstanceOf() throws LdapException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| Value sbv = Value.createValue( attribute ); |
| |
| assertTrue( sbv.isInstanceOf( attribute ) ); |
| |
| attribute = EntryUtils.getIA5StringAttributeType(); |
| |
| assertFalse( sbv.isInstanceOf( attribute ) ); |
| } |
| |
| |
| /** |
| * Test the normalize method |
| */ |
| @Test |
| public void testNormalize() throws LdapException |
| { |
| AttributeType attribute = EntryUtils.getBytesAttributeType(); |
| Value bv = Value.createValue( attribute ); |
| |
| assertEquals( null, bv.getBytes() ); |
| |
| bv = new Value( attribute, Strings.EMPTY_BYTES ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) ); |
| |
| bv = new Value( attribute, BYTES2 ); |
| assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) ); |
| } |
| |
| |
| /** |
| * Test the compareTo method |
| */ |
| @Test |
| public void testCompareTo() throws LdapInvalidAttributeValueException |
| { |
| AttributeType at1 = EntryUtils.getBytesAttributeType(); |
| Value v0 = new Value( at1, BYTES1 ); |
| Value v1 = new Value( at1, BYTES1 ); |
| |
| assertEquals( 0, v0.compareTo( v1 ) ); |
| assertEquals( 0, v1.compareTo( v0 ) ); |
| |
| Value v2 = new Value( at1, ( byte[] ) null ); |
| |
| assertEquals( 1, v0.compareTo( v2 ) ); |
| assertEquals( -1, v2.compareTo( v0 ) ); |
| } |
| |
| |
| /** |
| * Test serialization of a Value which normalized value is the same |
| * than the value |
| */ |
| @Test |
| public void testNormalizedBinarySameValueSerialization() throws LdapException, IOException, ClassNotFoundException |
| { |
| byte[] v1 = Strings.getBytesUtf8( "Test Test" ); |
| |
| // First check with a value which will be normalized |
| Value sbv = new Value( at, v1 ); |
| |
| Value sbvSer = deserializeValue( serializeValue( sbv ), at ); |
| |
| assertEquals( sbv, sbvSer ); |
| } |
| |
| |
| /** |
| * Test serialization of a Value which does not have a normalized value |
| */ |
| @Test |
| public void testNoNormalizedBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException |
| { |
| byte[] v1 = Strings.getBytesUtf8( "test" ); |
| byte[] v1Norm = Strings.getBytesUtf8( "test" ); |
| |
| // First check with a value which will be normalized |
| Value sbv = new Value( at, v1 ); |
| |
| byte[] normalized = sbv.getBytes(); |
| |
| assertTrue( Arrays.equals( v1Norm, normalized ) ); |
| assertTrue( Arrays.equals( v1, sbv.getBytes() ) ); |
| |
| Value sbvSer = deserializeValue( serializeValue( sbv ), at ); |
| |
| assertEquals( sbv, sbvSer ); |
| } |
| |
| |
| /** |
| * Test serialization of a null Value |
| */ |
| @Test |
| public void testNullBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException |
| { |
| // First check with a value which will be normalized |
| Value sbv = Value.createValue( at ); |
| |
| byte[] normalized = sbv.getBytes(); |
| |
| assertEquals( null, normalized ); |
| assertEquals( "", sbv.getString() ); |
| |
| Value sbvSer = deserializeValue( serializeValue( sbv ), at ); |
| |
| assertEquals( sbv, sbvSer ); |
| } |
| |
| |
| /** |
| * Test serialization of an empty Value |
| */ |
| @Test |
| public void testEmptyBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException |
| { |
| // First check with a value which will be normalized |
| Value sbv = new Value( at, Strings.EMPTY_BYTES ); |
| |
| byte[] normalized = sbv.getBytes(); |
| |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, normalized ) ); |
| assertTrue( Arrays.equals( Strings.EMPTY_BYTES, sbv.getBytes() ) ); |
| |
| Value sbvSer = deserializeValue( serializeValue( sbv ), at ); |
| |
| assertEquals( sbv, sbvSer ); |
| } |
| |
| |
| /** |
| * Test serialization of a Value which is the same than the value |
| */ |
| @Test |
| public void testSameNormalizedBinaryValueSerialization() throws LdapException, IOException, ClassNotFoundException |
| { |
| byte[] v1 = Strings.getBytesUtf8( "test" ); |
| byte[] v1Norm = Strings.getBytesUtf8( "test" ); |
| |
| // First check with a value which will be normalized |
| Value sbv = new Value( at, v1 ); |
| |
| byte[] normalized = sbv.getBytes(); |
| |
| assertTrue( Arrays.equals( v1Norm, normalized ) ); |
| assertTrue( Arrays.equals( v1, sbv.getBytes() ) ); |
| |
| Value sbvSer = deserializeValue( serializeValue( sbv ), at ); |
| |
| assertEquals( sbv, sbvSer ); |
| } |
| } |