1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.schema;
21
22
23 import java.io.Serializable;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.apache.directory.api.i18n.I18n;
33 import org.apache.directory.api.util.Strings;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public abstract class AbstractSchemaObject implements SchemaObject, Serializable
79 {
80
81 private static final long serialVersionUID = 2L;
82
83
84 protected String oid;
85
86
87 protected List<String> names;
88
89
90 protected boolean isEnabled = true;
91
92
93 protected boolean isReadOnly = false;
94
95
96 protected boolean isObsolete = false;
97
98
99 protected String description;
100
101
102 protected String specification;
103
104
105 protected String schemaName;
106
107
108 protected SchemaObjectType objectType;
109
110
111 protected Map<String, List<String>> extensions;
112
113
114 protected volatile boolean locked;
115
116
117 private int h;
118
119
120
121
122
123
124
125
126
127 protected AbstractSchemaObject( SchemaObjectType objectType, String oid )
128 {
129 this.objectType = objectType;
130 this.oid = oid;
131 extensions = new HashMap<>();
132 names = new ArrayList<>();
133 }
134
135
136
137
138
139
140
141
142 protected AbstractSchemaObject( SchemaObjectType objectType )
143 {
144 this.objectType = objectType;
145 extensions = new HashMap<>();
146 names = new ArrayList<>();
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160 @Override
161 public String getOid()
162 {
163 return oid;
164 }
165
166
167
168
169
170
171
172 @Override
173 public void setOid( String oid )
174 {
175 if ( locked )
176 {
177 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
178 }
179
180 this.oid = oid;
181 }
182
183
184
185
186
187
188
189
190 @Override
191 public List<String> getNames()
192 {
193 if ( names != null )
194 {
195 return Collections.unmodifiableList( names );
196 }
197 else
198 {
199 return Collections.emptyList();
200 }
201 }
202
203
204
205
206
207
208
209
210
211 @Override
212 public String getName()
213 {
214 if ( ( names != null ) && !names.isEmpty() )
215 {
216 return names.get( 0 );
217 }
218 else
219 {
220 return oid;
221 }
222 }
223
224
225
226
227
228
229
230
231 @Override
232 public void addName( String... namesToAdd )
233 {
234 if ( locked )
235 {
236 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
237 }
238
239 if ( !isReadOnly )
240 {
241
242 Set<String> lowerNames = new HashSet<>();
243
244
245 for ( String name : this.names )
246 {
247 lowerNames.add( Strings.toLowerCaseAscii( name ) );
248 }
249
250 for ( String name : namesToAdd )
251 {
252 if ( name != null )
253 {
254 String lowerName = Strings.toLowerCaseAscii( name );
255
256 if ( !lowerNames.contains( lowerName ) )
257 {
258 this.names.add( name );
259 lowerNames.add( lowerName );
260 }
261 }
262 }
263 }
264 }
265
266
267
268
269
270
271
272
273 @Override
274 public void setNames( List<String> names )
275 {
276 if ( locked )
277 {
278 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
279 }
280
281 if ( names == null )
282 {
283 return;
284 }
285
286 if ( !isReadOnly )
287 {
288 this.names = new ArrayList<>( names.size() );
289
290 for ( String name : names )
291 {
292 if ( name != null )
293 {
294 this.names.add( name );
295 }
296 }
297 }
298 }
299
300
301
302
303
304
305
306
307 public void setNames( String... names )
308 {
309 if ( locked )
310 {
311 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
312 }
313
314 if ( names == null )
315 {
316 return;
317 }
318
319 if ( !isReadOnly )
320 {
321 this.names.clear();
322
323 for ( String name : names )
324 {
325 if ( name != null )
326 {
327 this.names.add( name );
328 }
329 }
330 }
331 }
332
333
334
335
336
337
338
339 @Override
340 public String getDescription()
341 {
342 return description;
343 }
344
345
346
347
348
349
350
351 @Override
352 public void setDescription( String description )
353 {
354 if ( locked )
355 {
356 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
357 }
358
359 if ( !isReadOnly )
360 {
361 this.description = description;
362 }
363 }
364
365
366
367
368
369
370
371 @Override
372 public String getSpecification()
373 {
374 return specification;
375 }
376
377
378
379
380
381
382
383 @Override
384 public void setSpecification( String specification )
385 {
386 if ( locked )
387 {
388 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
389 }
390
391 if ( !isReadOnly )
392 {
393 this.specification = specification;
394 }
395 }
396
397
398
399
400
401
402
403
404 @Override
405 public boolean isEnabled()
406 {
407 return isEnabled;
408 }
409
410
411
412
413
414
415
416 @Override
417 public boolean isDisabled()
418 {
419 return !isEnabled;
420 }
421
422
423
424
425
426
427
428 @Override
429 public void setEnabled( boolean enabled )
430 {
431 if ( !isReadOnly )
432 {
433 isEnabled = enabled;
434 }
435 }
436
437
438
439
440
441
442
443 @Override
444 public boolean isReadOnly()
445 {
446 return isReadOnly;
447 }
448
449
450
451
452
453
454
455 @Override
456 public void setReadOnly( boolean readOnly )
457 {
458 if ( locked )
459 {
460 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
461 }
462
463 this.isReadOnly = readOnly;
464 }
465
466
467
468
469
470
471
472
473
474
475 @Override
476 public boolean isObsolete()
477 {
478 return isObsolete;
479 }
480
481
482
483
484
485
486
487 @Override
488 public void setObsolete( boolean obsolete )
489 {
490 if ( locked )
491 {
492 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
493 }
494
495 if ( !isReadOnly )
496 {
497 this.isObsolete = obsolete;
498 }
499 }
500
501
502
503
504
505 @Override
506 public Map<String, List<String>> getExtensions()
507 {
508 return extensions;
509 }
510
511
512
513
514
515 @Override
516 public boolean hasExtension( String extension )
517 {
518 return extensions.containsKey( Strings.toUpperCaseAscii( extension ) );
519 }
520
521
522
523
524
525 @Override
526 public List<String> getExtension( String extension )
527 {
528 String name = Strings.toUpperCaseAscii( extension );
529
530 if ( hasExtension( name ) )
531 {
532 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
533 {
534 String key = entry.getKey();
535
536 if ( name.equalsIgnoreCase( key ) )
537 {
538 return entry.getValue();
539 }
540 }
541 }
542
543 return null;
544 }
545
546
547
548
549
550
551
552 @Override
553 public void addExtension( String key, String... values )
554 {
555 if ( locked )
556 {
557 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
558 }
559
560 if ( !isReadOnly )
561 {
562 List<String> valueList = new ArrayList<>();
563
564 for ( String value : values )
565 {
566 valueList.add( value );
567 }
568
569 extensions.put( Strings.toUpperCaseAscii( key ), valueList );
570 }
571 }
572
573
574
575
576
577
578
579 @Override
580 public void addExtension( String key, List<String> values )
581 {
582 if ( locked )
583 {
584 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
585 }
586
587 if ( !isReadOnly )
588 {
589 extensions.put( Strings.toUpperCaseAscii( key ), values );
590 }
591 }
592
593
594
595
596
597
598
599 @Override
600 public void setExtensions( Map<String, List<String>> extensions )
601 {
602 if ( locked )
603 {
604 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
605 }
606
607 if ( !isReadOnly && ( extensions != null ) )
608 {
609 this.extensions = new HashMap<>();
610
611 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
612 {
613 List<String> values = new ArrayList<>();
614
615 for ( String value : entry.getValue() )
616 {
617 values.add( value );
618 }
619
620 this.extensions.put( Strings.toUpperCaseAscii( entry.getKey() ), values );
621 }
622
623 }
624 }
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 @Override
646 public SchemaObjectType getObjectType()
647 {
648 return objectType;
649 }
650
651
652
653
654
655
656
657 @Override
658 public String getSchemaName()
659 {
660 return schemaName;
661 }
662
663
664
665
666
667
668
669 @Override
670 public void setSchemaName( String schemaName )
671 {
672 if ( locked )
673 {
674 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
675 }
676
677 if ( !isReadOnly )
678 {
679 this.schemaName = schemaName;
680 }
681 }
682
683
684
685
686
687
688
689
690
691
692
693
694 @Override
695 public final int hashCode()
696 {
697 return h;
698 }
699
700
701
702
703
704 @Override
705 public boolean equals( Object o1 )
706 {
707 if ( this == o1 )
708 {
709 return true;
710 }
711
712 if ( !( o1 instanceof AbstractSchemaObject ) )
713 {
714 return false;
715 }
716
717 AbstractSchemaObject that = ( AbstractSchemaObject ) o1;
718
719
720
721
722
723 if ( !compareOid( oid, that.oid ) )
724 {
725 return false;
726 }
727
728
729 if ( names == null )
730 {
731 if ( that.names != null )
732 {
733 return false;
734 }
735 }
736 else if ( that.names == null )
737 {
738 return false;
739 }
740 else
741 {
742 int nbNames = 0;
743
744 for ( String name : names )
745 {
746 if ( !that.names.contains( name ) )
747 {
748 return false;
749 }
750
751 nbNames++;
752 }
753
754 if ( nbNames != names.size() )
755 {
756 return false;
757 }
758 }
759
760 if ( schemaName == null )
761 {
762 if ( that.schemaName != null )
763 {
764 return false;
765 }
766 }
767 else
768 {
769 if ( !schemaName.equalsIgnoreCase( that.schemaName ) )
770 {
771 return false;
772 }
773 }
774
775 if ( objectType != that.objectType )
776 {
777 return false;
778 }
779
780 if ( extensions != null )
781 {
782 if ( that.extensions == null )
783 {
784 return false;
785 }
786 else
787 {
788 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
789 {
790 String key = entry.getKey();
791
792 if ( !that.extensions.containsKey( key ) )
793 {
794 return false;
795 }
796
797 List<String> thisValues = entry.getValue();
798 List<String> thatValues = that.extensions.get( key );
799
800 if ( thisValues != null )
801 {
802 if ( thatValues == null )
803 {
804 return false;
805 }
806 else
807 {
808 if ( thisValues.size() != thatValues.size() )
809 {
810 return false;
811 }
812
813
814 }
815 }
816 else if ( thatValues != null )
817 {
818 return false;
819 }
820 }
821 }
822 }
823 else if ( that.extensions != null )
824 {
825 return false;
826 }
827
828 if ( this.isEnabled != that.isEnabled )
829 {
830 return false;
831 }
832
833 if ( this.isObsolete != that.isObsolete )
834 {
835 return false;
836 }
837
838 if ( this.isReadOnly != that.isReadOnly )
839 {
840 return false;
841 }
842
843 if ( this.description == null )
844 {
845 return that.description == null;
846 }
847 else
848 {
849 return this.description.equalsIgnoreCase( that.description );
850 }
851 }
852
853
854
855
856
857
858
859
860
861 protected boolean compareOid( String oid1, String oid2 )
862 {
863 if ( oid1 == null )
864 {
865 return oid2 == null;
866 }
867 else
868 {
869 return oid1.equals( oid2 );
870 }
871 }
872
873
874
875
876
877 @Override
878 public SchemaObject copy( SchemaObject original )
879 {
880
881 description = original.getDescription();
882
883
884 isEnabled = original.isEnabled();
885 isObsolete = original.isObsolete();
886 isReadOnly = original.isReadOnly();
887
888
889 names = new ArrayList<>();
890
891 for ( String name : original.getNames() )
892 {
893 names.add( name );
894 }
895
896
897 extensions = new HashMap<>();
898
899 for ( String key : original.getExtensions().keySet() )
900 {
901 List<String> extensionValues = original.getExtension( key );
902
903 List<String> cloneExtension = new ArrayList<>();
904
905 for ( String value : extensionValues )
906 {
907 cloneExtension.add( value );
908 }
909
910 extensions.put( key, cloneExtension );
911 }
912
913
914 schemaName = original.getSchemaName();
915
916
917 specification = original.getSpecification();
918
919 return this;
920 }
921
922
923
924
925
926
927 @Override
928 public void clear()
929 {
930
931 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
932 {
933 List<String> extensionList = entry.getValue();
934
935 extensionList.clear();
936 }
937
938 extensions.clear();
939
940
941 names.clear();
942 }
943
944
945
946
947
948 public void unlock()
949 {
950 locked = false;
951 }
952
953
954
955
956
957 @Override
958 public final void lock()
959 {
960 if ( locked )
961 {
962 return;
963 }
964
965 h = 37;
966
967
968 h += h * 17 + oid.hashCode();
969
970
971 h += h * 17 + objectType.getValue();
972
973
974 if ( ( names != null ) && !names.isEmpty() )
975 {
976 for ( String name : names )
977 {
978 h += h * 17 + name.hashCode();
979 }
980 }
981
982
983 if ( schemaName != null )
984 {
985 h += h * 17 + schemaName.hashCode();
986 }
987
988 h += h * 17 + ( isEnabled ? 1 : 0 );
989 h += h * 17 + ( isReadOnly ? 1 : 0 );
990
991
992 if ( description != null )
993 {
994 h += h * 17 + description.hashCode();
995 }
996
997
998 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
999 {
1000 String key = entry.getKey();
1001 h += h * 17 + key.hashCode();
1002
1003 List<String> values = entry.getValue();
1004
1005 if ( values != null )
1006 {
1007 for ( String value : values )
1008 {
1009 h += h * 17 + value.hashCode();
1010 }
1011 }
1012 }
1013
1014 locked = true;
1015 }
1016 }