harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r596693 [2/9] - in /harmony/enhanced/classlib/branches/java6: ./ depends/jars/ depends/libs/build/ make/ modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/ modules/auth/src/main/java/common/org/apache/harmony/auth/jgss...
Date Tue, 20 Nov 2007 14:43:29 GMT

Modified: harmony/enhanced/classlib/branches/java6/build.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/build.xml?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/build.xml (original)
+++ harmony/enhanced/classlib/branches/java6/build.xml Tue Nov 20 06:42:33 2007
@@ -289,7 +289,8 @@
     <target name="-init-hdk">
         <mkdir dir="${hy.hdk}/build/ant" />
         <copy file="make/properties.xml"
-              tofile="${hy.hdk}/build/ant/properties.xml">
+              tofile="${hy.hdk}/build/ant/properties.xml"
+              outputencoding="UTF-8" >
             <filterchain>
                 <tokenfilter>
                     <replacestring from="Top-Level property definitions"
@@ -307,7 +308,8 @@
           -->
         <mkdir dir="${hy.hdk}/build/ant" />
         <copy file="make/properties.xml"
-              tofile="${hy.hdk}/build/ant/properties.xml">
+              tofile="${hy.hdk}/build/ant/properties.xml"
+              outputencoding="UTF-8" >
             <filterchain>
                 <tokenfilter>
                     <replacestring from="Top-Level property definitions"

Propchange: harmony/enhanced/classlib/branches/java6/depends/jars/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Nov 20 06:42:33 2007
@@ -26,3 +26,4 @@
 derby-10.3.1.4
 xerces_2.9.1
 xmlsec_1.4.0
+bcprov-jdk15-138

Modified: harmony/enhanced/classlib/branches/java6/depends/libs/build/README.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/depends/libs/build/README.txt?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/depends/libs/build/README.txt (original)
+++ harmony/enhanced/classlib/branches/java6/depends/libs/build/README.txt Tue Nov 20 06:42:33 2007
@@ -88,8 +88,8 @@
        normally, jpeg-6b.
     2. Configure the build by running:
 
-	    For the release version: ./configure CFLAGS=’-O2 -fpic’
-	    For the debug version: ./configure CFLAGS=’-g -fpic’
+	    For the release version: ./configure CFLAGS="-O2 -fpic"
+	    For the debug version: ./configure CFLAGS="-g -fpic"
 
     3. Copy the file jconfig.h created during the previous step to
        the <EXTERNAL_LIBS_DIR>/jpeg/jconfig.lnx directory.
@@ -137,8 +137,8 @@
    1. Change the working directory to the libpng source directory.
    2. Configure the build by running:
 
-	    For the release version: ./configure CFLAGS=’-O2 -fpic’
-	    For the debug version: ./configure CFLAGS=’-g -fpic’
+	    For the release version: ./configure CFLAGS="-O2 -fpic"
+	    For the debug version: ./configure CFLAGS="-g -fpic"
 
    3. To build the library, run:
 
@@ -181,8 +181,8 @@
    1. Change the working directory to the LCMS source directory.
    2. Configure the build by running:
 
-   	For the release version: ./configure CFLAGS=’-O2 -fpic’
-   	For the debug version: ./configure CFLAGS=’-g -fpic’
+   	For the release version: ./configure CFLAGS="-O2 -fpic"
+   	For the debug version: ./configure CFLAGS="-g -fpic"
 
    3. To build the library, run:
 

Modified: harmony/enhanced/classlib/branches/java6/make/depends.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/make/depends.properties?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/make/depends.properties (original)
+++ harmony/enhanced/classlib/branches/java6/make/depends.properties Tue Nov 20 06:42:33 2007
@@ -38,11 +38,11 @@
 junit.url=${maven2.base}/junit/junit/3.8.2/junit-3.8.2.jar
 junit.md5=28e7eb9eeefe31a657c68755bfccc541
 
-bcprov.dir=${depends.jars}/bcprov-jdk15-137
+bcprov.dir=${depends.jars}/bcprov-jdk15-138
 bcprov.orig.jar=${bcprov.dir}/bcprov.jar
 bcprov.jar=${bcprov.dir}/bcprov.noidea.jar
-bcprov.url=http://www.bouncycastle.org/download/bcprov-jdk15-137.jar
-bcprov.md5=7cdb436aaa4b222db7fc02495dfcde51
+bcprov.url=http://www.bouncycastle.org/download/bcprov-jdk15-138.jar
+bcprov.md5=9c32fec75f2de26cfc18213b20461933
 
 msvcr.dir.x86=${depends.dir}/libs/windows.x86
 msvcr.dll.x86=${msvcr.dir.x86}/msvcr71.dll

Modified: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/KerberosUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/KerberosUtils.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/KerberosUtils.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/KerberosUtils.java Tue Nov 20 06:42:33 2007
@@ -21,11 +21,13 @@
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.Set;
 
 import javax.security.auth.DestroyFailedException;
 import javax.security.auth.RefreshFailedException;
 import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.kerberos.ServicePermission;
@@ -55,6 +57,12 @@
     public static final String KERBEROS_CONTEXT_INIT = "org.apache.harmony.auth.jgss.initiate";
 
     public static final String KERBEROS_CONTEXT_ACCEPT = "org.apache.harmony.auth.jgss.accept";
+    
+    public static final String SERVICE_PERMISSION_ACTION_INITIATE = "initiate";
+    
+    public static final String SERVICE_PERMISSION_ACTION_ACCEPT = "accept";
+    
+    public static final String[] SUPPORTED_KEY_ENCRYPT= {"DES"};
 
     static {
         try {
@@ -80,7 +88,7 @@
             final KerberosPrincipal clientPrincipal,
             final KerberosPrincipal serverPrincipal) {
         AccessControlContext acc = AccessController.getContext();
-        return AccessController.doPrivileged(
+        KerberosTicket tgt = AccessController.doPrivileged(
                 new PrivilegedAction<KerberosTicket>() {
 
                     public KerberosTicket run() {
@@ -91,7 +99,53 @@
                                 serverPrincipal);
                     }
                 }, acc);
-
+        if (tgt != null) {
+            checkTGTServicePermission(tgt);
+        }
+        return tgt;
+    }
+    
+    private static KerberosKey[] getKeysFromContext(final KerberosPrincipal serverPrincipal){
+        AccessControlContext acc = AccessController.getContext();
+        KerberosKey[] kerberosKeys = AccessController.doPrivileged(new PrivilegedAction<KerberosKey[]>(){
+            public KerberosKey[] run() {
+                AccessControlContext acc = AccessController
+                .getContext();
+                Subject subject = Subject.getSubject(acc);
+                return getKeysFromSubject(subject, serverPrincipal);
+            }}, acc);
+        if(kerberosKeys.length > 0){
+            //All keys in kerberosKeys have the same principal. Check the permission for the first key is enough.
+            checkServerKeyServicePermission(kerberosKeys[0]);
+            return kerberosKeys;
+        }
+        return null;
+    }
+    
+    private static KerberosPrincipal getPrincipalFromContext(){
+        AccessControlContext acc = AccessController.getContext();
+        return AccessController.doPrivileged(new PrivilegedAction<KerberosPrincipal>(){
+            public KerberosPrincipal run() {
+                AccessControlContext acc = AccessController
+                .getContext();
+                Subject subject = Subject.getSubject(acc);
+                Set<KerberosPrincipal> kerberosPrincipals = subject.getPrincipals(KerberosPrincipal.class);
+                if(kerberosPrincipals.size() == 0){
+                    return null;
+                }
+                return kerberosPrincipals.iterator().next();
+            }}, acc);
+    }
+    
+    private static KerberosKey[] getKeysFromSubject(Subject subject, final KerberosPrincipal serverPrincipal){
+        Set<KerberosKey> kerberosKeys = subject.getPrivateCredentials(KerberosKey.class);
+        ArrayList<KerberosKey> serverKeys = new ArrayList<KerberosKey>();
+        for(KerberosKey kerberosKey : kerberosKeys){
+            if(serverPrincipal.equals(kerberosKey.getPrincipal())){
+                serverKeys.add(kerberosKey);
+            }
+        }
+        return serverKeys.toArray(new KerberosKey[serverKeys.size()]);
     }
 
     private static KerberosTicket getTicketFromSubject(Subject subject,
@@ -147,9 +201,29 @@
             return null;
         }
         Subject subject = loginContext.getSubject();
+        if(clientPrincipal == null){
+            clientPrincipal = getPrincipalFromContext();
+        }
         return getTicketFromSubject(subject, clientPrincipal,
                 getTGTServerPrincipal(clientPrincipal));
     }
+    
+    private static KerberosKey[] getKeysFromLoginModule(KerberosPrincipal serverPrincipal){
+        LoginContext loginContext = null;
+        try {
+            loginContext = new LoginContext(KERBEROS_CONTEXT_ACCEPT);
+            loginContext.login();
+
+        } catch (LoginException e) {
+            e.printStackTrace();
+            return null;
+        }
+        Subject subject = loginContext.getSubject();
+        if(serverPrincipal == null){
+            serverPrincipal = getPrincipalFromContext();
+        }
+        return getKeysFromSubject(subject, serverPrincipal);
+    }
 
     private static KerberosPrincipal getTGTServerPrincipal(
             KerberosPrincipal clientPrincipal) {
@@ -163,15 +237,40 @@
             tgt = getKerberosTicketFromContext(clientPrincipal,
                     getTGTServerPrincipal(clientPrincipal));
         }
-        if (null == tgt) {
-            tgt = getTGTFromLoginModule(clientPrincipal);
-        }
         if (null != tgt) {
-            checkServicePermission(tgt.getServer(), "initiate");
+            return tgt;            
+        }
+        tgt = getTGTFromLoginModule(clientPrincipal);
+        if (null != tgt) {            
             // TODO CACHE : Whether should attach this tgt to the subject for
             // current AccessControlContext?
         }
         return tgt;
+    }
+    
+    public static KerberosKey[] getKeys(KerberosPrincipal serverPrincipal) {
+        KerberosKey[] keys = null;
+        if (serverPrincipal != null) {
+            keys = getKeysFromContext(serverPrincipal);
+        }
+        if (null != keys) {
+            return keys;
+        }
+        keys = getKeysFromLoginModule(serverPrincipal);
+        if (null != keys) {
+            // TODO CACHE : Whether should attach these keys to the subject for
+            // current AccessControlContext?
+        }
+        return keys;
+    }
+    
+        
+    public static void checkTGTServicePermission(KerberosTicket tgt){
+        checkServicePermission(tgt.getServer(), SERVICE_PERMISSION_ACTION_INITIATE);
+    }
+    
+    public static void checkServerKeyServicePermission(KerberosKey key){
+        checkServicePermission(key.getPrincipal(), SERVICE_PERMISSION_ACTION_ACCEPT);
     }
 
     public static void checkServicePermission(KerberosPrincipal principal,

Modified: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxImpl.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxImpl.java Tue Nov 20 06:42:33 2007
@@ -25,7 +25,7 @@
 /*
  * The class will wrap the dependency on external kerberos tools.
  */
-public class KerberosToolboxImpl implements KerberosToolboxSpi {
+public final class KerberosToolboxImpl implements KerberosToolboxSpi {
 
     private String kdc;
     
@@ -42,5 +42,15 @@
         // TODO Auto-generated method stub
         throw new NotImplementedException();
     }
+
+	public KerberosApplicationRequest decodeApplicationRequest(byte[] token) {
+		// TODO Auto-generated method stub
+		throw new NotImplementedException();
+	}
+
+	public byte[] encodeApplicationRequest(KerberosApplicationRequest kerberosApplicationRequest) {
+		// TODO Auto-generated method stub
+		throw new NotImplementedException();
+	}
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxSpi.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxSpi.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxSpi.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/auth/src/main/java/common/org/apache/harmony/auth/jgss/kerberos/toolbox/KerberosToolboxSpi.java Tue Nov 20 06:42:33 2007
@@ -22,4 +22,6 @@
 public interface KerberosToolboxSpi {    
     KerberosTicket getTGT(String clientPrincipalName, char[] password);
     KerberosTicket getTGS(String serverPrincipalName, KerberosTicket TGT);
+    byte[] encodeApplicationRequest(KerberosApplicationRequest kerberosApplicationRequest);
+    KerberosApplicationRequest decodeApplicationRequest(byte[] token);
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/Container.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/Container.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/Container.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/Container.java Tue Nov 20 06:42:33 2007
@@ -1352,7 +1352,7 @@
                     }
                 }
 
-                if ((fc == comp) || (container == c)) {
+                if ((fc == comp) || (container == c) || (fc == container)) {
                     break;
                 }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/image/Raster.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/image/Raster.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/image/Raster.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/image/Raster.java Tue Nov 20 06:42:33 2007
@@ -602,18 +602,8 @@
             throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
         }
         
-        if (sampleModel instanceof ComponentSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((ComponentSampleModel) sampleModel).getScanlineStride());
-        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((MultiPixelPackedSampleModel) sampleModel)
-                            .getScanlineStride());
-        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((SinglePixelPackedSampleModel) sampleModel)
-                            .getScanlineStride());
-        }
+        validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                sampleModel);
 
         this.sampleModel = sampleModel;
         this.dataBuffer = dataBuffer;
@@ -853,8 +843,54 @@
     }
 
     private static void validateDataBuffer(final DataBuffer dataBuffer, final int w,
-            final int h, final int scanlineStride) {
-        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
+            final int h, final SampleModel sampleModel) {
+
+        int size = 0;
+        
+        if (sampleModel instanceof ComponentSampleModel) {
+            ComponentSampleModel csm = (ComponentSampleModel) sampleModel;
+            int offsets[] = csm.getBandOffsets();
+            int maxOffset = offsets[0];
+            for (int i = 1; i < offsets.length; i++) {
+                if (offsets[i] > maxOffset) {
+                    maxOffset = offsets[i];
+                }
+            }
+            int scanlineStride = csm.getScanlineStride();
+            int pixelStride = csm.getPixelStride();
+            
+            size = (h - 1) * scanlineStride +
+            (w - 1) * pixelStride + maxOffset + 1;
+
+        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
+            MultiPixelPackedSampleModel mppsm = 
+                (MultiPixelPackedSampleModel) sampleModel;
+            
+            int scanlineStride = mppsm.getScanlineStride();
+            int dataBitOffset = mppsm.getDataBitOffset();
+            int dataType = dataBuffer.getDataType();
+            
+            size = scanlineStride * h;
+
+            switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                size += (dataBitOffset + 7) / 8;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                size += (dataBitOffset + 15) / 16;
+                break;
+            case DataBuffer.TYPE_INT:
+                size += (dataBitOffset + 31) / 32;
+                break;
+            }
+        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
+            SinglePixelPackedSampleModel sppsm = 
+                (SinglePixelPackedSampleModel) sampleModel;
+            
+            int scanlineStride = sppsm.getScanlineStride();
+            size = (h - 1) * scanlineStride + w;
+        }
+        if (dataBuffer.getSize() < size) {
             // awt.298=dataBuffer is too small
             throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/print/PrinterJob.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/print/PrinterJob.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/print/PrinterJob.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/java/awt/print/PrinterJob.java Tue Nov 20 06:42:33 2007
@@ -80,7 +80,7 @@
                 String s = System.getProperty("java.awt.printerjob"); //$NON-NLS-1$
 
                 if (s == null || s.equals("")){ //$NON-NLS-1$
-                    s = "org.apache.harmony.x.print.awt.PSPrinterJob"; //$NON-NLS-1$
+                    s = "java.awt.print.PrinterJobImpl"; //$NON-NLS-1$
                 }
                 try {
                     return (PrinterJob) Class.forName(s).newInstance();

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties Tue Nov 20 06:42:33 2007
@@ -488,6 +488,8 @@
 awt.297=Invalid keyLocation
 awt.298=dataBuffer is too small
 awt.299=Font file can not be read
+awt.29A=Neither Printable nor Pageable specified
+awt.29B=Printer not found
 
 awt.err.00=file dialog {0} error!
 awt.err.01=error: {0}

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxCursorFactory.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxCursorFactory.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxCursorFactory.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxCursorFactory.java Tue Nov 20 06:42:33 2007
@@ -26,6 +26,7 @@
 import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBufferByte;
+import java.awt.image.MultiPixelPackedSampleModel;
 import java.awt.image.WritableRaster;
 
 import org.apache.harmony.awt.gl.Utils;
@@ -95,23 +96,27 @@
         int width = img.getWidth(null);
         int height = img.getHeight(null);
         BufferedImage bufImg = Utils.getBufferedImage(img);
+        if(bufImg == null) throw new NullPointerException("Cursor Image is null");
+
         //must convert image into TYPE_BYTE_BINARY format of depth 1
-        BufferedImage bmpSrc = convertTo1Bit(/*bufImg*/img);
+        BufferedImage bmpSrc = convertTo1Bit(bufImg);
         BufferedImage bmpMask = getMask(bufImg);
         //get pixel data from bufImg & create X11 pixmap
         byte[] bmpSrcData = ((DataBufferByte) bmpSrc.getData().getDataBuffer()).getData();
+        byte[] rSrcData = convertToLSBFirst(bmpSrcData);
         byte[] bmpMaskData = ((DataBufferByte) bmpMask.getData().getDataBuffer()).getData();
+        byte[] rMaskData = convertToLSBFirst(bmpMaskData);
 
         ArrayAccessor arrayAccess = AccessorFactory.getArrayAccessor();
         long wnd = factory.getRootWindow();
-        LockedArray larr = arrayAccess.lockArrayShort(bmpSrcData);
+        LockedArray larr = arrayAccess.lockArrayShort(rSrcData);
         long dataPtr = larr.getAddress();
         long pixmap = x11.XCreateBitmapFromData(display, wnd,
                 dataPtr, width, height);
         //System.out.println("source pixmap=" + pixmap);
         larr.release();
 
-        larr = arrayAccess.lockArrayShort(bmpMaskData);
+        larr = arrayAccess.lockArrayShort(rMaskData);
         dataPtr = larr.getAddress();
         long pixmapMask = x11.XCreateBitmapFromData(display, wnd, dataPtr,
                 width, height);
@@ -132,6 +137,24 @@
         return new LinuxCursor(cursor, display);
     }
 
+    // Convert Bitmap bits to LSBFirst
+    private byte[] convertToLSBFirst(byte[] src){
+        int len = src.length;
+        byte[] dst = new byte[len];
+
+        for(int i = 0; i < len; i++){
+            int pix = src[i] & 0xff;
+            int rpix = pix & 0x1;
+            for( int j = 1; j < 8; j++){
+                pix >>= 1;
+                rpix <<= 1;
+                rpix |= (pix & 0x1) ;
+            }
+            dst[i] = (byte)rpix;
+        }
+        return dst;
+    }
+
     /**
      * Select one of bufImg pixel colors as background color
      * when foreground color is fgColor.
@@ -273,7 +296,11 @@
      * @param src Image to convert
      * @return new Buffered image containing 1-bit bitmap
      */
-    static BufferedImage convertTo1Bit(Image src) {
+    static BufferedImage convertTo1Bit(BufferedImage src) {
+        if(src.getType() == BufferedImage.TYPE_BYTE_BINARY){
+            MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) src.getRaster().getSampleModel();
+            if(mppsm.getPixelBitStride() == 1) return src;
+        }
         int w = src.getWidth(null);
         int h = src.getHeight(null);
 

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/windows/org/apache/harmony/awt/gl/windows/WinGDIPGraphics2D.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/windows/org/apache/harmony/awt/gl/windows/WinGDIPGraphics2D.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/windows/org/apache/harmony/awt/gl/windows/WinGDIPGraphics2D.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/java/windows/org/apache/harmony/awt/gl/windows/WinGDIPGraphics2D.java Tue Nov 20 06:42:33 2007
@@ -96,7 +96,6 @@
         size = new Dimension(b.width, b.height);
 
         gi = createGraphicsInfo(this.nw.getId(), tx, ty, b.width, b.height);
-        setTransformedClip(this.clip);        
         if (!FontManager.IS_FONTLIB) {
             jtr = GDIPTextRenderer.inst;
         }
@@ -112,7 +111,6 @@
         size = new Dimension(width, height);
 
         gi = createGraphicsInfo(this.nw.getId(), tx, ty, width, height);
-        setTransformedClip(this.clip);
         if (!FontManager.IS_FONTLIB) {
             jtr = GDIPTextRenderer.inst;
         }
@@ -138,7 +136,6 @@
         } else {
             this.gi = copyImageInfo(img.gi);
         }
-        setTransformedClip(this.clip);
         dstSurf = img.getImageSurface();
         blitter = GDIBlitter.getInstance();
         if (!FontManager.IS_FONTLIB) {

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/shared/SurfaceDataStructure.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/shared/SurfaceDataStructure.cpp?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/shared/SurfaceDataStructure.cpp (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/shared/SurfaceDataStructure.cpp Tue Nov 20 06:42:33 2007
@@ -461,10 +461,10 @@
                 src = (unsigned char *)srcDataPtr + src_offset;
                 dst = (unsigned int *)bmpDataPtr + dst_offset;
 
-                for(int _y = h; _y > 0; _y--, src += src_stride, dst += dst_stride){
+                for(int y = h; y > 0; y--, src += src_stride, dst += dst_stride){
                     d = dst;
 
-                    for(int _x = 0; _x < w; _x++){
+                    for(int x = 0; x < w; x++){
                         bitnum = x * pixelBits;
                         s = src + bitnum / 8;
                         elem = *s;

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/WinGDIPGraphics2D.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/WinGDIPGraphics2D.cpp?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/WinGDIPGraphics2D.cpp (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/WinGDIPGraphics2D.cpp Tue Nov 20 06:42:33 2007
@@ -105,6 +105,9 @@
     gi->bmp = 0;
     gi->matrix = new Matrix();
 
+    gi->clip = new Region(Rect(x, y, width, height));
+    gi->graphics->SetClip(gi->clip);
+
     return (jlong)gi;
 }
 
@@ -115,18 +118,21 @@
  */
 JNIEXPORT jlong JNICALL Java_org_apache_harmony_awt_gl_windows_WinGDIPGraphics2D_createGraphicsInfoFor
   (JNIEnv * env, jobject obj, jlong hdc, jchar pageUnit) {
-	GraphicsInfo * gi = (GraphicsInfo *) malloc(sizeof(GraphicsInfo));
+        GraphicsInfo * gi = (GraphicsInfo *) malloc(sizeof(GraphicsInfo));
+
+        gi->hdc = (HDC) hdc;
+        gi->graphics = new Graphics(gi->hdc);
+        gi->pen = 0;
+        gi->brush = 0;
+        gi->bmp = 0;
+        gi->matrix = new Matrix();
 
-	gi->hdc = (HDC) hdc;
-	gi->graphics = new Graphics(gi->hdc);
-	gi->pen = 0;
-	gi->brush = 0;
-	gi->bmp = 0;
-	gi->matrix = new Matrix();
+        gi->clip = new Region();
+        gi->graphics->SetClip(gi->clip);
 
-	gi->graphics->SetPageUnit((Gdiplus::Unit) pageUnit);
+        gi->graphics->SetPageUnit((Gdiplus::Unit) pageUnit);
 
-	return (jlong)gi;
+        return (jlong)gi;
 }
 
 /*
@@ -172,6 +178,9 @@
     gi->pen = 0;
     gi->brush = 0;   
     gi->matrix = 0;
+
+    gi->clip = new Region(Rect(0, 0, width, height));
+    gi->graphics->SetClip(gi->clip);
     
     return gi; 
 }
@@ -222,12 +231,13 @@
     gi->hdc = origgi->hdc;
     gi->bmp = 0;
     gi->graphics = new Graphics(gi->hdc);
+
+    gi->clip = new Region();
     if (origgi->graphics != NULL) {
-        Region clip;
-        origgi->graphics->GetClip(&clip);
-        gi->graphics->SetClip(&clip);
+        origgi->graphics->GetClip(gi->clip);
     }
     
+    gi->graphics->SetClip(gi->clip);
     gi->pen = (origgi->pen != NULL)?origgi->pen->Clone():0;
     gi->brush = (origgi->brush != NULL)?origgi->brush->Clone():0;
     gi->matrix = (origgi->matrix != NULL)?origgi->matrix->Clone():new Matrix();
@@ -264,6 +274,10 @@
         delete(gi->matrix);
     }
 
+    if (gi->clip) {
+        delete(gi->clip);
+    }
+
     // If hwnd and bmp are 0 then we should not destroy HDC 
     // because it's a copy of VolatileImage
     if (gi->hwnd != 0 || gi->bmp != 0) {    
@@ -679,7 +693,7 @@
         return;
         
     GraphicsInfo *gi = (GraphicsInfo *)gip;
-    gi->graphics->ResetClip();
+    gi->graphics->SetClip(gi->clip);
 }
 
 /*

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/include/gl_GDIPlus.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/include/gl_GDIPlus.h?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/include/gl_GDIPlus.h (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/gl/windows/include/gl_GDIPlus.h Tue Nov 20 06:42:33 2007
@@ -35,6 +35,7 @@
     Brush *brush;
     HBITMAP bmp;
     Matrix *matrix;
+    Region *clip;
 } GraphicsInfo;
 
 typedef struct _GLBITMAPINFO{

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/NativeCMM.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/NativeCMM.c?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/NativeCMM.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/NativeCMM.c Tue Nov 20 06:42:33 2007
@@ -22,7 +22,7 @@
 
 #include "NativeCMM.h"
 
-static BOOL cmsInitialized = FALSE; 
+static LCMSBOOL cmsInitialized = FALSE; 
 static char *errMsg = NULL;
 
 int gl_cmsErrorHandler(int errorCode, const char *msg) {
@@ -356,8 +356,8 @@
   int srcPixelStride, dstPixelStride;
   BYTE *srcPtr, *dstPtr;
   int i;
-  BOOL copyAlpha = FALSE;
-  BOOL fillAlpha = FALSE;
+  LCMSBOOL copyAlpha = FALSE;
+  LCMSBOOL fillAlpha = FALSE;
 
     cmsHTRANSFORM xform = (cmsHTRANSFORM) ((IDATA)transformHandle);
 

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmapi.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmapi.h?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmapi.h (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmapi.h Tue Nov 20 06:42:33 2007
@@ -26,16 +26,18 @@
 #define cmsFLAGS_NOTCACHE (0)
 #endif
 
+#if (LCMS_VERSION < 117)
+#define LCMSBOOL BOOL
+#endif
 
 // Just a useful macro
 #undef MIN
-
 #define MIN(a,b)    ((a) < (b) ? (a) : (b))
 
 
 LPLCMSICCPROFILE cmmOpenProfile(LPBYTE dataPtr, DWORD dwSize);
 
-BOOL cmmCloseProfile(LPLCMSICCPROFILE hProfile);
+LCMSBOOL cmmCloseProfile(LPLCMSICCPROFILE hProfile);
 
 
 
@@ -45,17 +47,17 @@
 
 
 
-BOOL cmmGetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data, size_t dwLen);
+LCMSBOOL cmmGetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data, size_t dwLen);
 
-BOOL cmmSetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data);
+LCMSBOOL cmmSetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data);
 
 
 
-BOOL cmmGetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPBYTE data, size_t *dataSize);
+LCMSBOOL cmmGetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPBYTE data, size_t *dataSize);
 
 long cmmGetProfileElementSize(LPLCMSICCPROFILE hProfile, icTagSignature sig);
 
-BOOL cmmSetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPVOID data, size_t size);
+LCMSBOOL cmmSetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPVOID data, size_t size);
 
 
 cmsHTRANSFORM cmmCreateTransform(cmsHPROFILE Input,

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmio.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmio.c?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmio.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmio.c Tue Nov 20 06:42:33 2007
@@ -52,8 +52,8 @@
 typedef struct {
   LPBYTE Base;    // Base pointer
   LPBYTE CurrPtr; // Moving pointer
-  BOOL needsUpdate; // Tag sizes changed or tags added/removed
-  BOOL needsUpdateCriticalTags; // Critical tags changed
+  LCMSBOOL needsUpdate; // Tag sizes changed or tags added/removed
+  LCMSBOOL needsUpdateCriticalTags; // Critical tags changed
   size_t size;
 } MemBuffer;
 
@@ -72,7 +72,7 @@
   return buffer;
 }
 
-static BOOL allocMemBuffer(LPVOID f, size_t size) {
+static LCMSBOOL allocMemBuffer(LPVOID f, size_t size) {
   MemBuffer* memBuffer = (MemBuffer*) f;
     
   memBuffer->CurrPtr = malloc(size);
@@ -88,7 +88,7 @@
   return TRUE;
 }
 
-static BOOL closeMemBuffer(MemBuffer **buffer) {
+static LCMSBOOL closeMemBuffer(MemBuffer **buffer) {
   if(*buffer)
     free(*buffer);
   *buffer = NULL;
@@ -105,7 +105,7 @@
   return count;
 }
 
-static BOOL seekMemBuffer(LPVOID f, size_t offset) {
+static LCMSBOOL seekMemBuffer(LPVOID f, size_t offset) {
   MemBuffer* memBuffer = (MemBuffer*) f;
   memBuffer->CurrPtr = memBuffer->Base + offset;
 
@@ -117,7 +117,7 @@
   return memBuffer->CurrPtr - memBuffer->Base;
 }
 
-static BOOL writeMemBuffer(LPVOID f, size_t size, LPBYTE Data) {
+static LCMSBOOL writeMemBuffer(LPVOID f, size_t size, LPBYTE Data) {
   MemBuffer* memBuffer = (MemBuffer*) f;
 
   if (size == 0) return TRUE;
@@ -145,7 +145,7 @@
 }
 
 
-static BOOL updateHeader(LPLCMSICCPROFILE Icc) {
+static LCMSBOOL updateHeader(LPLCMSICCPROFILE Icc) {
   icHeader head;
 
   readMemBuffer(&head, sizeof(icHeader), 1, Icc -> stream);
@@ -479,7 +479,7 @@
 
 
 
-BOOL cmmCloseProfile(LPLCMSICCPROFILE hProfile) {
+LCMSBOOL cmmCloseProfile(LPLCMSICCPROFILE hProfile) {
 
   return cmsCloseProfile(hProfile);
 
@@ -509,7 +509,7 @@
 
 
 
-BOOL cmmGetProfileElement(
+LCMSBOOL cmmGetProfileElement(
 
     LPLCMSICCPROFILE hProfile, 
 
@@ -572,7 +572,7 @@
 
 
 
-BOOL cmmGetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data, size_t size) {
+LCMSBOOL cmmGetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data, size_t size) {
 
   size_t bytesToRead = MIN(size, sizeof(icHeader));
 
@@ -586,7 +586,7 @@
 
 
 
-BOOL cmmSetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data) {
+LCMSBOOL cmmSetProfileHeader(LPLCMSICCPROFILE hProfile, LPBYTE data) {
 
   seekMemBuffer(hProfile->stream, 0);
 
@@ -606,7 +606,7 @@
 
 
 
-BOOL cmmSetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPVOID data, size_t size) {
+LCMSBOOL cmmSetProfileElement(LPLCMSICCPROFILE hProfile, icTagSignature sig, LPVOID data, size_t size) {
 
   MemBuffer *memBuffer;
 

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmxforms.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmxforms.c?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmxforms.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/main/native/lcmm/shared/cmmxforms.c Tue Nov 20 06:42:33 2007
@@ -27,7 +27,7 @@
   int count; // Number of transforms
 } MultiprofileXform;
 
-BOOL doMultiprofileTransform(MultiprofileXform *xform, LPVOID in, LPVOID out, unsigned int size) {
+LCMSBOOL doMultiprofileTransform(MultiprofileXform *xform, LPVOID in, LPVOID out, unsigned int size) {
     cmsHTRANSFORM* Transforms = xform->xforms;
     int i, bpp;
     DWORD outFmt;

Modified: harmony/enhanced/classlib/branches/java6/modules/awt/src/test/api/java/common/java/awt/image/BufferedImageTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/awt/src/test/api/java/common/java/awt/image/BufferedImageTest.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/awt/src/test/api/java/common/java/awt/image/BufferedImageTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/awt/src/test/api/java/common/java/awt/image/BufferedImageTest.java Tue Nov 20 06:42:33 2007
@@ -63,4 +63,148 @@
                      Image.UndefinedProperty, img.getProperty("XXX"));
     }
 
+    //Regression tests for HARMONY-5066
+    public final void testH5066_INT_RGB(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_INT_ARGB(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_INT_ARGB_PRE(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB_PRE);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_INT_BGR(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_BGR);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_3BYTE_BGR(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_3BYTE_BGR);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+
+    public final void testH5066_4BYTE_ABGR(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_4BYTE_ABGR);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+
+    public final void testH5066_4BYTE_ABGR_PRE(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_4BYTE_ABGR_PRE);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_USHORT_565_RGB(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_USHORT_565_RGB);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_USHORT_555_RGB(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_USHORT_555_RGB);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_BYTE_GRAY(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_GRAY);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_USHORT_GRAY(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_USHORT_GRAY);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
+    static byte[] cm1 = new byte[] {0, (byte)255 };
+    static byte[] cm2 = new byte[] {0, (byte)85, (byte)170, (byte)255};
+    static byte[] cm4 = new byte[] {0, (byte)17, (byte)34, (byte)51,
+                                  (byte)68, (byte)85,(byte) 102, (byte)119,
+                                  (byte)136, (byte)153, (byte)170, (byte)187,
+                                  (byte)204, (byte)221, (byte)238, (byte)255};
+
+    public final void testH5066_BYTE_BINARY(){
+        WritableRaster wr = null;
+        IndexColorModel icm = null;
+
+        try {
+            icm = new IndexColorModel(1, cm1.length, cm1, cm1, cm1);
+            wr = icm.createCompatibleWritableRaster(10, 10);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException (pixel bits = 1): " + e.getMessage());
+        }
+
+        try {
+            icm = new IndexColorModel(2, cm2.length, cm2, cm2, cm2);
+            wr = icm.createCompatibleWritableRaster(10, 10);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException (pixel bits = 2): " + e.getMessage());
+        }
+
+        try {
+            icm = new IndexColorModel(4, cm4.length, cm4, cm4, cm4);
+            wr = icm.createCompatibleWritableRaster(10, 10);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException (pixel bits = 4): " + e.getMessage());
+        }
+    }
+
+    public final void testH5066_BYTE_INDEXED(){
+        BufferedImage bi = null;
+        try {
+            bi = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_INDEXED);
+        } catch (RasterFormatException e) {
+            fail("Unexpected RasterFormatException: " + e.getMessage());
+        }
+    }
+
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/META-INF/MANIFEST.MF?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/META-INF/MANIFEST.MF (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/META-INF/MANIFEST.MF Tue Nov 20 06:42:33 2007
@@ -32,6 +32,8 @@
  javax.accessibility;resolution:=optional,
  javax.net,
  javax.net.ssl,
+ javax.security.auth.callback,
+ javax.security.sasl,
  org.apache.harmony.kernel.vm,
  org.apache.harmony.security.asn1;version="1.0.0",
  org.apache.harmony.security.x509;version="1.0.0",

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/make/exclude.common
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/make/exclude.common?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/make/exclude.common (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/make/exclude.common Tue Nov 20 06:42:33 2007
@@ -1,2 +1,10 @@
 # not a test
 org/apache/harmony/jndi/provider/dns/TestMgr.java
+
+# Add this to exclude list with patch for HARMONY-5131
+# this test is broken after add ldap bind operation when initial
+# LdapContextImpl, because it's hard to simulate ldap server to response
+# bind request, mock is so complex that
+# LdapContextFactory.getInitialContext will be tested in scenario tests
+#
+org/apache/harmony/jndi/provider/ldap/LdapContextFactoryTest.java

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java Tue Nov 20 06:42:33 2007
@@ -97,7 +97,13 @@
             // ignore
         }
 
-        // TODO: return a provider default implementation
+        try {
+            return  (StartTlsResponse) Class.forName(
+                    "org.apache.harmony.jndi.provider.ldap.ext.StartTlsResponseImpl", true, cl).newInstance();
+        } catch (Exception e) {
+            // ignore
+        }
+        
         throw new NamingException(Messages.getString("ldap.09")); //$NON-NLS-1$
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/internal/nls/messages.properties Tue Nov 20 06:42:33 2007
@@ -156,6 +156,9 @@
 jndi.8A=Invalid method number: {0}
 jndi.8B=attrs must not be null
 jndi.8C=component must not be null
+jndi.8D=Must supply attributes describing schema
+jndi.8E=Cannot create new entry under schema root
+jndi.8F=Class definition doesn'thave a numeric OID
 jndi.err.00=. The stack trace of the root exception is: 
 ldap.00=Should not be null
 ldap.01=is not an LdapName
@@ -198,6 +201,9 @@
 ldap.26=Only instances of CompositeName class or LdapName class are acceptable
 ldap.28=Parameter of filter should not be null
 ldap.29=Invalid search filter
+ldap.30=Illegal value: {0} for {1} property
+ldap.34=[LDAP: error code {0} - {1}]
+ldap.35=[LDAP: error code {0}]
 ldap.2B=LDAP URL should not be null
 ldap.2C=Invalid LDAP URL
 ldap.2D=LDAP URL may only contain host, port and dn components

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/AddOp.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/AddOp.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/AddOp.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/AddOp.java Tue Nov 20 06:42:33 2007
@@ -31,12 +31,13 @@
  * formate bytes to java objects.
  */
 final public class AddOp implements LdapOperation, ASN1Encodable {
+    // Attribute list
     private List<LdapAttribute> attrList;
 
     // LDAP distinguished name
     private String entry;
 
-    // Attribute list
+    // LDAP operation result
     private LdapResult result;
 
     public AddOp(String entry, List<LdapAttribute> attrList) {
@@ -76,6 +77,14 @@
     public void encodeValues(Object[] values) {
         values[0] = Utils.getBytes(entry);
         values[1] = attrList;
+    }
+
+    public List<LdapAttribute> getAttributeList() {
+        return attrList;
+    }
+
+    public String getEntry() {
+        return entry;
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/BindOp.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/BindOp.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/BindOp.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/BindOp.java Tue Nov 20 06:42:33 2007
@@ -25,66 +25,74 @@
 import org.apache.harmony.security.asn1.ASN1Integer;
 
 /**
- * Ldap Bind operation. Refer to
- * {@link http://www.rfc-editor.org/rfc/rfc2251.txt} for detailed information
- * 
+ * Ldap Bind operation
  */
-final public class BindOp implements LdapOperation, ASN1Encodable,
-        ASN1Decodable {
+public class BindOp implements LdapOperation {
 
-    private int version = DEFAULT_VERSION;
+    private String name;
 
-    private static final int DEFAULT_VERSION = 3;
+    private byte[] serverSaslCreds; // server's challenge
 
-    private String name;
+    private LdapResult result; // result from this Bind operation
 
-    private AuthenticationChoice authentication;
+    AuthenticationChoice authChoice;
 
-    final public static class SaslCredentials implements ASN1Encodable {
+    private class SaslCredentials implements ASN1Encodable {
 
         private String mechanism;
 
-        private String credentials;
+        private byte[] credentials;
+
+        public SaslCredentials(String mech, byte[] creds) {
+            this.mechanism = mech;
+            this.credentials = creds;
+        }
 
         public void encodeValues(Object[] values) {
             values[0] = Utils.getBytes(mechanism);
-            values[1] = Utils.getBytes(credentials);
+            values[1] = credentials;
         }
 
         public void setMechanism(String mechanism) {
             this.mechanism = mechanism;
         }
 
-        public void setCredentials(String credentials) {
+        public void setCredentials(byte[] credentials) {
             this.credentials = credentials;
         }
 
+        public byte[] getCredentials() {
+            return credentials;
+        }
+
     }
 
-    final public static class AuthenticationChoice implements ASN1Encodable {
+    private class AuthenticationChoice implements ASN1Encodable {
 
         public AuthenticationChoice(int index, SaslCredentials sasl) {
             this.index = index;
             this.sasl = sasl;
-            this.value = new Object[2];
-            sasl.encodeValues((Object[]) value);
         }
 
         public AuthenticationChoice(int index, String password) {
             this.index = index;
             this.password = password;
-            this.value = Utils.getBytes(this.password);
         }
 
         private int index;
 
-        private Object value;
-
         private SaslCredentials sasl;
 
         private String password;
 
         public void encodeValues(Object[] values) {
+            Object value;
+
+            if (index == 0) {
+                value = Utils.getBytes(password);
+            } else {
+                value = sasl;
+            }
             values[0] = new ChosenValue(index, value);
 
         }
@@ -93,48 +101,51 @@
             return index;
         }
 
-        public SaslCredentials getSasl() {
-            return sasl;
+        public byte[] getSaslCredentials() {
+            return sasl.getCredentials();
         }
 
-    }
-
-    private LdapResult result;
-
-    private byte[] response; // response from previous negotiation
+        public void setSaslCredentials(byte[] credentials) {
+            sasl.setCredentials(credentials);
+        }
 
-    public BindOp(int version, String dn) {
-        this.version = version;
-        this.name = dn;
-    }
-
-    public BindOp(String dn, String pwd) {
-        this.name = dn;
-        this.authentication = new AuthenticationChoice(0, pwd);
-        this.response = null;
     }
 
     public BindOp(String dn, String pwd, String saslMechanism, byte[] res) {
         this.name = dn;
-        SaslCredentials sasl = new SaslCredentials();
-        sasl.setMechanism(saslMechanism);
-        sasl.setCredentials(pwd);
-        this.authentication = new AuthenticationChoice(1, sasl);
-        this.response = res;
-    }
 
-    public LdapResult getResult() {
-        return result;
+        if (saslMechanism == null) {
+            authChoice = new AuthenticationChoice(0, pwd);
+        } else {
+            SaslCredentials saslCreds = new SaslCredentials(saslMechanism, res);
+            authChoice = new AuthenticationChoice(1, saslCreds);
+        }
     }
 
     public ASN1Encodable getRequest() {
-
-        return this;
+        return new ASN1Encodable() {
+            public void encodeValues(Object[] values) {
+                values[0] = ASN1Integer.fromIntValue(3);
+                values[1] = Utils.getBytes(name);
+                values[2] = authChoice;
+            }
+        };
     }
 
     public ASN1Decodable getResponse() {
 
-        return this;
+        return new ASN1Decodable() {
+            public void decodeValues(Object[] values) {
+                result = new LdapResult();
+                result.decodeValues(values);
+                if (values[4] != null) {
+                    serverSaslCreds = (byte[]) values[4];
+
+                }
+
+            }
+
+        };
     }
 
     public int getRequestId() {
@@ -145,21 +156,15 @@
         return LdapASN1Constant.OP_BIND_RESPONSE;
     }
 
-    public void encodeValues(Object[] values) {
-        values[0] = ASN1Integer.fromIntValue(version);
-        values[1] = Utils.getBytes(name);
-        Object[] auth = new Object[1];
-        // TODO: encoding AuthenticationChoice
-        authentication.encodeValues(auth);
-        values[2] = auth[0];
+    public void setSaslCredentials(byte[] credentials) {
+        authChoice.setSaslCredentials(credentials);
     }
 
-    public void decodeValues(Object[] values) {
-        result = new LdapResult();
-        result.decodeValues(values);
-        if (values[4] != null) {
-            authentication.getSasl().setCredentials(
-                    Utils.getString((byte[]) values[4]));
-        }
+    public LdapResult getResult() {
+        return result;
+    }
+
+    public byte[] getServerSaslCreds() {
+        return serverSaslCreds;
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/CompareOp.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/CompareOp.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/CompareOp.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/CompareOp.java Tue Nov 20 06:42:33 2007
@@ -61,4 +61,8 @@
         values[1] = objs;
     }
 
+    public LdapResult getResult() {
+        return result;
+    }
+
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/DeleteOp.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/DeleteOp.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/DeleteOp.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/DeleteOp.java Tue Nov 20 06:42:33 2007
@@ -27,7 +27,7 @@
  * {@link http://www.rfc-editor.org/rfc/rfc2251.txt} for detailed information
  * 
  */
-public class DeleteOp implements LdapOperation, ASN1Encodable, ASN1Decodable {
+public class DeleteOp implements LdapOperation, ASN1Encodable {
     /**
      * The distinguished name of the target entry
      */
@@ -63,8 +63,8 @@
         return result;
     }
 
-    public void decodeValues(Object[] values) {
-        dn = Utils.getString((byte[]) values[0]);
+    public String getDn() {
+        return dn;
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapAttribute.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapAttribute.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapAttribute.java Tue Nov 20 06:42:33 2007
@@ -19,6 +19,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 
 import javax.naming.NamingEnumeration;
@@ -52,70 +53,124 @@
     private DirContext attributeSyntaxDefinition = null;
 
     /**
-     * constructor for LdapAttribute
+     * whether the value of attribute is binary
+     */
+    private boolean isBinary;
+    
+    private LdapContextImpl context = null;
+
+    private static HashSet<String> BINARY_ATTRIBUTE = new HashSet<String>();
+    static {
+        BINARY_ATTRIBUTE.add("photo");
+        BINARY_ATTRIBUTE.add("personalSignature");
+        BINARY_ATTRIBUTE.add("audio");
+        BINARY_ATTRIBUTE.add("jpegPhoto");
+        BINARY_ATTRIBUTE.add("javaSerializedData");
+        BINARY_ATTRIBUTE.add("thumbnailPhoto");
+        BINARY_ATTRIBUTE.add("thumbnailLogo");
+        BINARY_ATTRIBUTE.add("userPassword");
+        BINARY_ATTRIBUTE.add("userCertificate");
+        BINARY_ATTRIBUTE.add("cACertificate");
+        BINARY_ATTRIBUTE.add("authorityRevocationList");
+        BINARY_ATTRIBUTE.add("certificateRevocationList");
+        BINARY_ATTRIBUTE.add("crossCertificatePair");
+        BINARY_ATTRIBUTE.add("x500UniqueIdentifier");
+    }
+
+    /**
+     * constructor for decode
      * 
      */
-    protected LdapAttribute() {
+    public LdapAttribute() {
         super("", false); //$NON-NLS-1$
     }
 
-    public LdapAttribute(String id) {
+    public LdapAttribute(String id, LdapContextImpl ctx) {
         super(id, false);
+        isBinary = isBinary(id);
+        context = ctx;
+    }
+    
+    void setContext(LdapContextImpl ctx) {
+        context = ctx;
     }
 
     /**
      * Constructs instance from already existing <code>Attribute</code>
      * 
      * @param attr
+     *            may never be <code>null</code>
      * @throws NamingException
      */
-    public LdapAttribute(Attribute attr) throws NamingException {
+    public LdapAttribute(Attribute attr, LdapContextImpl ctx) throws NamingException {
         super(attr.getID(), attr.isOrdered());
-        NamingEnumeration<?> values = attr.getAll();
-        while (values.hasMore()) {
-            add(values.next());
+        isBinary = isBinary(getID());
+        NamingEnumeration<?> enu = attr.getAll();
+        while (enu.hasMore()) {
+            Object value = enu.next();
+            add(value);
         }
 
-        attributeDefinition = attr.getAttributeDefinition();
-        attributeSyntaxDefinition = attr.getAttributeSyntaxDefinition();
+        attributeDefinition = null;
+        attributeSyntaxDefinition = null;
+        context = ctx;
     }
 
     @SuppressWarnings("unchecked")
-    public void decodeValues(Object[] values) {
-        byte[] type = (byte[]) values[0];
+    public void decodeValues(Object[] vs) {
+        byte[] type = (byte[]) vs[0];
         attrID = Utils.getString(type);
-        Collection<byte[]> list = (Collection<byte[]>) values[1];
-        for (byte[] bs : list) {
-            // TODO: convert to corresponding java type according to schema
-            add(Utils.getString(bs));
+        isBinary = isBinary(attrID);
+        Collection<byte[]> list = (Collection<byte[]>) vs[1];
+        // FIXME: deal with java.naming.ldap.attributes.binary
+        if (!isBinary) {
+            for (byte[] bs : list) {
+                add(Utils.getString(bs));
+            }
+        } else {
+            for (byte[] bs : list) {
+                add(bs);
+            }
         }
 
     }
 
-    public void encodeValues(Object[] values) {
-        values[0] = Utils.getBytes(attrID);
+    public void encodeValues(Object[] vs) {
+        vs[0] = Utils.getBytes(attrID);
 
         List<Object> list = new ArrayList<Object>(this.values.size());
 
         for (Object object : this.values) {
-            // TODO: convert other types to byte[]
-            if (object instanceof String) {
+            if (!isBinary && object instanceof String) {
                 String str = (String) object;
                 object = Utils.getBytes(str);
             }
 
             list.add(object);
         }
-        values[1] = list;
+        vs[1] = list;
     }
 
     @Override
     public DirContext getAttributeDefinition() throws NamingException {
-        return attributeDefinition;
+        if (attributeDefinition != null) {
+            return attributeDefinition;
+        }
+        // TODO: Not yet implemented
+        throw new NotYetImplementedException();
+
     }
 
     @Override
     public DirContext getAttributeSyntaxDefinition() throws NamingException {
-        return attributeSyntaxDefinition;
+        if (attributeSyntaxDefinition != null) {
+            return attributeSyntaxDefinition;
+        }
+        // TODO: Not yet implemented
+        throw new NotYetImplementedException();
+    }
+
+    private static boolean isBinary(String name) {
+        return BINARY_ATTRIBUTE.contains(name) || name.endsWith(";binary");
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java Tue Nov 20 06:42:33 2007
@@ -29,6 +29,7 @@
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.ldap.Control;
+import javax.naming.ldap.StartTlsRequest;
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 
@@ -43,21 +44,46 @@
  * 
  */
 public class LdapClient {
-    /*
+    /**
      * Socket used to communicate with Ldap Server.
      */
     private Socket socket;
 
-    /*
+    /**
      * Input stream of socket.
      */
     private InputStream in;
 
-    /*
+    /**
      * Output stream of socket.
      */
     private OutputStream out;
 
+    /**
+     * Address of connection
+     */
+    private String address;
+
+    /**
+     * port of connection
+     */
+    private int port;
+
+    /**
+     * blocked requests list which wait for response
+     */
+    private Hashtable<Integer, Element> requests = new Hashtable<Integer, Element>();
+
+    /**
+     * the max time to wait server response in milli-second
+     */
+    private long MAX_WAIT_TIME = 30 * 1000;
+
+    /**
+     * responsible for dispatching received messages
+     */
+    private Dispatcher dispatcher;
+
     // constructor for test
     public LdapClient() {
         // do nothing
@@ -79,12 +105,162 @@
      */
     public LdapClient(SocketFactory factory, String address, int port)
             throws UnknownHostException, IOException {
+        this.address = address;
+        this.port = port;
         socket = factory.createSocket(address, port);
-        in = socket.getInputStream();
+        // FIXME: Use of InputStreamWrap here is to deal with a potential bug of
+        // RI.
+        in = new InputStreamWrap(socket.getInputStream());
         out = socket.getOutputStream();
+        dispatcher = new Dispatcher();
+        dispatcher.start();
     }
 
     /**
+     * The instance of the class is daemon thread, which read messages from
+     * server and dispatch to corresponding thread.
+     */
+    class Dispatcher extends Thread {
+
+        private boolean isStopped = false;
+
+        public Dispatcher() {
+            /**
+             * must be daemon thread, otherwrise can't destory by gc
+             */
+            setDaemon(true);
+        }
+
+        public boolean isStopped() {
+            return isStopped;
+        }
+
+        public void setStopped(boolean isStopped) {
+            this.isStopped = isStopped;
+        }
+
+        @Override
+        public void run() {
+            while (!isStopped) {
+                try {
+                    // set response op to null, load later
+                    LdapMessage response = new LdapMessage(null) {
+
+                        /**
+                         * Dispatcher can't know which response operation should
+                         * be used until messageId had determined.
+                         * 
+                         * @return response according messageId
+                         */
+                        @Override
+                        public ASN1Decodable getResponseOp() {
+                            // responseOp has been load, just return it
+                            if (super.getResponseOp() != null) {
+                                return super.getResponseOp();
+                            }
+
+                            int messageId = getMessageId();
+
+                            // Unsolicited Notification
+                            if (messageId == 0) {
+                                // TODO return instance of
+                                // UnsolicitedNotificationImpl
+                            }
+
+                            // get response operation according messageId
+                            Element element = requests.get(Integer
+                                    .valueOf(messageId));
+                            if (element != null) {
+                                return element.response.getResponseOp();
+                            }
+
+                            /*
+                             * FIXME: if messageId not find in request list,
+                             * what should we do?
+                             */
+                            return null;
+                        }
+                    };
+
+                    Exception ex = null;
+                    /**
+                     * TODO read message data by ourselves then decode, this
+                     * would be robust
+                     */
+                    try {
+                        // read next message
+                        response.decode(in);
+                    } catch (IOException e) {
+                        // may socket has problem or decode occurs error
+                        ex = e;
+                    } catch (RuntimeException e) {
+                        // may socket has problem or decode occurs error
+                        ex = e;
+                    }
+
+                    processResponse(response, ex);
+
+                } catch (Exception e) {
+                    // may never reach
+                    e.printStackTrace();
+                }
+            }
+
+        }
+
+        private void processResponse(LdapMessage response, Exception ex) {
+            // unsolicited notification
+            if (response.getMessageId() == 0) {
+                // TODO notify unsolicited listeners
+                return;
+            }
+
+            Element element = requests.get(Integer.valueOf(response
+                    .getMessageId()));
+
+            if (element != null) {
+                element.response = response;
+                element.ex = ex;
+                // persistent search response
+                if (element.lock == null) {
+
+                    // TODO notify persistent search listeners
+
+                } else {
+                    /*
+                     * notify the thread which send request and wait for
+                     * response
+                     */
+                    if (element.response.getOperationIndex() == LdapASN1Constant.OP_EXTENDED_RESPONSE
+                            && ((ExtendedOp) element.response.getResponseOp())
+                                    .getExtendedRequest().getID().equals(
+                                            StartTlsRequest.OID)) {
+                        /*
+                         * When establishing TLS by StartTls extended operation, no 
+                         */
+                        isStopped = true;
+                    }
+                    
+                    synchronized (element.lock) {
+                        element.lock.notify();
+                    }
+                } // end of if (element.lock == null) else
+            } // end of if (element != null)
+
+            else if (ex != null) {
+                /*
+                 * may asn1 decode error or socket problem, can get message id,
+                 * so couldn't know which thread should be notified
+                 */
+                // FIXME: any better way?
+                close();
+            }
+            // FIXME message id not found and no exception, what shoud we do?
+
+        } // end of processResponse
+    } // Dispatcher
+
+    /**
      * Carry out the ldap operation encapsulated in operation with controls.
      * 
      * @param operation
@@ -117,17 +293,102 @@
     public LdapMessage doOperation(int opIndex, ASN1Encodable request,
             ASN1Decodable response, Control[] controls) throws IOException {
 
+        if (opIndex == LdapASN1Constant.OP_SEARCH_REQUEST) {
+            return doSearchOperation(request, response, controls);
+        }
+
         LdapMessage requestMsg = new LdapMessage(opIndex, request, controls);
-        out.write(requestMsg.encode());
-        out.flush();
-        LdapMessage responseMsg = new LdapMessage(response);
-        responseMsg.decode(in);
-        if (opIndex == LdapASN1Constant.OP_SEARCH_REQUEST
-                && responseMsg.getOperationIndex() != LdapASN1Constant.OP_SEARCH_RESULT_DONE) {
-            responseMsg = new LdapMessage(response);
-            responseMsg.decode(in);
+
+        Integer messageID = Integer.valueOf(requestMsg.getMessageId());
+
+        Object lock = new Object();
+        requests.put(messageID, new Element(lock, new LdapMessage(response)));
+
+        try {
+            out.write(requestMsg.encode());
+            out.flush();
+            return waitResponse(messageID, lock);
+
+        } finally {
+            // remove request from list
+            requests.remove(messageID);
         }
-        return responseMsg;
+
+    }
+
+    /**
+     * Block the current thread until get response from server or occurs error
+     * 
+     * @param messageID
+     *            id of request message, is same as id of response message
+     * @param response
+     *            decoder of the response
+     * @return response message, may not be null
+     * 
+     * @throws Exception
+     */
+    private LdapMessage waitResponse(Integer messageID, Object lock)
+            throws IOException {
+
+        synchronized (lock) {
+            try {
+                lock.wait(MAX_WAIT_TIME);
+            } catch (InterruptedException e) {
+                // ignore
+            }
+        }
+
+        Element element = requests.get(messageID);
+
+        // wait time out
+        if (element.response.getMessageId() != messageID.intValue()) {
+            // ldap.31=Read LDAP response message time out
+            throw new IOException(Messages.getString("ldap.31")); //$NON-NLS-1$
+        }
+
+        // error occurs when read response
+        if (element.ex != null) {
+            // socket is not connected
+            if (!socket.isConnected()) {
+                close();
+            }
+            // element.ex must be one of IOException or RuntimeException
+            if (element.ex instanceof IOException) {
+                throw (IOException) element.ex;
+            }
+
+            throw (RuntimeException) element.ex;
+        }
+
+        return element.response;
+
+    }
+
+    private LdapMessage doSearchOperation(ASN1Encodable request,
+            ASN1Decodable response, Control[] controls) throws IOException {
+        LdapMessage requestMsg = new LdapMessage(
+                LdapASN1Constant.OP_SEARCH_REQUEST, request, controls);
+
+        Integer messageID = Integer.valueOf(requestMsg.getMessageId());
+
+        Object lock = new Object();
+        requests.put(messageID, new Element(lock, new LdapMessage(response)));
+
+        try {
+            out.write(requestMsg.encode());
+            out.flush();
+            LdapMessage responseMsg = waitResponse(messageID, lock);
+
+            while (responseMsg.getOperationIndex() != LdapASN1Constant.OP_SEARCH_RESULT_DONE) {
+                responseMsg = waitResponse(messageID, lock);
+            }
+
+            return responseMsg;
+        } finally {
+            // remove request from list
+            requests.remove(messageID);
+        }
+
     }
 
     public void abandon(final int messageId, Control[] controls)
@@ -149,8 +410,50 @@
         out.flush();
     }
 
-    public void close() throws IOException {
-        socket.close();
+    /**
+     * Close network connection, stop dispather thread, and release all other
+     * resources
+     * 
+     * NOTE: invoke this method should be careful when this
+     * <code>LdapClient</code> instance is shared by multi
+     * <code>LdapContext</code>
+     * 
+     */
+    public void close() {
+        // close socket
+        if (socket != null) {
+            try {
+                socket.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+
+        socket = null;
+        in = null;
+        out = null;
+
+        // try to stop dispather
+        if (dispatcher != null) {
+            dispatcher.setStopped(true);
+            dispatcher.interrupt();
+        }
+
+        // notify all blocked thread
+        if (requests != null) {
+            for (Element element : requests.values()) {
+                if (element.lock != null) {
+                    synchronized (element.lock) {
+                        element.lock.notify();
+                    }
+                } else {
+                    // TODO notify persistent search listeners
+                }
+            }
+            requests.clear();
+            requests = null;
+        }
+
     }
 
     /**
@@ -222,5 +525,118 @@
         }
 
         return cls;
+    }
+
+    /**
+     * struct for holding necessary info to add to requests list
+     */
+    static class Element {
+        Object lock;
+
+        LdapMessage response;
+
+        Exception ex;
+
+        public Element(Object lock, LdapMessage response) {
+            this.lock = lock;
+            this.response = response;
+        }
+    }
+
+    // TODO: This class is used to deal with a potential bug of RI, may be
+    // removed in the future.
+    /**
+     * When use <code>InputStream</code> from SSL Socket, if invoke
+     * <code>InputStream.read(byte[])</code> with byte array of zero length,
+     * the method will be blocked. Seems it's bug of ri.
+     * 
+     * This wrap class delegate all request to wrapped instance, except
+     * returning immediately when the invoke
+     * <code>InputStream.read(byte[])</code> with byte array of zero length.
+     */
+    static class InputStreamWrap extends InputStream {
+        InputStream in;
+
+        public InputStreamWrap(InputStream in) {
+            this.in = in;
+        }
+
+        @Override
+        public int read() throws IOException {
+            return in.read();
+        }
+
+        @Override
+        public int read(byte[] bs, int offset, int len) throws IOException {
+            if (len == 0) {
+                return 0;
+            }
+            return in.read(bs, offset, len);
+        }
+
+        @Override
+        public void reset() throws IOException {
+            in.reset();
+
+        }
+
+        @Override
+        public int available() throws IOException {
+            return in.available();
+        }
+
+        @Override
+        public void close() throws IOException {
+            in.close();
+        }
+
+        @Override
+        public void mark(int readlimit) {
+            in.mark(readlimit);
+        }
+
+        @Override
+        public boolean markSupported() {
+            return in.markSupported();
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            return in.read(b);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            return in.skip(n);
+        }
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    protected void finalize() {
+        close();
+    }
+    
+    public Socket getSocket() {
+        return this.socket;
+    }
+
+    public void setSocket(Socket socket) throws IOException {
+        this.socket = socket;
+        this.in = new InputStreamWrap(socket.getInputStream());
+        this.out = socket.getOutputStream();
+        if (dispatcher != null) {
+            dispatcher.setStopped(true);
+            dispatcher.interrupt();
+        }
+        this.dispatcher = new Dispatcher();
+        this.dispatcher.start();
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextFactory.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextFactory.java?rev=596693&r1=596692&r2=596693&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextFactory.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapContextFactory.java Tue Nov 20 06:42:33 2007
@@ -25,15 +25,10 @@
 import javax.naming.NamingException;
 import javax.naming.spi.InitialContextFactory;
 
-import org.apache.harmony.jndi.internal.nls.Messages;
 import org.apache.harmony.jndi.provider.ldap.parser.LdapUrlParser;
 
 public class LdapContextFactory implements InitialContextFactory {
 
-    private static final int DEFAULT_PORT = 389;
-
-    private static final String DEFAULT_HOST = "localhost"; //$NON-NLS-1$
-
     public Context getInitialContext(Hashtable<?, ?> envmt)
             throws NamingException {
         Hashtable<Object, Object> myEnv = null;
@@ -53,18 +48,6 @@
         String host = parser.getHost();
         int port = parser.getPort();
         String dn = parser.getBaseObject();
-
-        if (host == null) {
-            host = DEFAULT_HOST;
-        }
-
-        if (port == -1) {
-            port = DEFAULT_PORT;
-        }
-
-        if (dn == null) {
-            dn = "";
-        }
 
         LdapClient client = LdapClient.newInstance(host, port, myEnv);
 



Mime
View raw message