/* | |
* 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.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashSet; | |
import java.util.List; | |
import javax.naming.NamingException; | |
import javax.naming.directory.InvalidAttributeValueException; | |
import org.apache.directory.shared.ldap.entry.Value; | |
import org.apache.directory.shared.ldap.schema.AttributeType; | |
import org.apache.directory.shared.ldap.schema.DeepTrimToLowerNormalizer; | |
import org.apache.directory.shared.ldap.schema.NoOpNormalizer; | |
import org.apache.directory.shared.ldap.schema.syntax.AcceptAllSyntaxChecker; | |
import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertNotSame; | |
import static org.junit.Assert.assertNull; | |
import static org.junit.Assert.assertTrue; | |
import static org.junit.Assert.fail; | |
import org.junit.Before; | |
import org.junit.Test; | |
import jdbm.helper.StringComparator; | |
/** | |
* Tests that the ServerStringValue 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> | |
* @version $Rev$, $Date$ | |
*/ | |
public class ServerStringValueTest | |
{ | |
private TestServerEntryUtils.S s; | |
private TestServerEntryUtils.AT at; | |
private TestServerEntryUtils.MR mr; | |
/** | |
* Initialize an AttributeType and the associated MatchingRule | |
* and Syntax | |
*/ | |
@Before public void initAT() | |
{ | |
s = new TestServerEntryUtils.S( "1.1.1.1", false ); | |
s.setSyntaxChecker( new AcceptAllSyntaxChecker( "1.1.1.1" ) ); | |
mr = new TestServerEntryUtils.MR( "1.1.2.1" ); | |
mr.syntax = s; | |
mr.comparator = new StringComparator(); | |
mr.normalizer = new DeepTrimToLowerNormalizer(); | |
at = new TestServerEntryUtils.AT( "1.1.3.1" ); | |
at.setEquality( mr ); | |
at.setOrdering( mr ); | |
at.setSubstr( mr ); | |
at.setSyntax( s ); | |
} | |
/** | |
* Test the constructor with a null value | |
*/ | |
@Test | |
public void testServerStringValueNullValue() | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue value = new ServerStringValue( attribute, null ); | |
assertNull( value.get() ); | |
assertTrue( value.isNull() ); | |
} | |
/** | |
* Test the getNormalizedValue method | |
*/ | |
@Test public void testGetNormalizedValue() | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue value = new ServerStringValue( attribute, null ); | |
assertFalse( value.isNormalized() ); | |
assertNull( value.getNormalizedValue() ); | |
assertTrue( value.isNormalized() ); | |
value.set( "" ); | |
assertFalse( value.isNormalized() ); | |
assertEquals( "", value.getNormalizedValue() ); | |
assertTrue( value.isNormalized() ); | |
value.set( "TEST" ); | |
assertFalse( value.isNormalized() ); | |
assertEquals( "test", value.getNormalizedValue() ); | |
assertTrue( value.isNormalized() ); | |
} | |
/** | |
* Test the isValid method | |
* | |
* The SyntaxChecker does not accept values longer than 5 chars. | |
*/ | |
@Test public void testIsValid() | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue value = new ServerStringValue( attribute, null ); | |
assertTrue( value.isValid() ); | |
value.set( "" ); | |
assertTrue( value.isValid() ); | |
value.set( "TEST" ); | |
assertTrue( value.isValid() ); | |
value.set( "testlong" ); | |
assertFalse( value.isValid() ); | |
} | |
/** | |
* Test the normalize method | |
*/ | |
@Test | |
public void testNormalize() throws NamingException | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue ssv = new ServerStringValue( attribute ); | |
ssv.normalize(); | |
assertEquals( null, ssv.getNormalizedValue() ); | |
ssv.set( "" ); | |
ssv.normalize(); | |
assertEquals( "", ssv.getNormalizedValue() ); | |
ssv.set( " This is a TEST " ); | |
ssv.normalize(); | |
assertEquals( "this is a test", ssv.getNormalizedValue() ); | |
} | |
/** | |
* Test the instanceOf method | |
*/ | |
@Test | |
public void testInstanceOf() throws NamingException | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue ssv = new ServerStringValue( attribute ); | |
assertTrue( ssv.instanceOf( attribute ) ); | |
attribute = TestServerEntryUtils.getBytesAttributeType(); | |
assertFalse( ssv.instanceOf( attribute ) ); | |
} | |
/** | |
* Test the getAttributeType method | |
*/ | |
@Test | |
public void testgetAttributeType() | |
{ | |
AttributeType attribute = TestServerEntryUtils.getIA5StringAttributeType(); | |
ServerStringValue ssv = new ServerStringValue( attribute ); | |
assertEquals( attribute, ssv.getAttributeType() ); | |
} | |
/** | |
* Test the equals method | |
*/ | |
@Test public void testEquals() | |
{ | |
AttributeType at1 = TestServerEntryUtils.getIA5StringAttributeType(); | |
AttributeType at2 = TestServerEntryUtils.getBytesAttributeType(); | |
ServerStringValue value1 = new ServerStringValue( at1, "test" ); | |
ServerStringValue value2 = new ServerStringValue( at1, "test" ); | |
ServerStringValue value3 = new ServerStringValue( at1, "TEST" ); | |
ServerStringValue value4 = new ServerStringValue( at1, "tes" ); | |
ServerStringValue value5 = new ServerStringValue( at1, null ); | |
ServerBinaryValue valueBytes = new ServerBinaryValue( at2, new byte[]{0x01} ); | |
ServerStringValue valueString = new ServerStringValue( at, "test" ); | |
assertTrue( value1.equals( value1 ) ); | |
assertTrue( value1.equals( value2 ) ); | |
assertTrue( value1.equals( value3 ) ); | |
assertFalse( value1.equals( value4 ) ); | |
assertFalse( value1.equals( value5 ) ); | |
assertFalse( value1.equals( "test" ) ); | |
assertFalse( value1.equals( null ) ); | |
assertFalse( value1.equals( valueString ) ); | |
assertFalse( value1.equals( valueBytes ) ); | |
} | |
/** | |
* Test the constructor with bad AttributeType | |
*/ | |
@Test public void testBadConstructor() | |
{ | |
try | |
{ | |
new ServerStringValue( null ); | |
fail(); | |
} | |
catch ( IllegalArgumentException iae ) | |
{ | |
// Expected... | |
} | |
// create a AT without any syntax | |
AttributeType attribute = new TestServerEntryUtils.AT( "1.1.3.1" ); | |
try | |
{ | |
new ServerStringValue( attribute ); | |
fail(); | |
} | |
catch ( IllegalArgumentException iae ) | |
{ | |
// Expected... | |
} | |
} | |
/** | |
* Tests to make sure the hashCode method is working properly. | |
* @throws Exception on errors | |
*/ | |
@Test public void testHashCode() | |
{ | |
AttributeType at1 = TestServerEntryUtils.getCaseIgnoringAttributeNoNumbersType(); | |
ServerStringValue v0 = new ServerStringValue( at1, "Alex" ); | |
ServerStringValue v1 = new ServerStringValue( at1, "ALEX" ); | |
ServerStringValue v2 = new ServerStringValue( at1, "alex" ); | |
assertEquals( v0.hashCode(), v1.hashCode() ); | |
assertEquals( v0.hashCode(), v2.hashCode() ); | |
assertEquals( v1.hashCode(), v2.hashCode() ); | |
assertEquals( v0, v1 ); | |
assertEquals( v0, v2 ); | |
assertEquals( v1, v2 ); | |
assertTrue( v0.isValid() ); | |
assertTrue( v1.isValid() ); | |
assertTrue( v2.isValid() ); | |
ServerStringValue v3 = new ServerStringValue( at1, "Timber" ); | |
assertTrue( v3.isValid() ); | |
assertNotSame( v0.hashCode(), v3.hashCode() ); | |
ServerStringValue v4 = new ServerStringValue( at, "Alex" ); | |
assertNotSame( v0.hashCode(), v4.hashCode() ); | |
} | |
/** | |
* Test the compareTo method | |
*/ | |
@Test | |
public void testCompareTo() | |
{ | |
AttributeType at1 = TestServerEntryUtils.getCaseIgnoringAttributeNoNumbersType(); | |
ServerStringValue v0 = new ServerStringValue( at1, "Alex" ); | |
ServerStringValue v1 = new ServerStringValue( at1, "ALEX" ); | |
assertEquals( 0, v0.compareTo( v1 ) ); | |
assertEquals( 0, v1.compareTo( v0 ) ); | |
ServerStringValue v2 = new ServerStringValue( at1, null ); | |
assertEquals( 1, v0.compareTo( v2 ) ); | |
assertEquals( -1, v2.compareTo( v0 ) ); | |
} | |
/** | |
* Test the clone method | |
*/ | |
@Test | |
public void testClone() throws NamingException | |
{ | |
AttributeType at1 = TestServerEntryUtils.getCaseIgnoringAttributeNoNumbersType(); | |
ServerStringValue ssv = new ServerStringValue( at1, "Test" ); | |
ServerStringValue ssv1 = ssv.clone(); | |
assertEquals( ssv, ssv1 ); | |
ssv.set( "" ); | |
assertNotSame( ssv, ssv1 ); | |
assertEquals( "", ssv.get() ); | |
ssv.set( " This is a TEST " ); | |
ssv1 = ssv.clone(); | |
assertEquals( ssv, ssv1 ); | |
ssv.normalize(); | |
assertEquals( ssv, ssv1 ); | |
} | |
/** | |
* Presumes an attribute which constrains it's values to some constant | |
* strings: LOW, MEDIUM, HIGH. Normalization does nothing. MatchingRules | |
* are exact case matching. | |
* | |
* @throws Exception on errors | |
*/ | |
@Test public void testConstrainedString() | |
{ | |
s.setSyntaxChecker( new SyntaxChecker() { | |
public String getSyntaxOid() { return "1.1.1.1"; } | |
public boolean isValidSyntax( Object value ) | |
{ | |
if ( value instanceof String ) | |
{ | |
String strval = ( String ) value; | |
return strval.equals( "HIGH" ) || strval.equals( "LOW" ) || strval.equals( "MEDIUM" ); | |
} | |
return false; | |
} | |
public void assertSyntax( Object value ) throws NamingException | |
{ if ( ! isValidSyntax( value ) ) {throw new InvalidAttributeValueException(); }} | |
}); | |
mr.syntax = s; | |
mr.comparator = new Comparator<String>() | |
{ | |
public int compare( String o1, String o2 ) | |
{ | |
if ( o1 == null ) | |
{ | |
if ( o2 == null ) | |
{ | |
return 0; | |
} | |
else | |
{ | |
return -1; | |
} | |
} | |
else if ( o2 == null ) | |
{ | |
return 1; | |
} | |
int i1 = getValue( o1 ); | |
int i2 = getValue( o2 ); | |
if ( i1 == i2 ) { return 0; } | |
if ( i1 > i2 ) { return 1; } | |
if ( i1 < i2 ) { return -1; } | |
throw new IllegalStateException( "should not get here at all" ); | |
} | |
public int getValue( String val ) | |
{ | |
if ( val.equals( "LOW" ) ) { return 0; } | |
if ( val.equals( "MEDIUM" ) ) { return 1; } | |
if ( val.equals( "HIGH" ) ) { return 2; } | |
throw new IllegalArgumentException( "Not a valid value" ); | |
} | |
}; | |
mr.normalizer = new NoOpNormalizer(); | |
at.setEquality( mr ); | |
at.setSyntax( s ); | |
// check that normalization and syntax checks work as expected | |
ServerStringValue value = new ServerStringValue( at, "HIGH" ); | |
assertEquals( value.get(), value.get() ); | |
assertTrue( value.isValid() ); | |
value = new ServerStringValue( at, "high" ); | |
assertFalse( value.isValid() ); | |
// create a bunch to best tested for equals and in containers | |
ServerStringValue v0 = new ServerStringValue( at, "LOW" ); | |
assertTrue( v0.isValid() ); | |
ServerStringValue v1 = new ServerStringValue( at, "LOW" ); | |
assertTrue( v1.isValid() ); | |
ServerStringValue v2 = new ServerStringValue( at, "MEDIUM" ); | |
assertTrue( v2.isValid() ); | |
ServerStringValue v3 = new ServerStringValue( at, "HIGH" ); | |
assertTrue( v3.isValid() ); | |
ServerStringValue v4 = new ServerStringValue( at ); | |
assertFalse( v4.isValid() ); | |
ServerStringValue v5 = new ServerStringValue( at ); | |
assertFalse( v5.isValid() ); | |
// check equals | |
assertTrue( v0.equals( v1 ) ); | |
assertTrue( v1.equals( v0 ) ); | |
assertEquals( 0, v0.compareTo( v1 ) ); | |
assertTrue( v4.equals( v5 ) ); | |
assertTrue( v5.equals( v4 ) ); | |
assertEquals( 0, v4.compareTo( v5 ) ); | |
assertFalse( v2.equals( v3 ) ); | |
assertFalse( v3.equals( v2 ) ); | |
assertTrue( v2.compareTo( v3 ) < 0 ); | |
assertTrue( v3.compareTo( v2 ) > 0 ); | |
// add all except v1 and v5 to a set | |
HashSet<ServerStringValue> set = new HashSet<ServerStringValue>(); | |
set.add( v0 ); | |
set.add( v2 ); | |
set.add( v3 ); | |
set.add( v4 ); | |
// check contains method | |
assertTrue( "since v1.equals( v0 ) and v0 was added then this should be true", set.contains( v1 ) ); | |
assertTrue( "since v4.equals( v5 ) and v4 was added then this should be true", set.contains( v5 ) ); | |
// check ordering based on the comparator | |
List<Value<String>> list = new ArrayList<Value<String>>(); | |
list.add( v1 ); | |
list.add( v3 ); | |
list.add( v5 ); | |
list.add( v0 ); | |
list.add( v2 ); | |
list.add( v4 ); | |
Collections.sort( list ); | |
// null ones are at first 2 indices | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 0 ).equals( v4 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 0 ).equals( v5 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 1 ).equals( v4 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 1 ).equals( v5 ) ); | |
// low ones are at the 3rd and 4th indices | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 2 ).equals( v0 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 2 ).equals( v1 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 3 ).equals( v0 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 3 ).equals( v1 ) ); | |
// medium then high next | |
assertTrue( "since v2 \"MEDIUM\" should be at index 4", list.get( 4 ).equals( v2 ) ); | |
assertTrue( "since v3 \"HIGH\" should be at index 5", list.get( 5 ).equals( v3 ) ); | |
assertEquals( 6, list.size() ); | |
} | |
/** | |
* Creates a string value with an attribute type that is of a syntax | |
* which accepts anything. Also there is no normalization since the | |
* value is the same as the normalized value. This makes the at technically | |
* a binary value however it can be dealt with as a string so this test | |
* is still OK. | |
* @throws Exception on errors | |
*/ | |
@Test public void testAcceptAllNoNormalization() | |
{ | |
// check that normalization and syntax checks work as expected | |
ServerStringValue value = new ServerStringValue( at, "hello" ); | |
assertEquals( value.get(), value.get() ); | |
assertTrue( value.isValid() ); | |
// create a bunch to best tested for equals and in containers | |
ServerStringValue v0 = new ServerStringValue( at, "hello" ); | |
ServerStringValue v1 = new ServerStringValue( at, "hello" ); | |
ServerStringValue v2 = new ServerStringValue( at, "next0" ); | |
ServerStringValue v3 = new ServerStringValue( at, "next1" ); | |
ServerStringValue v4 = new ServerStringValue( at ); | |
ServerStringValue v5 = new ServerStringValue( at ); | |
// check equals | |
assertTrue( v0.equals( v1 ) ); | |
assertTrue( v1.equals( v0 ) ); | |
assertTrue( v4.equals( v5 ) ); | |
assertTrue( v5.equals( v4 ) ); | |
assertFalse( v2.equals( v3 ) ); | |
assertFalse( v3.equals( v2 ) ); | |
// add all except v1 and v5 to a set | |
HashSet<ServerStringValue> set = new HashSet<ServerStringValue>(); | |
set.add( v0 ); | |
set.add( v2 ); | |
set.add( v3 ); | |
set.add( v4 ); | |
// check contains method | |
assertTrue( "since v1.equals( v0 ) and v0 was added then this should be true", set.contains( v1 ) ); | |
assertTrue( "since v4.equals( v5 ) and v4 was added then this should be true", set.contains( v5 ) ); | |
// check ordering based on the comparator | |
ArrayList<ServerStringValue> list = new ArrayList<ServerStringValue>(); | |
list.add( v1 ); | |
list.add( v3 ); | |
list.add( v5 ); | |
list.add( v0 ); | |
list.add( v2 ); | |
list.add( v4 ); | |
Comparator<ServerStringValue> c = new Comparator<ServerStringValue>() | |
{ | |
public int compare( ServerStringValue o1, ServerStringValue o2 ) | |
{ | |
String n1 = null; | |
String n2 = null; | |
if ( o1 != null ) | |
{ | |
n1 = o1.get(); | |
} | |
if ( o2 != null ) | |
{ | |
n2 = o2.get(); | |
} | |
if ( n1 == null ) | |
{ | |
return ( n2 == null ) ? 0 : -1; | |
} | |
else if ( n2 == null ) | |
{ | |
return 1; | |
} | |
try | |
{ | |
return mr.getComparator().compare( n1, n2 ); | |
} | |
catch ( NamingException ne ) | |
{ | |
throw new IllegalStateException( "Normalization and comparison should succeed!", ne ); | |
} | |
} | |
}; | |
Collections.sort( list, c ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 0 ).equals( v4 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 0 ).equals( v5 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 1 ).equals( v4 ) ); | |
assertTrue( "since v4 equals v5 and has no value either could be at index 0 & 1", list.get( 1 ).equals( v5 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 2 ).equals( v0 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 2 ).equals( v1 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 3 ).equals( v0 ) ); | |
assertTrue( "since v0 equals v1 either could be at index 2 & 3", list.get( 3 ).equals( v1 ) ); | |
assertTrue( "since v2 \"next0\" should be at index 4", list.get( 4 ).equals( v2 ) ); | |
assertTrue( "since v3 \"next1\" should be at index 5", list.get( 5 ).equals( v3 ) ); | |
assertEquals( 6, list.size() ); | |
} | |
/** | |
* Test serialization of a StringValue which has a normalized value | |
*/ | |
@Test public void testNormalizedStringValueSerialization() throws NamingException, IOException, ClassNotFoundException | |
{ | |
// First check with a value which will be normalized | |
ServerStringValue sv = new ServerStringValue( at, " Test Test " ); | |
sv.normalize(); | |
String normalized = sv.getNormalizedValue(); | |
assertEquals( "test test", normalized ); | |
assertEquals( " Test Test ", sv.get() ); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
ObjectOutputStream out = new ObjectOutputStream( baos ); | |
sv.writeExternal( out ); | |
ObjectInputStream in = null; | |
byte[] data = baos.toByteArray(); | |
in = new ObjectInputStream( new ByteArrayInputStream( data ) ); | |
ServerStringValue sv2 = new ServerStringValue( at ); | |
sv2.readExternal( in ); | |
assertEquals( sv, sv2 ); | |
} | |
/** | |
* Test serialization of a StringValue which does not have a normalized value | |
*/ | |
@Test public void testNoNormalizedStringValueSerialization() throws NamingException, IOException, ClassNotFoundException | |
{ | |
// First check with a value which will be normalized | |
ServerStringValue sv = new ServerStringValue( at, "test" ); | |
sv.normalize(); | |
String normalized = sv.getNormalizedValue(); | |
assertEquals( "test", normalized ); | |
assertEquals( "test", sv.get() ); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
ObjectOutputStream out = new ObjectOutputStream( baos ); | |
sv.writeExternal( out ); | |
ObjectInputStream in = null; | |
byte[] data = baos.toByteArray(); | |
in = new ObjectInputStream( new ByteArrayInputStream( data ) ); | |
ServerStringValue sv2 = new ServerStringValue( at ); | |
sv2.readExternal( in ); | |
assertEquals( sv, sv2 ); | |
} | |
/** | |
* Test serialization of a null StringValue | |
*/ | |
@Test public void testNullStringValueSerialization() throws NamingException, IOException, ClassNotFoundException | |
{ | |
// First check with a value which will be normalized | |
ServerStringValue sv = new ServerStringValue( at ); | |
sv.normalize(); | |
String normalized = sv.getNormalizedValue(); | |
assertEquals( null, normalized ); | |
assertEquals( null, sv.get() ); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
ObjectOutputStream out = new ObjectOutputStream( baos ); | |
sv.writeExternal( out ); | |
ObjectInputStream in = null; | |
byte[] data = baos.toByteArray(); | |
in = new ObjectInputStream( new ByteArrayInputStream( data ) ); | |
ServerStringValue sv2 = new ServerStringValue( at ); | |
sv2.readExternal( in ); | |
assertEquals( sv, sv2 ); | |
} | |
/** | |
* Test serialization of an empty StringValue | |
*/ | |
@Test public void testEmptyStringValueSerialization() throws NamingException, IOException, ClassNotFoundException | |
{ | |
// First check with a value which will be normalized | |
ServerStringValue sv = new ServerStringValue( at, "" ); | |
sv.normalize(); | |
String normalized = sv.getNormalizedValue(); | |
assertEquals( "", normalized ); | |
assertEquals( "", sv.get() ); | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
ObjectOutputStream out = new ObjectOutputStream( baos ); | |
sv.writeExternal( out ); | |
ObjectInputStream in = null; | |
byte[] data = baos.toByteArray(); | |
in = new ObjectInputStream( new ByteArrayInputStream( data ) ); | |
ServerStringValue sv2 = new ServerStringValue( at ); | |
sv2.readExternal( in ); | |
assertEquals( sv, sv2 ); | |
} | |
} |