/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://eng.tada.se/osprojects/COPYRIGHT.html */ package org.postgresql.pljava.internal; import java.sql.SQLException; import java.util.HashMap; /** * The <code>Oid</code> correspons to the internal PostgreSQL <code>Oid</code>. * Should the size of that change from 32 bit, this class must change too. * In Java, the InvalidOid is represented as <code>null</code>. * * @author Thomas Hallgren */ public class Oid extends Number { private static final HashMap s_class2typeId = new HashMap(); private static final HashMap s_typeId2class = new HashMap(); /** * Finds the PostgreSQL well known Oid for the given class. * @param clazz The class. * @return The well known Oid or null if no such Oid could be found. */ public static Oid forJavaClass(Class clazz) { return (Oid)s_class2typeId.get(clazz); } /** * Finds the PostgreSQL well known Oid for a type name. * @param typeString The name of the type, optionally qualified with a namespace. * @return The well known Oid. * @throws SQLException if the type could not be found */ public static Oid forTypeName(String typeString) throws SQLException { synchronized(Backend.THREADLOCK) { return new Oid(_forTypeName(typeString)); } } /** * Finds the PostgreSQL well known Oid for the XOPEN Sql type. * @param sqlType The XOPEN type code. * @throws SQLException if the type could not be found */ public static Oid forSqlType(int sqlType) throws SQLException { synchronized(Backend.THREADLOCK) { return new Oid(_forSqlType(sqlType)); } } /** * Returns the PostgreSQL type id for the Oid type. */ public static Oid getTypeId() { synchronized(Backend.THREADLOCK) { return _getTypeId(); } } /** * A Type well known to PostgreSQL but not known as a standard XOPEN * SQL type can be registered here. This includes types like the Oid * itself and all the geometry related types. * @param clazz The Java class that corresponds to the type id. * @param typeId The well known type id. */ public static void registerType(Class clazz, Oid typeId) { s_class2typeId.put(clazz, typeId); if(!s_typeId2class.containsKey(typeId)) s_typeId2class.put(typeId, clazz); } /* * The native Oid represented as a 32 bit quantity. * See definition in file "include/postgres_ext" of the * PostgreSQL distribution. */ private final int m_native; public Oid(int value) { m_native = value; } public double doubleValue() { return m_native; } /** * Checks to see if the other object is an <code>Oid</code>, and if so, * if the native value of that <code>Oid</code> equals the native value * of this <code>Oid</code>. * @return true if the objects are equal. */ public boolean equals(Object o) { return (o == this) || ((o instanceof Oid) && ((Oid)o).m_native == m_native); } public float floatValue() { return m_native; } public Class getJavaClass() throws SQLException { Class c = (Class)s_typeId2class.get(this); if(c == null) { String className; synchronized(Backend.THREADLOCK) { className = _getJavaClassName(m_native); } try { c = Class.forName(getCanonicalClassName(className, 0)); } catch(ClassNotFoundException e) { throw new SQLException(e.getMessage()); } s_typeId2class.put(this, c); s_class2typeId.put(c, this); } return c; } /** * The native value is used as the hash code. * @return The hashCode for this <code>Oid</code>. */ public int hashCode() { return m_native; } public int intValue() { return m_native; } public long longValue() { return m_native; } /** * Returns a string representation of this OID. */ public String toString() { return "OID(" + m_native + ')'; } private static String getCanonicalClassName(String name, int nDims) { if(name.endsWith("[]")) return getCanonicalClassName(name.substring(0, name.length() - 2), nDims + 1); boolean primitive = true; if(name.equals("boolean")) name = "Z"; else if(name.equals("byte")) name = "B"; else if(name.equals("char")) name = "C"; else if(name.equals("double")) name = "D"; else if(name.equals("float")) name = "F"; else if(name.equals("int")) name = "I"; else if(name.equals("long")) name = "J"; else if(name.equals("short")) name = "S"; else primitive = false; if(nDims > 0) { StringBuffer bld = new StringBuffer(); while(--nDims >= 0) bld.append('['); if(primitive) bld.append(name); else { bld.append('L'); bld.append(name); bld.append(';'); } name = bld.toString(); } return name; } private native static int _forTypeName(String typeString) throws SQLException; private native static int _forSqlType(int sqlType) throws SQLException; private native static Oid _getTypeId(); private native static String _getJavaClassName(int nativeOid) throws SQLException; }