10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.jndi.ldap;
27
28 import javax.naming.*;
29 import javax.naming.directory.*;
30 import java.util.Hashtable;
31 import java.util.Vector;
32
33 /**
34 * Netscape's 3.1 servers have some schema bugs:
35 * - It puts quotes around OIDs (such as those for SUP, SYNTAX).
36 * - When you try to write out the MUST/MAY list (such as "MUST cn"),
37 * it wants ("MUST (cn)") instead
38 */
39
40 final class LdapSchemaParser {
41
42 // do debugging
43 private static final boolean debug = false;
44
45
46 // names of attribute IDs in the LDAP schema entry
47 static final String OBJECTCLASSDESC_ATTR_ID = "objectClasses";
48 static final String ATTRIBUTEDESC_ATTR_ID = "attributeTypes";
49 static final String SYNTAXDESC_ATTR_ID = "ldapSyntaxes";
50 static final String MATCHRULEDESC_ATTR_ID = "matchingRules";
124 attributeDefAttr = schemaAttrs.get(ATTRIBUTEDESC_ATTR_ID);
125 if(attributeDefAttr != null) {
126 attrDescs2AttrDefs(attributeDefAttr, schemaRoot);
127 }
128
129 syntaxDefAttr = schemaAttrs.get(SYNTAXDESC_ATTR_ID);
130 if(syntaxDefAttr != null) {
131 syntaxDescs2SyntaxDefs(syntaxDefAttr, schemaRoot);
132 }
133
134 matchRuleDefAttr = schemaAttrs.get(MATCHRULEDESC_ATTR_ID);
135 if(matchRuleDefAttr != null) {
136 matchRuleDescs2MatchRuleDefs(matchRuleDefAttr, schemaRoot);
137 }
138 }
139
140 final private static DirContext objectDescs2ClassDefs(Attribute objDescsAttr,
141 LdapSchemaCtx schemaRoot)
142 throws NamingException {
143
144 NamingEnumeration objDescs;
145 Attributes objDef;
146 LdapSchemaCtx classDefTree;
147
148 // create the class def subtree
149 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
150 attrs.put(CLASS_DEF_ATTRS[0], CLASS_DEF_ATTRS[1]);
151 classDefTree = schemaRoot.setup(LdapSchemaCtx.OBJECTCLASS_ROOT,
152 OBJECTCLASS_DEFINITION_NAME, attrs);
153
154 objDescs = objDescsAttr.getAll();
155 String currentName;
156 while(objDescs.hasMore()) {
157 String objDesc = (String)objDescs.next();
158 try {
159 Object[] def = desc2Def(objDesc);
160 currentName = (String) def[0];
161 objDef = (Attributes) def[1];
162 classDefTree.setup(LdapSchemaCtx.OBJECTCLASS,
163 currentName, objDef);
164 } catch (NamingException ne) {
165 // error occurred while parsing, ignore current entry
166 }
167 }
168
169 return classDefTree;
170 }
171
172 final private static DirContext attrDescs2AttrDefs(Attribute attributeDescAttr,
173 LdapSchemaCtx schemaRoot)
174 throws NamingException {
175
176 NamingEnumeration attrDescs;
177 Attributes attrDef;
178 LdapSchemaCtx attrDefTree;
179
180 // create the AttributeDef subtree
181 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
182 attrs.put(ATTR_DEF_ATTRS[0], ATTR_DEF_ATTRS[1]);
183 attrDefTree = schemaRoot.setup(LdapSchemaCtx.ATTRIBUTE_ROOT,
184 ATTRIBUTE_DEFINITION_NAME, attrs);
185
186 attrDescs = attributeDescAttr.getAll();
187 String currentName;
188 while(attrDescs.hasMore()) {
189 String attrDesc = (String)attrDescs.next();
190 try {
191 Object[] def = desc2Def(attrDesc);
192 currentName = (String) def[0];
193 attrDef = (Attributes) def[1];
194 attrDefTree.setup(LdapSchemaCtx.ATTRIBUTE,
195 currentName, attrDef);
196 } catch (NamingException ne) {
197 // error occurred while parsing, ignore current entry
198 }
199 }
200
201 return attrDefTree;
202 }
203
204 final private static DirContext syntaxDescs2SyntaxDefs(
205 Attribute syntaxDescAttr,
206 LdapSchemaCtx schemaRoot)
207 throws NamingException {
208
209 NamingEnumeration syntaxDescs;
210 Attributes syntaxDef;
211 LdapSchemaCtx syntaxDefTree;
212
213 // create the SyntaxDef subtree
214 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
215 attrs.put(SYNTAX_DEF_ATTRS[0], SYNTAX_DEF_ATTRS[1]);
216 syntaxDefTree = schemaRoot.setup(LdapSchemaCtx.SYNTAX_ROOT,
217 SYNTAX_DEFINITION_NAME, attrs);
218
219 syntaxDescs = syntaxDescAttr.getAll();
220 String currentName;
221 while(syntaxDescs.hasMore()) {
222 String syntaxDesc = (String)syntaxDescs.next();
223 try {
224 Object[] def = desc2Def(syntaxDesc);
225 currentName = (String) def[0];
226 syntaxDef = (Attributes) def[1];
227 syntaxDefTree.setup(LdapSchemaCtx.SYNTAX,
228 currentName, syntaxDef);
229 } catch (NamingException ne) {
230 // error occurred while parsing, ignore current entry
231 }
232 }
233
234 return syntaxDefTree;
235 }
236
237 final private static DirContext matchRuleDescs2MatchRuleDefs(
238 Attribute matchRuleDescAttr,
239 LdapSchemaCtx schemaRoot)
240 throws NamingException {
241
242 NamingEnumeration matchRuleDescs;
243 Attributes matchRuleDef;
244 LdapSchemaCtx matchRuleDefTree;
245
246 // create the MatchRuleDef subtree
247 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
248 attrs.put(MATCHRULE_DEF_ATTRS[0], MATCHRULE_DEF_ATTRS[1]);
249 matchRuleDefTree = schemaRoot.setup(LdapSchemaCtx.MATCHRULE_ROOT,
250 MATCHRULE_DEFINITION_NAME, attrs);
251
252 matchRuleDescs = matchRuleDescAttr.getAll();
253 String currentName;
254 while(matchRuleDescs.hasMore()) {
255 String matchRuleDesc = (String)matchRuleDescs.next();
256 try {
257 Object[] def = desc2Def(matchRuleDesc);
258 currentName = (String) def[0];
259 matchRuleDef = (Attributes) def[1];
260 matchRuleDefTree.setup(LdapSchemaCtx.MATCHRULE,
261 currentName, matchRuleDef);
262 } catch (NamingException ne) {
503 switch( string.charAt(pos[0]) ) {
504 case OID_LIST_BEGIN:
505 return readQDescrList(string, pos);
506 case SINGLE_QUOTE:
507 return readQDString(string, pos);
508 default:
509 throw new InvalidAttributeValueException("unexpected oids " +
510 "string: " + string);
511 }
512 }
513
514 /**
515 * qdescrlist = [ qdescr *( qdescr ) ]
516 * qdescr = whsp "'" descr "'" whsp
517 * descr = keystring
518 */
519 final private static String[] readQDescrList(String string, int[] pos)
520 throws NamingException {
521
522 int begin, end;
523 Vector values = new Vector(5);
524
525 if (debug) {
526 System.err.println("ReadQDescrList: pos="+pos[0]);
527 }
528
529 pos[0]++; // skip '('
530 skipWhitespace(string, pos);
531 begin = pos[0];
532 end = string.indexOf(OID_LIST_END, begin);
533
534 if(end == -1) {
535 throw new InvalidAttributeValueException ("oidlist has no end "+
536 "mark: " + string);
537 }
538
539 while(begin < end) {
540 String[] one = readQDString(string, pos);
541
542 if (debug) {
543 System.err.println("ReadQDescrList: found '" + one[0] +
544 "' at begin=" + begin + " end =" + end);
545 }
546
547 values.addElement(one[0]);
548 skipWhitespace(string, pos);
549 begin = pos[0];
550 }
551
552 pos[0] = end+1; // skip ')'
553
554 String[] answer = new String[values.size()];
555 for (int i = 0; i < answer.length; i++) {
556 answer[i] = (String)values.elementAt(i);
557 }
558 return answer;
559 }
560
561 final private static String[] readWOID(String string, int[] pos)
562 throws NamingException {
563
564 if (debug) {
565 System.err.println("readWOIDs: pos="+pos[0]);
566 }
567
568 skipWhitespace(string, pos);
569
570 if (string.charAt(pos[0]) == SINGLE_QUOTE) {
571 // %%% workaround for Netscape schema bug
572 return readQDString(string, pos);
573 }
574
575 int begin, end;
576
597 * oidlist = woid *( "$" woid )
598 */
599 final private static String[] readOIDs(String string, int[] pos)
600 throws NamingException {
601
602 if (debug) {
603 System.err.println("readOIDs: pos="+pos[0]);
604 }
605
606 skipWhitespace(string, pos);
607
608 // Single OID
609 if (string.charAt(pos[0]) != OID_LIST_BEGIN) {
610 return readWOID(string, pos);
611 }
612
613 // Multiple OIDs
614
615 int begin, cur, end;
616 String oidName = null;
617 Vector values = new Vector(5);
618
619 if (debug) {
620 System.err.println("ReadOIDList: pos="+pos[0]);
621 }
622
623 pos[0]++;
624 skipWhitespace(string, pos);
625 begin = pos[0];
626 end = string.indexOf(OID_LIST_END, begin);
627 cur = string.indexOf(OID_SEPARATOR, begin);
628
629 if(end == -1) {
630 throw new InvalidAttributeValueException ("oidlist has no end "+
631 "mark: " + string);
632 }
633
634 if(cur == -1 || end < cur) {
635 cur = end;
636 }
637
646 pos[0] = cur + 1;
647 skipWhitespace(string, pos);
648 begin = pos[0];
649 cur = string.indexOf(OID_SEPARATOR, begin);
650 if(debug) {System.err.println("ReadOIDList: begin = " + begin);}
651 }
652
653 if (debug) {
654 System.err.println("ReadOIDList: found '" + oidName +
655 "' at begin=" + begin + " end =" + end);
656 }
657
658 int wsBegin = findTrailingWhitespace(string, end - 1);
659 oidName = string.substring(begin, wsBegin);
660 values.addElement(oidName);
661
662 pos[0] = end+1;
663
664 String[] answer = new String[values.size()];
665 for (int i = 0; i < answer.length; i++) {
666 answer[i] = (String)values.elementAt(i);
667 }
668 return answer;
669 }
670
671 // ----------------- "unparser" methods
672 // Methods that are used for translating a node in the schema tree
673 // into RFC2252 format for storage back into the LDAP directory
674 /*
675 static Attributes JNDI2LDAPSchema(DirContext schemaRoot)
676 throws NamingException {
677
678 Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID);
679 Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID);
680 Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID);
681 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
682 DirContext classDefs, attributeDefs, syntaxDefs;
683 Attributes classDefsAttrs, attributeDefsAttrs, syntaxDefsAttrs;
684 NamingEnumeration defs;
685 Object obj;
686 int i = 0;
826 count++;
827 }
828
829 attr = attrs.get(MUST_ID);
830 if (attr != null) {
831 objectDesc.append(writeOIDs(attr));
832 count++;
833 }
834
835 attr = attrs.get(MAY_ID);
836 if (attr != null) {
837 objectDesc.append(writeOIDs(attr));
838 count++;
839 }
840
841 // process any remaining attributes
842 if (count < attrs.size()) {
843 String attrId = null;
844
845 // use enumeration because attribute ID is not known
846 for (NamingEnumeration ae = attrs.getAll();
847 ae.hasMoreElements(); ) {
848
849 attr = (Attribute)ae.next();
850 attrId = attr.getID();
851
852 // skip those already processed
853 if (attrId.equals(NUMERICOID_ID) ||
854 attrId.equals(NAME_ID) ||
855 attrId.equals(SUP_ID) ||
856 attrId.equals(MAY_ID) ||
857 attrId.equals(MUST_ID) ||
858 attrId.equals(STRUCTURAL_ID) ||
859 attrId.equals(DESC_ID) ||
860 attrId.equals(AUXILARY_ID) ||
861 attrId.equals(ABSTRACT_ID) ||
862 attrId.equals(OBSOLETE_ID)) {
863 continue;
864
865 } else {
866 objectDesc.append(writeQDStrings(attr));
867 }
868 }
869 }
956 count++;
957 }
958
959 attr = attrs.get(NO_USER_MOD_ID);
960 if (attr != null) {
961 attrDesc.append(writeBoolean(attr));
962 count++;
963 }
964
965 attr = attrs.get(USAGE_ID);
966 if (attr != null) {
967 attrDesc.append(writeQDString(attr));
968 count++;
969 }
970
971 // process any remaining attributes
972 if (count < attrs.size()) {
973 String attrId = null;
974
975 // use enumeration because attribute ID is not known
976 for (NamingEnumeration ae = attrs.getAll();
977 ae.hasMoreElements(); ) {
978
979 attr = (Attribute)ae.next();
980 attrId = attr.getID();
981
982 // skip those already processed
983 if (attrId.equals(NUMERICOID_ID) ||
984 attrId.equals(NAME_ID) ||
985 attrId.equals(SYNTAX_ID) ||
986 attrId.equals(DESC_ID) ||
987 attrId.equals(SINGLE_VAL_ID) ||
988 attrId.equals(EQUALITY_ID) ||
989 attrId.equals(ORDERING_ID) ||
990 attrId.equals(SUBSTR_ID) ||
991 attrId.equals(NO_USER_MOD_ID) ||
992 attrId.equals(USAGE_ID) ||
993 attrId.equals(SUP_ID) ||
994 attrId.equals(COLLECTIVE_ID) ||
995 attrId.equals(OBSOLETE_ID)) {
996 continue;
997
998 } else {
999 attrDesc.append(writeQDStrings(attr));
1023 attr = attrs.get(NUMERICOID_ID);
1024 if (attr != null) {
1025 syntaxDesc.append(writeNumericOID(attr));
1026 count++;
1027 } else {
1028 throw new ConfigurationException("Attribute type doesn't" +
1029 "have a numeric OID");
1030 }
1031
1032 attr = attrs.get(DESC_ID);
1033 if (attr != null) {
1034 syntaxDesc.append(writeQDString(attr));
1035 count++;
1036 }
1037
1038 // process any remaining attributes
1039 if (count < attrs.size()) {
1040 String attrId = null;
1041
1042 // use enumeration because attribute ID is not known
1043 for (NamingEnumeration ae = attrs.getAll();
1044 ae.hasMoreElements(); ) {
1045
1046 attr = (Attribute)ae.next();
1047 attrId = attr.getID();
1048
1049 // skip those already processed
1050 if (attrId.equals(NUMERICOID_ID) ||
1051 attrId.equals(DESC_ID)) {
1052 continue;
1053
1054 } else {
1055 syntaxDesc.append(writeQDStrings(attr));
1056 }
1057 }
1058 }
1059
1060 syntaxDesc.append(")");
1061
1062 return syntaxDesc.toString();
1063 }
1064
1065 /**
1066 * Translate attributes that describe an attribute matching rule
1100 attr = attrs.get(OBSOLETE_ID);
1101 if (attr != null) {
1102 matchRuleDesc.append(writeBoolean(attr));
1103 count++;
1104 }
1105
1106 attr = attrs.get(SYNTAX_ID);
1107 if (attr != null) {
1108 matchRuleDesc.append(writeWOID(attr));
1109 count++;
1110 } else {
1111 throw new ConfigurationException("Attribute type doesn't" +
1112 "have a syntax OID");
1113 }
1114
1115 // process any remaining attributes
1116 if (count < attrs.size()) {
1117 String attrId = null;
1118
1119 // use enumeration because attribute ID is not known
1120 for (NamingEnumeration ae = attrs.getAll();
1121 ae.hasMoreElements(); ) {
1122
1123 attr = (Attribute)ae.next();
1124 attrId = attr.getID();
1125
1126 // skip those already processed
1127 if (attrId.equals(NUMERICOID_ID) ||
1128 attrId.equals(NAME_ID) ||
1129 attrId.equals(SYNTAX_ID) ||
1130 attrId.equals(DESC_ID) ||
1131 attrId.equals(OBSOLETE_ID)) {
1132 continue;
1133
1134 } else {
1135 matchRuleDesc.append(writeQDStrings(attr));
1136 }
1137 }
1138 }
1139
1140 matchRuleDesc.append(")");
1141
1142 return matchRuleDesc.toString();
1143 }
1184 * qdescrs = qdescr / ( whsp "(" qdescrlist ")" whsp )
1185 * qdescrlist = [ qdescr *( qdescr ) ]
1186 * qdescr = whsp "'" descr "'" whsp
1187 * descr = keystring
1188 */
1189 private final String writeQDescrs(Attribute attr) throws NamingException {
1190 switch(attr.size()) {
1191 case 0:
1192 throw new InvalidAttributeValueException(
1193 attr.getID() + "has no values");
1194 case 1:
1195 return writeQDString(attr);
1196 }
1197
1198 // write QDList
1199
1200 StringBuffer qdList = new StringBuffer(attr.getID());
1201 qdList.append(WHSP);
1202 qdList.append(OID_LIST_BEGIN);
1203
1204 NamingEnumeration values = attr.getAll();
1205
1206 while(values.hasMore()) {
1207 qdList.append(WHSP);
1208 qdList.append(SINGLE_QUOTE);
1209 qdList.append((String)values.next());
1210 qdList.append(SINGLE_QUOTE);
1211 qdList.append(WHSP);
1212 }
1213
1214 qdList.append(OID_LIST_END);
1215 qdList.append(WHSP);
1216
1217 return qdList.toString();
1218 }
1219
1220 final private String writeOIDs(Attribute oidsAttr)
1221 throws NamingException {
1222
1223 switch(oidsAttr.size()) {
1224 case 0:
1225 throw new InvalidAttributeValueException(
1226 oidsAttr.getID() + "has no values");
1227
1228 case 1:
1229 if (netscapeBug) {
1230 break; // %%% write out as list to avoid crashing server
1231 }
1232 return writeWOID(oidsAttr);
1233 }
1234
1235 // write OID List
1236
1237 StringBuffer oidList = new StringBuffer(oidsAttr.getID());
1238 oidList.append(WHSP);
1239 oidList.append(OID_LIST_BEGIN);
1240
1241 NamingEnumeration values = oidsAttr.getAll();
1242 oidList.append(WHSP);
1243 oidList.append(values.next());
1244
1245 while(values.hasMore()) {
1246 oidList.append(WHSP);
1247 oidList.append(OID_SEPARATOR);
1248 oidList.append(WHSP);
1249 oidList.append((String)values.next());
1250 }
1251
1252 oidList.append(WHSP);
1253 oidList.append(OID_LIST_END);
1254 oidList.append(WHSP);
1255
1256 return oidList.toString();
1257 }
1258
1259 private final String writeBoolean(Attribute booleanAttr)
1260 throws NamingException {
1261 return booleanAttr.getID() + WHSP;
|
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.jndi.ldap;
27
28 import javax.naming.*;
29 import javax.naming.directory.*;
30 import java.util.Vector;
31
32 /**
33 * Netscape's 3.1 servers have some schema bugs:
34 * - It puts quotes around OIDs (such as those for SUP, SYNTAX).
35 * - When you try to write out the MUST/MAY list (such as "MUST cn"),
36 * it wants ("MUST (cn)") instead
37 */
38
39 final class LdapSchemaParser {
40
41 // do debugging
42 private static final boolean debug = false;
43
44
45 // names of attribute IDs in the LDAP schema entry
46 static final String OBJECTCLASSDESC_ATTR_ID = "objectClasses";
47 static final String ATTRIBUTEDESC_ATTR_ID = "attributeTypes";
48 static final String SYNTAXDESC_ATTR_ID = "ldapSyntaxes";
49 static final String MATCHRULEDESC_ATTR_ID = "matchingRules";
123 attributeDefAttr = schemaAttrs.get(ATTRIBUTEDESC_ATTR_ID);
124 if(attributeDefAttr != null) {
125 attrDescs2AttrDefs(attributeDefAttr, schemaRoot);
126 }
127
128 syntaxDefAttr = schemaAttrs.get(SYNTAXDESC_ATTR_ID);
129 if(syntaxDefAttr != null) {
130 syntaxDescs2SyntaxDefs(syntaxDefAttr, schemaRoot);
131 }
132
133 matchRuleDefAttr = schemaAttrs.get(MATCHRULEDESC_ATTR_ID);
134 if(matchRuleDefAttr != null) {
135 matchRuleDescs2MatchRuleDefs(matchRuleDefAttr, schemaRoot);
136 }
137 }
138
139 final private static DirContext objectDescs2ClassDefs(Attribute objDescsAttr,
140 LdapSchemaCtx schemaRoot)
141 throws NamingException {
142
143 NamingEnumeration<?> objDescs;
144 Attributes objDef;
145 LdapSchemaCtx classDefTree;
146
147 // create the class def subtree
148 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
149 attrs.put(CLASS_DEF_ATTRS[0], CLASS_DEF_ATTRS[1]);
150 classDefTree = schemaRoot.setup(LdapSchemaCtx.OBJECTCLASS_ROOT,
151 OBJECTCLASS_DEFINITION_NAME, attrs);
152
153 objDescs = objDescsAttr.getAll();
154 String currentName;
155 while(objDescs.hasMore()) {
156 String objDesc = (String)objDescs.next();
157 try {
158 Object[] def = desc2Def(objDesc);
159 currentName = (String) def[0];
160 objDef = (Attributes) def[1];
161 classDefTree.setup(LdapSchemaCtx.OBJECTCLASS,
162 currentName, objDef);
163 } catch (NamingException ne) {
164 // error occurred while parsing, ignore current entry
165 }
166 }
167
168 return classDefTree;
169 }
170
171 final private static DirContext attrDescs2AttrDefs(Attribute attributeDescAttr,
172 LdapSchemaCtx schemaRoot)
173 throws NamingException {
174
175 NamingEnumeration<?> attrDescs;
176 Attributes attrDef;
177 LdapSchemaCtx attrDefTree;
178
179 // create the AttributeDef subtree
180 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
181 attrs.put(ATTR_DEF_ATTRS[0], ATTR_DEF_ATTRS[1]);
182 attrDefTree = schemaRoot.setup(LdapSchemaCtx.ATTRIBUTE_ROOT,
183 ATTRIBUTE_DEFINITION_NAME, attrs);
184
185 attrDescs = attributeDescAttr.getAll();
186 String currentName;
187 while(attrDescs.hasMore()) {
188 String attrDesc = (String)attrDescs.next();
189 try {
190 Object[] def = desc2Def(attrDesc);
191 currentName = (String) def[0];
192 attrDef = (Attributes) def[1];
193 attrDefTree.setup(LdapSchemaCtx.ATTRIBUTE,
194 currentName, attrDef);
195 } catch (NamingException ne) {
196 // error occurred while parsing, ignore current entry
197 }
198 }
199
200 return attrDefTree;
201 }
202
203 final private static DirContext syntaxDescs2SyntaxDefs(
204 Attribute syntaxDescAttr,
205 LdapSchemaCtx schemaRoot)
206 throws NamingException {
207
208 NamingEnumeration<?> syntaxDescs;
209 Attributes syntaxDef;
210 LdapSchemaCtx syntaxDefTree;
211
212 // create the SyntaxDef subtree
213 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
214 attrs.put(SYNTAX_DEF_ATTRS[0], SYNTAX_DEF_ATTRS[1]);
215 syntaxDefTree = schemaRoot.setup(LdapSchemaCtx.SYNTAX_ROOT,
216 SYNTAX_DEFINITION_NAME, attrs);
217
218 syntaxDescs = syntaxDescAttr.getAll();
219 String currentName;
220 while(syntaxDescs.hasMore()) {
221 String syntaxDesc = (String)syntaxDescs.next();
222 try {
223 Object[] def = desc2Def(syntaxDesc);
224 currentName = (String) def[0];
225 syntaxDef = (Attributes) def[1];
226 syntaxDefTree.setup(LdapSchemaCtx.SYNTAX,
227 currentName, syntaxDef);
228 } catch (NamingException ne) {
229 // error occurred while parsing, ignore current entry
230 }
231 }
232
233 return syntaxDefTree;
234 }
235
236 final private static DirContext matchRuleDescs2MatchRuleDefs(
237 Attribute matchRuleDescAttr,
238 LdapSchemaCtx schemaRoot)
239 throws NamingException {
240
241 NamingEnumeration<?> matchRuleDescs;
242 Attributes matchRuleDef;
243 LdapSchemaCtx matchRuleDefTree;
244
245 // create the MatchRuleDef subtree
246 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
247 attrs.put(MATCHRULE_DEF_ATTRS[0], MATCHRULE_DEF_ATTRS[1]);
248 matchRuleDefTree = schemaRoot.setup(LdapSchemaCtx.MATCHRULE_ROOT,
249 MATCHRULE_DEFINITION_NAME, attrs);
250
251 matchRuleDescs = matchRuleDescAttr.getAll();
252 String currentName;
253 while(matchRuleDescs.hasMore()) {
254 String matchRuleDesc = (String)matchRuleDescs.next();
255 try {
256 Object[] def = desc2Def(matchRuleDesc);
257 currentName = (String) def[0];
258 matchRuleDef = (Attributes) def[1];
259 matchRuleDefTree.setup(LdapSchemaCtx.MATCHRULE,
260 currentName, matchRuleDef);
261 } catch (NamingException ne) {
502 switch( string.charAt(pos[0]) ) {
503 case OID_LIST_BEGIN:
504 return readQDescrList(string, pos);
505 case SINGLE_QUOTE:
506 return readQDString(string, pos);
507 default:
508 throw new InvalidAttributeValueException("unexpected oids " +
509 "string: " + string);
510 }
511 }
512
513 /**
514 * qdescrlist = [ qdescr *( qdescr ) ]
515 * qdescr = whsp "'" descr "'" whsp
516 * descr = keystring
517 */
518 final private static String[] readQDescrList(String string, int[] pos)
519 throws NamingException {
520
521 int begin, end;
522 Vector<String> values = new Vector<>(5);
523
524 if (debug) {
525 System.err.println("ReadQDescrList: pos="+pos[0]);
526 }
527
528 pos[0]++; // skip '('
529 skipWhitespace(string, pos);
530 begin = pos[0];
531 end = string.indexOf(OID_LIST_END, begin);
532
533 if(end == -1) {
534 throw new InvalidAttributeValueException ("oidlist has no end "+
535 "mark: " + string);
536 }
537
538 while(begin < end) {
539 String[] one = readQDString(string, pos);
540
541 if (debug) {
542 System.err.println("ReadQDescrList: found '" + one[0] +
543 "' at begin=" + begin + " end =" + end);
544 }
545
546 values.addElement(one[0]);
547 skipWhitespace(string, pos);
548 begin = pos[0];
549 }
550
551 pos[0] = end+1; // skip ')'
552
553 String[] answer = new String[values.size()];
554 for (int i = 0; i < answer.length; i++) {
555 answer[i] = values.elementAt(i);
556 }
557 return answer;
558 }
559
560 final private static String[] readWOID(String string, int[] pos)
561 throws NamingException {
562
563 if (debug) {
564 System.err.println("readWOIDs: pos="+pos[0]);
565 }
566
567 skipWhitespace(string, pos);
568
569 if (string.charAt(pos[0]) == SINGLE_QUOTE) {
570 // %%% workaround for Netscape schema bug
571 return readQDString(string, pos);
572 }
573
574 int begin, end;
575
596 * oidlist = woid *( "$" woid )
597 */
598 final private static String[] readOIDs(String string, int[] pos)
599 throws NamingException {
600
601 if (debug) {
602 System.err.println("readOIDs: pos="+pos[0]);
603 }
604
605 skipWhitespace(string, pos);
606
607 // Single OID
608 if (string.charAt(pos[0]) != OID_LIST_BEGIN) {
609 return readWOID(string, pos);
610 }
611
612 // Multiple OIDs
613
614 int begin, cur, end;
615 String oidName = null;
616 Vector<String> values = new Vector<>(5);
617
618 if (debug) {
619 System.err.println("ReadOIDList: pos="+pos[0]);
620 }
621
622 pos[0]++;
623 skipWhitespace(string, pos);
624 begin = pos[0];
625 end = string.indexOf(OID_LIST_END, begin);
626 cur = string.indexOf(OID_SEPARATOR, begin);
627
628 if(end == -1) {
629 throw new InvalidAttributeValueException ("oidlist has no end "+
630 "mark: " + string);
631 }
632
633 if(cur == -1 || end < cur) {
634 cur = end;
635 }
636
645 pos[0] = cur + 1;
646 skipWhitespace(string, pos);
647 begin = pos[0];
648 cur = string.indexOf(OID_SEPARATOR, begin);
649 if(debug) {System.err.println("ReadOIDList: begin = " + begin);}
650 }
651
652 if (debug) {
653 System.err.println("ReadOIDList: found '" + oidName +
654 "' at begin=" + begin + " end =" + end);
655 }
656
657 int wsBegin = findTrailingWhitespace(string, end - 1);
658 oidName = string.substring(begin, wsBegin);
659 values.addElement(oidName);
660
661 pos[0] = end+1;
662
663 String[] answer = new String[values.size()];
664 for (int i = 0; i < answer.length; i++) {
665 answer[i] = values.elementAt(i);
666 }
667 return answer;
668 }
669
670 // ----------------- "unparser" methods
671 // Methods that are used for translating a node in the schema tree
672 // into RFC2252 format for storage back into the LDAP directory
673 /*
674 static Attributes JNDI2LDAPSchema(DirContext schemaRoot)
675 throws NamingException {
676
677 Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID);
678 Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID);
679 Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID);
680 Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
681 DirContext classDefs, attributeDefs, syntaxDefs;
682 Attributes classDefsAttrs, attributeDefsAttrs, syntaxDefsAttrs;
683 NamingEnumeration defs;
684 Object obj;
685 int i = 0;
825 count++;
826 }
827
828 attr = attrs.get(MUST_ID);
829 if (attr != null) {
830 objectDesc.append(writeOIDs(attr));
831 count++;
832 }
833
834 attr = attrs.get(MAY_ID);
835 if (attr != null) {
836 objectDesc.append(writeOIDs(attr));
837 count++;
838 }
839
840 // process any remaining attributes
841 if (count < attrs.size()) {
842 String attrId = null;
843
844 // use enumeration because attribute ID is not known
845 for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
846 ae.hasMoreElements(); ) {
847
848 attr = ae.next();
849 attrId = attr.getID();
850
851 // skip those already processed
852 if (attrId.equals(NUMERICOID_ID) ||
853 attrId.equals(NAME_ID) ||
854 attrId.equals(SUP_ID) ||
855 attrId.equals(MAY_ID) ||
856 attrId.equals(MUST_ID) ||
857 attrId.equals(STRUCTURAL_ID) ||
858 attrId.equals(DESC_ID) ||
859 attrId.equals(AUXILARY_ID) ||
860 attrId.equals(ABSTRACT_ID) ||
861 attrId.equals(OBSOLETE_ID)) {
862 continue;
863
864 } else {
865 objectDesc.append(writeQDStrings(attr));
866 }
867 }
868 }
955 count++;
956 }
957
958 attr = attrs.get(NO_USER_MOD_ID);
959 if (attr != null) {
960 attrDesc.append(writeBoolean(attr));
961 count++;
962 }
963
964 attr = attrs.get(USAGE_ID);
965 if (attr != null) {
966 attrDesc.append(writeQDString(attr));
967 count++;
968 }
969
970 // process any remaining attributes
971 if (count < attrs.size()) {
972 String attrId = null;
973
974 // use enumeration because attribute ID is not known
975 for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
976 ae.hasMoreElements(); ) {
977
978 attr = ae.next();
979 attrId = attr.getID();
980
981 // skip those already processed
982 if (attrId.equals(NUMERICOID_ID) ||
983 attrId.equals(NAME_ID) ||
984 attrId.equals(SYNTAX_ID) ||
985 attrId.equals(DESC_ID) ||
986 attrId.equals(SINGLE_VAL_ID) ||
987 attrId.equals(EQUALITY_ID) ||
988 attrId.equals(ORDERING_ID) ||
989 attrId.equals(SUBSTR_ID) ||
990 attrId.equals(NO_USER_MOD_ID) ||
991 attrId.equals(USAGE_ID) ||
992 attrId.equals(SUP_ID) ||
993 attrId.equals(COLLECTIVE_ID) ||
994 attrId.equals(OBSOLETE_ID)) {
995 continue;
996
997 } else {
998 attrDesc.append(writeQDStrings(attr));
1022 attr = attrs.get(NUMERICOID_ID);
1023 if (attr != null) {
1024 syntaxDesc.append(writeNumericOID(attr));
1025 count++;
1026 } else {
1027 throw new ConfigurationException("Attribute type doesn't" +
1028 "have a numeric OID");
1029 }
1030
1031 attr = attrs.get(DESC_ID);
1032 if (attr != null) {
1033 syntaxDesc.append(writeQDString(attr));
1034 count++;
1035 }
1036
1037 // process any remaining attributes
1038 if (count < attrs.size()) {
1039 String attrId = null;
1040
1041 // use enumeration because attribute ID is not known
1042 for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
1043 ae.hasMoreElements(); ) {
1044
1045 attr = ae.next();
1046 attrId = attr.getID();
1047
1048 // skip those already processed
1049 if (attrId.equals(NUMERICOID_ID) ||
1050 attrId.equals(DESC_ID)) {
1051 continue;
1052
1053 } else {
1054 syntaxDesc.append(writeQDStrings(attr));
1055 }
1056 }
1057 }
1058
1059 syntaxDesc.append(")");
1060
1061 return syntaxDesc.toString();
1062 }
1063
1064 /**
1065 * Translate attributes that describe an attribute matching rule
1099 attr = attrs.get(OBSOLETE_ID);
1100 if (attr != null) {
1101 matchRuleDesc.append(writeBoolean(attr));
1102 count++;
1103 }
1104
1105 attr = attrs.get(SYNTAX_ID);
1106 if (attr != null) {
1107 matchRuleDesc.append(writeWOID(attr));
1108 count++;
1109 } else {
1110 throw new ConfigurationException("Attribute type doesn't" +
1111 "have a syntax OID");
1112 }
1113
1114 // process any remaining attributes
1115 if (count < attrs.size()) {
1116 String attrId = null;
1117
1118 // use enumeration because attribute ID is not known
1119 for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
1120 ae.hasMoreElements(); ) {
1121
1122 attr = ae.next();
1123 attrId = attr.getID();
1124
1125 // skip those already processed
1126 if (attrId.equals(NUMERICOID_ID) ||
1127 attrId.equals(NAME_ID) ||
1128 attrId.equals(SYNTAX_ID) ||
1129 attrId.equals(DESC_ID) ||
1130 attrId.equals(OBSOLETE_ID)) {
1131 continue;
1132
1133 } else {
1134 matchRuleDesc.append(writeQDStrings(attr));
1135 }
1136 }
1137 }
1138
1139 matchRuleDesc.append(")");
1140
1141 return matchRuleDesc.toString();
1142 }
1183 * qdescrs = qdescr / ( whsp "(" qdescrlist ")" whsp )
1184 * qdescrlist = [ qdescr *( qdescr ) ]
1185 * qdescr = whsp "'" descr "'" whsp
1186 * descr = keystring
1187 */
1188 private final String writeQDescrs(Attribute attr) throws NamingException {
1189 switch(attr.size()) {
1190 case 0:
1191 throw new InvalidAttributeValueException(
1192 attr.getID() + "has no values");
1193 case 1:
1194 return writeQDString(attr);
1195 }
1196
1197 // write QDList
1198
1199 StringBuffer qdList = new StringBuffer(attr.getID());
1200 qdList.append(WHSP);
1201 qdList.append(OID_LIST_BEGIN);
1202
1203 NamingEnumeration<?> values = attr.getAll();
1204
1205 while(values.hasMore()) {
1206 qdList.append(WHSP);
1207 qdList.append(SINGLE_QUOTE);
1208 qdList.append((String)values.next());
1209 qdList.append(SINGLE_QUOTE);
1210 qdList.append(WHSP);
1211 }
1212
1213 qdList.append(OID_LIST_END);
1214 qdList.append(WHSP);
1215
1216 return qdList.toString();
1217 }
1218
1219 final private String writeOIDs(Attribute oidsAttr)
1220 throws NamingException {
1221
1222 switch(oidsAttr.size()) {
1223 case 0:
1224 throw new InvalidAttributeValueException(
1225 oidsAttr.getID() + "has no values");
1226
1227 case 1:
1228 if (netscapeBug) {
1229 break; // %%% write out as list to avoid crashing server
1230 }
1231 return writeWOID(oidsAttr);
1232 }
1233
1234 // write OID List
1235
1236 StringBuffer oidList = new StringBuffer(oidsAttr.getID());
1237 oidList.append(WHSP);
1238 oidList.append(OID_LIST_BEGIN);
1239
1240 NamingEnumeration<?> values = oidsAttr.getAll();
1241 oidList.append(WHSP);
1242 oidList.append(values.next());
1243
1244 while(values.hasMore()) {
1245 oidList.append(WHSP);
1246 oidList.append(OID_SEPARATOR);
1247 oidList.append(WHSP);
1248 oidList.append((String)values.next());
1249 }
1250
1251 oidList.append(WHSP);
1252 oidList.append(OID_LIST_END);
1253 oidList.append(WHSP);
1254
1255 return oidList.toString();
1256 }
1257
1258 private final String writeBoolean(Attribute booleanAttr)
1259 throws NamingException {
1260 return booleanAttr.getID() + WHSP;
|