You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/07/15 16:06:38 UTC
svn commit: r422223 - in /db/ojb/trunk/src/java/org/apache/ojb/broker/lob:
./ BlobHandle.java BlobImpl.java ClobHandle.java ClobImpl.java
InactiveLobException.java Lob.java LobException.java LobHandle.java
LobHelper.java LobHelperImpl.java
Author: arminw
Date: Sat Jul 15 07:06:37 2006
New Revision: 422223
URL: http://svn.apache.org/viewvc?rev=422223&view=rev
Log:
merge trunk with 1.0.x, lob support
Added:
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobHandle.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobHandle.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/InactiveLobException.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/Lob.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobException.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHandle.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelper.java
db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java
Added: db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobHandle.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobHandle.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobHandle.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobHandle.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,125 @@
+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.PersistenceBrokerInternal;
+
+/**
+ * This class is a wrapper for {@link java.sql.Blob} objects.
+ *
+ * @version $Id$
+ */
+public class BlobHandle extends LobHandle implements Blob
+{
+ /**
+ * NB: update serialVersionUID when making class incompatible with serialized data!
+ */
+ private static final long serialVersionUID = 1L;
+
+ BlobHandle(PersistenceBrokerInternal broker, Blob blob)
+ {
+ super(broker, blob);
+ }
+
+ private BlobHandle()
+ {
+ super();
+ }
+
+ public LobHandle decoupledCopy()
+ {
+ return new BlobHandle();
+ }
+
+ /**
+ * Returns the innermost {@link java.sql.Blob} instance.
+ *
+ * @return The innermost wrapped LOB instance.
+ */
+ public Blob getBlob()
+ {
+ Blob result = (Blob) getLocator(false);
+ if(result instanceof BlobHandle)
+ {
+ result = ((BlobHandle) result).getBlob();
+ }
+ return result;
+ }
+
+ private Blob getLocalBlob()
+ {
+ return (Blob) getLocator(true);
+ }
+
+ public long length() throws SQLException
+ {
+ return getLocalBlob().length();
+ }
+
+ public byte[] getBytes(long pos, int length) throws SQLException
+ {
+ return getLocalBlob().getBytes(pos, length);
+ }
+
+ public long position(byte pattern[], long start) throws SQLException
+ {
+ return getLocalBlob().position(pattern, start);
+ }
+
+ public InputStream getBinaryStream() throws SQLException
+ {
+ return getLocalBlob().getBinaryStream();
+ }
+
+ public long position(Blob pattern, long start) throws SQLException
+ {
+ return getLocalBlob().position(pattern, start);
+ }
+
+//#ifdef JDBC30
+
+ public OutputStream setBinaryStream(long pos) throws SQLException
+ {
+ markDirty();
+ return getLocalBlob().setBinaryStream(pos);
+ }
+
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException
+ {
+ markDirty();
+ return getLocalBlob().setBytes(pos, bytes, offset, len);
+ }
+
+ public int setBytes(long pos, byte[] bytes) throws SQLException
+ {
+ markDirty();
+ return getLocalBlob().setBytes(pos, bytes);
+ }
+
+ public void truncate(long len) throws SQLException
+ {
+ markDirty();
+ getLocalBlob().truncate(len);
+ }
+
+//#endif
+
+}
Added: db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobImpl.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobImpl.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/BlobImpl.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,185 @@
+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, Serializable, Lob
+{
+ /**
+ * NB: update serialVersionUID when making class incompatible with serialized data!
+ */
+ private static final long serialVersionUID = 1L;
+ 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/trunk/src/java/org/apache/ojb/broker/lob/ClobHandle.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobHandle.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobHandle.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobHandle.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,137 @@
+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.PersistenceBrokerInternal;
+
+/**
+ * This class is a wrapper for {@link java.sql.Clob} objects.
+ *
+ * @version $Id$
+ */
+public class ClobHandle extends LobHandle implements Clob
+{
+ /**
+ * NB: update serialVersionUID when making class incompatible with serialized data!
+ */
+ private static final long serialVersionUID = 1L;
+ ClobHandle(PersistenceBrokerInternal broker, Clob clob)
+ {
+ super(broker, clob);
+ }
+
+ private ClobHandle()
+ {
+ super();
+ }
+
+ public LobHandle decoupledCopy()
+ {
+ return new ClobHandle();
+ }
+
+ /**
+ * Returns the innermost {@link java.sql.Clob} instance.
+ *
+ * @return The innermost wrapped LOB instance.
+ */
+ public Clob getClob()
+ {
+ Clob result = (Clob) getLocator(false);
+ if(result instanceof ClobHandle)
+ {
+ result = ((ClobHandle) result).getClob();
+ }
+ return result;
+ }
+
+ private Clob getLocalClob()
+ {
+ return (Clob) getLocator(true);
+ }
+
+ public long length() throws SQLException
+ {
+ return getLocalClob().length();
+ }
+
+ public InputStream getAsciiStream() throws SQLException
+ {
+ return getLocalClob().getAsciiStream();
+ }
+
+ public Reader getCharacterStream() throws SQLException
+ {
+ return getLocalClob().getCharacterStream();
+ }
+
+ public String getSubString(long pos, int length) throws SQLException
+ {
+ return getLocalClob().getSubString(pos, length);
+ }
+
+ public long position(String searchstr, long start) throws SQLException
+ {
+ return getLocalClob().position(searchstr, start);
+ }
+
+ public long position(Clob searchstr, long start) throws SQLException
+ {
+ return getLocalClob().position(searchstr, start);
+ }
+
+//#ifdef JDBC30
+
+ public int setString(long pos, String str) throws SQLException
+ {
+ markDirty();
+ return getLocalClob().setString(pos, str);
+ }
+
+ public int setString(long pos, String str, int offset, int len) throws SQLException
+ {
+ markDirty();
+ return getLocalClob().setString(pos, str, offset, len);
+ }
+
+ public Writer setCharacterStream(long pos) throws SQLException
+ {
+ markDirty();
+ return getLocalClob().setCharacterStream(pos);
+ }
+
+ public OutputStream setAsciiStream(long pos) throws SQLException
+ {
+ markDirty();
+ return getLocalClob().setAsciiStream(pos);
+ }
+
+ public void truncate(long len) throws SQLException
+ {
+ markDirty();
+ getLocalClob().truncate(len);
+ }
+
+//#endif
+
+}
Added: db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobImpl.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobImpl.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/ClobImpl.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,189 @@
+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
+{
+ /**
+ * NB: update serialVersionUID when making class incompatible with serialized data!
+ */
+ private static final long serialVersionUID = 1L;
+ 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().toString().indexOf(searchstr, (int) --start);
+ }
+
+ public long position(Clob searchstr, long start) throws SQLException
+ {
+ checkMethod();
+ return getWriter().getBuffer().toString().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/trunk/src/java/org/apache/ojb/broker/lob/InactiveLobException.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/InactiveLobException.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/InactiveLobException.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/InactiveLobException.java Sat Jul 15 07:06:37 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/trunk/src/java/org/apache/ojb/broker/lob/Lob.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/Lob.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/Lob.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/Lob.java Sat Jul 15 07:06:37 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's LOB object implementations.
+ *
+ * @version $Id: $
+ */
+public interface Lob
+{
+}
Added: db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobException.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobException.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobException.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobException.java Sat Jul 15 07:06:37 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/trunk/src/java/org/apache/ojb/broker/lob/LobHandle.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHandle.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHandle.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHandle.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,213 @@
+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.Serializable;
+
+import org.apache.ojb.broker.PBStateEvent;
+import org.apache.ojb.broker.PBStateListener;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+
+/**
+ * Base class for OJB LOB-object wrapper classes like Blob, Clob
+ * but also all other locator based advanced jdbc data types.
+ *
+ * @version $Id: $
+ */
+abstract public class LobHandle implements PBStateListener, Serializable
+{
+ private boolean active;
+ private boolean isTransient;
+ private transient Object locator;
+ private boolean dirty;
+
+ protected LobHandle()
+ {
+
+ }
+
+ LobHandle(PersistenceBrokerInternal broker, Object locator)
+ {
+ if(locator == null)
+ {
+ throw new NullPointerException("The locator object may not be 'null'");
+ }
+ this.locator = locator;
+ isTransient = false;
+ active = broker.isInTransaction();
+ if(locator instanceof Lob)
+ {
+ isTransient = true;
+ markDirty();
+ }
+ if(active)
+ {
+ broker.addListener(this, false);
+ }
+ }
+
+ /**
+ * Returns a <em>deactivated, decoupled</em> locator copy
+ * of this instance.
+ *
+ * @return A decoupled locator wrapper instance copy of this locator.
+ */
+ abstract public LobHandle decoupledCopy();
+
+ /**
+ * Returns <em>true</em> if the locator object was manipulated.
+ *
+ * @return If the locator object was modified <em>true</em> is returned, else <em>false</em>.
+ */
+ public boolean isDirty()
+ {
+ return dirty && this.locator != null;
+ }
+
+ /**
+ * Set the state of this locator.
+ *
+ * @param dirty The state flag of this locator.
+ */
+ public void setDirty(boolean dirty)
+ {
+ this.dirty = dirty;
+ }
+
+ /**
+ * Mark this locator as dirty.
+ */
+ protected void markDirty()
+ {
+ setDirty(true);
+ }
+
+ /**
+ * Return the locator object.
+ *
+ * @param check If <em>true</em> a validation check is done, else simply the locator is returned.
+ * @return The locator object.
+ */
+ protected Object getLocator(boolean check)
+ {
+ if(check) checkActive();
+ return locator;
+ }
+
+ /**
+ * Returns <em>true</em> if the wrapped locator object is
+ * a ojb specific {@link Lob} implementation (and not a database specific
+ * locator object of a column entry). Else <em>false</em> is returned.
+ */
+ public boolean isTransient()
+ {
+ return isTransient;
+ }
+
+// protected void setTransient(boolean aTransient)
+// {
+// isTransient = aTransient;
+// }
+
+ protected void txFail()
+ {
+ this.active = false;
+ if(!isTransient()) this.locator = null;
+ }
+
+ protected void txSuccess()
+ {
+ this.active = false;
+ this.isTransient = false;
+ this.dirty = false;
+ this.locator = null;
+ }
+
+ /**
+ * Called to decouple this LOB object from
+ * a associated {@link org.apache.ojb.broker.PersistenceBroker} instance.
+ */
+ protected void decouple()
+ {
+ this.active = false;
+ if(!isTransient())
+ {
+ this.dirty = false;
+ this.locator = null;
+ }
+ }
+
+ /**
+ * Returns <em>true</em> if this LOB object is associated
+ * with a {@link org.apache.ojb.broker.PersistenceBroker} instance.
+ */
+ protected boolean isCoupled()
+ {
+ return this.active;
+ }
+
+ public void checkActive()
+ {
+ if(!(isTransient() || isCoupled())) throw new InactiveLobException(
+ "Current LOB is not valid for access (no active PB-tx or PB-tx changed), "
+ + "refresh the persistent object LOB content after PB-tx starts");
+ }
+
+ public boolean isActive()
+ {
+ return isTransient() || isCoupled();
+ }
+
+
+ //===================================================================
+ // Listener methods
+ //===================================================================
+ public void beforeClose(PBStateEvent event)
+ {
+ decouple();
+ }
+
+ 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/trunk/src/java/org/apache/ojb/broker/lob/LobHelper.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelper.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelper.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelper.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,202 @@
+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;
+import org.apache.ojb.broker.metadata.FieldDescriptor;
+
+/**
+ * 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 <em>true</em> 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
+ * internal with OJB specific wrapper classes</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/>
+ * Wrap the specified LOB value ({@link java.sql.Blob} and {@link java.sql.Clob}
+ * instances returned by the database) with OJB specific LOB-wrapper class.
+ *
+ * @param fld The field of the specified value.
+ * @param value The LOB content value of the field.
+ * @return The wrapped LOB content.
+ */
+ public Object wrapLobField(FieldDescriptor fld, Object value);
+
+// /**
+// * 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/trunk/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java?rev=422223&view=auto
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java (added)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/lob/LobHelperImpl.java Sat Jul 15 07:06:37 2006
@@ -0,0 +1,258 @@
+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(cld.hasLobField())
+ {
+ if(broker.isInTransaction())
+ {
+ 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))
+ {
+ performRefreshLob(field, target, pkFields);
+ }
+ }
+ }
+ else
+ {
+ if(log.isDebugEnabled())
+ {
+ log.debug("No active transaction, can't refresh LOB-content for object " + target);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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 performRefreshLob(FieldDescriptor lobField, Object source, FieldDescriptor[] pkFields)
+ {
+ if(source == null)
+ {
+ throw new NullPointerException("Persistence capable object instance 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).isCoupled())
+ {
+ // 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));
+// }
+// }
+// }
+// }
+// }
+// }
+
+ public Object wrapLobField(FieldDescriptor fld, Object value)
+ {
+ if(value != null && !(value instanceof LobHandle))
+ {
+ if(isBlobField(fld))
+ {
+ return new BlobHandle(broker, (Blob) value);
+ }
+ else
+ {
+ return new ClobHandle(broker, (Clob) value);
+ }
+ }
+ return value;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org