db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject svn commit: r398725 - in /db/ojb/branches/OJB_1_0_RELEASE/src: java/org/apache/ojb/broker/lob/ test/org/apache/ojb/broker/lob/
Date Mon, 01 May 2006 23:10:52 GMT
Author: arminw
Date: Mon May  1 16:10:50 2006
New Revision: 398725

URL: http://svn.apache.org/viewcvs?rev=398725&view=rev
Log:
initial, LOB support

Added:
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobHandle.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobImpl.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobHandle.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobImpl.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/InactiveLobException.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/Lob.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobException.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHandle.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelper.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/LOBTest.java

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobHandle.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobHandle.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobHandle.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobHandle.java Mon May  1 16:10:50 2006
@@ -0,0 +1,115 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import org.apache.ojb.broker.PersistenceBroker;
+
+/**
+ * This class is a wrapper for {@link java.sql.Blob} objects.
+ *
+ * @version $Id: $
+ */
+public class BlobHandle extends LobHandle implements Blob
+{
+    private Blob blob;
+
+    BlobHandle(PersistenceBroker broker, Blob blob)
+    {
+        super(broker);
+        this.blob = blob;
+        if(blob instanceof Lob)
+        {
+            setTransient(true);
+        }
+    }
+
+    protected void txFail()
+    {
+        super.txFail();
+        if(!isTransient()) this.blob = null;
+    }
+
+    protected void txSuccess()
+    {
+        super.txSuccess();
+        this.blob = null;
+    }
+
+    protected void inactivate()
+    {
+        super.inactivate();
+        if(!isTransient()) this.blob = null;
+    }
+
+    public long length() throws SQLException
+    {
+        checkActive();
+        return blob.length();
+    }
+
+    public void truncate(long len) throws SQLException
+    {
+        checkActive();
+        blob.truncate(len);
+    }
+
+    public byte[] getBytes(long pos, int length) throws SQLException
+    {
+        checkActive();
+        return blob.getBytes(pos, length);
+    }
+
+    public int setBytes(long pos, byte[] bytes) throws SQLException
+    {
+        checkActive();
+        return blob.setBytes(pos, bytes);
+    }
+
+    public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException
+    {
+        checkActive();
+        return blob.setBytes(pos, bytes, offset, len);
+    }
+
+    public long position(byte pattern[], long start) throws SQLException
+    {
+        checkActive();
+        return blob.position(pattern, start);
+    }
+
+    public InputStream getBinaryStream() throws SQLException
+    {
+        checkActive();
+        return blob.getBinaryStream();
+    }
+
+    public OutputStream setBinaryStream(long pos) throws SQLException
+    {
+        checkActive();
+        return blob.setBinaryStream(pos);
+    }
+
+    public long position(Blob pattern, long start) throws SQLException
+    {
+        checkActive();
+        return blob.position(pattern, start);
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobImpl.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobImpl.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobImpl.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/BlobImpl.java Mon May  1 16:10:50 2006
@@ -0,0 +1,181 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import org.apache.commons.lang.ArrayUtils;
+
+/**
+ * This class is OJB's implementation of the {@link java.sql.Blob} interface.
+ *
+ * @version $Id: $
+ */
+class BlobImpl implements Blob, Lob, Serializable
+{
+    private byte[] bytes = new byte[]{};
+    private transient InputStream in;
+
+    public BlobImpl()
+    {
+    }
+
+    public BlobImpl(byte[] value)
+    {
+        if(value != null) this.bytes = value;
+    }
+
+    public BlobImpl(InputStream in)
+    {
+        this.in = in;
+    }
+
+    private void checkMethod()
+    {
+        if(in != null)
+        {
+            throw new UnsupportedOperationException("Unsupported method when using this Blob implementation with InputStream");
+        }
+    }
+
+    public byte[] getBytes()
+    {
+        return bytes;
+    }
+
+    public byte[] getBytes(long pos, int length) throws SQLException
+    {
+        checkMethod();
+        pos--;
+        return ArrayUtils.subarray(bytes, (int) pos, (int) (pos + length));
+    }
+
+    public int setBytes(long pos, byte[] bytes) throws SQLException
+    {
+        return setBytes(pos, bytes, 1, bytes.length);
+    }
+
+    public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException
+    {
+        checkMethod();
+        offset--;
+        OJBStream out = prepareStream(pos);
+        out.write(bytes, offset, len);
+        try
+        {
+            out.close();
+        }
+        catch(IOException e)
+        {
+            throw new LobException("Unexpected failure while write bytes", e);
+        }
+        return len;
+    }
+
+    public InputStream getBinaryStream() throws SQLException
+    {
+        if(in != null) return in;
+        else return new ByteArrayInputStream(bytes);
+    }
+
+    public OutputStream setBinaryStream(long pos) throws SQLException
+    {
+        checkMethod();
+        return prepareStream(pos);
+    }
+
+    public OJBStream prepareStream(long pos) throws SQLException
+    {
+        if(pos < 1)
+        {
+            throw new IndexOutOfBoundsException("Invalid index: " + pos);
+        }
+
+        OJBStream out = new OJBStream(this);
+        if(this.bytes.length > 0) out.write(this.bytes, 0, (int) --pos);
+        return out;
+    }
+
+    public long length() throws SQLException
+    {
+        return in != null ? -1 : bytes.length;
+    }
+
+    public long position(byte pattern[], long start) throws SQLException
+    {
+        throw new UnsupportedOperationException("Not supported method");
+    }
+
+    public long position(Blob pattern, long start) throws SQLException
+    {
+        throw new UnsupportedOperationException("Not supported method");
+    }
+
+    public void truncate(long len) throws SQLException
+    {
+        checkMethod();
+        bytes = ArrayUtils.subarray(bytes, 0, (int) len);
+    }
+
+    public void streamClosed(OJBStream out)
+    {
+        int streamSize = out.size();
+        if(streamSize < this.bytes.length)
+        {
+            out.write(this.bytes, streamSize, this.bytes.length - streamSize);
+        }
+        this.bytes = out.toByteArray();
+    }
+
+//    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+//    {
+//        byte[] array = (byte[]) in.readObject();
+//        bytes.write(array);
+//    }
+//
+//    public void writeExternal(ObjectOutput out) throws IOException
+//    {
+//        out.writeObject(bytes.toByteArray());
+//    }
+
+    static class OJBStream extends ByteArrayOutputStream
+    {
+        BlobImpl home;
+
+        public OJBStream(BlobImpl home)
+        {
+            this.home = home;
+        }
+
+        byte[] getBytes()
+        {
+            return buf;
+        }
+
+        public void close() throws IOException
+        {
+            super.close();
+            home.streamClosed(this);
+        }
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobHandle.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobHandle.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobHandle.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobHandle.java Mon May  1 16:10:50 2006
@@ -0,0 +1,129 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import org.apache.ojb.broker.PersistenceBroker;
+
+/**
+ * This class is a wrapper for {@link java.sql.Clob} objects.
+ *
+ * @version $Id: $
+ */
+public class ClobHandle extends LobHandle implements Clob
+{
+    private Clob clob;
+
+    ClobHandle(PersistenceBroker broker, Clob clob)
+    {
+        super(broker);
+        this.clob = clob;
+        if(clob instanceof Lob)
+        {
+            setTransient(true);
+        }
+    }
+
+    protected void txFail()
+    {
+        super.txFail();
+        if(!isTransient()) this.clob = null;
+    }
+
+    protected void txSuccess()
+    {
+        super.txSuccess();
+        this.clob = null;
+    }
+
+    protected void inactivate()
+    {
+        super.inactivate();
+        if(!isTransient()) this.clob = null;
+    }
+
+    public long length() throws SQLException
+    {
+        checkActive();
+        return clob.length();
+    }
+
+    public void truncate(long len) throws SQLException
+    {
+        checkActive();
+        clob.truncate(len);
+    }
+
+    public InputStream getAsciiStream() throws SQLException
+    {
+        checkActive();
+        return clob.getAsciiStream();
+    }
+
+    public OutputStream setAsciiStream(long pos) throws SQLException
+    {
+        checkActive();
+        return clob.setAsciiStream(pos);
+    }
+
+    public Reader getCharacterStream() throws SQLException
+    {
+        checkActive();
+        return clob.getCharacterStream();
+    }
+
+    public Writer setCharacterStream(long pos) throws SQLException
+    {
+        checkActive();
+        return clob.setCharacterStream(pos);
+    }
+
+    public String getSubString(long pos, int length) throws SQLException
+    {
+        checkActive();
+        return clob.getSubString(pos, length);
+    }
+
+    public int setString(long pos, String str) throws SQLException
+    {
+        checkActive();
+        return clob.setString(pos, str);
+    }
+
+    public int setString(long pos, String str, int offset, int len) throws SQLException
+    {
+        checkActive();
+        return clob.setString(pos, str, offset, len);
+    }
+
+    public long position(String searchstr, long start) throws SQLException
+    {
+        checkActive();
+        return clob.position(searchstr, start);
+    }
+
+    public long position(Clob searchstr, long start) throws SQLException
+    {
+        checkActive();
+        return clob.position(searchstr, start);
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobImpl.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobImpl.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobImpl.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/ClobImpl.java Mon May  1 16:10:50 2006
@@ -0,0 +1,185 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.ojb.broker.util.ReaderInputStream;
+
+/**
+ * This class is OJB's implementation of the {@link java.sql.Clob} interface.
+ *
+ * @version $Id: $
+ */
+class ClobImpl implements Clob, Externalizable, Lob
+{
+    private transient StringWriter writer;
+    private transient Reader reader;
+
+    public ClobImpl()
+    {
+        this.writer = new StringWriter();
+    }
+
+    public ClobImpl(String str)
+    {
+        this();
+        if(str != null) writer.write(str);
+    }
+
+    public ClobImpl(Reader reader)
+    {
+        this.reader = reader;
+    }
+
+    private void checkMethod()
+    {
+        if(reader != null)
+        {
+            throw new UnsupportedOperationException("Unsupported method when using this Blob implementation with Reader");
+        }
+    }
+
+    protected StringWriter getWriter()
+    {
+        return writer;
+    }
+
+    public InputStream getAsciiStream() throws SQLException
+    {
+        if(reader != null)
+        {
+            return new ReaderInputStream(reader);
+        }
+        else return new ByteArrayInputStream(getWriter().toString().getBytes());
+    }
+
+    public OutputStream setAsciiStream(long pos) throws SQLException
+    {
+        checkMethod();
+        String str = getWriter().toString();
+        byte[] bytes = str.getBytes();
+        bytes = ArrayUtils.subarray(bytes, 0, (int) --pos);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try
+        {
+            bos.write(bytes);
+        }
+        catch(IOException e)
+        {
+            throw new SQLException("Can't write existing bytes: " + ExceptionUtils.getFullStackTrace(e));
+        }
+        return bos;
+    }
+
+    public Reader getCharacterStream() throws SQLException
+    {
+        if(reader != null) return reader;
+        return new StringReader(getWriter().toString());
+    }
+
+    public Writer setCharacterStream(long pos) throws SQLException
+    {
+        checkMethod();
+        String result = getWriter().getBuffer().substring(0, (int) --pos);
+        writer = new StringWriter();
+        writer.write(result);
+        return getWriter();
+    }
+
+    public String getSubString(long pos, int length) throws SQLException
+    {
+        checkMethod();
+        pos--;
+        return getWriter().getBuffer().substring((int) pos, (int) (pos + length));
+    }
+
+    public int setString(long pos, String str) throws SQLException
+    {
+        checkMethod();
+        return setString(pos, str, 0, str.length());
+    }
+
+    public int setString(long pos, String str, int offset, int len) throws SQLException
+    {
+        checkMethod();
+        if(pos < 1)
+        {
+            throw new IndexOutOfBoundsException("Illegal start position: " + pos);
+        }
+        if(str == null)
+        {
+            throw new NullPointerException("Specified string is 'null'");
+        }
+        pos--;
+        StringBuffer charBuf = this.writer.getBuffer();
+        String replaceString = str.substring(offset, len);
+        charBuf.replace((int) pos, (int) (pos + replaceString.length()), replaceString);
+        return replaceString.length();
+    }
+
+    public long length() throws SQLException
+    {
+        return reader != null ? -1 : getWriter().getBuffer().length();
+    }
+
+    public long position(String searchstr, long start) throws SQLException
+    {
+        checkMethod();
+        return getWriter().getBuffer().indexOf(searchstr, (int) --start);
+    }
+
+    public long position(Clob searchstr, long start) throws SQLException
+    {
+        checkMethod();
+        return getWriter().getBuffer().indexOf(
+                searchstr.getSubString(0, (int) searchstr.length()), (int) --start);
+    }
+
+    public void truncate(long len) throws SQLException
+    {
+        checkMethod();
+        String str = getWriter().getBuffer().substring(0, (int) len);
+        writer = new StringWriter();
+        writer.write(str);
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+    {
+        String str = (String) in.readObject();
+        writer.write(str);
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException
+    {
+        out.writeObject(writer.toString());
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/InactiveLobException.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/InactiveLobException.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/InactiveLobException.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/InactiveLobException.java Mon May  1 16:10:50 2006
@@ -0,0 +1,43 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Thrown if access or usage of current LOB object isn't valid.
+ *
+ * @version $Id: $
+ */
+public class InactiveLobException extends LobException
+{
+    public InactiveLobException()
+    {
+    }
+
+    public InactiveLobException(String msg)
+    {
+        super(msg);
+    }
+
+    public InactiveLobException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    public InactiveLobException(String msg, Throwable cause)
+    {
+        super(msg, cause);
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/Lob.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/Lob.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/Lob.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/Lob.java Mon May  1 16:10:50 2006
@@ -0,0 +1,26 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+
+/**
+ * Marker interface for OJB LOB objects.
+ *
+ * @version $Id: $
+ */
+public interface Lob
+{
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobException.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobException.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobException.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobException.java Mon May  1 16:10:50 2006
@@ -0,0 +1,46 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+
+import org.apache.ojb.broker.OJBRuntimeException;
+
+/**
+ * Thrown when an invalid LOB opertation occurs.
+ *
+ * @version $Id: $
+ */
+public class LobException extends OJBRuntimeException
+{
+    public LobException()
+    {
+    }
+
+    public LobException(String msg)
+    {
+        super(msg);
+    }
+
+    public LobException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    public LobException(String msg, Throwable cause)
+    {
+        super(msg, cause);
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHandle.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHandle.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHandle.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHandle.java Mon May  1 16:10:50 2006
@@ -0,0 +1,129 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import org.apache.ojb.broker.PBStateEvent;
+import org.apache.ojb.broker.PBStateListener;
+import org.apache.ojb.broker.PersistenceBroker;
+
+/**
+ * Base class for OJB LOB-objects.
+ *
+ * @version $Id: $
+ */
+abstract class LobHandle implements PBStateListener
+{
+    private boolean active;
+    private boolean isTransient;
+
+    public LobHandle(PersistenceBroker broker)
+    {
+        isTransient = false;
+        active = broker.isInTransaction();
+        if(active)
+        {
+            broker.addListener(this, false);
+        }
+        /*
+        Think we should allow to query objects with LOB fields without a running
+        PB-tx. If the user try to access the LOB field, method #checkActive() will throw an
+        exception.
+        */
+//        else
+//        {
+//            throw new LobException("LOB opertations only valid when the used PersistanceBroker is in PB-tx");
+//        }
+    }
+
+    public boolean isTransient()
+    {
+        return isTransient;
+    }
+
+    protected void setTransient(boolean aTransient)
+    {
+        isTransient = aTransient;
+    }
+
+    protected void txFail()
+    {
+        this.active = false;
+    }
+
+    protected void txSuccess()
+    {
+        this.active = false;
+        this.isTransient = false;
+    }
+
+    protected void inactivate()
+    {
+        this.active = false;
+        this.isTransient = false;
+    }
+
+    protected boolean isActive()
+    {
+        return this.active;
+    }
+
+    protected void checkActive()
+    {
+        if(!isTransient() && !isActive()) throw new InactiveLobException(
+                "Current LOB is not valid for access (no active PB-tx or PB-tx changed), "
+                + "refresh the persistent object this LOB belongs too");
+    }
+
+
+    //===================================================================
+    // Listener methods
+    //===================================================================
+    public void beforeClose(PBStateEvent event)
+    {
+        inactivate();
+    }
+
+    public void beforeRollback(PBStateEvent event)
+    {
+        txFail();
+    }
+
+    public void afterCommit(PBStateEvent event)
+    {
+        txSuccess();
+    }
+
+    public void afterBegin(PBStateEvent event)
+    {
+        if(isTransient()) this.active = true;
+    }
+
+    public void afterOpen(PBStateEvent event)
+    {
+    }
+
+    public void beforeBegin(PBStateEvent event)
+    {
+    }
+
+    public void beforeCommit(PBStateEvent event)
+    {
+    }
+
+    public void afterRollback(PBStateEvent event)
+    {
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelper.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelper.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelper.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelper.java Mon May  1 16:10:50 2006
@@ -0,0 +1,190 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.Blob;
+import java.sql.Clob;
+
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+
+/**
+ * Helper class support handling of LOB-locator-object
+ * fields ({@link java.sql.Blob} and {@link java.sql.Clob} fields)
+ * in persistence capable objects.
+ *
+ * @version $Id: $
+ */
+public interface LobHelper
+{
+    /**
+     * Returns a new {@link java.sql.Blob} instance.
+     *
+     * @param in The data source stream.
+     * @return The new {@link java.sql.Blob} instance.
+     */
+    public Blob newBlob(InputStream in);
+
+    /**
+     * Returns a new {@link java.sql.Blob} instance.
+     *
+     * @param value The byte array data.
+     * @return The new {@link java.sql.Blob} instance.
+     */
+    public Blob newBlob(byte[] value);
+
+    /**
+     * Returns a new <em>empty</em> {@link java.sql.Blob} instance.
+     *
+     * @return The new {@link java.sql.Blob} instance.
+     */
+    public Blob newBlob();
+
+    /**
+     * Returns a new {@link java.sql.Clob} instance.
+     *
+     * @param reader The data source reader.
+     * @return The new {@link java.sql.Clob} instance.
+     */
+    public Clob newClob(Reader reader);
+
+    /**
+     * Returns a new {@link java.sql.Clob} instance.
+     *
+     * @param value The data source as {@link String}.
+     * @return The new {@link java.sql.Clob} instance.
+     */
+    public Clob newClob(String value);
+
+    /**
+     * Returns a new <em>empty</em> {@link java.sql.Clob} instance.
+     *
+     * @return The new {@link java.sql.Clob} instance.
+     */
+    public Clob newClob();
+
+    /**
+     * Returns <em>true</em> if automatic refresh of LOB-locator
+     * fields is enabled.
+     *
+     * @see #setLobAutoRefresh(boolean)
+     */
+    public boolean isLobAutoRefresh();
+
+    /**
+     * @param autoRefresh If <em>true</em> automatic refresh for LOB-locator
+     * objects will be enabled.
+     */
+    public void setLobAutoRefresh(boolean autoRefresh);
+
+    /**
+     * INTERNAL USED METHOD!
+     * This method was internally called when automatic refresh of
+     * LOB-locator-object field is enabled - see {@link #setLobAutoRefresh(boolean)}.
+     */
+    public void internalAutoRefresh(Object target, ClassDescriptor cld);
+
+    /**
+     * See method {@link #refreshLob(Object, org.apache.ojb.broker.metadata.ClassDescriptor)}.
+     *
+     * @param target The target object with the LOB-fields to refresh.
+     */
+    public void refreshLob(Object target);
+
+    /**
+     * Refresh all LOB-locator instances of the specified persistence capable object
+     * if the following conditions are true for the target object:
+     * <ul>
+     * <li>active {@link org.apache.ojb.broker.PersistenceBroker}-tx is running</li>
+     * <li>contains LOB fields</li>
+     * <li>LOB fields wrapped by OJB's LOB wrapping classes (normally
+     * all LOB fields of persistence capable objects are automatically wrapped
+     * with OJB specific wrapper classes by internal calls to
+     * {@link #wrapLobFields(org.apache.ojb.broker.metadata.ClassDescriptor, Object)})</li>
+     * <li>one or more fields are inactive/invalid (there is no active
+     * {@link org.apache.ojb.broker.PersistenceBroker} instance associated with detected LOB-fields)</li>
+     * </ul>
+     * In all other cases the method will return immediately.
+     * On each LOB-fields refresh, OJB query a new LOB-locator instance from the database.
+     *
+     * @param target The target object with the LOB-fields to refresh.
+     * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the target object.
+     */
+    public void refreshLob(Object target, ClassDescriptor cld);
+
+//    /**
+//     * Internal used method!
+//     * <br/>
+//     * Refresh the specified LOB-locator instance field of the persistence capable object.
+//     * For each refresh OJB query a new Locator instance from the database.
+//     * The refresh of LOB-fields is only possible within an active
+//     * {@link org.apache.ojb.broker.PersistenceBroker}-tx, else the method will return immediately.
+//     *
+//     * @param lobField The LOB field to refresh.
+//     * @param target The target object with the field to refresh.
+//     * @param pkFields The promary key values of the target object.
+//     */
+//    public void refreshLob(FieldDescriptor lobField, Object target, FieldDescriptor[] pkFields);
+
+    /**
+     * Internal used method!
+     * <br/>
+     * Wraps the target object LOB instances ({@link java.sql.Blob} and {@link java.sql.Clob}
+     * instances returned by the database) with OJB specific LOB-wrapper classes.
+     *
+     * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the target object.
+     * @param target The target object.
+     */
+    public void wrapLobFields(ClassDescriptor cld, Object target);
+
+//    /**
+//     * Returns <em>true</em> if the specified persistence capable object
+//     * fulfill the conditions below:
+//     * <ul>
+//     * <li>contains LOB fields</li>
+//     * <li>LOB fields wrapped by OJB's LOB wrapping classes (normally
+//     * all LOB fields of persistence capable objects are automatically wrapped
+//     * with OJB specific wrapper classes by internal calls to
+//     * {@link #wrapLobFields(org.apache.ojb.broker.metadata.ClassDescriptor, Object)})</li>
+//     * <li>one or more fields are inactive/invalid</li>
+//     * </ul>
+//     * In all other cases <em>false</em> will be returned.
+//     *
+//     * @param source The persistence capable object.
+//     * @return <em>True</em> if source object has inactive/invalid LOB-fields.
+//     */
+//    public boolean needsRefresh(Object source);
+//
+//    /**
+//     * Returns <em>true</em> if the specified persistence capable object
+//     * fulfill the conditions below:
+//     * <ul>
+//     * <li>contains LOB fields</li>
+//     * <li>LOB fields wrapped by OJB's LOB wrapping classes (normally
+//     * all LOB fields of persistence capable objects are automatically wrapped
+//     * with OJB specific wrapper classes by internal calls to
+//     * {@link #wrapLobFields(org.apache.ojb.broker.metadata.ClassDescriptor, Object)})</li>
+//     * <li>one or more fields are inactive/invalid</li>
+//     * </ul>
+//     * In all other cases <em>false</em> will be returned.
+//     *
+//     * @param source The persistence capable object.
+//     * @param cld The associated {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
+//     * @return <em>True</em> if source object has inactive/invalid LOB-fields.
+//     */
+//    public boolean needsRefresh(Object source, ClassDescriptor cld);
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java Mon May  1 16:10:50 2006
@@ -0,0 +1,243 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.Iterator;
+
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.metadata.FieldTypes;
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryFactory;
+import org.apache.ojb.broker.util.logging.Logger;
+import org.apache.ojb.broker.util.logging.LoggerFactory;
+
+/**
+ * Helper class for LOB object creation.
+ *
+ * @version $Id: $
+ */
+public class LobHelperImpl implements LobHelper
+{
+    private Logger log = LoggerFactory.getLogger(LobHelperImpl.class);
+
+    private PersistenceBrokerInternal broker;
+    private boolean lobAutoRefresh;
+
+    public LobHelperImpl(PersistenceBrokerInternal broker)
+    {
+        this.broker = broker;
+    }
+
+    public Blob newBlob(InputStream in)
+    {
+        BlobImpl result = new BlobImpl(in);
+        return new BlobHandle(broker, result);
+    }
+
+    public Blob newBlob(byte[] value)
+    {
+        BlobImpl result = new BlobImpl(value);
+        return new BlobHandle(broker, result);
+    }
+
+    public Blob newBlob()
+    {
+        return newBlob((byte[]) null);
+    }
+
+    public Clob newClob(Reader reader)
+    {
+        ClobImpl result = new ClobImpl(reader);
+        return new ClobHandle(broker, result);
+    }
+
+    public Clob newClob(String value)
+    {
+        ClobImpl result = new ClobImpl(value);
+        return new ClobHandle(broker, result);
+    }
+
+    public Clob newClob()
+    {
+        return newClob((String) null);
+    }
+
+    public boolean isLobAutoRefresh()
+    {
+        return this.lobAutoRefresh;
+    }
+
+    public void setLobAutoRefresh(boolean autoRefresh)
+    {
+        this.lobAutoRefresh = autoRefresh;
+    }
+
+    public void internalAutoRefresh(Object target, ClassDescriptor cld)
+    {
+        if(lobAutoRefresh)
+        {
+            refreshLob(target, cld);
+        }
+    }
+
+    public void refreshLob(Object target)
+    {
+        ClassDescriptor cld = broker.getClassDescriptor(target.getClass());
+        refreshLob(target, cld);
+    }
+
+    public void refreshLob(Object target, ClassDescriptor cld)
+    {
+        if(broker.isInTransaction())
+        {
+            if(cld.hasLobField())
+            {
+                FieldDescriptor[] pkFields = cld.getPkFields();
+                FieldDescriptor[] fields = cld.getFieldDescriptor(true);
+                for(int i = 0; i < fields.length; i++)
+                {
+                    FieldDescriptor field = fields[i];
+                    if(needsRefresh(field, target))
+                    {
+                        refreshLob(field, target, pkFields);
+                    }
+                }
+            }
+        }
+        else
+        {
+            if(log.isDebugEnabled())
+            {
+                log.debug("Can't refresh LOB-objects, an active PB-tx is needed. Specified PersistenceBroker: "
+                        + broker);
+            }
+        }
+    }
+
+    /**
+     * Refresh the specified LOB type field by querying a new LOB-locator object via ReportQuery
+     * and replace the LOB-object in source object.
+     */
+    protected void refreshLob(FieldDescriptor lobField, Object source, FieldDescriptor[] pkFields)
+    {
+        if(source == null)
+        {
+            throw new NullPointerException("Persistent object is 'null'");
+        }
+        if(lobField.isLobFieldType())
+        {
+            Object result = null;
+            FieldDescriptor fld;
+            Criteria crit = new Criteria();
+            for(int i = 0; i < pkFields.length; i++)
+            {
+                fld = pkFields[i];
+                crit.addEqualTo(fld.getAttributeName(), fld.getPersistentField().get(source));
+            }
+            Query query = QueryFactory.newReportQuery(
+                    source.getClass(), new String[]{lobField.getAttributeName()}, crit, false);
+            Iterator iter = broker.getReportQueryIteratorByQuery(query);
+            while(iter.hasNext())
+            {
+                Object[] arr = (Object[]) iter.next();
+                if(arr.length > 0)
+                {
+                    result = arr[0];
+                    break;
+                }
+            }
+            if(result != null)
+            {
+                if(log.isDebugEnabled())
+                {
+                    log.debug("Refresh LOB field for " + lobField.getClassDescriptor().getClassNameOfObject()
+                            + "." + lobField.getAttributeName());
+                }
+                if(isBlobField(lobField))
+                {
+                    result = new BlobHandle(broker, (Blob) result);
+                }
+                else
+                {
+                    result = new ClobHandle(broker, (Clob) result);
+                }
+            }
+            lobField.getPersistentField().set(source, result);
+        }
+        else
+        {
+            throw new LobException("Specified field isn't of type LOB (Blob or Clob): " + lobField);
+        }
+    }
+
+    /**
+     * Returns <em>true</em> if the specified field is of type LOB (Blob or Clob type)
+     * and wrapped by OJB's LOB wrapper and the LOB wrapper isn't active.
+     */
+    protected boolean needsRefresh(FieldDescriptor field, Object source)
+    {
+        boolean result = field.isLobFieldType();
+        if(result)
+        {
+            Object lob = field.getPersistentField().get(source);
+            if(lob instanceof LobHandle && ((LobHandle) lob).isActive())
+            {
+                // used LOB value doesn't need refresh, it's already bound to a PB instance
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    protected boolean isBlobField(FieldDescriptor fld)
+    {
+        return FieldTypes.BlobFieldType.class.isAssignableFrom(fld.getJdbcType().getFieldType().getClass());
+    }
+
+    public void wrapLobFields(ClassDescriptor cld, Object target)
+    {
+        if(cld.hasLobField())
+        {
+            FieldDescriptor[] fields = cld.getFieldDescriptor(true);
+            for(int i = 0; i < fields.length; i++)
+            {
+                FieldDescriptor field = fields[i];
+                if(field.isLobFieldType())
+                {
+                    Object lob = field.getPersistentField().get(target);
+                    if(lob != null && !(lob instanceof LobHandle))
+                    {
+                        if(isBlobField(field))
+                        {
+                            field.getPersistentField().set(target, new BlobHandle(broker, (Blob) lob));
+                        }
+                        else
+                        {
+                            field.getPersistentField().set(target, new ClobHandle(broker, (Clob) lob));
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

Added: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/LOBTest.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/LOBTest.java?rev=398725&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/LOBTest.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/lob/LOBTest.java Mon May  1 16:10:50 2006
@@ -0,0 +1,765 @@
+package org.apache.ojb.broker.lob;
+
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.io.Writer;
+import java.sql.Blob;
+import java.sql.Clob;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.SerializationUtils;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.platforms.PlatformHsqldbImpl;
+import org.apache.ojb.broker.util.ObjectModification;
+import org.apache.ojb.junit.PBTestCase;
+
+/**
+ * This TestCase tests OJB's handling with LOB's. Persistent objects with BLOB/CLOB and
+ * byte[]/String attributes are used.
+ * Object {@link org.apache.ojb.broker.lob.LOBTest.LobObject} has Blob/Clob fields unlike class
+ * {@link org.apache.ojb.broker.lob.LOBTest.LobObjectExt} which use byte[] and String fields but
+ * BLOB/CLOB columns in database.
+ *
+ * @version $Id: LOBTest.java 365232 2005-12-21 23:36:07 +0100 (Mi, 21 Dez 2005) tomdz $
+ */
+public class LOBTest extends PBTestCase
+{
+    public static void main(String[] args)
+    {
+        String[] arr = {LOBTest.class.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+
+    public LOBTest(String name)
+    {
+        super(name);
+    }
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+    }
+
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+    }
+
+    public void testLobAutoRefresh() throws Exception
+    {
+        int size = 50;
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, new String(carr));
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+        broker.store(obj);
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        broker.serviceLobHelper().setLobAutoRefresh(false);
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+
+        // if no cache is used skip this test
+        if(broker.serviceObjectCache().lookup(oid) == null) return;
+
+        LobObject objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+
+        try
+        {
+            // not valid to access LOB fields
+            objRead.getBlob().length();
+            fail("Expected an LobException");
+        }
+        catch(LobException expected)
+        {
+        }
+
+        broker.serviceLobHelper().refreshLob(objRead);
+        assertEquals(50, objRead.getBlob().length());
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        broker.serviceLobHelper().setLobAutoRefresh(true);
+        oid = broker.serviceIdentity().buildIdentity(obj);
+
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+
+        assertEquals(50, objRead.getBlob().length());
+        broker.commitTransaction();
+    }
+
+    public void testLOBStream() throws Exception
+    {
+        int size = 5000;
+
+        byte[] barr = new byte[size];
+        StringBuffer buf = new StringBuffer();
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            buf.append('y');
+        }
+
+        ByteArrayInputStream in = new ByteArrayInputStream(barr);
+        StringReader reader = new StringReader(buf.toString());
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob(in);
+        Clob c = broker.serviceLobHelper().newClob(reader);
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+
+        broker.store(obj);
+        broker.commitTransaction();
+
+        //broker.clearCache();
+        broker.beginTransaction();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObject objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+        byte[] result_2 = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+        // System.out.println("result: " + result_2.length);
+        assertTrue(ArrayUtils.isEquals(barr, result_2));
+        assertEquals(buf.toString(),
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        objRead.setBlob(null);
+        objRead.setClob(null);
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+        broker.clearCache();
+
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertEquals(null, objRead.getBlob());
+        assertEquals(null, objRead.getClob());
+    }
+
+    public void testLOBUpdateSetBytesSetString() throws Exception
+    {
+        if(getPlatformClass().equals(PlatformHsqldbImpl.class.getName()))
+        {
+            ojbSkipTestMessage("# Skip unsupported operation for platform: " + getPlatformClass() + " #");
+            return;
+        }
+        doUpdate(UpdateSetBytesSetString);
+    }
+
+    public void testLOBUpdateSetBlobSetClob() throws Exception
+    {
+        if(getPlatformClass().equals(PlatformHsqldbImpl.class.getName()))
+        {
+            ojbSkipTestMessage("# Skip unsupported operation for platform: " + getPlatformClass() + " #");
+            return;
+        }
+        doUpdate(UpdateSetBlobSetClob);
+    }
+
+    public void testLOBUpdateSetBinaryStreamSetCharacterStream() throws Exception
+    {
+        if(getPlatformClass().equals(PlatformHsqldbImpl.class.getName()))
+        {
+            ojbSkipTestMessage("# Skip unsupported operation for platform: " + getPlatformClass() + " #");
+            return;
+        }
+        doUpdate(UpdateSetBinaryStreamSetCharacterStream);
+    }
+
+    final int UpdateSetBlobSetClob = 1;
+    final int UpdateSetBytesSetString = 2;
+    final int UpdateSetBinaryStreamSetCharacterStream = 3;
+
+    public void doUpdate(int updateType) throws Exception
+    {
+        int size = 10;
+
+        byte[] barr = new byte[size];
+        String carr = "yyyyyyyyyy";
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+        }
+        byte[] updateByteArr = new byte[]{'u', 'p', 'd', 'a', 't', 'e'};
+        byte[] expectedByte = new byte[]{'u', 'p', 'd', 'a', 't', 'e', 'x', 'x', 'x', 'x'};
+        String updateString = "update";
+        String expectedString = "updateyyyy";
+
+        byte[] updateByteArr2 = new byte[]{'u', 'p', 'd', 'a', 't', 'e', '_', '2'};
+        byte[] expectedByte2 = new byte[]{'u', 'p', 'd', 'a', 't', 'e', '_', '2', 'x', 'x'};
+        String updateString2 = "update_2";
+        String expectedString2 = "update_2yy";
+
+        // insert
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, carr);
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+        broker.store(obj);
+        broker.commitTransaction();
+
+        broker.clearCache();
+        broker.beginTransaction();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObject objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+        byte[] resultArray = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+        assertTrue(ArrayUtils.isEquals(barr, resultArray));
+        assertEquals(carr,
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        // update within PB-tx
+        broker.beginTransaction();
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        try
+        {
+            switch(updateType)
+            {
+                case UpdateSetBinaryStreamSetCharacterStream:
+                    OutputStream out = objRead.getBlob().setBinaryStream(1);
+                    out.write(updateByteArr);
+                    out.flush();
+                    out.close();
+                    Writer writer = objRead.getClob().setCharacterStream(1);
+                    writer.write(updateString);
+                    writer.flush();
+                    writer.close();
+                    break;
+                case UpdateSetBlobSetClob:
+                    Blob blob = broker.serviceLobHelper().newBlob(expectedByte);
+                    Clob clob = broker.serviceLobHelper().newClob(expectedString);
+                    objRead.setBlob(blob);
+                    objRead.setClob(clob);
+                    break;
+                case UpdateSetBytesSetString:
+                    objRead.getBlob().setBytes(1, updateByteArr);
+                    objRead.getClob().setString(1, updateString);
+                    break;
+                default:
+                    throw new RuntimeException("Unkown LOB update type specified");
+            }
+        }
+        catch(UnsupportedOperationException e)
+        {
+            ojbSkipTestMessage("Skip unsupported operation for platform: "
+                    + getPlatformClass() + ", message: " + e.getMessage());
+            return;
+        }
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        oid = broker.serviceIdentity().buildIdentity(obj);
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        resultArray = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+//        System.out.println("");
+//        System.out.println("# exp: " + ArrayUtils.toString(expectedByte));
+//        System.out.println("# get: " + ArrayUtils.toString(resultArray));
+//        System.out.println("# set: " + updateString);
+//        System.out.println("# get: " + objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        assertTrue(ArrayUtils.isEquals(expectedByte, resultArray));
+        assertEquals(expectedString,
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        // try update 2
+        broker.beginTransaction();
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        try
+        {
+            switch(updateType)
+            {
+                case UpdateSetBinaryStreamSetCharacterStream:
+                    OutputStream out = objRead.getBlob().setBinaryStream(1);
+                    out.write(updateByteArr2);
+                    out.flush();
+                    out.close();
+                    Writer writer = objRead.getClob().setCharacterStream(1);
+                    writer.write(updateString2);
+                    writer.flush();
+                    writer.close();
+                    break;
+                case UpdateSetBlobSetClob:
+                    Blob blob = broker.serviceLobHelper().newBlob(expectedByte2);
+                    Clob clob = broker.serviceLobHelper().newClob(expectedString2);
+                    objRead.setBlob(blob);
+                    objRead.setClob(clob);
+                    break;
+                case UpdateSetBytesSetString:
+                    objRead.getBlob().setBytes(1, updateByteArr2);
+                    objRead.getClob().setString(1, updateString2);
+                    break;
+                default:
+                    throw new RuntimeException("Unkown LOB update type specified");
+            }
+        }
+        catch(UnsupportedOperationException e)
+        {
+            ojbSkipTestMessage("# Skip unsupported operation for platform: " + getPlatformClass() + ", message: " + e.getMessage() + " #");
+            return;
+        }
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        oid = broker.serviceIdentity().buildIdentity(obj);
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        resultArray = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+        assertTrue(ArrayUtils.isEquals(expectedByte2, resultArray));
+        assertEquals(expectedString2,
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        objRead.setBlob(null);
+        objRead.setClob(null);
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertEquals(null, objRead.getBlob());
+        assertEquals(null, objRead.getClob());
+    }
+
+
+    public void testLOBInsertRead() throws Exception
+    {
+        int size = 5000;
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, new String(carr));
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+
+        broker.store(obj);
+        broker.commitTransaction();
+
+        //broker.clearCache();
+        broker.beginTransaction();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObject objRead = (LobObject) broker.getObjectByIdentity(oid);
+        broker.serviceLobHelper().refreshLob(objRead);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+        byte[] result_2 = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+        assertTrue(ArrayUtils.isEquals(barr, result_2));
+        assertEquals(new String(carr),
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        objRead.setBlob(null);
+        objRead.setClob(null);
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+        broker.clearCache();
+
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertEquals(null, objRead.getBlob());
+        assertEquals(null, objRead.getClob());
+    }
+
+    public void testLOBDelete() throws Exception
+    {
+        int size = 5000;
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, new String(carr));
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+
+        broker.store(obj);
+        broker.commitTransaction();
+
+        broker.clearCache();
+        broker.beginTransaction();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObject objRead = (LobObject) broker.getObjectByIdentity(oid);
+        //LOBHelper.refreshLob( objRead);
+        assertNotNull("BLOB was not stored", objRead.getBlob());
+        assertNotNull("CLOB was not stored", objRead.getClob());
+        byte[] result_2 = objRead.getBlob().getBytes(1, (int) objRead.getBlob().length());
+        assertTrue(ArrayUtils.isEquals(barr, result_2));
+        assertEquals(new String(carr),
+                objRead.getClob().getSubString(1, (int) objRead.getClob().length()));
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        broker.delete(objRead);
+        broker.commitTransaction();
+
+        objRead = (LobObject) broker.getObjectByIdentity(oid);
+        assertNull(objRead);
+    }
+
+    public void testLOBFail_1() throws Exception
+    {
+        int size = 5;
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, new String(carr));
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+        broker.store(obj);
+        broker.commitTransaction();
+
+        broker.beginTransaction();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        // if object was in cache, we have to refresh the LOB fields
+        LobObject source = (LobObject) broker.serviceObjectCache().lookup(oid);
+        if(source != null)
+        {
+            try
+            {
+                source.getBlob().length();
+                fail("LobException expected");
+            }
+            catch(LobException expected)
+            {
+            }
+
+            broker.serviceLobHelper().refreshLob(source);
+            assertEquals(5, source.getBlob().length());
+            assertEquals(5, source.getClob().length());
+        }
+        broker.commitTransaction();
+    }
+
+    public void testLOBFail_2() throws Exception
+    {
+        int size = 5;
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        broker.beginTransaction();
+        Blob b = broker.serviceLobHelper().newBlob();
+        b.setBytes(1, barr);
+        Clob c = broker.serviceLobHelper().newClob();
+        c.setString(1, new String(carr));
+        LobObject obj = new LobObject();
+        obj.setBlob(b);
+        obj.setClob(c);
+        broker.store(obj);
+        broker.commitTransaction();
+
+        broker.clearCache();
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObject source = (LobObject) broker.getObjectByIdentity(oid);
+        try
+        {
+            source.getBlob().length();
+            fail("LobException expected");
+        }
+        catch(LobException expected)
+        {
+        }
+        broker.beginTransaction();
+        broker.serviceLobHelper().refreshLob(source);
+        assertEquals(5, source.getBlob().length());
+        broker.commitTransaction();
+    }
+
+
+    public void testByteArrayStringInsertRead() throws Exception
+    {
+        int size = 5000;
+
+        LobObjectExt obj = new LobObjectExt();
+
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        // obj.setId(1); we use autoincrement
+        obj.setBlobArray(barr);
+        obj.setClobString(new String(carr));
+        broker.beginTransaction();
+        broker.store(obj);
+        broker.commitTransaction();
+        broker.clearCache();
+
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObjectExt objRead = (LobObjectExt) broker.getObjectByIdentity(oid);
+        assertNotNull("BLOB was not stored", objRead.getBlobArray());
+        assertNotNull("CLOB was not stored", objRead.getClobString());
+        assertEquals(obj.getBlobArray().length, objRead.getBlobArray().length);
+        assertEquals(obj.getClobString().length(), objRead.getClobString().length());
+
+        broker.beginTransaction();
+        objRead.setBlobArray(null);
+        objRead.setClobString(null);
+        broker.store(objRead, ObjectModification.UPDATE);
+        broker.commitTransaction();
+        broker.clearCache();
+
+        objRead = (LobObjectExt) broker.getObjectByIdentity(oid);
+        assertEquals(null, objRead.getBlobArray());
+        assertEquals(null, objRead.getClobString());
+    }
+
+    public void testByteArrayStringDelete() throws Exception
+    {
+        int size = 5000;
+        LobObjectExt obj = new LobObjectExt();
+        byte[] barr = new byte[size];
+        char[] carr = new char[size];
+        for(int i = 0; i < size; i++)
+        {
+            barr[i] = (byte) 'x';
+            carr[i] = 'y';
+        }
+
+        // obj.setId(1); we use autoincrement
+        obj.setBlobArray(barr);
+        obj.setClobString(new String(carr));
+        broker.beginTransaction();
+        broker.store(obj);
+        broker.commitTransaction();
+        broker.clearCache();
+
+        Identity oid = broker.serviceIdentity().buildIdentity(obj);
+        LobObjectExt objRead = (LobObjectExt) broker.getObjectByIdentity(oid);
+        assertNotNull("BLOB was not stored", objRead.getBlobArray());
+        assertNotNull("CLOB was not stored", objRead.getClobString());
+        assertEquals(obj.getBlobArray().length, objRead.getBlobArray().length);
+        assertEquals(obj.getClobString().length(), objRead.getClobString().length());
+
+        broker.beginTransaction();
+        broker.delete(objRead);
+        broker.commitTransaction();
+
+        objRead = (LobObjectExt) broker.getObjectByIdentity(oid);
+        assertNull(objRead);
+    }
+
+    public void testLOBImplementations_1() throws Exception
+    {
+        byte[] b = new byte[]{'a', 'b', 'c', 'd', 'e'};
+        String c = "abcdefgh";
+        BlobImpl blob = new BlobImpl();
+        ClobImpl clob = new ClobImpl();
+
+        blob.setBytes(1, b);
+        clob.setString(1, c);
+
+        BlobImpl blob2 = (BlobImpl) SerializationUtils.clone(blob);
+        ClobImpl clob2 = (ClobImpl) SerializationUtils.clone(clob);
+
+        assertTrue(ArrayUtils.isEquals(blob.getBytes(), blob2.getBytes()));
+        assertTrue(ArrayUtils.isEquals(b, blob2.getBytes()));
+        assertEquals(clob.getSubString(1, (int) clob.length()), clob2.getSubString(1, (int) clob2.length()));
+        assertEquals(c, clob2.getSubString(1, (int) clob2.length()));
+    }
+
+    public void testLOBImplementations_2() throws Exception
+    {
+        byte[] b = new byte[]{'a', 'b', 'c', 'd', 'e'};
+        String c = "abcdefgh";
+        BlobImpl blob = new BlobImpl();
+        ClobImpl clob = new ClobImpl();
+
+        OutputStream out = blob.setBinaryStream(1);
+        out.write(b);
+        out.close();
+        Writer writer = clob.setCharacterStream(1);
+        writer.write(c);
+        writer.close();
+
+        BlobImpl blob2 = (BlobImpl) SerializationUtils.clone(blob);
+        ClobImpl clob2 = (ClobImpl) SerializationUtils.clone(clob);
+
+//        System.out.println("# old: " + ArrayUtils.toString(blob2.getBytes()));
+//        System.out.println("# old: " + clob2.getSubString(1, (int) clob2.length()));
+        assertTrue(ArrayUtils.isEquals(blob.getBytes(), blob2.getBytes()));
+        assertTrue(ArrayUtils.isEquals(b, blob2.getBytes()));
+        assertEquals(clob.getSubString(1, (int) clob.length()), clob2.getSubString(1, (int) clob2.length()));
+        assertEquals(c, clob2.getSubString(1, (int) clob2.length()));
+
+        blob2.setBytes(3, new byte[]{'C', 'D'});
+        clob2.setString(3, "CD");
+//        System.out.println("# new: " + ArrayUtils.toString(blob2.getBytes()));
+//        System.out.println("# new: " + ArrayUtils.toString(clob2.getSubString(1, (int) clob2.length())));
+        assertTrue(ArrayUtils.isEquals(new byte[]{'a', 'b', 'C', 'D', 'e'}, blob2.getBytes()));
+        assertEquals("abCDefgh", clob2.getSubString(1, (int) clob2.length()));
+    }
+
+
+    //*******************************************************
+    // inner class - test class
+    //*******************************************************
+    public static class LobObject implements Serializable
+    {
+        private int id;
+        private Blob blob;
+        private Clob clob;
+
+        public LobObject()
+        {
+        }
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId(int id)
+        {
+            this.id = id;
+        }
+
+        public Blob getBlob()
+        {
+            return blob;
+        }
+
+        public void setBlob(Blob blob)
+        {
+            this.blob = blob;
+        }
+
+        public Clob getClob()
+        {
+            return clob;
+        }
+
+        public void setClob(Clob clob)
+        {
+            this.clob = clob;
+        }
+    }
+
+    public static class LobObjectExt implements Serializable
+    {
+        private int id;
+        private byte[] blobArray;
+        private String clobString;
+
+        public LobObjectExt()
+        {
+        }
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId(int id)
+        {
+            this.id = id;
+        }
+
+        public byte[] getBlobArray()
+        {
+            return blobArray;
+        }
+
+        public void setBlobArray(byte[] blobArray)
+        {
+            this.blobArray = blobArray;
+        }
+
+        public String getClobString()
+        {
+            return clobString;
+        }
+
+        public void setClobString(String clobString)
+        {
+            this.clobString = clobString;
+        }
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message