You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/05/30 13:25:01 UTC

svn commit: r410240 [4/4] - in /incubator/harmony/enhanced/classlib/trunk/modules/jndi: make/ make/common/ src/main/java/org/apache/harmony/jndi/provider/ src/main/java/org/apache/harmony/jndi/provider/dns/ src/main/java/org/apache/harmony/util/ src/ma...

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/ResourceRecord.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/ResourceRecord.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/ResourceRecord.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/ResourceRecord.java Tue May 30 04:24:59 2006
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.StringTokenizer;
+
+/**
+ * Represents domain protocol Resource Record
+ * 
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ * @see RFC 1035
+ */
+public class ResourceRecord {
+    
+    /** a domain name */
+    private String name;
+    
+    /** resource record type */
+    private int rrType;
+    
+    /** resource record class*/ 
+    private int rrClass;
+    
+    /** time to live */
+    private long ttl;
+    
+    /** resource data length */
+//    private int rdLength;
+    
+    /** resource data itself */
+    private Object rData;
+
+    /** empty constructor */
+    public ResourceRecord() {}
+
+    /**
+     * Constructs new ResourceRecord object from given values.
+     * 
+     * @param name a domain name
+     * @param rrType resource record type
+     * @param rrClass resource record class
+     * @param ttl time to live
+     * @param rdLength resource data length
+     * @param rData resource data itself
+     */
+    public ResourceRecord(
+            String name,
+            int rrType,
+            int rrClass,
+            long ttl,
+            //int rdLength,
+            Object rData)
+    {
+        this.name = name;
+        this.rrType = rrType;
+        this.rrClass = rrClass;
+        this.ttl = ttl;
+        //this.rdLength = rdLength;
+        this.rData = rData;
+    }
+    
+    /**
+     * Creates the sequence of bytes that represents the current resource
+     *  record.
+     * 
+     * @param buffer the buffer to write the bytes into
+     * @param startIdx starting index
+     * @return updated index
+     * @throws DomainProtocolException if something went wrong
+     * @throws ArrayIndexOutOfBoundsException if the buffer border unpredictably
+     * encountered
+     */
+    public int writeBytes(byte[] buffer, int startIdx)
+            throws DomainProtocolException
+    {
+        int idx = startIdx;
+
+        // basic checking
+        if (buffer == null) {
+            throw new DomainProtocolException("buffer is null");
+        }
+        // NAME
+        idx = ProviderMgr.writeName(name, buffer, idx);
+        // TYPE
+        idx = ProviderMgr.write16Int(rrType, buffer, idx);
+        // CLASS
+        idx = ProviderMgr.write16Int(rrClass, buffer, idx);
+        // TTL
+        idx = ProviderMgr.write32Int(ttl, buffer, idx);
+        // RDLENGTH & RDATA
+        if (rrType == ProviderConstants.NS_TYPE ||
+            rrType == ProviderConstants.CNAME_TYPE ||
+            rrType == ProviderConstants.PTR_TYPE)
+        {
+            int idx0 = idx;
+
+            idx += 2;
+            // RDATA
+            idx = ProviderMgr.writeName((String) rData, buffer, idx);
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        else if (rrType == ProviderConstants.A_TYPE) {
+            byte[] ipBytes = ProviderMgr.parseIpStr((String) rData);
+
+            // RDLENGTH
+            idx = ProviderMgr.write16Int(ipBytes.length, buffer, idx);
+            // RDATA
+            for (int i = 0; i < ipBytes.length; i++) {
+                buffer[idx++] = ipBytes[i];
+            }
+        }
+        else if (rrType == ProviderConstants.SOA_TYPE) {
+            StringTokenizer st = new StringTokenizer((String) rData, " ");
+            String token;
+            int idx0 = idx; // saving RDLENGTH position
+
+            if (st.countTokens() != 7) {
+                throw new DomainProtocolException(
+                        "Invalid number of fields while parsing SOA record");
+            }
+            idx += 2; // skip RDLENGTH for now
+            // RDATA
+            // MNAME
+            token = st.nextToken();
+            idx = ProviderMgr.writeName((String) token, buffer, idx);
+            // RNAME
+            token = st.nextToken();
+            idx = ProviderMgr.writeName((String) token, buffer, idx);
+            // SERIAL
+            // REFRESH
+            // RETRY
+            // EXPIRE
+            // MINIMUM
+            try {
+                for (int i = 0; i < 5; i++) {
+                    token = st.nextToken();
+                    idx = ProviderMgr.write32Int(
+                            Long.parseLong(token), buffer, idx);
+                }
+            }
+            catch (NumberFormatException e) {
+                throw new DomainProtocolException(
+                        "Error while parsing SOA record", e);
+            }
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        else if (rrType == ProviderConstants.MX_TYPE) {
+            StringTokenizer st = new StringTokenizer((String) rData, " ");
+            String token;
+            int idx0 = idx; // saving RDLENGTH position
+
+            if (st.countTokens() != 2) {
+                throw new DomainProtocolException(
+                        "Invalid number of fields while parsing MX record");
+            }
+            idx += 2; // skip RDLENGTH for now
+            // PREFERENCE
+            token = st.nextToken();
+            try {
+                ProviderMgr.write16Int(Integer.parseInt(token), buffer, idx);
+            }
+            catch (NumberFormatException e) {
+                throw new DomainProtocolException(
+                        "Error while parsing MX record", e);
+            }
+            // EXCHANGE
+            token = st.nextToken();
+            idx = ProviderMgr.writeName(token, buffer, idx);
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        else if (rrType == ProviderConstants.HINFO_TYPE) {
+            StringTokenizer st = new StringTokenizer((String) rData, " ");
+            String token;
+            int idx0 = idx; // saving RDLENGTH position
+
+            if (st.countTokens() != 2) {
+                throw new DomainProtocolException(
+                        "Invalid number of fields while parsing HINFO record");
+            }
+            idx += 2; // skip RDLENGTH for now
+            // CPU
+            // OS
+            for (int i = 0; i < 2; i++) {
+                token = st.nextToken();
+                idx = ProviderMgr.writeCharString(token, buffer, idx);
+            }
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        else if (rrType == ProviderConstants.TXT_TYPE) {
+            // character string with preceding length octet
+            int idx0 = idx;
+            StringTokenizer st = new StringTokenizer((String) rData, " ");
+
+            idx += 2;
+            // RDATA
+            while (st.hasMoreTokens()) {
+                String token = st.nextToken();
+
+                if (token.getBytes().length > 255) {
+                    throw new DomainProtocolException(
+                            "The length of character string exceed 255 octets");
+                }
+                idx = ProviderMgr.writeCharString(token, buffer, idx);
+            }
+            if (idx - 2 - idx0 > 65535) {
+                throw new DomainProtocolException(
+                        "Length of TXT field exceed 65535");
+            }
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        else if (rrType == ProviderConstants.SRV_TYPE) {
+            StringTokenizer st = new StringTokenizer((String) rData, " ");
+            String token;
+            int idx0 = idx; // saving RDLENGTH position
+
+            idx += 2;
+            if (st.countTokens() != 4) {
+                throw new DomainProtocolException(
+                        "Invalid number of fields while parsing SRV record");
+            }
+            // RDATA
+
+            // PRIORITY
+            // WEIGHT
+            // PORT
+            try {
+                for (int i = 0; i < 3; i++) {
+                    token = st.nextToken();
+                    idx = ProviderMgr.write16Int(
+                            Integer.parseInt(token), buffer, idx);                    
+                }
+            }
+            catch (NumberFormatException e) {
+                throw new DomainProtocolException(
+                        "Error while parsing SRV record", e);
+            }
+            // TARGET
+            token = st.nextToken();
+            idx = ProviderMgr.writeName(token, buffer, idx);
+            // RDLENGTH
+            ProviderMgr.write16Int(idx - 2 - idx0, buffer, idx0);
+        }
+        // TODO add more Resource Record types here
+        else {
+            byte[] bytes;
+            
+            if (!(rData instanceof byte[])) {
+                throw new DomainProtocolException(
+                        "RDATA for unknown record type " + rrType +
+                        " should have value of byte[] type");
+            }
+            bytes = (byte[]) rData;
+            // RDLENGTH
+            idx = ProviderMgr.write16Int(bytes.length, buffer, idx);
+            // RDATA
+            for (int i = 0; i < bytes.length; i++) {
+                buffer[idx++] = bytes[i];
+            }
+        }
+        return idx;
+    }
+
+    /**
+     * Parses given sequence of bytes and constructs a resource record from it.
+     * 
+     * @param mesBytes the byte array that should be parsed
+     * @param startIdx an index of <code>mesBytes</code> array to start the
+     *  parsing at
+     * @param resultRR an object the result of the operation will be stored into
+     * @return updated index of <code>mesBytes</code> array
+     * @throws DomainProtocolException if something went wrong
+     * @throws ArrayIndexOutOfBoundsException if the array border unpredictably
+     * encountered
+     */
+    public static int parseRecord(byte[] mesBytes, int startIdx,
+            ResourceRecord resultRR) throws DomainProtocolException
+    {
+        int idx = startIdx;
+        StringBuffer nameSB = new StringBuffer();
+        int rrType;
+        int rdLen;
+        Object rDat = null; 
+
+        if (resultRR == null) {
+            throw new NullPointerException("Given resultRR is null");
+        }
+        // NAME
+        idx = ProviderMgr.parseName(mesBytes, idx, nameSB);
+        resultRR.setName(ProviderMgr.normalizeName(nameSB.toString()));
+        // TYPE
+        rrType = ProviderMgr.parse16Int(mesBytes, idx);
+        resultRR.setRRType(rrType);
+        idx += 2;
+        // CLASS
+        resultRR.setRRClass(ProviderMgr.parse16Int(mesBytes, idx));
+        idx += 2;
+        // TTL
+        resultRR.setTtl(ProviderMgr.parse32Int(mesBytes, idx));
+        idx += 4;
+        // RDLENGTH
+        rdLen = ProviderMgr.parse16Int(mesBytes, idx);
+        idx += 2;
+        // RDATA
+        if (rrType == ProviderConstants.NS_TYPE ||
+            rrType == ProviderConstants.CNAME_TYPE ||
+            rrType == ProviderConstants.PTR_TYPE)
+        {
+            // let's parse the domain name
+            StringBuffer name = new StringBuffer();
+
+            idx = ProviderMgr.parseName(mesBytes, idx, name);
+            rDat = ProviderMgr.normalizeName(name.toString());
+        }
+        else if (rrType == ProviderConstants.A_TYPE) {
+            // let's parse the 32 bit Internet address
+            byte tmpArr[] = new byte[4];
+
+            for (int i = 0; i < 4 ; i++) {
+                tmpArr[i] = mesBytes[idx + i];
+            }
+            rDat = ProviderMgr.getIpStr(tmpArr);
+            idx += 4;
+        }
+        else if (rrType == ProviderConstants.MX_TYPE)
+        {
+            // 16 bit integer (preference) followed by domain name
+            int preference;
+            StringBuffer name = new StringBuffer();
+
+            preference = ProviderMgr.parse16Int(mesBytes, idx);
+            idx += 2;
+            idx = ProviderMgr.parseName(mesBytes, idx, name);
+            rDat = "" + preference + " " +
+                    ProviderMgr.normalizeName(name.toString());
+        }
+        else if (rrType == ProviderConstants.SOA_TYPE) {
+            StringBuffer mName = new StringBuffer();
+            StringBuffer rName = new StringBuffer();
+            long serial;
+            long refresh;
+            long retry;
+            long expire;
+            long minimum;
+
+            idx = ProviderMgr.parseName(mesBytes, idx, mName);
+            idx = ProviderMgr.parseName(mesBytes, idx, rName);
+            serial = ProviderMgr.parse32Int(mesBytes, idx);
+            idx += 4;
+            refresh = ProviderMgr.parse32Int(mesBytes, idx);
+            idx += 4;
+            retry = ProviderMgr.parse32Int(mesBytes, idx);
+            idx += 4;
+            expire = ProviderMgr.parse32Int(mesBytes, idx);
+            idx += 4;
+            minimum = ProviderMgr.parse32Int(mesBytes, idx);
+            idx += 4;
+            rDat = ProviderMgr.normalizeName(mName.toString()) + " " +
+                    ProviderMgr.normalizeName(rName.toString()) + " " +
+                    serial + " " + refresh + " " + retry + " " + expire + " " +
+                    minimum;
+        }
+        else if (rrType == ProviderConstants.TXT_TYPE) {
+            StringBuffer sbuf = new StringBuffer();
+            int idx0 = idx;
+
+            while (true) {
+                int len11 = ProviderMgr.parse8Int(mesBytes, idx++);
+
+                if (idx - idx0 + len11 > rdLen) {
+                    idx--;
+                    break;
+                }
+                if (sbuf.length() > 0) {
+                    sbuf.append(' ');
+                }
+                sbuf.append(new String(mesBytes, idx, len11)); 
+                idx += len11;
+            }
+            rDat = sbuf.toString();
+        }
+        else if (rrType == ProviderConstants.HINFO_TYPE) {
+            // two character strings with preceding length octets
+            StringBuffer res = new StringBuffer();
+
+            idx = ProviderMgr.parseCharString(mesBytes, idx, res);
+            res.append(" ");
+            idx = ProviderMgr.parseCharString(mesBytes, idx, res);
+            rDat = res.toString();
+        }
+        else if (rrType == ProviderConstants.SRV_TYPE) {
+            int priority;
+            int weight;
+            int port;
+            StringBuffer name = new StringBuffer();
+
+            priority = ProviderMgr.parse16Int(mesBytes, idx);
+            idx += 2;
+            weight = ProviderMgr.parse16Int(mesBytes, idx);
+            idx += 2;
+            port = ProviderMgr.parse16Int(mesBytes, idx);
+            idx += 2;
+            idx = ProviderMgr.parseName(mesBytes, idx, name);
+            rDat = "" + priority + " " + weight + " " + port + " " +
+                    ProviderMgr.normalizeName(name.toString());
+        }
+        // TODO add more Resource Record types here
+        else {
+            // copy bytes since the retrieved bytes
+            // could contain unknown binary data
+            rDat = new byte[rdLen];
+            for (int i = 0; i < rdLen; i++) {
+                ((byte[]) rDat)[i] = mesBytes[idx++];
+            }
+        }
+        resultRR.setRData(rDat);
+        return idx;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(name);
+        sb.append(" ");
+        sb.append(ProviderConstants.rrTypeNames[rrType]);
+        sb.append(" ");
+        sb.append(rrClass);
+        sb.append(" ");
+        sb.append("TTL=" + ttl);
+        sb.append(" ");
+        sb.append(rData.toString());
+        return sb.toString();
+    }
+
+    
+    // getters and setters
+    
+    /**
+     * @return Returns the name.
+     */
+    public String getName() {
+        return name;
+    }
+    /**
+     * @param name The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+    /**
+     * @return Returns the rData.
+     */
+    public Object getRData() {
+        return rData;
+    }
+    /**
+     * @param data The rData to set.
+     */
+    public void setRData(Object data) {
+        rData = data;
+    }
+    /**
+     * @return Returns the rdLength.
+     */
+    //public int getRDLength() {
+    //    return rdLength;
+    //}
+    /**
+     * @param rdLength The rdLength to set.
+     */
+    //public void setRDLength(int rdLength) {
+    //    this.rdLength = rdLength;
+    //}
+    /**
+     * @return Returns the rrClass.
+     */
+    public int getRRClass() {
+        return rrClass;
+    }
+    /**
+     * @param rrClass The rrClass to set.
+     */
+    public void setRRClass(int rrClass) {
+        this.rrClass = rrClass;
+    }
+    /**
+     * @return Returns the rrType.
+     */
+    public int getRRType() {
+        return rrType;
+    }
+    /**
+     * @param rrType The rrType to set.
+     */
+    public void setRRType(int rrType) {
+        this.rrType = rrType;
+    }
+    /**
+     * @return Returns the TTL.
+     */
+    public long getTtl() {
+        return ttl;
+    }
+    /**
+     * @param ttl The TTL to set.
+     */
+    public void setTtl(long ttl) {
+        this.ttl = ttl;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/ResourceRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/SList.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/SList.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/SList.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/SList.java Tue May 30 04:24:59 2006
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+
+/**
+ * Represents DNS resolver's SLIST - the structure to keep the collected
+ *  information about active DNS servers and zones they contain information
+ *  about. 
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.5 $
+ * @see RFC 1034
+ * TODO some methods can be optimized
+ */
+class SList {
+    
+    public static int NETWORK_FAILURE = Integer.MAX_VALUE - 3;
+    public static int TIMEOUT = Integer.MAX_VALUE - 2;
+    public static int SERVER_FAILURE = Integer.MAX_VALUE - 1;
+    public static int UNKNOWN = 0;
+
+    // Hash with vectors; one vector of server entries per zone
+    private Hashtable zones;
+    
+    // the array with known DNS servers information
+    private Vector servers;
+    
+    /**
+     * @see #getInstance()
+     */
+    private SList() {
+        zones = new Hashtable();
+        servers = new Vector();
+    }
+
+    private static SList instance = null;
+
+    /**
+     * <code>SList</code> is a singleton class.
+     * @return instance of <code>SList</code>
+     */
+    static SList getInstance() {
+        if (instance == null) {
+            instance = new SList();
+        }
+        return instance;
+    }
+
+    /**
+     * Updates existent SLIST entry or creates a new one. S-List will
+     * be sorted according the response time. Entries with bigger response will
+     * be placed father from the beginning of the list.
+     * 
+     * @param zone the name of DNS zone
+     * @param server the server that is known to have the information about
+     *  given zone
+     * @param responseTime response time for server for this particular DNS zone
+     */
+    void updateEntry(String zone, Server server, int responseTime)
+    {
+        String normZoneName = ProviderMgr.normalizeName(zone); 
+        Vector vect;
+        Entry entryToAdd =
+                new Entry(normZoneName, getServerNum(server), responseTime);
+
+        synchronized (zones) {
+            vect =
+                (Vector) zones.get(ProviderMgr.normalizeName(normZoneName));
+            if (vect == null) {
+                vect = new Vector();
+                vect.addElement(entryToAdd);
+                zones.put(normZoneName, vect);
+            }
+            else {
+                boolean added = false;
+    
+                // delete previous occurrence of given server
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry curEntry = (Entry) vect.elementAt(i);
+    
+                    if (server.equals(serverAtNum(curEntry.getServerNum()))) {
+                        vect.removeElementAt(i);
+                        break;
+                    }
+                }
+    
+                // and insert a new one with updated response time
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry curEntry = (Entry) vect.elementAt(i);
+    
+                    if (responseTime < curEntry.getResponseTime()) {
+                        vect.insertElementAt(entryToAdd, i);
+                        added = true;
+                        break;
+                    }
+                }
+                // append to the end of list if not found
+                if (!added) {
+                    vect.addElement(entryToAdd);
+                }
+            }
+        } // synchronized block
+    }
+
+    /**
+     * Returns the best guess about that DNS server should be chosen to send the
+     *  request concerning the particular DNS zone. 
+     * @param zone the name of DNS zone
+     * @return best guess - a <code>SList.Server</code> object;
+     *  <code>null</code> if the information is not found
+     */
+    Server getBestGuess(String zone, Hashtable serversToIgnore) {
+        Vector vect;
+
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+            if (vect != null && vect.size() > 0) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+    
+                    if (serversToIgnore != null) {
+                        if (serversToIgnore.get(
+                                serverAtNum(entry.getServerNum())) != null)
+                        {
+                            continue;
+                        }
+                    }
+                    return serverAtNum(entry.getServerNum());
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes occurrence of given server related to given zone from the SLIST. 
+     * @param zone DNS zone 
+     * @param server the server to remove
+     */
+    void dropServer(String zone, Server server) {
+        Vector vect;
+
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+            if (vect != null) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+    
+                    if (server.equals(serverAtNum(entry.getServerNum()))) {
+                        vect.removeElementAt(i);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @param zone the name of zone
+     * @param server DNS server
+     * @return <code>true</code> if SList has information about specified
+     * server & zone combination; <code>false</code> otherwise
+     */
+    boolean hasServer(String zone, Server server) {
+        Vector vect;
+
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+            if (vect != null) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+    
+                    if (server.equals(serverAtNum(entry.getServerNum()))) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param zone the name DNS zone
+     * @param srvName the name of the server
+     * @param srvPort the port of the server
+     * @return <code>Server</code> object with specified attributes
+     */
+    Server getServerByName(String zone, String name, int port) {
+        Vector vect;
+
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+            if (vect != null) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+        
+                    if (ProviderMgr.namesAreEqual(name,
+                            serverAtNum(entry.getServerNum()).getName())
+                            && port == serverAtNum(
+                                    entry.getServerNum()).getPort())
+                    {
+                        return serverAtNum(entry.getServerNum());
+                    }
+                }
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * @param zone name of DNS zone
+     * @param srvIP IPv4 address of server
+     * @param srvPort port on server
+     * @return <code>Server</code> object with specified attributes
+     */
+    Server getServerByIP(String zone, String ip, int port) {
+        Vector vect;
+
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+            if (vect != null) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+    
+                    if (ip.equals(serverAtNum(entry.getServerNum()).getIP()) &&
+                            port == serverAtNum(entry.getServerNum()).getPort())
+                    {
+                        return serverAtNum(entry.getServerNum());
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param zone the name of DNS zone to query SLIST with 
+     * @param server the server to compare with
+     * @return first <code>Server</code> object from SLIST that equals to
+     * specified server in terms of <code>equals()</code> method;
+     * <code>null</code> if not found.
+     * @see SList.Server#equals(SList.Server)
+     */
+    Server getServerByServer(String zone, Server server) {
+        Vector vect;
+        
+        synchronized (zones) {
+            vect = (Vector) zones.get(ProviderMgr.normalizeName(zone));
+    
+            if (vect != null) {
+                for (int i = 0; i < vect.size(); i++) {
+                    Entry entry = (Entry) vect.elementAt(i);
+    
+                    if (server.equals(serverAtNum(entry.getServerNum())));
+                    {
+                        return serverAtNum(entry.getServerNum());
+                    }
+                }
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Clears the SLIST.
+     */
+    void clear() {
+        synchronized (zones) {
+            zones = new Hashtable();
+        }
+    }
+
+    // --- managing local list of servers ---
+    
+    // since the list of servers is add-only entity a write synchronization
+    // should be enough
+    
+    /**
+     * @return number of given server in the internal array of servers; add the
+     * server if not found
+     */
+    private int getServerNum(Server server) {
+        if (servers.contains(server)) {
+            return servers.indexOf(server);
+        }
+        else {
+            synchronized (servers) {
+                servers.addElement(server);
+                return servers.size() - 1;
+            }
+        }
+    }
+
+    /**
+     * @param num internal number of server
+     * @return <code>Server</code> object found at specified index
+     */
+    private Server serverAtNum(int num) {
+        if (num < servers.size()) {
+            return (Server) servers.elementAt(num);
+        }
+        else {
+            return null;
+        }
+    }
+
+    /**
+     * Checks if given server is present in the internal list of known servers.
+     *  
+     * @param hostname host name of server
+     * @return <code>true</code> or <code>false</code>
+     */
+    boolean hasServer(String hostname) {
+        return servers.contains(new Server(hostname, null,
+                ProviderConstants.DEFAULT_DNS_PORT));
+    }
+
+    /**
+     * Returns all occurences of server with specified
+     * @param name hostname
+     * @return found server object or <code>null</code> if not found
+     */
+    Enumeration getServersByName(String name) {
+        Vector result = new Vector();
+        
+        if (name == null) {
+            throw new NullPointerException("hostname is null");
+        }
+        for (int i = 0; i < servers.size(); i++) {
+            Server curServ = (Server) servers.get(i);
+            
+            if (curServ.getName() != null &&
+                    ProviderMgr.namesAreEqual(name, curServ.getName()))
+            {
+                result.addElement(curServ);
+            }
+        }
+        return result.elements();
+    }
+    
+    /**
+     * Add IP information of server in list. Affects only servers with IP set
+     * to <code>null</code>. 
+     * @param hostname hostname of server
+     * @param newIP new IP
+     */
+    void setServerIP(String hostname, String newIP) {
+        String nameNorm = ProviderMgr.normalizeName(hostname);
+        
+        for (int i = 0; i < servers.size(); i++) {
+            SList.Server serv = (Server) servers.elementAt(i);
+
+            if (nameNorm.equals(serv.getName()) &&
+                serv.getIP() == null)
+            {
+                serv.setIP(newIP);
+                break;
+            }
+        }
+    }
+
+    // --- additional classes ---
+    
+    /**
+     * Represents an SLIST entry. 
+     * @author Alexei Zakharov
+     */
+    static class Entry {
+
+        private String zoneName;
+        private int serverNum;
+        private int responseTime;
+
+        /**
+         * Creates new SLIST entry.
+         * @param zoneName
+         * @param server
+         * @param respTime
+         */
+        public Entry(String zoneName, int serverNum, int respTime) {
+            this.zoneName = zoneName;
+            this.serverNum = serverNum;
+            this.responseTime = respTime;            
+        }
+
+        /**
+         * @return Returns the responseTime.
+         */
+        public int getResponseTime() {
+            return responseTime;
+        }
+        /**
+         * @param responseTime The responseTime to set.
+         */
+        public void setResponseTime(int responseTime) {
+            this.responseTime = responseTime;
+        }
+        /**
+         * @return Returns the server.
+         */
+        public int getServerNum() {
+            return serverNum;
+        }
+        /**
+         * @param server The server to set.
+         */
+        public void setServerNum(int serverNum) {
+            this.serverNum = serverNum;
+        }
+        /**
+         * @return Returns the zoneName.
+         */
+        public String getZoneName() {
+            return zoneName;
+        }
+        /**
+         * @param zoneName The zoneName to set.
+         */
+        public void setZoneName(String zoneName) {
+            this.zoneName = zoneName;
+        }
+    }
+
+    /**
+     * Represents a DNS server.
+     * @author Alexei Zakharov
+     */
+    static class Server {
+
+        private String serverName;
+        private String serverIP;
+        private int serverPort;
+
+        /**
+         * Constructs new <code>Server</code> object with given parameters.
+         * 
+         * @param serverName the name of the server
+         * @param serverIP IP address of the server
+         * @param serverPort a port number
+         */
+        public Server(String serverName, String serverIP, int serverPort) {
+            this.serverName = ProviderMgr.normalizeName(serverName);
+            this.serverIP = serverIP;
+            this.serverPort = serverPort;
+        }
+
+        /**
+         * Returns <code>true</code> if two servers are equal,
+         *  <code>false</code> otherwise.
+         * @param obj a <code>Server</code> object to compare with
+         * @return <code>true</code> or <code>false</code>
+         */
+        public boolean equals(Object obj) {
+            SList.Server srv = null;
+
+            if (!(obj instanceof SList.Server)) {
+                return false;
+            }
+            srv = (SList.Server) obj;
+            if (serverIP == null || srv.getIP() == null) {
+                if (this.getName() == null || srv.getName() == null) {
+                    return false;
+                }
+                return ProviderMgr.namesAreEqual(
+                                this.getName(), srv.getName()) &&
+                       this.getPort() == srv.getPort();
+            } else {
+                return this.getIP().equals(srv.getIP()) &&
+                       this.getPort() == srv.getPort();
+            }
+        }
+        
+        /**
+         * @return Returns the serverIP.
+         */
+        public String getIP() {
+            return serverIP;
+        }
+        /**
+         * @return Returns the serverName.
+         */
+        public String getName() {
+            return serverName;
+        }
+        /**
+         * @return Returns the serverPort.
+         */
+        public int getPort() {
+            return serverPort;
+        }
+        /**
+         * @param serverIP The serverIP to set.
+         */
+        public void setIP(String serverIP) {
+            this.serverIP = serverIP;
+        }
+        /**
+         * @param serverName The serverName to set.
+         */
+        public void setName(String serverName) {
+            this.serverName = ProviderMgr.normalizeName(serverName);
+        }
+        /**
+         * @param serverPort The serverPort to set.
+         */
+        public void setPort(int serverPort) {
+            this.serverPort = serverPort;
+        }
+
+        public String toString() {
+            if (this.serverName != null) {
+                return serverName + ":" + serverPort; 
+            }
+            else {
+                return serverIP + ":" + serverPort;
+            }
+        }
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/SList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/TransportMgr.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/TransportMgr.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/TransportMgr.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/TransportMgr.java Tue May 30 04:24:59 2006
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.nio.channels.IllegalBlockingModeException;
+
+/**
+ * Contains service methods that are used for transporting DNS messages from
+ * DNS client to DNS server and vice versa.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class TransportMgr {
+
+    /**
+     * Sends the packet contained in <code>outBuf</code>, receives
+     * the answer and stores it in <code>inBuf</code> array.
+     * 
+     * @param server server's IP-address in string form
+     * @param serverPort server port
+     * @param outBuf bytes of the message to send 
+     * @param outBufLen length of the <code>outBuf</code>
+     * @param inBuf buffer to store received bytes at
+     * @param inBufLen length of the <code>inBuf</code>
+     * @param timeout time to wait for an answer, in milliseconds;
+     *  0 stands for infinite timeout 
+     * @return number of received bytes
+     * @throws SocketTimeoutException in case of timeout
+     * @throws SecurityException if security violation error occured; normally
+     * this happens if the access to the network subsystem has not been granted
+     * @throws DomainProtocolException if some configuration or network
+     *  problem encountered 
+     */
+    public static int sendReceiveUDP(String server,
+                                     int serverPort,
+                                     byte[] outBuf,
+                                     int outBufLen,
+                                     byte[] inBuf,
+                                     int inBufLen,
+                                     int timeout)
+            throws DomainProtocolException,
+                   SocketTimeoutException,
+                   SecurityException
+    {
+        byte srvAddrArr[] = null;
+        InetAddress srvAddr = null;
+        DatagramSocket dSocket = null;
+        DatagramPacket inPacket = null;
+        DatagramPacket outPacket = null;
+    
+        try {
+            srvAddrArr = ProviderMgr.parseIpStr(server);
+        } catch (IllegalArgumentException e) {
+            throw new DomainProtocolException(
+                    "Unable to connect: bad IP address");
+        }
+        try {
+            dSocket = new DatagramSocket();
+            srvAddr = Inet4Address.getByAddress(srvAddrArr);
+            dSocket.connect(srvAddr, serverPort);
+            outPacket = new DatagramPacket(
+                    outBuf, outBufLen, srvAddr, serverPort);
+            dSocket.setSoTimeout(timeout);
+            dSocket.send(outPacket);
+            inPacket = new DatagramPacket(inBuf, inBufLen, srvAddr, serverPort);
+            dSocket.receive(inPacket);
+        } catch (IllegalBlockingModeException e) {
+            throw new DomainProtocolException(
+                    "Error while querying DNS server", e);
+        } catch (SocketTimeoutException e) {
+            throw (e);
+        } catch (IOException e) {
+            throw new DomainProtocolException(
+                    "Error while querying DNS server", e);
+        } finally {
+            if (dSocket != null) {
+                dSocket.close();
+            }
+        }
+        if (inPacket != null) {
+            return inPacket.getLength();
+        } else {
+            throw new DomainProtocolException("unknown error");
+        }
+    }
+
+    /**
+     * Establishes TCP connection, transmit bytes from <code>inBuf</code>,
+     * stores received answer in <code>outBuf</code>.
+     * 
+     * @param server the server's IP-address in string form
+     * @param serverPort server port
+     * @param outBuf bytes of the message to send 
+     * @param outBufLen length of the <code>outBuf</code>
+     * @param inBuf buffer to store received bytes at
+     * @param inBufLen length of the <code>inBuf</code>
+     * @param timeout time to wait for an answer, in milliseconds;
+     *  0 stands for infinite timeout 
+     * @return number of received bytes
+     * @throws SocketTimeoutException in case of timeout
+     * @throws SecurityException if security violation error occured; normally
+     * this happens if the access to the network subsystem has not been granted
+     * @throws DomainProtocolException if some configuration or network
+     *  problem encountered 
+     * TODO pool of connections may speed up things
+     */
+    public static int sendReceiveTCP(String server,
+                                     int serverPort,
+                                     byte[] outBuf,
+                                     int outBufLen,
+                                     byte[] inBuf,
+                                     int inBufLen,
+                                     int timeout)
+            throws DomainProtocolException,
+                   SocketTimeoutException,
+                   SecurityException
+    {
+        byte srvAddrArr[] = null;
+        InetAddress srvAddr = null;
+        Socket socket = null;
+        InputStream iStream = null;
+        BufferedOutputStream oStream = null;
+        byte tmpArr[] = new byte[2];
+        int inLen;
+        int actualLen = -1;
+
+        try {
+            srvAddrArr = ProviderMgr.parseIpStr(server);
+        } catch (IllegalArgumentException e) {
+            throw new DomainProtocolException(
+                    "Unable to connect: bad IP address");
+        }
+        try {
+            srvAddr = Inet4Address.getByAddress(srvAddrArr);
+            socket = new Socket(srvAddr, serverPort);
+            socket.setSoTimeout(timeout);
+            oStream = new BufferedOutputStream(socket.getOutputStream());
+            ProviderMgr.write16Int(outBufLen, tmpArr, 0);
+            oStream.write(tmpArr, 0, 2);
+            oStream.write(outBuf, 0, outBufLen);
+            oStream.flush();
+            iStream = socket.getInputStream();
+            iStream.read(tmpArr, 0, 2);
+            inLen = ProviderMgr.parse16Int(tmpArr, 0);
+            if (inLen > inBufLen) {
+                throw new DomainProtocolException("Output buffer is too small");
+            }
+            actualLen = iStream.read(inBuf, 0, inLen);
+            if (actualLen != inLen) {
+                throw new DomainProtocolException(
+                        "Error while receiving message over TCP");
+            }
+        } catch (IllegalBlockingModeException e) {
+            throw new DomainProtocolException(
+                    "Error while querying DNS server", e);
+        } catch (SocketTimeoutException e) {
+            throw (e);
+        } catch (IOException e) {
+            throw new DomainProtocolException(
+                    "Error while querying DNS server", e);
+        } finally {
+            if (socket != null && !socket.isClosed()) {
+                try {
+                    socket.close();
+                } catch (IOException e) {}
+            }
+        }
+        return actualLen;
+    }
+
+    /**
+     * Tries to determine IP address by hostname using
+     * <code>Inet4Address.getByName(String)</code> method.
+     * @return determined address or <code>null</code> if not found
+     * @see java.net.InetAddress#getByName(String)
+     */
+    public static InetAddress getIPByName_OS(String hostname) {
+        InetAddress addr = null;
+
+        try {
+            addr = Inet4Address.getByName(hostname);
+        } catch (UnknownHostException e) {
+            // ignore it
+        }
+        return addr;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/TransportMgr.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContext.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContext.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContext.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContext.java Tue May 30 04:24:59 2006
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+/**
+ * DNS context that is capable of serving requests with DNS URL's given as
+ * names.
+ * 
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class dnsURLContext extends DNSContext {
+
+    /**
+     * Constructs new DNS URL context.
+     * @param env environment
+     * @throws NamingException if such exception was encountered
+     */
+    public dnsURLContext(Hashtable env) throws NamingException {
+        super(env);
+    }
+
+    /**
+     * @param name well formed DNS URL that points to some context
+     * @param attrNames array of attribute identifiers
+     * @return collection of attributes
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#getAttributes(String, String[])
+     */
+    public Attributes getAttributes(String name, String[] attrNames)
+            throws NamingException
+    {
+        process(name);
+        return super.getAttributes(new DNSName(), attrNames);
+    }
+    
+    /**
+     * @param name well formed DNS URL
+     * @return retrieved collection of attributes
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#getAttributes(String) 
+     */
+    public Attributes getAttributes(String name) throws NamingException {
+        return getAttributes(name, null);
+    }
+    
+    /**
+     * @param name well formed DNS URL
+     * @return collection of <code>NameClassPair</code> 
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#list(String)
+     */
+    public NamingEnumeration list(String name) throws NamingException {
+        process(name);
+        return super.list(new DNSName());
+    }
+
+    /**
+     * @param name well formed DNS URL
+     * @return collection of <code>Binding</code> 
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#listBindings(String)
+     */
+    public NamingEnumeration listBindings(String name) throws NamingException {
+        process(name);
+        return super.listBindings(new DNSName());
+    }
+
+    /**
+     * @param name well formed DNS URL
+     * @return found object
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#lookup(String)
+     */
+    public Object lookup(String name) throws NamingException {
+        process(name);
+        return super.lookup(new DNSName());
+    }
+
+    /**
+     * @param name well formed DNS URL
+     * @return found object
+     * @throws NamingException if such exception was encountered
+     * @throws NullPointerException if <code>name</code> is null
+     * @see DNSContext#lookupLink(String)
+     */
+    public Object lookupLink(String name) throws NamingException {
+        return lookup(name);
+    }
+
+    /**
+     * Service method
+     * @param name DNS URL
+     * @throws NamingException if was encountered
+     * @throws NullPointerException if name is null
+     */
+    private void process(String name) throws NamingException {
+        if (name == null) {
+            throw new NullPointerException("name is null");
+        }
+        addToEnvironment(Context.PROVIDER_URL, name);
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContextFactory.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContextFactory.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContextFactory.java Tue May 30 04:24:59 2006
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.spi.ObjectFactory;
+
+
+/**
+ * Factory to create DNS URL contexts.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class dnsURLContextFactory implements ObjectFactory {
+    
+    /**
+     * Returns new instance of DNS URL context.
+     * @param obj either <code>null</code>, URL in string form or array
+     * of URL in string form  
+     * @param name ignored
+     * @param nameCtx ignored
+     * @param environment is passed to the context being created
+     * @return created DNS context, an instance of either
+     *  <code>dnsURLContext</code> or <code>DNSContext</code> class
+     * @throws IllegalArgumentException if bad <code>obj</code> is given
+     * @throws NamingException if such exception was encountered 
+     * @see ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable)
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+            Hashtable environment) throws NamingException
+    {
+        if (obj == null) {
+            return new dnsURLContext(environment);
+        } else if (obj instanceof String) {
+            Hashtable newEnv = (Hashtable) environment.clone();
+
+            newEnv.put(Context.PROVIDER_URL, obj);
+            return new DNSContext(newEnv);
+        } else if (obj instanceof String[]) {
+            Hashtable newEnv = (Hashtable) environment.clone();
+            StringBuffer sb = new StringBuffer();
+            String urlArr[] = (String[]) obj;
+
+            for (int i = 0; i < urlArr.length; i++) {
+                if (i != 0) {
+                    sb.append(' ');
+                }
+                sb.append(urlArr[i]);
+            }
+            newEnv.put(Context.PROVIDER_URL, sb.toString());
+            return new DNSContext(newEnv);
+        } else {
+            throw new IllegalArgumentException(
+                    "obj should be either null, String or array of String");
+        }
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/dnsURLContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/util/logging/LogConst.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/util/logging/LogConst.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/util/logging/LogConst.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/util/logging/LogConst.java Tue May 30 04:24:59 2006
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+package org.apache.harmony.util.logging;
+
+public class LogConst {
+    
+    /**
+     * Set to TRUE to enable debug messages.
+     */
+    public static final boolean DEBUG = true;
+}
\ No newline at end of file

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/util/logging/LogConst.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSContextTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSContextTest.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSContextTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSContextTest.java Tue May 30 04:24:59 2006
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.Hashtable;
+
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * <code>org.apache.harmony.jndi.provider.dns.DNSContext</class> class unit test. 
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+public class DNSContextTest extends TestCase {
+
+    private DNSNameParser nameParser = null;
+    
+    protected void setUp() {
+        nameParser = new DNSNameParser();
+    }
+    
+    public void testGetNameInNamespace() throws NamingException {
+        Context ctx;
+        String propStr1 = "dns://localhost/example.com";
+        String propStr2 = "dns://localhost";
+        Hashtable env = new Hashtable();
+
+        env.put(Context.PROVIDER_URL, propStr1);
+        ctx = new DNSContext(env);
+        assertEquals("example.com.", ctx.getNameInNamespace());
+        env.put(Context.PROVIDER_URL, propStr2);
+        ctx = new DNSContext(env);
+        assertEquals(".", ctx.getNameInNamespace());
+    }
+    
+    public void testComposeName() throws NamingException {
+        Name name = null;
+        Name prefix = null;
+        Name result = null;
+        String resultStr = null;
+        String propStr1 = "dns://localhost/example.com";
+        Hashtable env = new Hashtable();
+        Context ctx;
+
+        env.put(Context.PROVIDER_URL, propStr1);
+        ctx = new DNSContext(env);
+        // #composeName(Name, Name)
+        // NULL & NULL
+        try {
+            ctx.composeName(name, prefix);
+            fail("NullPointerException has not been thrown");
+        } catch (NullPointerException e) {}
+        // CompositeName & CompositeName
+        name = new CompositeName("host1/file1.html");
+        prefix = new CompositeName("/example.com");
+        result = ctx.composeName(name, prefix);
+        assertEquals("/host1.example.com/file1.html", result.toString());
+        // DNSName & CompositeName
+        name = nameParser.parse("host1.mysubdomain");
+        prefix = new CompositeName("schema2:/example.com");
+        result = ctx.composeName(name, prefix);
+        assertEquals("schema2:/host1.mysubdomain.example.com",
+                result.toString());
+        // CompositeName & DNSName
+        name = new CompositeName("host1/file1.html");
+        prefix = nameParser.parse("subdomain.example.com."); 
+        result = ctx.composeName(name, prefix);    
+        assertEquals("host1.subdomain.example.com./file1.html",
+                result.toString());
+        // DNSName & DNSName
+        name = nameParser.parse("host1.subdomain1");
+        prefix = nameParser.parse("subdomain2.example.com."); 
+        result = ctx.composeName(name, prefix);    
+        assertEquals("host1.subdomain1.subdomain2.example.com.",
+                result.toString());
+
+        // error
+        name = ProviderConstants.ROOT_ZONE_NAME_OBJ;
+        prefix = new CompositeName("schema33:/domain.com");
+        try {
+            result = ctx.composeName(name, prefix);
+            fail("NamingException should be thrown");
+        } catch (NamingException e) {}
+
+        // string form
+        resultStr = ctx.composeName("host1/file1.html", "/example.com");
+        assertEquals("/host1.example.com/file1.html", resultStr);
+        resultStr = ctx.composeName("host1", "example.com");
+        assertEquals("host1.example.com", resultStr);
+        resultStr = ctx.composeName("host1/mamba", "example.com");
+        assertEquals("host1.example.com/mamba", resultStr);
+        resultStr = ctx.composeName("host1.subdomain", "schema17:/example.com");
+        assertEquals("schema17:/host1.subdomain.example.com", resultStr);
+        // error
+        try {
+            ctx.composeName(".", "schema17:/example.com");
+            fail("NamingException should be thrown");
+        } catch (NamingException e) {}
+    }
+
+    public void testConstructor() throws NoSuchFieldException,
+            IllegalArgumentException, SecurityException, NamingException
+    {
+        Hashtable env = new Hashtable();
+        DNSContext context = null;
+        SList slist = null;
+        SList.Server serv = null;
+        
+        env.put(Context.AUTHORITATIVE, "true");
+        env.put(DNSContext.LOOKUP_ATTR, "IN A");
+        env.put(DNSContext.RECURSION, "true");
+        env.put(DNSContext.TIMEOUT_INITIAL, "5000");
+        env.put(DNSContext.TIMEOUT_RETRIES, "5");
+        env.put(DNSContext.THREADS_MAX, "17");
+        env.put(Context.PROVIDER_URL, "dns://superdns.com/intel.com");
+        context = new DNSContext(env);
+        assertEquals(true, TestMgr.getBoolField(context, "authoritative"));
+        assertEquals(ProviderConstants.A_TYPE,
+                TestMgr.getIntField(context, "lookupAttrType"));
+        assertEquals(ProviderConstants.IN_CLASS,
+                TestMgr.getIntField(context, "lookupAttrClass"));
+        assertEquals(true, TestMgr.getBoolField(context, "recursion"));
+        assertEquals(5000, TestMgr.getIntField(context, "timeoutInitial"));
+        assertEquals(5, TestMgr.getIntField(context, "timeoutRetries"));
+        assertEquals(17, TestMgr.getIntField(context, "maxThreads"));
+
+        env.put(Context.AUTHORITATIVE, "blah blah blah");
+        env.put(DNSContext.LOOKUP_ATTR, "MX");
+        env.put(DNSContext.RECURSION, "trueee");
+        env.remove(DNSContext.THREADS_MAX);
+        context = new DNSContext(env);
+        assertEquals(false, TestMgr.getBoolField(context, "authoritative"));
+        assertEquals(ProviderConstants.MX_TYPE,
+                TestMgr.getIntField(context, "lookupAttrType"));
+        assertEquals(ProviderConstants.IN_CLASS,
+                TestMgr.getIntField(context, "lookupAttrClass"));
+        assertEquals(false, TestMgr.getBoolField(context, "recursion"));
+        assertEquals(ProviderConstants.DEFAULT_MAX_THREADS,
+                TestMgr.getIntField(context, "maxThreads"));
+
+        env.put(DNSContext.LOOKUP_ATTR, "IN ZZZZZZZ");
+        try {
+            context = new DNSContext(env);
+            fail("NamingException has not been thrown");
+        } catch (NamingException e) {}
+
+        env.put(DNSContext.LOOKUP_ATTR, "ZZZZZZZ");
+        try {
+            context = new DNSContext(env);
+            fail("NamingException has not been thrown");
+        } catch (NamingException e) {}
+        env.put(DNSContext.LOOKUP_ATTR, "TXT");
+
+        env.put(DNSContext.TIMEOUT_INITIAL, "q");
+        try {
+            context = new DNSContext(env);
+            fail("NumberFormatException has not been thrown");
+        } catch (NumberFormatException e) {}
+        env.put(DNSContext.TIMEOUT_INITIAL, "5000");
+
+        env.put(DNSContext.TIMEOUT_RETRIES, "q");
+        try {
+            context = new DNSContext(env);
+            fail("NumberFormatException has not been thrown");
+        } catch (NumberFormatException e) {}
+        env.put(DNSContext.TIMEOUT_RETRIES, "5");
+
+        env.put(DNSContext.PROVIDER_URL,
+                "dns://dnsserver1.com/super.zone.ru. " +
+                "dns://123.456.78.90/super.zone.ru");
+        context = new DNSContext(env);
+        slist = SList.getInstance();
+        serv = slist.getServerByName("super.zone.ru", "dnsserver1.com", 53);
+        if (serv == null) {
+            fail("DNS server has not been added");
+        }
+        serv = slist.getServerByIP("super.zone.ru.", "123.456.78.90", 53);
+        if (serv == null) {
+            fail("DNS server has not been added");
+        }
+        
+        env.put(DNSContext.PROVIDER_URL, "file:/etc/passwd");
+        try {
+            context = new DNSContext(env);
+            fail("NamingException has not been thrown");
+        }
+        catch (NamingException e) {}
+        
+    }
+    
+    /**
+     * Tests <code>addToEnvironment(), getEnvironment()</code> and
+     * <code>removeFromEnvironment()</code> methods.
+     */
+    public void testEnvironment() throws NamingException {
+        DNSContext context = null;
+        Hashtable env = new Hashtable();
+        Hashtable env2 = null;
+
+        // no side effect
+        env.put(DNSContext.TIMEOUT_INITIAL, "2000");
+        context = new DNSContext(env);
+        env.put(DNSContext.TIMEOUT_INITIAL, "2001");
+        env2 = context.getEnvironment();
+        assertEquals("2000", env2.get(DNSContext.TIMEOUT_INITIAL));
+        
+        // add to environment
+        context.addToEnvironment(DNSContext.TIMEOUT_RETRIES, "15");
+        env2 = context.getEnvironment();
+        assertEquals("15", env2.get(DNSContext.TIMEOUT_RETRIES));
+
+        // replace with new value
+        context.addToEnvironment(DNSContext.TIMEOUT_RETRIES, "16");
+        env2 = context.getEnvironment();
+        assertEquals("16", env2.get(DNSContext.TIMEOUT_RETRIES));
+        
+        // remove from environment
+        context.removeFromEnvironment(DNSContext.TIMEOUT_INITIAL);
+        env2 = context.getEnvironment();
+        assertEquals(null, env2.get(DNSContext.TIMEOUT_INITIAL));        
+    }
+    
+//    public void testConstructCannotProceedException() {
+//        // TODO
+//    }
+
+    protected void tearDown() {
+        nameParser = null;
+    }
+    
+    public static Test suite() {
+        return new TestSuite(DNSContextTest.class);
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(DNSContextTest.class);
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSNameParserTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSNameParserTest.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSNameParserTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSNameParserTest.java Tue May 30 04:24:59 2006
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NamingException;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test class to test 
+ * <code>org.apache.harmony.jndi.provider.dns.DNSNameParser</code> class. 
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class DNSNameParserTest extends TestCase {
+
+    /**
+     * Tests a <code>parse()</code> method.
+     * @see org.apache.harmony.jndi.provider.dns.DNSNameParser#parse(String)
+     */
+    public void testParse() throws NamingException {
+        String nameStr1 = "www.intel.com";
+        String nameStr2 = "mydomain.com.";
+        String nameStr3 = "myhost.mysubdomain.mydomain.com.";
+        String nameStr4 = "mydomain.com..";
+        String nameStr5 = "ddddddddddddddddddddddddddddddddddddddddddddddd" +
+                "dddddddddddddddddddddddddddddddddddddddddddddddddd" +
+                "dddddddddddddddddddddddddddddddddddddddddddddddddd.a.com";
+        String nameStr6 = "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa." +
+                "aaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaa";
+        Name name;
+        
+        DNSNameParser parser = new DNSNameParser();
+        name = parser.parse(nameStr1);
+        assertEquals("The size of the name is wrong", 3, name.size());
+        assertEquals("Wrong label", "com", name.get(0));
+        assertEquals("Wrong label", "intel", name.get(1));
+        assertEquals("Wrong label", "www", name.get(2));
+        name = parser.parse(nameStr2);
+        assertEquals("The size of the name is wrong", 3, name.size());
+        assertEquals("Wrong label", "", name.get(0));
+        assertEquals("Wrong label", "com", name.get(1));
+        assertEquals("Wrong label", "mydomain", name.get(2));
+        name = parser.parse(nameStr3);
+        assertEquals("The size of the name is wrong", 5, name.size());
+        assertEquals("Wrong label", "", name.get(0));
+        assertEquals("Wrong label", "com", name.get(1));
+        assertEquals("Wrong label", "mydomain", name.get(2));
+        assertEquals("Wrong label", "mysubdomain", name.get(3));
+        assertEquals("Wrong label", "myhost", name.get(4));
+        try {
+            name = parser.parse(nameStr4);
+            fail("DNS name contains two null labels but " +
+                    "InvalidNameException has not been thrown while parsing");
+        } catch (InvalidNameException e) {}
+        try {
+            name = parser.parse(nameStr5);
+            fail("Too long label was given but " +
+                    "InvalidNameException was not thrown while parsing");
+        } catch (InvalidNameException e) {}
+        try {
+            name = parser.parse(nameStr6);
+            fail("Too long name was given but " +
+                    "InvalidNameException was not thrown while parsing");
+        } catch (InvalidNameException e) {}            
+    }
+
+    public static Test suite() {
+        return new TestSuite(DNSNameParserTest.class);
+    }
+
+    public static void main(String argv[]) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSNameParserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSPseudoURLTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSPseudoURLTest.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSPseudoURLTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSPseudoURLTest.java Tue May 30 04:24:59 2006
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import junit.framework.TestCase;
+
+/**
+ * <code>org.apache.harmony.jndi.provider.dns.DNSPseudoURL</code> unit test.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+public class DNSPseudoURLTest extends TestCase {
+
+    public void testConstructor() {
+        DNSPseudoURL url = null;
+
+        url = new DNSPseudoURL("dns://super.puper.server.ru:54/sub.domain.com");
+        assertEquals("super.puper.server.ru", url.getHost());
+        assertEquals(false, url.isHostIpGiven());
+        assertEquals(54, url.getPort());
+        assertEquals("sub.domain.com.", url.getDomain());
+
+        url = new DNSPseudoURL("dns://123.456.678.1/example.com.");
+        assertEquals("123.456.678.1", url.getHost());
+        assertEquals(true, url.isHostIpGiven());
+        assertEquals(53, url.getPort());
+        assertEquals("example.com.", url.getDomain());
+        
+        try {
+            url = new DNSPseudoURL("dns://a.com/domain.com/mama");
+            fail("IllegalArgumentException was not thrown");
+        } catch (IllegalArgumentException e) {
+            // correct behaviour
+        }
+    }
+    
+    public void testConstructorDefaults() {
+        DNSPseudoURL url;
+
+        url = new DNSPseudoURL("dns://www.mydomain.ru");
+        assertEquals("www.mydomain.ru", url.getHost());
+        assertEquals(false, url.isHostIpGiven());
+        assertEquals(53, url.getPort());
+        assertEquals(".", url.getDomain());
+
+        url = new DNSPseudoURL("dns:/mydomain.org");
+        assertEquals("localhost", url.getHost());
+        assertEquals(false, url.isHostIpGiven());
+        assertEquals(53, url.getPort());
+        assertEquals("mydomain.org.", url.getDomain());
+
+        url = new DNSPseudoURL("dns:");
+        assertEquals("localhost", url.getHost());
+        assertEquals(false, url.isHostIpGiven());
+        assertEquals(53, url.getPort());
+        assertEquals(".", url.getDomain());
+    }
+    
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(DNSPseudoURLTest.class);
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/DNSPseudoURLTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/NSLookup.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/NSLookup.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/NSLookup.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/NSLookup.java Tue May 30 04:24:59 2006
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+/**
+ * Simple NS lookup utility.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class NSLookup {
+    
+    // add real IP of your DNS server here
+    public static final String DNS_SERVER = "127.0.0.1"; 
+
+    /**
+     * Empty constructor
+     */
+    public NSLookup() {}
+
+    /**
+     * Main method.
+     * @param args the hostname we want to get information for should be given
+     *  as an argument 
+     */
+    public static void main(String[] args) throws NamingException {
+        Hashtable env = new Hashtable();
+        DirContext ctx = null;
+        Attributes attrs = null;
+        String[] attrNames = new String[1];
+        NamingEnumeration attrEnum;
+
+        if (args.length == 0) {
+            System.out.println("USAGE: java " + 
+                    "org.apache.harmony.jndi.provider.dns.NSLookup <hostname>");
+            return;
+        }
+        env.put(Context.INITIAL_CONTEXT_FACTORY,
+                "org.apache.harmony.jndi.provider.dns.DNSContextFactory");
+        env.put(Context.PROVIDER_URL, "dns://" + DNS_SERVER + "/.");
+        env.put(Context.AUTHORITATIVE, "false");
+        env.put(DNSContext.RECURSION, "true");
+        ctx = new InitialDirContext(env);
+        attrNames[0] = "A";
+        attrs = ctx.getAttributes(args[0], attrNames);
+        attrEnum = attrs.getAll();
+        while (attrEnum.hasMoreElements()) {
+            Attribute attr = (Attribute) attrEnum.nextElement();
+            NamingEnumeration vals = attr.getAll();
+
+            while (vals.hasMoreElements()) {
+                System.out.println(attr.getID() + " " + vals.nextElement());
+            }
+        }
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/NSLookup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/ResourceRecordTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/ResourceRecordTest.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/ResourceRecordTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/ResourceRecordTest.java Tue May 30 04:24:59 2006
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.5 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for testing
+ * <code>org.apache.harmony.jndi.provider.dns.ResourceRecord</code> class.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.5 $
+ * 
+ * TODO add testcase(s)
+ */
+public class ResourceRecordTest extends TestCase {
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(ResourceRecordTest.class);
+    }
+
+    public void testWriteBytes() {
+    }
+
+    public void testParseRecord() {
+    }
+
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/ResourceRecordTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/TestMgr.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/TestMgr.java?rev=410240&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/TestMgr.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/TestMgr.java Tue May 30 04:24:59 2006
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexei Y. Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+
+package org.apache.harmony.jndi.provider.dns;
+
+
+import java.lang.reflect.Field;
+
+/**
+ * Contains several utility methods. Is used from unit tests.
+ * @author Alexei Zakharov
+ * @version $Revision: 1.1.2.4 $
+ */
+public class TestMgr {
+    
+    /**
+     * Retrieves the field information and set accessible to
+     * <code>true</code>. 
+     * 
+     * @return retrieved <code>Field</code> object
+     * @throws SecurityException is such operation is prohibited by system
+     * security manager
+     * @throws NoSuchFieldException if the filed with such name has not been
+     * found
+     */
+    static Field getField(Object obj, String fieldName)
+            throws SecurityException, NoSuchFieldException
+    {
+        Field field = obj.getClass().getDeclaredField(fieldName);
+
+        field.setAccessible(true);
+        return field;
+    }
+
+    /**
+     * Retrieves the value of an integer field regardless to it's access
+     * modifier.  
+     * @param obj object to retrieve the field value from
+     * @param fieldName name of the field
+     * @return retrieved value of the field
+     * @throws SecurityException is such operation is prohibited by system
+     * security manager
+     * @throws NoSuchFieldException if the filed with such name has not been
+     * found
+     */
+    static int getIntField(Object obj, String fieldName)
+            throws SecurityException, NoSuchFieldException,
+                   IllegalArgumentException
+    {
+        Field field = getField(obj, fieldName);
+        int n = -1;
+
+        try {
+            n = field.getInt(obj);
+        }
+        catch (IllegalAccessException e) {
+            // FIXME
+            e.printStackTrace();
+        }
+        return n;
+    }
+
+    /**
+     * Retrieves the value of a boolean field regardless to it's access
+     * modifier.  
+     * @param obj object to retrieve the field value from
+     * @param fieldName name of the field
+     * @return retrieved value of the field
+     * @throws SecurityException is such operation is prohibited by system
+     * security manager
+     * @throws NoSuchFieldException if the filed with such name has not been
+     * found
+     */
+    static boolean getBoolField(Object obj, String fieldName)
+            throws SecurityException, NoSuchFieldException,
+                   IllegalArgumentException
+    {
+        Field field = getField(obj, fieldName);
+        boolean  b = false;
+
+        try {
+            b = field.getBoolean(obj);
+        }
+        catch (IllegalAccessException e) {
+            // FIXME
+            e.printStackTrace();
+        }
+        return b;
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/dns/TestMgr.java
------------------------------------------------------------------------------
    svn:eol-style = native