/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Rodrigo Westrupp
*/
package com.caucho.quercus.lib.db;
import com.caucho.quercus.annotation.ReturnNullAsFalse;
import com.caucho.quercus.env.BooleanValue;
import com.caucho.quercus.env.Env;
import com.caucho.quercus.env.LongValue;
import com.caucho.quercus.env.Value;
import com.caucho.util.L10N;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.sql.Array;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Quercus Oracle OCI-Collection object oriented API.
*/
public class OracleOciCollection {
private static final Logger log = Logger.getLogger(
OracleOciCollection.class.getName());
private static final L10N L = new L10N(OracleOciCollection.class);
// The Oracle array descriptor
private Object _arrayDescriptor;
// The Oracle collection
private Array _collection;
// The cached Java collection
private ArrayList _javaCollection;
// The Oracle JDBC connection
private Connection _jdbcConn;
// Cache class oracle.sql.ARRAY
private static Class classOracleARRAY;
static {
try {
classOracleARRAY = Class.forName("oracle.sql.ARRAY");
} catch (Exception e) {
L.l("Unable to load ARRAY class oracle.sql.ARRAY.");
}
}
/**
* Constructor for OracleOciCollection
*/
OracleOciCollection(Connection jdbcConn,
Object arrayDescriptor)
{
_jdbcConn = jdbcConn;
_arrayDescriptor = arrayDescriptor;
_collection = null;
_javaCollection = new ArrayList();
}
/**
* Appends element to the collection
*
* @param value can be a string or a number
*/
public boolean append(Env env,
Value value)
{
try {
_javaCollection.add(value.toJavaObject());
return true;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return false;
}
}
/**
* Assigns a value to the collection from another existing collection
*/
public boolean assign(Env env,
OracleOciCollection fromCollection)
{
try {
_javaCollection.addAll(fromCollection.getJavaCollection());
return true;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return false;
}
}
/**
* Assigns a value to the element of the collection
*
* @param index 1-based index
* @param value can be a string or a number
*/
public boolean assignElem(Env env,
int index,
Value value)
{
try {
if ((index < 1) || (index > _javaCollection.size())) {
return false;
}
_javaCollection.set(index - 1, value.toJavaObject());
return true;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return false;
}
}
/**
* Frees the resources associated with the collection object
*/
public boolean free(Env env)
{
try {
_collection = null;
_javaCollection = null;
return true;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return false;
}
}
/**
* Returns the underlying Oracle collection
*/
protected Array getCollection()
{
try {
// oracle.sql.ARRAY array = new oracle.sql.ARRAY(
// arrayDesc, jdbcConn, arrayValues);
Class clArrayDescriptor = Class.forName("oracle.sql.ArrayDescriptor");
Constructor constructor = classOracleARRAY.getDeclaredConstructor(
new Class[]
{clArrayDescriptor, Connection.class, Object.class});
Object []elements = _javaCollection.toArray();
_collection = (Array) constructor.newInstance(new Object[]
{_arrayDescriptor, _jdbcConn, elements});
if (_collection != null) {
// Optimization
Method setAutoBuffering
= classOracleARRAY.getDeclaredMethod("setAutoBuffering",
new Class[] {Boolean.TYPE});
setAutoBuffering.invoke(_collection, new Object[] {true});
}
return _collection;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return null;
}
}
/**
* Returns value of the element by index (1-based)
*/
public Value getElem(Env env,
int index)
{
try {
if ((index < 1) || (index > _javaCollection.size())) {
return BooleanValue.FALSE;
}
return env.wrapJava(_javaCollection.get(index - 1));
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return BooleanValue.FALSE;
}
}
/**
* Returns the underlying Java collection
*/
protected ArrayList getJavaCollection()
{
return _javaCollection;
}
/**
* Returns the maximum number of elements in the collection
* If the returned value is 0, then the number of elements
* is not limited. Returns FALSE in case of error.
*/
@ReturnNullAsFalse
public LongValue max(Env env)
{
try {
return LongValue.create(0);
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return null;
}
}
/**
* Returns size of the collection
*/
@ReturnNullAsFalse
public LongValue size(Env env)
{
try {
return LongValue.create(_javaCollection.size());
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return null;
}
}
/**
* Trims num elements from the end of the collection
*/
public boolean trim(Env env,
int num)
{
try {
if (num < 0) {
return false;
}
if (num == 0) {
return true;
}
int length = _javaCollection.size();
if (num > length) {
num = length;
}
int i = length - num;
_javaCollection.subList(i, length).clear();
return true;
} catch (Exception ex) {
log.log(Level.FINE, ex.toString(), ex);
return false;
}
}
public String toString() {
return "OracleOciCollection()";
}
}