0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: *
0015: * See the License for the specific language governing permissions and
0016: * limitations under the License.
0017: */
0018:
0019: /**
0020: * @author Alexei Y. Zakharov
0021: * @version $Revision: 1.1.2.5 $
0022: */package org.apache.harmony.jndi.provider.dns;
0023:
0024: import java.util.Enumeration;
0025: import java.util.HashSet;
0026: import java.util.Hashtable;
0027: import java.util.Iterator;
0028: import java.util.StringTokenizer;
0029:
0030: import javax.naming.Binding;
0031: import javax.naming.CannotProceedException;
0032: import javax.naming.CompositeName;
0033: import javax.naming.ConfigurationException;
0034: import javax.naming.Context;
0035: import javax.naming.InvalidNameException;
0036: import javax.naming.Name;
0037: import javax.naming.NameClassPair;
0038: import javax.naming.NameParser;
0039: import javax.naming.NamingEnumeration;
0040: import javax.naming.NamingException;
0041: import javax.naming.NoPermissionException;
0042: import javax.naming.NotContextException;
0043: import javax.naming.OperationNotSupportedException;
0044: import javax.naming.RefAddr;
0045: import javax.naming.Reference;
0046: import javax.naming.directory.Attribute;
0047: import javax.naming.directory.Attributes;
0048: import javax.naming.directory.BasicAttribute;
0049: import javax.naming.directory.BasicAttributes;
0050: import javax.naming.directory.DirContext;
0051: import javax.naming.directory.InvalidAttributeIdentifierException;
0052: import javax.naming.directory.ModificationItem;
0053: import javax.naming.directory.SearchControls;
0054: import javax.naming.directory.SearchResult;
0055: import javax.naming.spi.DirectoryManager;
0056: import javax.naming.spi.NamingManager;
0057:
0058: import org.apache.harmony.jndi.internal.nls.Messages;
0059:
0060: /**
0061: * This class represents DNS context. This is the main class and the main entry
0062: * point to DNS service provider for JNDI.
0063: *
0064: * @see dnsURLContext
0065: * @see DNSName
0066: * @see DNSNameParser
0067: */
0068: public class DNSContext implements DirContext, Cloneable {
0069:
0070: // some environment property names
0071: public static final String LOOKUP_ATTR = "org.apache.harmony.jndi.provider.dns.lookup.attr"; //$NON-NLS-1$
0072:
0073: public static final String RECURSION = "org.apache.harmony.jndi.provider.dns.recursion"; //$NON-NLS-1$
0074:
0075: public static final String TIMEOUT_INITIAL = "org.apache.harmony.jndi.provider.dns.timeout.initial"; //$NON-NLS-1$
0076:
0077: public static final String TIMEOUT_RETRIES = "org.apache.harmony.jndi.provider.dns.timeout.retries"; //$NON-NLS-1$
0078:
0079: public static final String THREADS_MAX = "org.apache.harmony.jndi.provider.dns.threads.max"; //$NON-NLS-1$
0080:
0081: // used in internal methods
0082: private static final int NAME_CLASS_SWT = 1;
0083:
0084: private static final int BINDING_SWT = 2;
0085:
0086: private DNSNameParser nameParser;
0087:
0088: private Hashtable<Object, Object> environment;
0089:
0090: private Resolver resolver;
0091:
0092: private DNSName contextName;
0093:
0094: // default values for properties that has been read from the environment
0095: private boolean authoritative = ProviderConstants.DEFAULT_AUTHORITATIVE;
0096:
0097: private int lookupAttrType = ProviderConstants.DEFAULT_LOOKUP_ATTR_TYPE;
0098:
0099: private int lookupAttrClass = ProviderConstants.DEFAULT_LOOKUP_ATTR_CLASS;
0100:
0101: private boolean recursion = ProviderConstants.DEFAULT_RECURSION;
0102:
0103: private int timeoutInitial = ProviderConstants.DEFAULT_INITIAL_TIMEOUT;
0104:
0105: private int timeoutRetries = ProviderConstants.DEFAULT_TIMEOUT_RETRIES;
0106:
0107: private int maxThreads = ProviderConstants.DEFAULT_MAX_THREADS;
0108:
0109: // <--- start of constructor section
0110:
0111: /**
0112: * A DNS context constructor. Should not be accessed directly.
0113: *
0114: * @param env
0115: * the hash table with environment variables. The context will
0116: * make a clone of given hash table.
0117: * @throws InvalidNameException
0118: * something wrong with domain names given in
0119: * <code>java.naming.provider.url</code> property
0120: * @throws ConfigurationException
0121: * if some error occurred during parsing of configuration
0122: * parameters
0123: * @throws NamingException
0124: * if some parse error occurred
0125: * @throws NullPointerException
0126: * if the environment is null
0127: *
0128: */
0129: @SuppressWarnings("unchecked")
0130: DNSContext(Hashtable<?, ?> env) throws NamingException {
0131: nameParser = new DNSNameParser();
0132: if (env == null) {
0133: // jndi.45=environment is null
0134: throw new NullPointerException(Messages
0135: .getString("jndi.45")); //$NON-NLS-1$
0136: }
0137: this .environment = (Hashtable<Object, Object>) env.clone();
0138: parseBoolProp(Context.AUTHORITATIVE);
0139: parseLookupProp();
0140: if (environment.containsKey(RECURSION)) {
0141: parseBoolProp(RECURSION);
0142: }
0143: if (environment.containsKey(TIMEOUT_INITIAL)) {
0144: parseIntProp(TIMEOUT_INITIAL);
0145: }
0146: if (environment.containsKey(TIMEOUT_RETRIES)) {
0147: parseIntProp(TIMEOUT_RETRIES);
0148: }
0149: parseIntProp(THREADS_MAX);
0150: resolver = new Resolver(timeoutInitial, timeoutRetries,
0151: maxThreads, authoritative, recursion);
0152: parseProviderUrlProp();
0153: }
0154:
0155: /**
0156: * Parses integer environment property and fills appropriate internal
0157: * variable if necessary.
0158: *
0159: * @param paramName
0160: * name of parameter
0161: * @throws NumberFormatException
0162: * if error encountered while parsing
0163: */
0164: private void parseIntProp(String paramName)
0165: throws NumberFormatException {
0166: Object tmp = environment.get(paramName);
0167:
0168: if (tmp != null && tmp instanceof String) {
0169: try {
0170: int n = Integer.parseInt((String) tmp);
0171:
0172: if (paramName.equals(TIMEOUT_RETRIES)) {
0173: timeoutRetries = n;
0174: } else if (paramName.equals(TIMEOUT_INITIAL)) {
0175: timeoutInitial = n;
0176: } else if (paramName.equals(THREADS_MAX)) {
0177: maxThreads = n;
0178: }
0179: } catch (NumberFormatException e) {
0180: throw e;
0181: }
0182: }
0183: }
0184:
0185: /**
0186: * Parses boolean environment property and fills appropriate internal
0187: * variable if necessary.
0188: *
0189: * @param paramName
0190: * name of parameter
0191: */
0192: private void parseBoolProp(String paramName) {
0193: Object tmp = environment.get(paramName);
0194: boolean val = false;
0195:
0196: if (tmp != null) {
0197: if (tmp instanceof String && tmp.equals("true")) { //$NON-NLS-1$
0198: val = true;
0199: }
0200: if (paramName.equals(Context.AUTHORITATIVE)) {
0201: authoritative = val;
0202: } else if (paramName.equals(DNSContext.RECURSION)) {
0203: recursion = val;
0204: }
0205: }
0206: }
0207:
0208: /**
0209: * Parses "lookup attribute" environment property and fills appropriate
0210: * internal variable.
0211: *
0212: * @throws ConfigurationException
0213: * if some DNS type or DNS class is unknown
0214: */
0215: private void parseLookupProp() throws ConfigurationException {
0216: Object tmp;
0217:
0218: if (environment.containsKey(LOOKUP_ATTR)) {
0219: int k;
0220: String recClassName;
0221: String recTypeName;
0222: String lookupAttr;
0223:
0224: tmp = environment.get(LOOKUP_ATTR);
0225: if (tmp instanceof String) {
0226: lookupAttr = (String) tmp;
0227: k = lookupAttr.indexOf(" "); //$NON-NLS-1$
0228: if (k > -1) {
0229: recClassName = lookupAttr.substring(0, k);
0230:
0231: lookupAttrClass = ProviderMgr
0232: .getRecordClassNumber(recClassName);
0233: if (lookupAttrClass == -1) {
0234: // jndi.46=DNS class {0} is not supported
0235: throw new ConfigurationException(Messages
0236: .getString("jndi.46", recClassName));//$NON-NLS-1$
0237: }
0238: recTypeName = lookupAttr.substring(k).trim();
0239: } else {
0240: lookupAttrClass = ProviderConstants.DEFAULT_LOOKUP_ATTR_CLASS;
0241: recTypeName = lookupAttr.trim();
0242: }
0243: lookupAttrType = ProviderMgr
0244: .getRecordTypeNumber(recTypeName);
0245: if (lookupAttrType == -1) {
0246: // jndi.47=DNS type {0} is not supported
0247: throw new ConfigurationException(Messages
0248: .getString("jndi.47", recTypeName)); //$NON-NLS-1$
0249: }
0250: }
0251: }
0252: }
0253:
0254: /**
0255: * Parses "provider URL" environment property and fills appropriate internal
0256: * variable.
0257: *
0258: * @throws NamingException
0259: * if such exception encountered while parsing
0260: */
0261: private void parseProviderUrlProp() throws NamingException {
0262: Object tmp;
0263:
0264: if (environment.containsKey(Context.PROVIDER_URL)) {
0265: tmp = environment.get(Context.PROVIDER_URL);
0266: if (tmp instanceof String) {
0267: StringTokenizer st = new StringTokenizer((String) tmp,
0268: " "); //$NON-NLS-1$
0269:
0270: while (st.hasMoreTokens()) {
0271: String token = st.nextToken();
0272: DNSPseudoURL dnsURL;
0273:
0274: try {
0275: dnsURL = new DNSPseudoURL(token);
0276: if (dnsURL.isHostIpGiven()) {
0277: resolver.addInitialServer(null, dnsURL
0278: .getHost(), dnsURL.getPort(),
0279: dnsURL.getDomain());
0280: } else {
0281: resolver.addInitialServer(dnsURL.getHost(),
0282: null, dnsURL.getPort(), dnsURL
0283: .getDomain());
0284: }
0285: if (contextName == null) {
0286: contextName = (DNSName) nameParser
0287: .parse(dnsURL.getDomain());
0288: } else {
0289: DNSName name2 = (DNSName) nameParser
0290: .parse(dnsURL.getDomain());
0291:
0292: if (name2.compareTo(contextName) != 0) {
0293: // jndi.48=conflicting domains: {0} and {1}
0294: throw new ConfigurationException(
0295: Messages
0296: .getString(
0297: "jndi.48", contextName, name2)); //$NON-NLS-1$
0298: }
0299: }
0300: } catch (IllegalArgumentException e) {
0301: // jndi.49=Unable to parse DNS URL {0}. {1}
0302: throw new ConfigurationException(
0303: Messages
0304: .getString(
0305: "jndi.49", token, e.getMessage())); //$NON-NLS-1$
0306: }
0307: }
0308: }
0309: } else {
0310: contextName = ProviderConstants.ROOT_ZONE_NAME_OBJ;
0311: }
0312: }
0313:
0314: /**
0315: * Constructs new DNS context with given name. This constructor will read
0316: * all private properties from its ancestor context. The environment will
0317: * not be parsed.
0318: *
0319: * @param ancestorCtx
0320: * an ancestor context to read all internal properties from
0321: * @param name
0322: * name of newly created context in the ancestor context
0323: */
0324: @SuppressWarnings("unchecked")
0325: DNSContext(DNSContext ancestorCtx, DNSName name) {
0326: this .contextName = (DNSName) name.clone();
0327: this .nameParser = ancestorCtx.nameParser;
0328: this .environment = (Hashtable<Object, Object>) ancestorCtx.environment
0329: .clone();
0330: this .resolver = ancestorCtx.resolver;
0331: this .authoritative = ancestorCtx.authoritative;
0332: this .lookupAttrType = ancestorCtx.lookupAttrType;
0333: this .lookupAttrClass = ancestorCtx.lookupAttrClass;
0334: this .recursion = ancestorCtx.recursion;
0335: this .timeoutInitial = ancestorCtx.timeoutInitial;
0336: this .timeoutRetries = ancestorCtx.timeoutRetries;
0337: this .maxThreads = ancestorCtx.maxThreads;
0338: }
0339:
0340: /**
0341: * Obtains all attributes associated with given name.
0342: *
0343: * @param name
0344: * domain name or composite name in string form
0345: * @return collection of found attributes
0346: * @throws NamingException
0347: * or its subtype if such has been encountered
0348: * @see DNSContext#getAttributes(Name, String[]) for more details
0349: * @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
0350: */
0351: public Attributes getAttributes(String name) throws NamingException {
0352: return getAttributes(convertNameFromStringForm(name), null);
0353: }
0354:
0355: /**
0356: * This method is not supported by the DNS provider.
0357: *
0358: * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
0359: * int, javax.naming.directory.Attributes)
0360: */
0361: public void modifyAttributes(String arg0, int arg1, Attributes arg2)
0362: throws NamingException {
0363: Object obj = lookup(arg0);
0364:
0365: if (obj instanceof DNSContext) {
0366: throw new OperationNotSupportedException();
0367: } else if (obj instanceof DirContext) {
0368: ((DirContext) obj).modifyAttributes("", arg1, arg2); //$NON-NLS-1$
0369: } else {
0370: // jndi.4A=found object is not a DirContext
0371: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0372: }
0373: }
0374:
0375: /**
0376: * Determines all attributes associated with given name.
0377: *
0378: * @param name
0379: * the name to look for; should be an instance of either
0380: * <code>DNSName</code> class or <code>CompositeName</code>
0381: * class
0382: * @return collection of found attributes
0383: * @throws NamingException
0384: * or its subtype if such has been encountered
0385: * @see DNSContext#getAttributes(Name, String[]) for more details
0386: * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
0387: */
0388: public Attributes getAttributes(Name name) throws NamingException {
0389: return getAttributes(name, null);
0390: }
0391:
0392: /**
0393: * This method is not supported by the DNS provider.
0394: *
0395: * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name,
0396: * int, javax.naming.directory.Attributes)
0397: */
0398: public void modifyAttributes(Name arg0, int arg1, Attributes arg2)
0399: throws NamingException {
0400: Object obj = lookup(arg0);
0401:
0402: if (obj instanceof DNSContext) {
0403: throw new OperationNotSupportedException();
0404: } else if (obj instanceof DirContext) {
0405: ((DirContext) obj).modifyAttributes("", arg1, arg2); //$NON-NLS-1$
0406: } else {
0407: // jndi.4A=found object is not a DirContext
0408: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0409: }
0410: }
0411:
0412: /**
0413: * This method is not supported by the DNS provider.
0414: *
0415: * @see javax.naming.directory.DirContext#getSchema(java.lang.String)
0416: */
0417: public DirContext getSchema(String arg0) throws NamingException {
0418: Object obj = lookup(arg0);
0419:
0420: if (obj instanceof DNSContext) {
0421: throw new OperationNotSupportedException();
0422: } else if (obj instanceof DirContext) {
0423: return ((DirContext) obj).getSchema(""); //$NON-NLS-1$
0424: } else {
0425: // jndi.4A=found object is not a DirContext
0426: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0427: }
0428: }
0429:
0430: /**
0431: * This method is not supported.
0432: *
0433: * @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
0434: */
0435: public DirContext getSchemaClassDefinition(String arg0)
0436: throws NamingException {
0437: Object obj = lookup(arg0);
0438:
0439: if (obj instanceof DNSContext) {
0440: throw new OperationNotSupportedException();
0441: } else if (obj instanceof DirContext) {
0442: return ((DirContext) obj).getSchemaClassDefinition(""); //$NON-NLS-1$
0443: } else {
0444: // jndi.4A=found object is not a DirContext
0445: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0446: }
0447: }
0448:
0449: /**
0450: * This method is not supported.
0451: *
0452: * @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
0453: */
0454: public DirContext getSchema(Name arg0) throws NamingException {
0455: Object obj = lookup(arg0);
0456:
0457: if (obj instanceof DNSContext) {
0458: throw new OperationNotSupportedException();
0459: } else if (obj instanceof DirContext) {
0460: return ((DirContext) obj).getSchema(""); //$NON-NLS-1$
0461: } else {
0462: // jndi.4A=found object is not a DirContext
0463: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0464: }
0465: }
0466:
0467: /**
0468: * This method is not supported.
0469: *
0470: * @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
0471: */
0472: public DirContext getSchemaClassDefinition(Name arg0)
0473: throws NamingException {
0474: Object obj = lookup(arg0);
0475:
0476: if (obj instanceof DNSContext) {
0477: throw new OperationNotSupportedException();
0478: } else if (obj instanceof DirContext) {
0479: return ((DirContext) obj).getSchemaClassDefinition(""); //$NON-NLS-1$
0480: } else {
0481: // jndi.4A=found object is not a DirContext
0482: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0483: }
0484: }
0485:
0486: /**
0487: * This method is not supported.
0488: *
0489: * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String,
0490: * javax.naming.directory.ModificationItem[])
0491: */
0492: public void modifyAttributes(String arg0, ModificationItem[] arg1)
0493: throws NamingException {
0494: Object obj = lookup(arg0);
0495:
0496: if (obj instanceof DNSContext) {
0497: throw new OperationNotSupportedException();
0498: } else if (obj instanceof DirContext) {
0499: ((DirContext) obj).modifyAttributes("", arg1); //$NON-NLS-1$
0500: } else {
0501: // jndi.4A=found object is not a DirContext
0502: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0503: }
0504: }
0505:
0506: /**
0507: * This method is not supported.
0508: *
0509: * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name,
0510: * javax.naming.directory.ModificationItem[])
0511: */
0512: public void modifyAttributes(Name arg0, ModificationItem[] arg1)
0513: throws NamingException {
0514: Object obj = lookup(arg0);
0515:
0516: if (obj instanceof DNSContext) {
0517: throw new OperationNotSupportedException();
0518: } else if (obj instanceof DirContext) {
0519: ((DirContext) obj).modifyAttributes("", arg1); //$NON-NLS-1$
0520: } else {
0521: // jndi.4A=found object is not a DirContext
0522: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0523: }
0524: }
0525:
0526: /**
0527: * This method is not supported.
0528: *
0529: * @see javax.naming.directory.DirContext#search(java.lang.String,
0530: * javax.naming.directory.Attributes)
0531: */
0532: public NamingEnumeration<SearchResult> search(String arg0,
0533: Attributes arg1) throws NamingException {
0534: Object obj = lookup(arg0);
0535:
0536: if (obj instanceof DNSContext) {
0537: throw new OperationNotSupportedException();
0538: } else if (obj instanceof DirContext) {
0539: return ((DirContext) obj).search("", arg1); //$NON-NLS-1$
0540: } else {
0541: // jndi.4A=found object is not a DirContext
0542: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0543: }
0544: }
0545:
0546: /**
0547: * This method is not supported.
0548: *
0549: * @see javax.naming.directory.DirContext#search(javax.naming.Name,
0550: * javax.naming.directory.Attributes)
0551: */
0552: public NamingEnumeration<SearchResult> search(Name arg0,
0553: Attributes arg1) throws NamingException {
0554: Object obj = lookup(arg0);
0555:
0556: if (obj instanceof DNSContext) {
0557: throw new OperationNotSupportedException();
0558: } else if (obj instanceof DirContext) {
0559: return ((DirContext) obj).search("", arg1); //$NON-NLS-1$
0560: } else {
0561: // jndi.4A=found object is not a DirContext
0562: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0563: }
0564: }
0565:
0566: /**
0567: * This method is not supported.
0568: *
0569: * @see javax.naming.directory.DirContext#bind(java.lang.String,
0570: * java.lang.Object, javax.naming.directory.Attributes)
0571: */
0572: public void bind(String arg0, Object arg1, Attributes arg2)
0573: throws NamingException {
0574: bind(convertNameFromStringForm(arg0), arg1, arg2);
0575: }
0576:
0577: /**
0578: * This method is not supported.
0579: *
0580: * @see javax.naming.directory.DirContext#rebind(java.lang.String,
0581: * java.lang.Object, javax.naming.directory.Attributes)
0582: */
0583: public void rebind(String arg0, Object arg1, Attributes arg2)
0584: throws NamingException {
0585: rebind(convertNameFromStringForm(arg0), arg1, arg2);
0586: }
0587:
0588: /**
0589: * This method is not supported.
0590: *
0591: * @see javax.naming.directory.DirContext#bind(javax.naming.Name,
0592: * java.lang.Object, javax.naming.directory.Attributes)
0593: */
0594: public void bind(Name arg0, Object arg1, Attributes arg2)
0595: throws NamingException {
0596: ContextNamePair pair;
0597:
0598: try {
0599: pair = getTargetNamespaceContextNamePair(arg0);
0600: } catch (IllegalArgumentException e) {
0601: throw new OperationNotSupportedException();
0602: }
0603: if (pair.context instanceof DirContext) {
0604: ((DirContext) pair.context).bind(pair.name, arg1, arg2);
0605: } else {
0606: // jndi.4A=found object is not a DirContext
0607: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0608: }
0609: }
0610:
0611: /**
0612: * This method is not supported.
0613: *
0614: * @see javax.naming.directory.DirContext#rebind(javax.naming.Name,
0615: * java.lang.Object, javax.naming.directory.Attributes)
0616: */
0617: public void rebind(Name arg0, Object arg1, Attributes arg2)
0618: throws NamingException {
0619: ContextNamePair pair;
0620:
0621: try {
0622: pair = getTargetNamespaceContextNamePair(arg0);
0623: } catch (IllegalArgumentException e) {
0624: throw new OperationNotSupportedException();
0625: }
0626: if (pair.context instanceof DirContext) {
0627: ((DirContext) pair.context).rebind(pair.name, arg1, arg2);
0628: } else {
0629: // jndi.4A=found object is not a DirContext
0630: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0631: }
0632: }
0633:
0634: /**
0635: * Retrieves attributes associated with given name.
0636: *
0637: * @param name
0638: * name to look for; should be either domain name or composite
0639: * name in string form
0640: * @param attrNames
0641: * array of attribute names that should be retrieved
0642: * @return collection of found attributes
0643: * @throws NamingException
0644: * or its subtypes if such have been encountered
0645: * @see #getAttributes(Name) for details
0646: * @see javax.naming.directory.DirContext#getAttributes(java.lang.String,
0647: * java.lang.String[])
0648: */
0649: public Attributes getAttributes(String name, String[] attrNames)
0650: throws NamingException {
0651: return getAttributes(convertNameFromStringForm(name), attrNames);
0652: }
0653:
0654: /**
0655: * Obtains attributes associated with the given name. Each members of
0656: * <code>attrNames</code> array should be the correct name of DNS resource
0657: * record type (possibly prefixed with correct DNS resource record class) as
0658: * specified in RFC 1035. If class name is given then it should be separated
0659: * with space from the type name. If class name is missed then IN class is
0660: * used by default.
0661: *
0662: * @param name
0663: * the name to look for; should have either <code>DNSName</code>
0664: * type or <code>CompositeName</code> type
0665: * @param attrNames
0666: * the array with names of attributes to look for; if null then
0667: * all attributes will be retrieved; if empty then none of
0668: * attributes will be retrieved
0669: * @throws InvalidNameException
0670: * if <code>name</code> is neither the instance of
0671: * <code>DNSName</code> nor <code>CompositeName</code> class
0672: * or the first component of composite name is not a domain name
0673: * @throws InvalidAttributeIdentifierException
0674: * if the name of DNS type or DNS class given in
0675: * <code>attrNames</code> array is invalid
0676: * @throws NameNotFoundException
0677: * if authoritative server for desired zone was contacted but
0678: * given name has not been found in that zone
0679: * @throws ServiceUnavailableException
0680: * if no authoritative server for desired name was found or all
0681: * servers are dead or malfunction
0682: * @throws NoPermissionException
0683: * if no appropriate permissions on using network resources were
0684: * granted
0685: * @throws NullPointerException
0686: * if <code>name</code> is null
0687: * @throws NamingException
0688: * if some other type of problem has been encountered
0689: * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name,
0690: * java.lang.String[])
0691: * @see RFC 1035
0692: */
0693: public Attributes getAttributes(Name name, String[] attrNames)
0694: throws NamingException {
0695: int[] types;
0696: int[] classes;
0697: DNSName nameToLookFor = null;
0698: DNSName altName = null;
0699: CompositeName remainingName = null;
0700: Attributes attrs = null;
0701:
0702: // analyze given name object
0703: if (name == null) {
0704: // jndi.2E=The name is null
0705: throw new NullPointerException(Messages
0706: .getString("jndi.2E")); //$NON-NLS-1$
0707: } else if (name.size() == 0) {
0708: // attributes of the current context are requested
0709: nameToLookFor = (DNSName) contextName.clone();
0710: } else if (name instanceof CompositeName) {
0711: // treat the first component of the given composite name as
0712: // a domain name and the rest as a Next Naming System name
0713: String tmp = name.get(0);
0714: // check if it is really a domain name
0715: altName = (DNSName) nameParser.parse(tmp);
0716: // if (!altName.isAbsolute()) {
0717: nameToLookFor = (DNSName) composeName(altName, contextName);
0718: // } else {
0719: // nameToLookFor = (DNSName) altName.clone();
0720: // }
0721: if (name.size() > 1) {
0722: remainingName = (CompositeName) name.getSuffix(1);
0723: }
0724: } else if (name instanceof DNSName) {
0725: // if (!((DNSName) name).isAbsolute()) {
0726: nameToLookFor = (DNSName) composeName(name, contextName);
0727: // } else {
0728: // nameToLookFor = (DNSName) name.clone();
0729: // }
0730: } else {
0731: // jndi.4B=Only instances of CompositeName class or DNSName class
0732: // are acceptable
0733: throw new InvalidNameException(Messages
0734: .getString("jndi.4B")); //$NON-NLS-1$
0735: }
0736:
0737: // we should have correct nameToLookFor at this point
0738: if (remainingName != null) {
0739: CannotProceedException cpe = constructCannotProceedException(
0740: altName, remainingName);
0741: DirContext nnsContext = DirectoryManager
0742: .getContinuationDirContext(cpe);
0743:
0744: attrs = nnsContext.getAttributes(remainingName, attrNames);
0745: } else {
0746: // analyze given attrNames object
0747: if (attrNames == null) {
0748: // this means that all attributes should be obtained
0749: types = new int[1];
0750: classes = new int[1];
0751: types[0] = ProviderConstants.ANY_QTYPE;
0752: classes[0] = ProviderConstants.ANY_QCLASS;
0753: } else {
0754: HashSet<Integer> classesSet = new HashSet<Integer>();
0755: HashSet<Integer> typesSet = new HashSet<Integer>();
0756: Iterator<Integer> iter;
0757: int j;
0758:
0759: for (String element : attrNames) {
0760: int k = element.indexOf(' ');
0761: String typeStr = null;
0762: int classInt;
0763: int typesInt;
0764:
0765: if (k > 0) {
0766: String classStr = element.substring(0, k);
0767:
0768: classInt = ProviderMgr
0769: .getRecordClassNumber(classStr);
0770: if (classInt == -1) {
0771: // jndi.4C=Unknown record class: {0}
0772: throw new InvalidAttributeIdentifierException(
0773: Messages.getString(
0774: "jndi.4C", classStr)); //$NON-NLS-1$
0775: }
0776: classesSet.add(new Integer(classInt));
0777: typeStr = element
0778: .substring(k, element.length()).trim();
0779: } else {
0780: classesSet.add(new Integer(
0781: ProviderConstants.IN_CLASS));
0782: typeStr = element.trim();
0783: }
0784: typesInt = ProviderMgr.getRecordTypeNumber(typeStr);
0785: if (typesInt == -1) {
0786: // jndi.4D=Unknown record type: {0}
0787: throw new InvalidAttributeIdentifierException(
0788: Messages.getString("jndi.4D", typeStr)); //$NON-NLS-1$
0789: }
0790: typesSet.add(new Integer(typesInt));
0791: }
0792: // filling classes array
0793: classes = new int[classesSet.size()];
0794: iter = classesSet.iterator();
0795: j = 0;
0796: while (iter.hasNext()) {
0797: Integer n = iter.next();
0798:
0799: classes[j++] = n.intValue();
0800: }
0801: // filling types array
0802: types = new int[typesSet.size()];
0803: iter = typesSet.iterator();
0804: j = 0;
0805: while (iter.hasNext()) {
0806: Integer n = iter.next();
0807:
0808: types[j++] = n.intValue();
0809: }
0810: }
0811:
0812: // we should have correct nameToLookFor, classes and types at this
0813: // point
0814: // let's look for attributes
0815: try {
0816: Enumeration<ResourceRecord> records = resolver.lookup(
0817: nameToLookFor.toString(), types, classes);
0818:
0819: attrs = createAttributesFromRecords(records);
0820: } catch (SecurityException e) {
0821: NoPermissionException e2 = new NoPermissionException();
0822:
0823: e2.setRootCause(e);
0824: throw e2;
0825: } catch (NamingException e) {
0826: throw e;
0827: } catch (Exception e) {
0828: NamingException ne = new NamingException();
0829:
0830: ne.setRootCause(e);
0831: throw ne;
0832: }
0833: }
0834: return attrs;
0835: }
0836:
0837: /**
0838: * This method is not supported.
0839: *
0840: * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String,
0841: * javax.naming.directory.Attributes)
0842: */
0843: public DirContext createSubcontext(String arg0, Attributes arg1)
0844: throws NamingException {
0845: return createSubcontext(convertNameFromStringForm(arg0), arg1);
0846: }
0847:
0848: /**
0849: * This method is not supported.
0850: *
0851: * @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name,
0852: * javax.naming.directory.Attributes)
0853: */
0854: public DirContext createSubcontext(Name arg0, Attributes arg1)
0855: throws NamingException {
0856: ContextNamePair pair;
0857:
0858: try {
0859: pair = getTargetNamespaceContextNamePair(arg0);
0860: } catch (IllegalArgumentException e) {
0861: throw new OperationNotSupportedException();
0862: }
0863: if (pair.context instanceof DirContext) {
0864: return ((DirContext) pair.context).createSubcontext(
0865: pair.name, arg1);
0866: }
0867: // jndi.4A=found object is not a DirContext
0868: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0869: }
0870:
0871: /**
0872: * This method is not supported.
0873: *
0874: * @see javax.naming.directory.DirContext#search(java.lang.String,
0875: * javax.naming.directory.Attributes, java.lang.String[])
0876: */
0877: public NamingEnumeration<SearchResult> search(String arg0,
0878: Attributes arg1, String[] arg2) throws NamingException {
0879: Object obj = lookup(arg0);
0880:
0881: if (obj instanceof DNSContext) {
0882: throw new OperationNotSupportedException();
0883: } else if (obj instanceof DirContext) {
0884: return ((DirContext) obj).search("", arg1, arg2); //$NON-NLS-1$
0885: } else {
0886: // jndi.4A=found object is not a DirContext
0887: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0888: }
0889: }
0890:
0891: /**
0892: * This method is not supported.
0893: *
0894: * @see javax.naming.directory.DirContext#search(javax.naming.Name,
0895: * javax.naming.directory.Attributes, java.lang.String[])
0896: */
0897: public NamingEnumeration<SearchResult> search(Name arg0,
0898: Attributes arg1, String[] arg2) throws NamingException {
0899: Object obj = lookup(arg0);
0900:
0901: if (obj instanceof DNSContext) {
0902: throw new OperationNotSupportedException();
0903: } else if (obj instanceof DirContext) {
0904: return ((DirContext) obj).search("", arg1, arg2); //$NON-NLS-1$
0905: } else {
0906: // jndi.4A=found object is not a DirContext
0907: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0908: }
0909: }
0910:
0911: /**
0912: * This method is not supported.
0913: *
0914: * @see javax.naming.directory.DirContext#search(java.lang.String,
0915: * java.lang.String, javax.naming.directory.SearchControls)
0916: */
0917: public NamingEnumeration<SearchResult> search(String arg0,
0918: String arg1, SearchControls arg2) throws NamingException {
0919: Object obj = lookup(arg0);
0920:
0921: if (obj instanceof DNSContext) {
0922: throw new OperationNotSupportedException();
0923: } else if (obj instanceof DirContext) {
0924: return ((DirContext) obj).search("", arg1, arg2); //$NON-NLS-1$
0925: } else {
0926: // jndi.4A=found object is not a DirContext
0927: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0928: }
0929: }
0930:
0931: /**
0932: * This method is not supported.
0933: *
0934: * @see javax.naming.directory.DirContext#search(javax.naming.Name,
0935: * java.lang.String, javax.naming.directory.SearchControls)
0936: */
0937: public NamingEnumeration<SearchResult> search(Name arg0,
0938: String arg1, SearchControls arg2) throws NamingException {
0939: Object obj = lookup(arg0);
0940:
0941: if (obj instanceof DNSContext) {
0942: throw new OperationNotSupportedException();
0943: } else if (obj instanceof DirContext) {
0944: return ((DirContext) obj).search("", arg1, arg2); //$NON-NLS-1$
0945: } else {
0946: // jndi.4A=found object is not a DirContext
0947: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0948: }
0949: }
0950:
0951: /**
0952: * This method is not supported.
0953: *
0954: * @see javax.naming.directory.DirContext#search(java.lang.String,
0955: * java.lang.String, java.lang.Object[],
0956: * javax.naming.directory.SearchControls)
0957: */
0958: public NamingEnumeration<SearchResult> search(String arg0,
0959: String arg1, Object[] arg2, SearchControls arg3)
0960: throws NamingException {
0961: Object obj = lookup(arg0);
0962:
0963: if (obj instanceof DNSContext) {
0964: throw new OperationNotSupportedException();
0965: } else if (obj instanceof DirContext) {
0966: return ((DirContext) obj).search("", arg1, arg2, arg3); //$NON-NLS-1$
0967: } else {
0968: // jndi.4A=found object is not a DirContext
0969: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0970: }
0971: }
0972:
0973: /**
0974: * This method is not supported.
0975: *
0976: * @see javax.naming.directory.DirContext#search(javax.naming.Name,
0977: * java.lang.String, java.lang.Object[],
0978: * javax.naming.directory.SearchControls)
0979: */
0980: public NamingEnumeration<SearchResult> search(Name arg0,
0981: String arg1, Object[] arg2, SearchControls arg3)
0982: throws NamingException {
0983: Object obj = lookup(arg0);
0984:
0985: if (obj instanceof DNSContext) {
0986: throw new OperationNotSupportedException();
0987: } else if (obj instanceof DirContext) {
0988: return ((DirContext) obj).search("", arg1, arg2, arg3); //$NON-NLS-1$
0989: } else {
0990: // jndi.4A=found object is not a DirContext
0991: throw new NotContextException(Messages.getString("jndi.4A")); //$NON-NLS-1$
0992: }
0993: }
0994:
0995: /**
0996: * Frees all resources obtained by the current context.
0997: *
0998: * @see javax.naming.Context#close()
0999: */
1000: public void close() throws NamingException {
1001: // do nothing right now
1002: }
1003:
1004: /**
1005: * @return fully qualified DNS name of the current context
1006: * @see javax.naming.Context#getNameInNamespace()
1007: */
1008: public String getNameInNamespace() {
1009: return contextName.toString();
1010: }
1011:
1012: /**
1013: * This method is not supported.
1014: *
1015: * @see javax.naming.Context#destroySubcontext(java.lang.String)
1016: */
1017: public void destroySubcontext(String arg0) throws NamingException {
1018: destroySubcontext(convertNameFromStringForm(arg0));
1019: }
1020:
1021: /**
1022: * This method is not supported.
1023: *
1024: * @see javax.naming.Context#unbind(java.lang.String)
1025: */
1026: public void unbind(String arg0) throws NamingException {
1027: unbind(convertNameFromStringForm(arg0));
1028: }
1029:
1030: /**
1031: * Returns a clone of the environment associated with this context.
1032: *
1033: * @return a hash table with the context's environment
1034: * @see javax.naming.Context#getEnvironment()
1035: */
1036: public Hashtable<?, ?> getEnvironment() throws NamingException {
1037: return (Hashtable<?, ?>) environment.clone();
1038: }
1039:
1040: /**
1041: * This method is not supported.
1042: *
1043: * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
1044: */
1045: public void destroySubcontext(Name arg0) throws NamingException {
1046: ContextNamePair pair;
1047:
1048: try {
1049: pair = getTargetNamespaceContextNamePair(arg0);
1050: } catch (IllegalArgumentException e) {
1051: throw new OperationNotSupportedException();
1052: }
1053: if (pair.context instanceof Context) {
1054: ((Context) pair.context).destroySubcontext(pair.name);
1055: } else {
1056: // jndi.4E=found object is not a Context
1057: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1058: }
1059: }
1060:
1061: /**
1062: * This method is not supported.
1063: *
1064: * @see javax.naming.Context#unbind(javax.naming.Name)
1065: */
1066: public void unbind(Name arg0) throws NamingException {
1067: ContextNamePair pair;
1068:
1069: try {
1070: pair = getTargetNamespaceContextNamePair(arg0);
1071: } catch (IllegalArgumentException e) {
1072: throw new OperationNotSupportedException();
1073: }
1074: if (pair.context instanceof Context) {
1075: ((Context) pair.context).unbind(pair.name);
1076: } else {
1077: // jndi.4E=found object is not a Context
1078: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1079: }
1080: }
1081:
1082: /**
1083: * Performs the lookup operation for given name. The method will try to
1084: * construct a composite name from given argument value. If it is succeed
1085: * and resulting composite name has the size more than one then the
1086: * <code>lookup(Name)</code> version of <code>lookup</code> method will
1087: * be called with constructed composite name as an argument. If the size of
1088: * constructed composite name equals to one then the value of given argument
1089: * will be treated as a string form of a domain name and an attempt to
1090: * create an instance of <code>DNSName</code> class will be made. The
1091: * <code>lookup(Name)</code> will be called after this.
1092: *
1093: * @param name
1094: * the name to look for
1095: * @return an object associated with given name
1096: * @throws InvalidNameException
1097: * if given argument is a string representation of neither a
1098: * composite name nor a domain name; or the first component of
1099: * the composite name is not a domain name.
1100: * @throws NamingException
1101: * if some other type of <code>NamingException</code> was
1102: * encountered
1103: * @throws NullPointerException
1104: * if the name is null
1105: * @see #lookup(Name)
1106: * @see javax.naming.Context#lookup(java.lang.String)
1107: */
1108: public Object lookup(String name) throws NamingException {
1109: return lookup(convertNameFromStringForm(name));
1110: }
1111:
1112: /**
1113: * @param nameStr
1114: * string representation of a name
1115: * @return an instance of <code>CompositeName</code> or
1116: * <code>DNSName</code> class
1117: * @throws InvalidNameException
1118: * if <code>nameStr</code> is neither a string representation
1119: * of <code>CompositeName</code> class nor an instance of
1120: * <code>DNSName</code> class.
1121: */
1122: private Name convertNameFromStringForm(String nameStr)
1123: throws InvalidNameException {
1124: Name nameObj = null;
1125:
1126: if (nameStr == null) {
1127: // jndi.2E=The name is null
1128: throw new NullPointerException(Messages
1129: .getString("jndi.2E")); //$NON-NLS-1$
1130: }
1131: nameObj = new CompositeName(nameStr);
1132: if (nameObj.size() == 1) {
1133: nameObj = nameParser.parse(nameStr);
1134: } else if (nameObj.size() == 0) {
1135: nameObj = new DNSName();
1136: }
1137: return nameObj;
1138: }
1139:
1140: /**
1141: * Looks for a object associated with the given name. This methods just
1142: * forwards the request to <code>#lookup(String)</code> method and do
1143: * nothing more.
1144: *
1145: * @param name
1146: * name to look for
1147: * @return found object
1148: * @throws NamingException
1149: * if encountered
1150: * @see #lookup(String) for details
1151: * @see javax.naming.Context#lookupLink(javax.naming.Name)
1152: */
1153:
1154: public Object lookupLink(String name) throws NamingException {
1155: return lookup(name);
1156: }
1157:
1158: /**
1159: * Removes the property with given name from the context's environment.
1160: *
1161: * @param name
1162: * the name of the property to remove
1163: * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
1164: */
1165: public Object removeFromEnvironment(String name) {
1166: return environment.remove(name);
1167: }
1168:
1169: /**
1170: * This method is not supported.
1171: *
1172: * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
1173: */
1174: public void bind(String arg0, Object arg1) throws NamingException {
1175: bind(convertNameFromStringForm(arg0), arg1);
1176: }
1177:
1178: /**
1179: * This method is not supported.
1180: *
1181: * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
1182: */
1183: public void rebind(String arg0, Object arg1) throws NamingException {
1184: rebind(convertNameFromStringForm(arg0), arg1);
1185: }
1186:
1187: /**
1188: * Performs the lookup operation for the given name in the current context.
1189: *
1190: * @param name
1191: * this method looks for object associated with given name
1192: * @return found object
1193: * @throws InvalidNameException
1194: * if the argument is not a valid type, e.g.
1195: * <code>CompositeName</code> or <code>DNSName</code>; or
1196: * the first component of given composite name is not a domain
1197: * name
1198: * @throws NameNotFoundException
1199: * if authoritative server for desired zone was contacted but
1200: * given name has not been found in that zone
1201: * @throws ServiceUnavailableException
1202: * if no authoritative server for desired name was found or all
1203: * servers are dead or malfunction
1204: * @throws NoPermissionException
1205: * if no appropriate permissions on using network resources were
1206: * granted
1207: * @throws NullPointerException
1208: * if <code>name</code> is null
1209: * @throws NamingException
1210: * if some other type of <code>NamingException</code> was
1211: * encountered
1212: * @see javax.naming.Context#lookup(javax.naming.Name)
1213: */
1214: public Object lookup(Name name) throws NamingException {
1215: int[] types = new int[1];
1216: int[] classes = new int[1];
1217: DNSName nameToLookFor = null;
1218: DNSName altName = null;
1219: CompositeName remainingName = null;
1220: Object result = null;
1221:
1222: // analyze given name object
1223: if (name == null) {
1224: // jndi.2E=The name is null
1225: throw new NullPointerException(Messages
1226: .getString("jndi.2E")); //$NON-NLS-1$
1227: } else if (name.size() == 0) {
1228: // attributes of the current context are requested
1229: nameToLookFor = (DNSName) contextName.clone();
1230: } else if (name instanceof CompositeName) {
1231: // treat the first component of the given composite name as
1232: // a domain name and the rest as a Next Naming System name
1233: String tmp = name.get(0);
1234: // check if it is really a domain name
1235: altName = (DNSName) nameParser.parse(tmp);
1236: // if (!altName.isAbsolute()) {
1237: nameToLookFor = (DNSName) composeName(altName, contextName);
1238: // } else {
1239: // nameToLookFor = (DNSName) altName.clone();
1240: // }
1241: if (name.size() > 1) {
1242: remainingName = (CompositeName) name.getSuffix(1);
1243: }
1244: } else if (name instanceof DNSName) {
1245: // if (!((DNSName) name).isAbsolute()) {
1246: nameToLookFor = (DNSName) composeName(name, contextName);
1247: // } else {
1248: // nameToLookFor = (DNSName) name.clone();
1249: // }
1250: } else {
1251: // jndi.4B=Only instances of CompositeName class or DNSName class
1252: // are acceptable
1253: throw new InvalidNameException(Messages
1254: .getString("jndi.4B")); //$NON-NLS-1$
1255: }
1256: // we should have correct nameToLookFor at this point
1257: types[0] = lookupAttrType;
1258: classes[0] = lookupAttrClass;
1259: if (remainingName != null) {
1260: CannotProceedException cpe = constructCannotProceedException(
1261: altName, remainingName);
1262: Context nnsContext = DirectoryManager
1263: .getContinuationContext(cpe);
1264:
1265: result = nnsContext.lookup(remainingName);
1266: } else {
1267: try {
1268: DNSContext resolvedCtx = new DNSContext(this ,
1269: nameToLookFor);
1270: Enumeration<ResourceRecord> records = resolver.lookup(
1271: nameToLookFor.toString(), types, classes);
1272: Attributes attrs = createAttributesFromRecords(records);
1273:
1274: result = DirectoryManager.getObjectInstance(
1275: resolvedCtx, name, this , environment, attrs);
1276: } catch (SecurityException e) {
1277: NoPermissionException e2 = new NoPermissionException(e
1278: .getMessage());
1279:
1280: e2.setRootCause(e);
1281: throw e2;
1282: } catch (NamingException e) {
1283: throw e;
1284: } catch (Exception e) {
1285: NamingException ne = new NamingException(e.getMessage());
1286:
1287: ne.setRootCause(e);
1288: throw ne;
1289: }
1290: }
1291: return result;
1292: }
1293:
1294: /**
1295: * Constructs <code>CannotProcessException</code> object and fills it with
1296: * necessary information. Values of some instance variables of the current
1297: * context are used.
1298: *
1299: * @param name
1300: * the portion of name that belongs to DNS namespace
1301: * @param remainingName
1302: * the remainder of the name that belongs to NNS namespace
1303: * @return newly constructed exception object
1304: * @throws NamingException
1305: * if <code>NamingException</code> was encountered somewhere
1306: */
1307: private CannotProceedException constructCannotProceedException(
1308: DNSName name, CompositeName remainingName)
1309: throws NamingException {
1310: DNSName nameToLookFor = (DNSName) composeName(name, contextName);
1311: final DNSContext resolvedCtx = new DNSContext(this ,
1312: nameToLookFor);
1313: // namespace border violation, need to ask NNS
1314: RefAddr refAddr = new RefAddr("nns") { //$NON-NLS-1$
1315: private static final long serialVersionUID = 8654740210501193418L;
1316:
1317: DNSContext context = (DNSContext) resolvedCtx.clone();
1318:
1319: @Override
1320: public Object getContent() {
1321: return context;
1322: }
1323: };
1324: Reference ref = new Reference(this .getClass().getName(),
1325: refAddr);
1326: CannotProceedException cpe = null;
1327: CompositeName resolvedName = null;
1328:
1329: if (environment.containsKey(NamingManager.CPE)) {
1330: cpe = (CannotProceedException) environment
1331: .get(NamingManager.CPE);
1332: resolvedName = (CompositeName) cpe.getResolvedName();
1333: // remove the last component if it is ""
1334: // (the sign of the next naming system)
1335: if (resolvedName != null
1336: && resolvedName.get(resolvedName.size() - 1)
1337: .equals("")) //$NON-NLS-1$
1338: {
1339: resolvedName.remove(resolvedName.size() - 1);
1340: }
1341: } else {
1342: cpe = new CannotProceedException();
1343: }
1344: cpe.setEnvironment((Hashtable) environment.clone());
1345: cpe.setAltName(name);
1346: cpe.setAltNameCtx((DNSContext) this .clone());
1347: cpe.setRemainingName(remainingName);
1348: if (resolvedName == null) {
1349: resolvedName = new CompositeName();
1350: }
1351: resolvedName.add(nameToLookFor.toString());
1352: // the sign of the next naming system
1353: resolvedName.add(""); //$NON-NLS-1$
1354: cpe.setResolvedName(resolvedName);
1355: cpe.setResolvedObj(ref);
1356: return cpe;
1357: }
1358:
1359: /**
1360: * Creates an <code>Attributes</code> object from the given enumeration of
1361: * resource records.
1362: *
1363: * @param recs
1364: * enumeration of resource records received from the resolver
1365: * @return corresponding instance of <code>Attributes</code>
1366: */
1367: private static Attributes createAttributesFromRecords(
1368: Enumeration<ResourceRecord> recs) {
1369: Attributes attrs = new BasicAttributes(true);
1370:
1371: while (recs.hasMoreElements()) {
1372: ResourceRecord curRec = recs.nextElement();
1373: String clssTypeStr = null;
1374: Attribute oldAttr = null;
1375:
1376: if (curRec.getRRClass() == ProviderConstants.IN_CLASS) {
1377: clssTypeStr = ProviderConstants.rrTypeNames[curRec
1378: .getRRType()];
1379: } else {
1380: clssTypeStr = ProviderConstants.rrClassNames[curRec
1381: .getRRClass()]
1382: + " " + //$NON-NLS-1$
1383: ProviderConstants.rrTypeNames[curRec
1384: .getRRType()];
1385: }
1386: oldAttr = attrs.get(clssTypeStr);
1387: if (oldAttr != null) {
1388: oldAttr.add(oldAttr.size(), curRec.getRData());
1389: } else {
1390: BasicAttribute attr = new BasicAttribute(clssTypeStr,
1391: curRec.getRData(), false);
1392:
1393: attrs.put(attr);
1394: }
1395: }
1396: return attrs;
1397: }
1398:
1399: /**
1400: * Looks for a object associated with the given name. This methods just
1401: * forwards the request to <code>#lookup(Name)</code> method and do
1402: * nothing more.
1403: *
1404: * @param name
1405: * name to look for
1406: * @return found object
1407: * @throws NamingException
1408: * if encountered
1409: * @see #lookup(Name) for details
1410: * @see javax.naming.Context#lookupLink(javax.naming.Name)
1411: */
1412: public Object lookupLink(Name name) throws NamingException {
1413: return lookup(name);
1414: }
1415:
1416: /**
1417: * This method is not supported.
1418: *
1419: * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
1420: */
1421: public void bind(Name arg0, Object arg1) throws NamingException {
1422: ContextNamePair pair;
1423:
1424: try {
1425: pair = getTargetNamespaceContextNamePair(arg0);
1426: } catch (IllegalArgumentException e) {
1427: throw new OperationNotSupportedException();
1428: }
1429: if (pair.context instanceof Context) {
1430: ((Context) pair.context).bind(pair.name, arg1);
1431: } else {
1432: // jndi.4E=found object is not a Context
1433: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1434: }
1435: }
1436:
1437: /**
1438: * This method is not supported.
1439: *
1440: * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
1441: */
1442: public void rebind(Name arg0, Object arg1) throws NamingException {
1443: ContextNamePair pair;
1444:
1445: try {
1446: pair = getTargetNamespaceContextNamePair(arg0);
1447: } catch (IllegalArgumentException e) {
1448: throw new OperationNotSupportedException();
1449: }
1450: if (pair.context instanceof Context) {
1451: ((Context) pair.context).rebind(pair.name, arg1);
1452: } else {
1453: // jndi.4E=found object is not a Context
1454: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1455: }
1456: }
1457:
1458: /**
1459: * This method is not supported.
1460: *
1461: * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
1462: */
1463: public void rename(String arg0, String arg1) throws NamingException {
1464: rename(convertNameFromStringForm(arg0),
1465: convertNameFromStringForm(arg1));
1466: }
1467:
1468: /**
1469: * This method is not supported.
1470: *
1471: * @see javax.naming.Context#createSubcontext(java.lang.String)
1472: */
1473: public Context createSubcontext(String arg0) throws NamingException {
1474: return createSubcontext(convertNameFromStringForm(arg0));
1475: }
1476:
1477: /**
1478: * This method is not supported.
1479: *
1480: * @see javax.naming.Context#createSubcontext(javax.naming.Name)
1481: */
1482: public Context createSubcontext(Name arg0) throws NamingException {
1483: ContextNamePair pair;
1484:
1485: try {
1486: pair = getTargetNamespaceContextNamePair(arg0);
1487: } catch (IllegalArgumentException e) {
1488: throw new OperationNotSupportedException();
1489: }
1490: if (pair.context instanceof Context) {
1491: return ((Context) pair.context).createSubcontext(pair.name);
1492: }
1493: // jndi.4E=found object is not a Context
1494: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1495: }
1496:
1497: /**
1498: * This method is not supported.
1499: *
1500: * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
1501: */
1502: public void rename(Name arg0, Name arg1) throws NamingException {
1503: ContextNamePair pair1;
1504: ContextNamePair pair2;
1505:
1506: try {
1507: pair1 = getTargetNamespaceContextNamePair(arg0);
1508: pair2 = getTargetNamespaceContextNamePair(arg1);
1509: } catch (IllegalArgumentException e) {
1510: throw new OperationNotSupportedException();
1511: }
1512: if (pair1.context instanceof Context
1513: && pair1.context.getClass().getName().equals(
1514: pair2.context.getClass().getName())
1515: && ((Context) pair1.context).getNameInNamespace()
1516: .equals(
1517: ((Context) pair2.context)
1518: .getNameInNamespace())) {
1519: ((Context) pair1.context).rename(pair1.name, pair2.name);
1520: } else {
1521: // jndi.4F=found object is not a Context or target contexts are not
1522: // equal
1523: throw new NotContextException(Messages.getString("jndi.4F")); //$NON-NLS-1$
1524: }
1525: }
1526:
1527: /**
1528: * Returns the name parser for given name.
1529: *
1530: * @param name
1531: * a name in the string form to return a name parser for
1532: * @return the name parser found
1533: * @throws NotContextException
1534: * if found object is not a context
1535: * @throws NamingException
1536: * if such exception was encountered during lookup
1537: * @see DNSContext#getNameParser(Name) for details
1538: * @see javax.naming.Context#getNameParser(java.lang.String)
1539: */
1540: public NameParser getNameParser(String name) throws NamingException {
1541: Object obj;
1542:
1543: if (name == null) {
1544: // jndi.2E=The name is null
1545: throw new NullPointerException(Messages
1546: .getString("jndi.2E")); //$NON-NLS-1$
1547: }
1548: obj = lookup(name);
1549: if (obj instanceof DNSContext) {
1550: return nameParser;
1551: } else if (obj instanceof Context) {
1552: return ((Context) obj).getNameParser(""); //$NON-NLS-1$
1553: }
1554: // jndi.4E=found object is not a Context
1555: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1556: }
1557:
1558: /**
1559: * Tries to look for the context associated with the given name and returns
1560: * the appropriate name parser. For <code>DNSContext</code> this method
1561: * will return an instance of <code>DNSNameParser</code> class.
1562: *
1563: * @param a
1564: * name to return a name parser for
1565: * @return a name parser for the naming system the found context is
1566: * associated with
1567: * @throws NotContextException
1568: * if found object is not a context so we cannot obtain a name
1569: * parser from it
1570: * @throws NamingException
1571: * if such exception was encountered during lookup
1572: * @see javax.naming.Context#getNameParser(javax.naming.Name)
1573: */
1574: public NameParser getNameParser(Name name) throws NamingException {
1575: Object obj;
1576:
1577: if (name == null) {
1578: // jndi.2E=The name is null
1579: throw new NullPointerException(Messages
1580: .getString("jndi.2E")); //$NON-NLS-1$
1581: }
1582: obj = lookup(name);
1583: if (obj instanceof DNSContext) {
1584: return nameParser;
1585: } else if (obj instanceof Context) {
1586: return ((Context) obj).getNameParser(""); //$NON-NLS-1$
1587: }
1588: // jndi.4E=found object is not a Context
1589: throw new NotContextException(Messages.getString("jndi.4E")); //$NON-NLS-1$
1590: }
1591:
1592: /**
1593: * Lists all names along with corresponding class names contained by given
1594: * context.
1595: *
1596: * @param name
1597: * context name to list
1598: * @return enumeration of <code>NameClassPair</code> objects
1599: * @throws NamingException
1600: * if an error was encountered
1601: * @see javax.naming.Context#list(javax.naming.Name)
1602: */
1603: public NamingEnumeration<NameClassPair> list(String name)
1604: throws NamingException {
1605: return list_common(convertNameFromStringForm(name),
1606: NAME_CLASS_SWT);
1607: }
1608:
1609: /**
1610: * Lists all names along with corresponding objects contained by given
1611: * context.
1612: *
1613: * @param name
1614: * context name to list
1615: * @return enumeration of <code>Binding</code> objects
1616: * @throws NamingException
1617: * if an error was encountered
1618: * @see javax.naming.Context#listBindings(java.lang.String)
1619: */
1620: public NamingEnumeration<Binding> listBindings(String name)
1621: throws NamingException {
1622: return list_common(convertNameFromStringForm(name), BINDING_SWT);
1623: }
1624:
1625: /**
1626: * Lists all names along with corresponding class names contained by given
1627: * context.
1628: *
1629: * @param name
1630: * context name to list
1631: * @return enumeration of <code>NameClassPair</code> objects
1632: * @throws NoPermissionException
1633: * if the resolver is not allowed to use a network subsystem
1634: * @throws NameNotFoundException
1635: * if authoritative server(s) was not found
1636: * @throws ServiceUnavailableException
1637: * if none of found servers permits zone transfers
1638: * @throws DomainProtocolException
1639: * if some DNS specific error has occurred
1640: * @throws NamingException
1641: * if other type of error has occurred
1642: * @see javax.naming.Context#list(javax.naming.Name)
1643: */
1644: public NamingEnumeration<NameClassPair> list(Name name)
1645: throws NamingException {
1646: return list_common(name, NAME_CLASS_SWT);
1647: }
1648:
1649: /**
1650: * Lists all names along with corresponding class names contained by given
1651: * context.
1652: *
1653: * @param name
1654: * context name to list
1655: * @param contentSwt
1656: * method will return enumeration of <code>NameClassPair</code>
1657: * objects if this switch is set to
1658: * <code>1<code>; enumeration of <code>Binding</code> if the switch is set
1659: * to <code>2</code>
1660: * @return enumeration of <code>NameClassPair</code> or
1661: * <code>Binding</code> objects
1662: * @throws NamingException
1663: *
1664: * TODO better resolve situation then the zone just has been transferred and
1665: * then ANY_QTYPE request is performed; we could take the result from
1666: * resolver's cache since we are sure the cache is up to date and contains
1667: * absolutely all records from target zone
1668: */
1669: @SuppressWarnings("unchecked")
1670: private <T> NamingEnumeration<T> list_common(Name name,
1671: int contentSwt) throws NamingException {
1672: DNSName nameToList = null;
1673: DNSName altName = null;
1674: CompositeName remainingName = null;
1675: NamingEnumeration<T> result = null;
1676:
1677: if (contentSwt != 1 && contentSwt != 2) {
1678: // jndi.50=contentSwt should be equal to 1 or 2
1679: throw new IllegalArgumentException(Messages
1680: .getString("jndi.50")); //$NON-NLS-1$
1681: }
1682: if (name == null) {
1683: // jndi.2E=The name is null
1684: throw new NullPointerException(Messages
1685: .getString("jndi.2E")); //$NON-NLS-1$
1686: }
1687: // analyze given name object
1688: else if (name.size() == 0) {
1689: // attributes of the current context are requested
1690: nameToList = (DNSName) contextName.clone();
1691: } else if (name instanceof CompositeName) {
1692: // treat the first component of the given composite name as
1693: // a domain name and the rest as a Next Naming System name
1694: String tmp = name.get(0);
1695: // check if it is really a domain name
1696: altName = (DNSName) nameParser.parse(tmp);
1697: // if (!altName.isAbsolute()) {
1698: nameToList = (DNSName) composeName(altName, contextName);
1699: // } else {
1700: // nameToList = (DNSName) altName.clone();
1701: // }
1702: if (name.size() > 1) {
1703: remainingName = (CompositeName) name.getSuffix(1);
1704: }
1705: } else if (name instanceof DNSName) {
1706: // if (!((DNSName) name).isAbsolute()) {
1707: nameToList = (DNSName) composeName(name, contextName);
1708: // } else {
1709: // nameToList = (DNSName) name.clone();
1710: // }
1711: } else {
1712: throw new InvalidNameException(Messages
1713: .getString("jndi.4B")); //$NON-NLS-1$
1714: }
1715: // we should have correct nameToLookFor at this point
1716: if (remainingName != null) {
1717: CannotProceedException cpe = constructCannotProceedException(
1718: altName, remainingName);
1719: Context nnsContext = DirectoryManager
1720: .getContinuationContext(cpe);
1721:
1722: result = (NamingEnumeration<T>) nnsContext
1723: .list(remainingName);
1724: } else {
1725: // do the job
1726: try {
1727: Enumeration<ResourceRecord> resEnum = resolver
1728: .list(nameToList.toString());
1729: Hashtable<String, T> entries = new Hashtable<String, T>();
1730: DNSContext targetCtx = new DNSContext(this , nameToList);
1731:
1732: // collecting direct children
1733: while (resEnum.hasMoreElements()) {
1734: ResourceRecord rr = resEnum.nextElement();
1735: // fullName is an full name of current record
1736: Name curName = nameParser.parse(rr.getName());
1737:
1738: // if contains direct child of current context
1739: if (curName.startsWith(nameToList)
1740: && curName.size() > nameToList.size()) {
1741: // extract relative name of direct child
1742: String elNameStr = curName.get(nameToList
1743: .size());
1744:
1745: // if we don't have such child yet
1746: if (!entries.containsKey(elNameStr)) {
1747: Object elObj;
1748: T objToPut = null;
1749: // absolute name of direct child
1750: DNSName elNameAbs = null;
1751: // relative name of direct child
1752: DNSName elNameRel = null;
1753: // context that represents direct child
1754: DNSContext elCtx;
1755:
1756: elNameRel = new DNSName();
1757: elNameRel.add(elNameStr);
1758: elNameAbs = (DNSName) nameToList.clone();
1759: elNameAbs.add(elNameStr);
1760: elCtx = new DNSContext(this , elNameAbs);
1761: elObj = DirectoryManager.getObjectInstance(
1762: elCtx, elNameRel, targetCtx,
1763: environment, null);
1764: switch (contentSwt) {
1765: case 1:
1766: // NameClassPair
1767: objToPut = (T) new NameClassPair(
1768: elNameStr, elObj.getClass()
1769: .getName(), true);
1770: break;
1771: case 2:
1772: // Binding
1773: objToPut = (T) new Binding(elNameStr,
1774: elObj, true);
1775: break;
1776: }
1777: entries.put(elNameStr, objToPut);
1778: }
1779: }
1780: }
1781: result = new BasicNamingEnumerator<T>(entries
1782: .elements());
1783: } catch (SecurityException e) {
1784: throw e;
1785: } catch (NamingException e) {
1786: throw e;
1787: } catch (Exception e) {
1788: NamingException e2 = new NamingException(e.getMessage());
1789:
1790: e2.setRootCause(e);
1791: throw e2;
1792: }
1793:
1794: }
1795: return result;
1796: }
1797:
1798: /**
1799: * Lists all names along with corresponding objects contained by given
1800: * context.
1801: *
1802: * @param name
1803: * context name to list
1804: * @return enumeration of <code>Binding</code> objects
1805: * @throws NamingException
1806: * if an error was encountered
1807: * @see javax.naming.Context#listBindings(javax.naming.Name)
1808: */
1809: public NamingEnumeration<Binding> listBindings(Name name)
1810: throws NamingException {
1811: return list_common(name, BINDING_SWT);
1812: }
1813:
1814: /**
1815: * Add a new property to the environment.
1816: *
1817: * @param propName
1818: * a name for the new property
1819: * @param propValue
1820: * a value of the new property
1821: * @return an old value of this property; <code>null</code> if not found
1822: * @throws NullPointerException
1823: * if <code>propName</code> or <code>propValue</code> is
1824: * null.
1825: * @throws NamingException
1826: * if such was encountered
1827: * @see javax.naming.Context#addToEnvironment(java.lang.String,
1828: * java.lang.Object)
1829: */
1830: public Object addToEnvironment(String propName, Object propValue)
1831: throws NamingException {
1832: Object oldVal = environment.put(propName, propValue);
1833:
1834: if (propName.equals(Context.AUTHORITATIVE)) {
1835: parseBoolProp(Context.AUTHORITATIVE);
1836: resolver.setAuthoritativeAnswerDesired(authoritative);
1837: } else if (propName.equals(RECURSION)) {
1838: parseBoolProp(RECURSION);
1839: resolver.setRecursionDesired(recursion);
1840: } else if (propName.equals(TIMEOUT_INITIAL)) {
1841: parseIntProp(TIMEOUT_INITIAL);
1842: resolver.setInitialTimeout(timeoutInitial);
1843: } else if (propName.equals(TIMEOUT_RETRIES)) {
1844: parseIntProp(TIMEOUT_RETRIES);
1845: resolver.setTimeoutRetries(timeoutRetries);
1846: } else if (propName.equals(THREADS_MAX)) {
1847: parseIntProp(THREADS_MAX);
1848: resolver.setThreadNumberLimit(maxThreads);
1849: } else if (propName.equals(LOOKUP_ATTR)) {
1850: parseLookupProp();
1851: } else if (propName.equals(Context.PROVIDER_URL)) {
1852: parseProviderUrlProp();
1853: }
1854: return oldVal;
1855: }
1856:
1857: /**
1858: * Appends one name to another. The method initially tries to construct
1859: * composite names from given strings. If it succeeds and resulting
1860: * composite names have length more than 1 then the method
1861: * <code>composeName(Name, Name)</code> will be called with constructed
1862: * composite names as arguments. If one of constructed composite names (or
1863: * both) have the length less or equal to 1 then it will be treated as a
1864: * string representation of DNS name. The <code>DNSNameParser.parse</code>
1865: * method will be called with given string as an argument. If no exception
1866: * is thrown then the <code>composeName(Name, Name)</code> will be called
1867: * with the parsed <code>DNSName</code> as an argument.
1868: *
1869: * @param name
1870: * a name relative to the current context
1871: * @param prefix
1872: * the name of the current context in one of its ancestors
1873: * @return a composition of <code>prefix</code> and <code>name</code>
1874: * @throws NamingException
1875: * @throws NullPointerException
1876: * if the value of any argument is null
1877: * @see DNSContext#composeName(Name, Name)
1878: * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
1879: */
1880: public String composeName(String name, String prefix)
1881: throws NamingException {
1882: Name name1 = null;
1883: Name name2 = null;
1884:
1885: if (name == null || prefix == null) {
1886: // jndi.51=Given name of prefix is null
1887: throw new NullPointerException(Messages
1888: .getString("jndi.51")); //$NON-NLS-1$
1889: }
1890: if (name.length() == 0) {
1891: return prefix;
1892: }
1893: if (prefix.length() == 0) {
1894: return name;
1895: }
1896: try {
1897: name1 = new CompositeName(name);
1898: name2 = new CompositeName(prefix);
1899: } catch (InvalidNameException e) {
1900: }
1901: if (name1 == null || name1.size() <= 1) {
1902: name1 = nameParser.parse(name);
1903: }
1904: if (name2 == null || name2.size() <= 1) {
1905: name2 = nameParser.parse(prefix);
1906: }
1907: return composeName(name1, name2).toString();
1908: }
1909:
1910: /**
1911: * Adds <code>name</code> to the end of <code>prefix</code>. Following
1912: * cases are checked:
1913: * <ol>
1914: * <li><code>suffix</code> is a composite name, <code>name</code> is
1915: * compound one</li>
1916: * <li><code>suffix</code> is a compound name, <code>name</code> is
1917: * composite one</li>
1918: * <li>Both <code>suffix</code> and <code>name</code> are compound
1919: * names</li>
1920: * <li>Both <code>suffix</code> and <code>name</code> are composite
1921: * names</li>
1922: * </ol>
1923: * If one of names is a composite name then the result will be also a
1924: * composite name. If we are composing compound name and composite name then
1925: * the compound name will be converted to the string form and appended as a
1926: * member to the resulting composite name.
1927: *
1928: * @param name
1929: * a name relative to the current context
1930: * @param prefix
1931: * the name of the current context in one of its ancestors
1932: * @return a composition of <code>prefix</code> and <code>name</code>
1933: * @throws NamingException
1934: * if the compound name is not an instance of
1935: * <code>DNSName</code> class or we are trying to append an
1936: * absolute DNS name to the non-root prefix.
1937: * @throws NullPointerException
1938: * if <code>name</code> or <code>prefix</code> is null
1939: * @see javax.naming.Context#composeName(javax.naming.Name,
1940: * javax.naming.Name)
1941: */
1942: public Name composeName(Name name, Name prefix)
1943: throws NamingException {
1944: Name result = null;
1945:
1946: if (name == null || prefix == null) {
1947: // jndi.51=Given name of prefix is null
1948: throw new NullPointerException(Messages
1949: .getString("jndi.51")); //$NON-NLS-1$
1950: }
1951: if (name.size() == 0) {
1952: return prefix;
1953: }
1954: if (prefix.size() == 0) {
1955: return name;
1956: }
1957: if (name instanceof CompositeName
1958: && prefix instanceof CompositeName) {
1959: // probably we need to glue together the last element of the prefix
1960: // and the first element of the name
1961: String comp1 = name.get(0);
1962: String comp2 = prefix.get(prefix.size() - 1);
1963:
1964: result = new CompositeName();
1965: if (prefix.size() > 1) {
1966: result.addAll(prefix.getPrefix(prefix.size() - 1));
1967: }
1968: try {
1969: result.add(concatenateDNSNames(comp1, comp2));
1970: } catch (InvalidNameException e) {
1971: // comp1 or comp2 is not a valid DNS name
1972: // components should be strongly separated
1973: result.add(comp2);
1974: result.add(comp1);
1975: }
1976: if (name.size() > 1) {
1977: result.addAll(name.getSuffix(1));
1978: }
1979: } else if (prefix instanceof CompositeName
1980: && name instanceof DNSName) {
1981: // probably we need to glue together the last element of the prefix
1982: // and the name
1983: String comp1 = name.toString();
1984: String comp2 = prefix.get(prefix.size() - 1);
1985:
1986: result = new CompositeName();
1987: if (prefix.size() > 1) {
1988: result.addAll(prefix.getPrefix(prefix.size() - 1));
1989: }
1990: try {
1991: result.add(concatenateDNSNames(comp1, comp2));
1992: } catch (InvalidNameException e) {
1993: // comp2 is not a valid DNS name
1994: // components should be strongly separated
1995: result.add(comp2);
1996: result.add(comp1);
1997: }
1998: } else if (prefix instanceof DNSName
1999: && name instanceof CompositeName) {
2000: // probably we need to glue together the prefix and
2001: // the first element of the name
2002: String comp1 = name.get(0);
2003: String comp2 = prefix.toString();
2004:
2005: result = new CompositeName();
2006: try {
2007: result.add(concatenateDNSNames(comp1, comp2));
2008: } catch (InvalidNameException e) {
2009: // comp2 is not a valid DNS name
2010: // components should be strongly separated
2011: result.add(comp2);
2012: result.add(comp1);
2013: }
2014: if (name.size() > 1) {
2015: result.addAll(name.getSuffix(1));
2016: }
2017: } else if (prefix instanceof DNSName && name instanceof DNSName) {
2018: DNSName rootZone = ProviderConstants.ROOT_ZONE_NAME_OBJ;
2019: boolean prefixIsRoot = (prefix.compareTo(rootZone) == 0);
2020: boolean nameIsRoot = (name.compareTo(rootZone) == 0);
2021: boolean nameStartsFromRoot = name.get(0).equals(""); //$NON-NLS-1$
2022:
2023: if (nameStartsFromRoot) {
2024: // jndi.52=Can't append an absolute DNS name
2025: throw new NamingException(Messages.getString("jndi.52")); //$NON-NLS-1$
2026: }
2027: if (prefixIsRoot && nameIsRoot) {
2028: result = (DNSName) rootZone.clone();
2029: } else if (!prefixIsRoot && nameIsRoot) {
2030: // jndi.53=Root domain should be the rightmost one
2031: throw new NamingException(Messages.getString("jndi.53")); //$NON-NLS-1$
2032: } else {
2033: result = new DNSName();
2034: result.addAll(prefix);
2035: result.addAll(name);
2036: }
2037: } else {
2038: // jndi.4B=Only instances of CompositeName class or DNSName class
2039: // are acceptable
2040: throw new NamingException(Messages.getString("jndi.4B")); //$NON-NLS-1$
2041: }
2042: return result;
2043: }
2044:
2045: /**
2046: * Concatenate two DNS name components into one DNS name
2047: *
2048: * @param comp1
2049: * @param comp2
2050: * @return concatenation of <code>comp1</code> and <code>comp2</code>
2051: * @throws InvalidNameException
2052: * if either <code>comp1</code> or <code>comp2</code> cannot
2053: * be parsed
2054: * @throws NamingException
2055: * if DNS name syntax is violated during composition of a new
2056: * name from given components
2057: */
2058: private String concatenateDNSNames(String comp1, String comp2)
2059: throws NamingException {
2060: boolean comp1IsRoot = comp1.equals("."); //$NON-NLS-1$
2061: boolean comp2IsRoot = comp2.equals("."); //$NON-NLS-1$
2062: String composition = null;
2063:
2064: nameParser.parse(comp1);
2065: nameParser.parse(comp2);
2066: if (comp1.endsWith(".")) { //$NON-NLS-1$
2067: // jndi.52=Can't append an absolute DNS name
2068: throw new NamingException(Messages.getString("jndi.52")); //$NON-NLS-1$
2069: }
2070: if (comp1IsRoot && comp2IsRoot) {
2071: composition = "."; //$NON-NLS-1$
2072: } else if (!comp1IsRoot && comp2IsRoot) {
2073: composition = comp1 + "."; //$NON-NLS-1$
2074: } else if (comp1IsRoot && !comp2IsRoot) {
2075: // jndi.53=Root domain should be the rightmost one
2076: throw new NamingException(Messages.getString("jndi.53")); //$NON-NLS-1$
2077: } else {
2078: composition = comp1 + "." + comp2; //$NON-NLS-1$
2079: }
2080: return composition;
2081: }
2082:
2083: /**
2084: * Constructs the clone of this DNS context.
2085: *
2086: * @see Object#clone()
2087: */
2088: @Override
2089: public Object clone() {
2090: return new DNSContext(this , contextName);
2091: }
2092:
2093: /**
2094: * Checks if the given object is equal to the current context. It will
2095: * return <code>true</code> if and only if the specified object is an
2096: * instance of <code>DNSContext</code> class and has the same domain name.
2097: *
2098: * @param obj
2099: * an object to compare with
2100: * @return <code>true</code> if given object is equal to this one;
2101: * <code>false</code> otherwise
2102: */
2103: @Override
2104: public boolean equals(Object obj) {
2105: if (obj != null && obj instanceof DNSContext
2106: && contextName.equals(((DNSContext) obj).contextName)) {
2107: return true;
2108: }
2109: return false;
2110: }
2111:
2112: /**
2113: * @param name
2114: * composite name to process
2115: * @return root context of the namespace to that the target object belongs
2116: * and the name relative to this root context
2117: */
2118: private ContextNamePair getTargetNamespaceContextNamePair(
2119: Name cmpName) throws NamingException {
2120: CompositeName nameToLookFor;
2121: String remainingName;
2122: Object obj;
2123:
2124: if (cmpName == null || !(cmpName instanceof CompositeName)
2125: || cmpName.size() < 2) {
2126: throw new IllegalArgumentException();
2127: }
2128: remainingName = cmpName.get(cmpName.size() - 1);
2129: nameToLookFor = (CompositeName) cmpName.getPrefix(cmpName
2130: .size() - 1);
2131: nameToLookFor.add(""); //$NON-NLS-1$
2132: obj = lookup(nameToLookFor);
2133: return new ContextNamePair(obj, remainingName);
2134: }
2135:
2136: static class ContextNamePair {
2137: ContextNamePair(Object context, String name) {
2138: this .context = context;
2139: this .name = name;
2140: }
2141:
2142: Object context;
2143:
2144: String name;
2145: }
2146:
2147: }
|