1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.entry;
20
21
22 import java.io.IOException;
23 import java.io.ObjectInput;
24 import java.io.ObjectOutput;
25
26 import javax.naming.NamingException;
27 import javax.naming.directory.InvalidAttributeValueException;
28
29 import org.apache.directory.shared.asn1.primitives.OID;
30 import org.apache.directory.shared.ldap.entry.EntryAttribute;
31 import org.apache.directory.shared.ldap.entry.Value;
32 import org.apache.directory.shared.ldap.entry.client.ClientBinaryValue;
33 import org.apache.directory.shared.ldap.entry.client.ClientStringValue;
34 import org.apache.directory.shared.ldap.entry.client.DefaultClientAttribute;
35 import org.apache.directory.shared.ldap.schema.AttributeType;
36 import org.apache.directory.shared.ldap.util.StringTools;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46
47 public final class DefaultServerAttribute extends DefaultClientAttribute implements ServerAttribute
48 {
49 public static final long serialVersionUID = 1L;
50
51
52 private static final Logger LOG = LoggerFactory.getLogger( DefaultServerAttribute.class );
53
54
55 private AttributeType attributeType;
56
57
58
59
60
61
62
63
64
65
66
67 private String getUpId( AttributeType at )
68 {
69 String atUpId = at.getName();
70
71 if ( atUpId == null )
72 {
73 atUpId = at.getOid();
74 }
75
76 return atUpId;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public DefaultServerAttribute( AttributeType attributeType, EntryAttribute attribute )
93 {
94
95 this.attributeType = attributeType;
96 this.id = attribute.getId();
97 this.upId = attribute.getUpId();
98
99 if ( attribute instanceof ServerAttribute )
100 {
101 isHR = attribute.isHR();
102
103
104 for ( Value<?> value:attribute )
105 {
106 add( value.clone() );
107 }
108 }
109 else
110 {
111
112 try
113 {
114 isHR = attributeType.getSyntax().isHumanReadable();
115 }
116 catch ( NamingException ne )
117 {
118
119 }
120
121
122
123 for ( Value<?> clientValue:attribute )
124 {
125 Value<?> serverValue = null;
126
127
128 if ( clientValue instanceof ClientStringValue )
129 {
130 if ( isHR )
131 {
132 serverValue = new ServerStringValue( attributeType, (String)clientValue.get() );
133 }
134 else
135 {
136
137 serverValue = new ServerBinaryValue( attributeType,
138 StringTools.getBytesUtf8( (String)clientValue.get() ) );
139 }
140 }
141 else if ( clientValue instanceof ClientBinaryValue )
142 {
143 if ( isHR )
144 {
145
146 serverValue = new ServerStringValue( attributeType,
147 StringTools.utf8ToString( (byte[])clientValue.get() ) );
148 }
149 else
150 {
151 serverValue = new ServerBinaryValue( attributeType, (byte[])clientValue.get() );
152 }
153 }
154
155 add( serverValue );
156 }
157 }
158 }
159
160
161
162
163
164
165
166
167
168 public DefaultServerAttribute( AttributeType attributeType )
169 {
170 if ( attributeType == null )
171 {
172 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
173 }
174
175 setAttributeType( attributeType );
176 }
177
178
179
180
181
182
183
184
185 public DefaultServerAttribute( String upId, AttributeType attributeType )
186 {
187 if ( attributeType == null )
188 {
189 String message = "The AttributeType parameter should not be null";
190 LOG.error( message );
191 throw new IllegalArgumentException( message );
192 }
193
194 setAttributeType( attributeType );
195 setUpId( upId );
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209 public DefaultServerAttribute( AttributeType attributeType, Value<?>... vals )
210 {
211 this( null, attributeType, vals );
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 public DefaultServerAttribute( String upId, AttributeType attributeType, Value<?>... vals )
229 {
230 if ( attributeType == null )
231 {
232 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
233 }
234
235 setAttributeType( attributeType );
236 setUpId( upId, attributeType );
237 add( vals );
238 }
239
240
241
242
243
244
245
246
247 public DefaultServerAttribute( AttributeType attributeType, String... vals )
248 {
249 this( null, attributeType, vals );
250 }
251
252
253
254
255
256
257
258
259
260 public DefaultServerAttribute( String upId, AttributeType attributeType, String... vals )
261 {
262 if ( attributeType == null )
263 {
264 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
265 }
266
267 setAttributeType( attributeType );
268 add( vals );
269 setUpId( upId, attributeType );
270 }
271
272
273
274
275
276
277
278
279 public DefaultServerAttribute( AttributeType attributeType, byte[]... vals )
280 {
281 this( null, attributeType, vals );
282 }
283
284
285
286
287
288
289
290
291
292 public DefaultServerAttribute( String upId, AttributeType attributeType, byte[]... vals )
293 {
294 if ( attributeType == null )
295 {
296 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
297 }
298
299 setAttributeType( attributeType );
300 add( vals );
301 setUpId( upId, attributeType );
302 }
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 public int add( byte[]... vals )
331 {
332 if ( !isHR )
333 {
334 int nbAdded = 0;
335
336 for ( byte[] val:vals )
337 {
338 Value<?> value = new ServerBinaryValue( attributeType, val );
339
340 try
341 {
342 value.normalize();
343 }
344 catch( NamingException ne )
345 {
346
347 LOG.error( "The value '" + val + "' can't be normalized, it hasn't been added" );
348 return 0;
349 }
350
351 if ( add( value ) != 0 )
352 {
353 nbAdded++;
354 }
355 else
356 {
357 LOG.error( "The value '" + val + "' is incorrect, it hasn't been added" );
358 }
359 }
360
361 return nbAdded;
362 }
363 else
364 {
365
366 return 0;
367 }
368 }
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 public int add( String... vals )
389 {
390 if ( isHR )
391 {
392 int nbAdded = 0;
393
394 for ( String val:vals )
395 {
396 if ( add( new ServerStringValue( attributeType, val ) ) != 0 )
397 {
398 nbAdded++;
399 }
400 else
401 {
402 LOG.error( "The value '" + val + "' is incorrect, it hasn't been added" );
403 }
404 }
405
406 return nbAdded;
407 }
408 else
409 {
410
411 return 0;
412 }
413 }
414
415
416
417
418
419
420
421 public int add( Value<?>... vals )
422 {
423 int nbAdded = 0;
424
425 for ( Value<?> val:vals )
426 {
427 try
428 {
429 if ( attributeType.getSyntax().isHumanReadable() )
430 {
431 if ( val == null )
432 {
433 Value<String> nullSV = new ServerStringValue( attributeType, (String)null );
434
435 if ( !values.contains( nullSV ) )
436 {
437 values.add( nullSV );
438 nbAdded++;
439 }
440 }
441 else if ( val instanceof ServerStringValue )
442 {
443 if ( !values.contains( val ) )
444 {
445 if ( values.add( val ) )
446 {
447 nbAdded++;
448 }
449 }
450 }
451 else if ( val instanceof ClientStringValue )
452 {
453
454 Value<String> serverStringValue = new ServerStringValue( attributeType, (String)val.get() );
455
456 if ( !values.contains( serverStringValue ) )
457 {
458 if ( values.add( serverStringValue ) )
459 {
460 nbAdded++;
461 }
462 }
463 }
464 else
465 {
466 String message = "The value must be a String, as its AttributeType is H/R";
467 LOG.error( message );
468 }
469 }
470 else
471 {
472 if ( val == null )
473 {
474 Value<byte[]> nullSV = new ServerBinaryValue( attributeType, (byte[])null );
475
476 if ( !values.contains( nullSV ) )
477 {
478 values.add( nullSV );
479 nbAdded++;
480 }
481 }
482 else if ( ( val instanceof ClientBinaryValue ) )
483 {
484 Value<byte[]> serverBinaryValue = new ServerBinaryValue( attributeType, (byte[])val.get() );
485
486 if ( !values.contains( serverBinaryValue ) )
487 {
488 if ( values.add( serverBinaryValue ) )
489 {
490 nbAdded++;
491 }
492 }
493 }
494 else if ( val instanceof ServerBinaryValue )
495 {
496 if ( !values.contains( val ) )
497 {
498 if ( values.add( val ) )
499 {
500 nbAdded++;
501 }
502 }
503 }
504 else
505 {
506 String message = "The value must be a byte[], as its AttributeType is not H/R";
507 LOG.error( message );
508 }
509 }
510 }
511 catch ( NamingException ne )
512 {
513 String message = "Error while adding value '" + val.toString() +"' : " + ne.getMessage();
514 LOG.error( message );
515 }
516 }
517
518 return nbAdded;
519 }
520
521
522
523
524
525
526 public void clear()
527 {
528 values.clear();
529 }
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545 public boolean contains( byte[]... vals )
546 {
547 if ( !isHR )
548 {
549
550
551 for ( byte[] val:vals )
552 {
553 ServerBinaryValue value = new ServerBinaryValue( attributeType, val );
554
555 try
556 {
557 value.normalize();
558 }
559 catch ( NamingException ne )
560 {
561 return false;
562 }
563
564 if ( !values.contains( value ) )
565 {
566 return false;
567 }
568 }
569
570 return true;
571 }
572 else
573 {
574 return false;
575 }
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592 public boolean contains( String... vals )
593 {
594 if ( isHR )
595 {
596
597
598 for ( String val:vals )
599 {
600 ServerStringValue value = new ServerStringValue( attributeType, val );
601
602 if ( !values.contains( value ) )
603 {
604 return false;
605 }
606 }
607
608 return true;
609 }
610 else
611 {
612 return false;
613 }
614 }
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629 public boolean contains( Value<?>... vals )
630 {
631
632
633
634 if ( isHR )
635 {
636 for ( Value<?> val:vals )
637 {
638 if ( val instanceof ServerStringValue )
639 {
640 if ( !values.contains( val ) )
641 {
642 return false;
643 }
644 }
645 else if ( val instanceof ClientStringValue )
646 {
647 ServerStringValue serverValue = new ServerStringValue( attributeType, (String)val.get() );
648
649 if ( !values.contains( serverValue ) )
650 {
651 return false;
652 }
653 }
654 else
655 {
656
657 return false;
658 }
659 }
660 }
661 else
662 {
663 for ( Value<?> val:vals )
664 {
665 if ( val instanceof ClientBinaryValue )
666 {
667 if ( !values.contains( val ) )
668 {
669 return false;
670 }
671 }
672 else
673 {
674
675 return false;
676 }
677 }
678 }
679
680 return true;
681 }
682
683
684
685
686
687
688
689 public AttributeType getAttributeType()
690 {
691 return attributeType;
692 }
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709 public boolean instanceOf( String attributeId ) throws InvalidAttributeValueException
710 {
711 String trimmedId = StringTools.trim( attributeId );
712
713 if ( StringTools.isEmpty( trimmedId ) )
714 {
715 return false;
716 }
717
718 String normId = StringTools.lowerCaseAscii( trimmedId );
719
720 for ( String name:attributeType.getNamesRef() )
721 {
722 if ( normId.equalsIgnoreCase( name ) )
723 {
724 return true;
725 }
726 }
727
728 return normId.equalsIgnoreCase( attributeType.getOid() );
729 }
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744 public boolean isValid() throws NamingException
745 {
746
747
748 if ( attributeType.isSingleValue() && ( values.size() > 1 ) )
749 {
750 return false;
751 }
752
753 for ( Value<?> value : values )
754 {
755 if ( ! value.isValid() )
756 {
757 return false;
758 }
759 }
760
761 return true;
762 }
763
764
765
766
767
768
769
770 public boolean remove( byte[]... vals )
771 {
772 if ( isHR )
773 {
774 return false;
775 }
776
777 boolean removed = true;
778
779 for ( byte[] val:vals )
780 {
781 ServerBinaryValue value = new ServerBinaryValue( attributeType, val );
782 removed &= values.remove( value );
783 }
784
785 return removed;
786 }
787
788
789
790
791
792
793
794 public boolean remove( String... vals )
795 {
796 if ( !isHR )
797 {
798 return false;
799 }
800
801 boolean removed = true;
802
803 for ( String val:vals )
804 {
805 ServerStringValue value = new ServerStringValue( attributeType, val );
806 removed &= values.remove( value );
807 }
808
809 return removed;
810 }
811
812
813
814
815
816
817
818 public boolean remove( Value<?>... vals )
819 {
820 boolean removed = true;
821
822
823
824
825 if ( isHR )
826 {
827 for ( Value<?> val:vals )
828 {
829 if ( val instanceof ClientStringValue )
830 {
831 ServerStringValue ssv = new ServerStringValue( attributeType, (String)val.get() );
832 removed &= values.remove( ssv );
833 }
834 else if ( val instanceof ServerStringValue )
835 {
836 removed &= values.remove( val );
837 }
838 else
839 {
840 removed = false;
841 }
842 }
843 }
844 else
845 {
846 for ( Value<?> val:vals )
847 {
848 if ( val instanceof ClientBinaryValue )
849 {
850 ServerBinaryValue sbv = new ServerBinaryValue( attributeType, (byte[])val.get() );
851 removed &= values.remove( sbv );
852 }
853 else if ( val instanceof ServerBinaryValue )
854 {
855 removed &= values.remove( val );
856 }
857 else
858 {
859 removed = false;
860 }
861 }
862 }
863
864 return removed;
865 }
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 public void setAttributeType( AttributeType attributeType )
882 {
883 if ( attributeType == null )
884 {
885 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
886 }
887
888 this.attributeType = attributeType;
889 setUpId( null, attributeType );
890
891 try
892 {
893 if ( attributeType.getSyntax().isHumanReadable() )
894 {
895 isHR = true;
896 }
897 else
898 {
899 isHR = false;
900 }
901 }
902 catch ( NamingException ne )
903 {
904
905
906 isHR = false;
907 }
908 }
909
910
911
912
913
914
915
916
917
918
919
920
921 public void setHR( boolean isHR )
922 {
923
924 }
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942 public void setId( String id )
943 {
944 if ( !StringTools.isEmpty( StringTools.trim( id ) ) )
945 {
946 if ( attributeType.getName() == null )
947 {
948
949 if ( OID.isOID( id ) && attributeType.getOid().equals( id ) )
950 {
951
952
953 super.setId( id );
954 }
955 }
956 else
957 {
958
959
960
961 String normId = StringTools.lowerCaseAscii( StringTools.trim( id ) );
962
963 for ( String atName:attributeType.getNamesRef() )
964 {
965 if ( atName.equalsIgnoreCase( normId ) )
966 {
967
968 super.setId( normId );
969 return;
970 }
971 }
972
973
974 if ( OID.isOID( normId ) && attributeType.getOid().equals( normId ) )
975 {
976
977 super.setUpId( normId );
978 }
979 else
980 {
981
982 throw new IllegalArgumentException( "The ID '" + id + "'is incompatible with the AttributeType's id '" +
983 attributeType.getName() + "'" );
984 }
985 }
986 }
987 else
988 {
989 throw new IllegalArgumentException( "An ID cannnot be null, empty, or resolved to an emtpy" +
990 " value when trimmed" );
991 }
992 }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 public void setUpId( String upId )
1011 {
1012 if ( !StringTools.isEmpty( StringTools.trim( upId ) ) )
1013 {
1014 if ( attributeType.getName() == null )
1015 {
1016
1017 if ( OID.isOID( upId ) && attributeType.getOid().equals( upId ) )
1018 {
1019
1020
1021 super.setUpId( upId );
1022
1023 }
1024 }
1025 else
1026 {
1027
1028
1029
1030 String normUpId = StringTools.lowerCaseAscii( StringTools.trim( upId ) );
1031
1032 for ( String atId:attributeType.getNamesRef() )
1033 {
1034 if ( atId.equalsIgnoreCase( normUpId ) )
1035 {
1036
1037 super.setUpId( upId );
1038 return;
1039 }
1040 }
1041
1042
1043 if ( OID.isOID( normUpId ) && attributeType.getOid().equals( normUpId ) )
1044 {
1045
1046 super.setUpId( upId );
1047 }
1048 }
1049 }
1050 }
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 public void setUpId( String upId, AttributeType attributeType )
1074 {
1075 if ( StringTools.isEmpty( StringTools.trim( upId ) ) )
1076 {
1077 super.setUpId( getUpId( attributeType ) );
1078 this.attributeType = attributeType;
1079 }
1080 else
1081 {
1082 String name = attributeType.getName();
1083
1084 if ( name == null )
1085 {
1086
1087 if ( OID.isOID( upId ) && attributeType.getOid().equals( upId ) )
1088 {
1089
1090 super.setUpId( upId );
1091 this.attributeType = attributeType;
1092 }
1093 else
1094 {
1095
1096
1097 LOG.warn( "The upID ({}) is not an OID or is different from the AttributeType OID({})",
1098 upId, attributeType.getOid() );
1099 super.setUpId( attributeType.getOid() );
1100 this.attributeType = attributeType;
1101 }
1102 }
1103 else
1104 {
1105
1106
1107
1108 String normUpId = StringTools.lowerCaseAscii( StringTools.trim( upId ) );
1109
1110 for ( String atId:attributeType.getNamesRef() )
1111 {
1112 if ( atId.equalsIgnoreCase( normUpId ) )
1113 {
1114
1115 super.setUpId( upId );
1116 this.attributeType = attributeType;
1117 return;
1118 }
1119 }
1120
1121
1122
1123 if ( OID.isOID( normUpId ) && attributeType.getOid().equals( normUpId ) )
1124 {
1125
1126 super.setUpId( upId );
1127 this.attributeType = attributeType;
1128 }
1129 else
1130 {
1131 String message = "The upID (" + upId + ") is not an OID or is different from the AttributeType OID (" +
1132 attributeType.getOid() + ")";
1133
1134 LOG.error( message );
1135 throw new IllegalArgumentException( message );
1136 }
1137 }
1138 }
1139 }
1140
1141
1142
1143
1144
1145
1146
1147 public EntryAttribute toClientAttribute()
1148 {
1149
1150 EntryAttribute clientAttribute = new DefaultClientAttribute( upId );
1151
1152
1153 for ( Value<?> value:this )
1154 {
1155 Value<?> clientValue = null;
1156
1157 if ( value instanceof ServerStringValue )
1158 {
1159 clientValue = new ClientStringValue( (String)value.get() );
1160 }
1161 else
1162 {
1163 clientValue = new ClientBinaryValue( (byte[])value.get() );
1164 }
1165
1166 clientAttribute.add( clientValue );
1167 }
1168
1169 return clientAttribute;
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183 public void writeExternal( ObjectOutput out ) throws IOException
1184 {
1185 throw new IllegalStateException( "Cannot use standard serialization for a ServerAttribute" );
1186 }
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 public void serialize( ObjectOutput out ) throws IOException
1201 {
1202
1203 out.writeUTF( upId );
1204
1205
1206 if ( isHR != null )
1207 {
1208 out.writeBoolean( true );
1209 out.writeBoolean( isHR );
1210 }
1211 else
1212 {
1213 out.writeBoolean( false );
1214 }
1215
1216
1217 out.writeInt( size() );
1218
1219 if ( size() > 0 )
1220 {
1221
1222 for ( Value<?> value:values )
1223 {
1224
1225 if ( value instanceof ServerStringValue )
1226 {
1227 ((ServerStringValue)value).serialize( out );
1228 }
1229 else
1230 {
1231 ((ServerBinaryValue)value).serialize( out );
1232 }
1233 }
1234 }
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244 public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
1245 {
1246 throw new IllegalStateException( "Cannot use standard serialization for a ServerAttribute" );
1247 }
1248
1249
1250
1251
1252
1253 public void deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
1254 {
1255
1256 upId = in.readUTF();
1257
1258
1259 setUpId( upId );
1260
1261
1262 if ( in.readBoolean() )
1263 {
1264 isHR = in.readBoolean();
1265 }
1266
1267
1268 int nbValues = in.readInt();
1269
1270 if ( nbValues > 0 )
1271 {
1272 for ( int i = 0; i < nbValues; i++ )
1273 {
1274 Value<?> value = null;
1275
1276 if ( isHR )
1277 {
1278 value = new ServerStringValue( attributeType );
1279 ((ServerStringValue)value).deserialize( in );
1280 }
1281 else
1282 {
1283 value = new ServerBinaryValue( attributeType );
1284 ((ServerBinaryValue)value).deserialize( in );
1285 }
1286
1287 try
1288 {
1289 value.normalize();
1290 }
1291 catch ( NamingException ne )
1292 {
1293
1294 }
1295
1296 values.add( value );
1297 }
1298 }
1299 }
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312 public ServerAttribute clone()
1313 {
1314
1315 ServerAttribute clone = (ServerAttribute)super.clone();
1316
1317
1318 return clone;
1319 }
1320
1321
1322
1323
1324
1325
1326
1327 public boolean equals( Object obj )
1328 {
1329 if ( obj == this )
1330 {
1331 return true;
1332 }
1333
1334 if ( ! (obj instanceof ServerAttribute ) )
1335 {
1336 return false;
1337 }
1338
1339 ServerAttribute other = (ServerAttribute)obj;
1340
1341 if ( !attributeType.equals( other.getAttributeType() ) )
1342 {
1343 return false;
1344 }
1345
1346 if ( values.size() != other.size() )
1347 {
1348 return false;
1349 }
1350
1351 for ( Value<?> val:values )
1352 {
1353 if ( ! other.contains( val ) )
1354 {
1355 return false;
1356 }
1357 }
1358
1359 return true;
1360 }
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 public int hashCode()
1372 {
1373 int h = super.hashCode();
1374
1375 if ( attributeType != null )
1376 {
1377 h = h*17 + attributeType.hashCode();
1378 }
1379
1380 return h;
1381 }
1382
1383
1384
1385
1386
1387
1388
1389 public String toString()
1390 {
1391 StringBuilder sb = new StringBuilder();
1392
1393 if ( ( values != null ) && ( values.size() != 0 ) )
1394 {
1395 for ( Value<?> value:values )
1396 {
1397 sb.append( " " ).append( upId ).append( ": " );
1398
1399 if ( value.isNull() )
1400 {
1401 sb.append( "''" );
1402 }
1403 else
1404 {
1405 sb.append( value );
1406 }
1407
1408 sb.append( '\n' );
1409 }
1410 }
1411 else
1412 {
1413 sb.append( " " ).append( upId ).append( ": (null)\n" );
1414 }
1415
1416 return sb.toString();
1417 }
1418 }