Hi,
I just attached two abstract classes that can are useful as base classes
for type drivers, and a sample implementation that serves a PGobject
implementation.
During hacking, I noticed that adding a "String sqltype" parameter to
the get* methods would help for complete type orthogonality (this way a
single Driver could handle all PGobjects, and possibly a second one all
the typeMap / SQLData issues).
Markus
/*
* AbstractTextBinaryTypeDriver.java
*
* (C) 28.02.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
*
* $Id: $
*/
package org.postgresql.types;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
/** Should serve as a convenience base class for most TypeDrivers */
public abstract class AbstractTextBinaryTypeDriver extends AbstractTextTypeDriver
implements
TypeBinaryReader,
TypeBinaryWriter {
public boolean supportsBinaryWrite() {
return true;
}
public boolean supportsBinaryReading() {
return true;
}
// *** TypeBinaryReader methods ***
public String getString(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public boolean getBoolean(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public byte getByte(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public short getShort(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public int getInt(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public long getLong(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public float getFloat(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public double getDouble(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public BigDecimal getBigDecimal(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public byte[] getBytes(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Date getDate(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Date getDate(byte[] data, int start, int length, Calendar cal) throws SQLException {
throw new SQLException("Unknown type!");
}
public Time getTime(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Time getTime(byte[] data, int start, int length, Calendar cal) throws SQLException {
throw new SQLException("Unknown type!");
}
public Timestamp getTimestamp(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Timestamp getTimestamp(byte[] data, int start, int length, Calendar cal)
throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getAsciiStream(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getUnicodeStream(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getBinaryStream(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Object getObject(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public Reader getCharacterStream(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
public URL getURL(byte[] data, int start, int length) throws SQLException {
throw new SQLException("Unknown type!");
}
// *** TypeBinaryWriter Methods ***
public abstract int objectBytesLength(Object data) throws SQLException;
public abstract void renderObject(Object data, byte[] target, int startindex);
public void renderObject(Object data, OutputStream outstream) throws SQLException, IOException {
byte[] temp = new byte[objectBytesLength(data)];
renderObject(data, temp, 0);
outstream.write(temp);
}
}
/*
* AbstractTextBinaryTypeDriver.java
*
* (C) 28.02.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
*
* $Id: $
*/
package org.postgresql.types;
import org.postgresql.PGConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
/** Should serve as a convenience base class for most TypeDrivers */
public abstract class AbstractTextTypeDriver implements TypeTextReader, TypeTextWriter, TypeDriver {
public static final Class[] EMPTY_CLASSES = new Class[0];
public static final String[] EMPTY_TYPES = new String[0];
protected Class[] supportedClasses = EMPTY_CLASSES;
protected String[] supportedTypes = EMPTY_TYPES;
// *** TypeDriver methods ***
public Class[] getSupportedClasses() {
return supportedClasses;
}
public String[] getSupportedTypes() {
return supportedTypes;
}
public boolean supports(String type) {
for (int i = 0; i < supportedTypes.length; i++) {
if (supportedTypes[i].equals(type)) {
return true;
}
}
return false;
}
public boolean supports(Class klass) {
for (int i = 0; i < supportedClasses.length; i++) {
if (supportedClasses[i].isAssignableFrom(klass)) {
return true;
}
}
return false;
}
public abstract String sqlType(Object data) throws SQLException;
public boolean supportsBinaryWrite() {
return false;
}
public boolean supportsTextWrite() {
return true;
}
public boolean supportsBinaryReading() {
return false;
}
public boolean supportsTextReading() {
return true;
}
public TypeDriver forConnection(PGConnection conn) {
return this;
}
// *** TypeTextReader Methods
public String getString(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public boolean getBoolean(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public byte getByte(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public short getShort(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public int getInt(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public long getLong(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public float getFloat(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public double getDouble(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public BigDecimal getBigDecimal(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public byte[] getBytes(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Date getDate(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Date getDate(String data, Calendar cal) throws SQLException {
throw new SQLException("Unknown type!");
}
public Time getTime(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Time getTime(String data, Calendar cal) throws SQLException {
throw new SQLException("Unknown type!");
}
public Timestamp getTimestamp(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Timestamp getTimestamp(String data, Calendar cal) throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getAsciiStream(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getUnicodeStream(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public InputStream getBinaryStream(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Object getObject(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public Reader getCharacterStream(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
public URL getURL(String data) throws SQLException {
throw new SQLException("Unknown type!");
}
// *** TypeTextWriter Methods ***
public abstract int objectCharLength(Object data) throws SQLException;
public abstract String renderObject(Object data);
public void renderObject(Object data, StringBuffer sb) {
sb.append(renderObject(data));
}
public void renderObject(Object data, char[] target, int startindex) {
String rep = renderObject(data);
for (int i = 0; i < rep.length(); i++) {
target[i + startindex] = rep.charAt(i);
}
}
public void renderObject(Object data, Writer target) throws IOException {
target.write(renderObject(data));
}
}
/*
* PGobjectHandler.java
*
* (C) 28.02.2005 Markus Schaber, Logi-Track ag, CH 8001 Zuerich
*
* $Id: $
*/
package org.postgresql.types;
import org.postgresql.util.PGobject;
import java.io.IOException;
import java.io.Writer;
import java.sql.SQLException;
public class PGobjectHandler extends AbstractTextTypeDriver {
public PGobjectHandler(String sqltype, Class klass) {
this.supportedClasses = new Class[]{klass};
this.supportedTypes = new String[]{sqltype};
}
public String sqlType(Object data) throws SQLException {
PGobject po = (PGobject) data;
return po.getType();
}
public int objectCharLength(Object data) throws SQLException {
PGobject po = (PGobject) data;
return po.getValue().length();
}
public String renderObject(Object data) {
PGobject po = (PGobject) data;
return po.getValue();
}
public String getString(String data) throws SQLException {
return data;
}
public Object getObject(String data) throws SQLException {
PGobject po;
try {
po = (PGobject) supportedClasses[0].newInstance();
} catch (InstantiationException e) {
throw new SQLException("Cannot create PGObject instance " + e.getMessage());
} catch (IllegalAccessException e) {
throw new SQLException("Cannot create PGObject instance " + e.getMessage());
}
po.setValue(data);
return po;
}
public void renderObject(Object data, StringBuffer sb) {
sb.append(renderObject(data));
}
public void renderObject(Object data, char[] target, int startindex) {
String rep = renderObject(data);
for (int i = 0; i < rep.length(); i++) {
target[i + startindex] = rep.charAt(i);
}
}
public void renderObject(Object data, Writer target) throws IOException {
target.write(renderObject(data));
}
}