package com.hwlcn.ldap.ldap.sdk.schema; import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.LinkedHashMap; import com.hwlcn.ldap.ldap.sdk.LDAPException; import com.hwlcn.ldap.ldap.sdk.ResultCode; import com.hwlcn.core.annotation.NotMutable; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.util.ThreadSafetyLevel; import static com.hwlcn.ldap.ldap.sdk.schema.SchemaMessages.*; import static com.hwlcn.ldap.util.StaticUtils.*; import static com.hwlcn.ldap.util.Validator.*; @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class AttributeSyntaxDefinition extends SchemaElement { private static final long serialVersionUID = 8593718232711987488L; private final Map<String,String[]> extensions; private final String description; private final String attributeSyntaxString; private final String oid; public AttributeSyntaxDefinition(final String s) throws LDAPException { ensureNotNull(s); attributeSyntaxString = s.trim(); final int length = attributeSyntaxString.length(); if (length == 0) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_EMPTY.get()); } else if (attributeSyntaxString.charAt(0) != '(') { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_NO_OPENING_PAREN.get( attributeSyntaxString)); } int pos = skipSpaces(attributeSyntaxString, 1, length); StringBuilder buffer = new StringBuilder(); pos = readOID(attributeSyntaxString, pos, length, buffer); oid = buffer.toString(); String descr = null; final Map<String,String[]> exts = new LinkedHashMap<String,String[]>(); while (true) { pos = skipSpaces(attributeSyntaxString, pos, length); final int tokenStartPos = pos; while ((pos < length) && (attributeSyntaxString.charAt(pos) != ' ')) { pos++; } final String token = attributeSyntaxString.substring(tokenStartPos, pos); final String lowerToken = toLowerCase(token); if (lowerToken.equals(")")) { if (pos < length) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_CLOSE_NOT_AT_END.get( attributeSyntaxString)); } break; } else if (lowerToken.equals("desc")) { if (descr == null) { pos = skipSpaces(attributeSyntaxString, pos, length); buffer = new StringBuilder(); pos = readQDString(attributeSyntaxString, pos, length, buffer); descr = buffer.toString(); } else { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_MULTIPLE_DESC.get( attributeSyntaxString)); } } else if (lowerToken.startsWith("x-")) { pos = skipSpaces(attributeSyntaxString, pos, length); final ArrayList<String> valueList = new ArrayList<String>(); pos = readQDStrings(attributeSyntaxString, pos, length, valueList); final String[] values = new String[valueList.size()]; valueList.toArray(values); if (exts.containsKey(token)) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_DUP_EXT.get( attributeSyntaxString, token)); } exts.put(token, values); } else { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTRSYNTAX_DECODE_UNEXPECTED_TOKEN.get( attributeSyntaxString, token)); } } description = descr; extensions = Collections.unmodifiableMap(exts); } public AttributeSyntaxDefinition(final String oid, final String description, final Map<String,String[]> extensions) { ensureNotNull(oid); this.oid = oid; this.description = description; if (extensions == null) { this.extensions = Collections.emptyMap(); } else { this.extensions = Collections.unmodifiableMap(extensions); } final StringBuilder buffer = new StringBuilder(); createDefinitionString(buffer); attributeSyntaxString = buffer.toString(); } private void createDefinitionString(final StringBuilder buffer) { buffer.append("( "); buffer.append(oid); if (description != null) { buffer.append(" DESC '"); encodeValue(description, buffer); buffer.append('\''); } for (final Map.Entry<String,String[]> e : extensions.entrySet()) { final String name = e.getKey(); final String[] values = e.getValue(); if (values.length == 1) { buffer.append(' '); buffer.append(name); buffer.append(" '"); encodeValue(values[0], buffer); buffer.append('\''); } else { buffer.append(' '); buffer.append(name); buffer.append(" ("); for (final String value : values) { buffer.append(" '"); encodeValue(value, buffer); buffer.append('\''); } buffer.append(" )"); } } buffer.append(" )"); } public String getOID() { return oid; } public String getDescription() { return description; } public Map<String,String[]> getExtensions() { return extensions; } @Override() public int hashCode() { return oid.hashCode(); } @Override() public boolean equals(final Object o) { if (o == null) { return false; } if (o == this) { return true; } if (! (o instanceof AttributeSyntaxDefinition)) { return false; } final AttributeSyntaxDefinition d = (AttributeSyntaxDefinition) o; return (oid.equals(d.oid) && bothNullOrEqualIgnoreCase(description, d.description) && extensionsEqual(extensions, d.extensions)); } @Override() public String toString() { return attributeSyntaxString; } }