// $Id: ProxySDArray.java,v 1.4 2007-08-27 20:13:04 brucef Exp $
/*
* Copyright 1997-2000 Unidata Program Center/University Corporation for
* Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
* support@unidata.ucar.edu.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library 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. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package dods.servers.agg;
import dods.dap.Server.*;
import dods.dap.*;
import java.io.*;
import java.util.*;
/**
* Proxy for an array in another (DODS) dataset.
* If its 1D, read the entire array the first time and cache it.
*
* @version $Revision: 1.4 $
* @author jcaron
*/
public class ProxySDArray extends SDArray implements HasProxyObject {
private DODSDataset df;
private boolean isString;
private PrimitiveVector cachedData = null;
private int ndims = 0;
private boolean debug = false, debugRead = false;
/**
* Constructor
* @param AggDataset.DodsFile df: the other dataset
* @param DArray org: proxy for this array in df
*/
ProxySDArray(DODSDataset df, DArray org) {
super(org.getName());
this.df = df;
// set dimensions
java.util.Enumeration dims = org.getDimensions();
while (dims.hasMoreElements()) {
DArrayDimension dd = (DArrayDimension) dims.nextElement();
appendDim(dd.getSize(), dd.getName());
ndims++;
}
// set the data type
PrimitiveVector pv = org.getPrimitiveVector();
addVariable( assignBaseType( pv.getTemplate()));
isString = (pv.getTemplate() instanceof DString);
}
/* ProxySDArray(String name) {
super(name);
} */
/** get/set the underlying proxy */
public void setProxy(Object v) { this.df = (DODSDataset) v; }
public Object getProxy() { return df; }
/** Read the value from original dataset (parameters are ignored).*/
public boolean read(String datasetName, Object specialO) throws IOException, EOFException {
// if (cachedData == null) {
// read the data
PrimitiveVector data = read( this.getDimensions(), df.getConnection());
// needs to be transferred to this pv
PrimitiveVector pv = getPrimitiveVector();
if (!isString)
pv.setInternalStorage( data.getInternalStorage());
else { // array of strings
BaseTypePrimitiveVector btdata = (BaseTypePrimitiveVector) data;
BaseTypePrimitiveVector btpv = (BaseTypePrimitiveVector) pv;
int nelems = data.getLength();
btpv.setLength( nelems);
for (int i=0; i<nelems; i++) {
DString val = (DString) btdata.getValue(i);
btpv.setValue( i, new AggSDString(val)); // wrap each one
}
}
// }
/* if you have filled cached Data, now subset if needed
if (cachedData != null) {
System.out.println("use cachedData ");
// full data is alread in cachedData, just have to subset it
try {
PrimitiveVector subset = cachedData.subset( getStart(0), getStop(0), getStride(0));
getPrimitiveVector().setInternalStorage( subset.getInternalStorage());
} catch (dods.dap.Server.InvalidParameterException e) { }
} */
setRead(true);
return (false);
}
/** this does the actual work of reading from the remote dataset.
* it uses the projection info stored in the DArrayDimension's
*/
private PrimitiveVector read(Enumeration dims, DConnect connect) throws IOException, EOFException {
// create the constraint expression
StringBuffer buff = new StringBuffer(100);
buff.setLength(0);
buff.append('?');
buff.append( getName());
// if 1D, read all of it
// otherwise add the element constraints
// if (ndims > 1) {
// loop through the dimensions
while (dims.hasMoreElements()) {
DArrayDimension dd = (DArrayDimension) dims.nextElement();
buff.append("[");
buff.append(dd.getStart());
buff.append(':');
if (dd.getStride() > 1) {
buff.append(dd.getStride());
buff.append(':');
}
buff.append(dd.getStop());
buff.append("]");
}
// }
if (debugRead) {
System.out.println("ProxySDArray read "+getName()+" : connect to = "+ df.getConnection().URL());
System.out.println("ProxySDArray read: constraint = "+ buff);
}
// read the data
dods.dap.DataDDS dataDDS;
try {
dataDDS = connect.getData(buff.toString(), null);
} catch (DODSException e) {
System.out.println("ProxySDArray read getData failed = "+e);
throw new IOException(e.getMessage());
} catch (dods.dap.parser.ParseException e) {
System.out.println("ProxySDArray read getData failed = "+e);
throw new IOException(e.getMessage());
}
if (debugRead) {
System.out.println("ProxySDArray dataDDS returned == ");
dataDDS.print(System.out);
}
// get data
Enumeration enumx = dataDDS.getVariables();
BaseType bt = (BaseType) enumx.nextElement();
DVector dv;
if (bt instanceof DGrid) {
DGrid grid = (DGrid) bt;
try {
dv = (DVector) grid.getVariable(grid.getName());
} catch (NoSuchVariableException e) {
throw new IllegalStateException(e.getMessage());
}
} else
dv = (DVector) bt;
boolean checkTypes = true;
if (checkTypes) {
BaseType proxyBT = getPrimitiveVector().getTemplate(); // proxy var
BaseType dataBT = dv.getPrimitiveVector().getTemplate(); // proxy var
if (!proxyBT.getName().equals( dataBT.getName())) {
System.out.println(" ProxySDArray wrong data type proxy="+proxyBT.getName()+" data="+dataBT.getName());
System.out.println(" dataRequest = "+buff);
System.out.println(" dataDDS = ");
dataDDS.print(System.out);
throw new IOException(" ProxySDArray wrong data type proxy="+proxyBT.getName()+" data="+dataBT.getName());
}
}
/* if (ndims <= 1) {
cachedData = (PrimitiveVector) dv.getPrimitiveVector().clone();
} */
return dv.getPrimitiveVector();
}
/**
* Override so we can cache the whole array, and subset it locally.
*
* @param dataset
* @param sink
* @param ce
* @param specialO
* @throws NoSuchVariableException
* @throws SDODSException
* @throws IOException
*
public void serialize(String dataset, DataOutputStream sink, CEEvaluator ce, Object specialO)
throws NoSuchVariableException,SDODSException, IOException {
if (!ce.evalClauses(specialO)) return;
if(!isRead())
read(dataset, specialO);
PrimitiveVector vals = getPrimitiveVector();
if (cachedData) {
// full data is in the PrimitiveVector, just have to subset it
int stride0 = (getStride(0) > 1) ? getStride(0) : 1;
int length = 1 + (getStop(0) - getStart(0)) / stride0;
sink.writeInt(length);
if(vals instanceof BaseTypePrimitiveVector){
BaseTypePrimitiveVector bvals = (BaseTypePrimitiveVector) vals;
for(int i=getStart(0); i<=getStop(0); i+=stride0) {
ServerMethods sm = (ServerMethods) bvals.getValue(i);
sm.serialize(dataset,sink,ce, specialO);
}
} else {
sink.writeInt(length);
vals.externalize( sink, getStart(0), getStop(0), stride0);
}
} else {
// just the wanted data is in the PrimitiveVector
int length = vals.getLength();
sink.writeInt(length);
if(vals instanceof BaseTypePrimitiveVector){
BaseTypePrimitiveVector bvals = (BaseTypePrimitiveVector) vals;
for(int i=0; i<length ;i++){
ServerMethods sm = (ServerMethods) bvals.getValue(i);
sm.serialize(dataset,sink,ce, specialO);
}
} else {
sink.writeInt(length);
vals.externalize(sink);
}
}
} */
/*
* The following is logically seperate from ProxySDArray. We get DXXXX types and we need
* to convert them to SDXXX types.
*/
static public BaseType assignBaseType( BaseType bt) {
if (bt instanceof DFloat64)
return new AggSDFloat64(bt.getName());
else if (bt instanceof DFloat32)
return new AggSDFloat32(bt.getName());
else if (bt instanceof DInt32)
return new AggSDInt32(bt.getName());
else if (bt instanceof DInt16)
return new AggSDInt16(bt.getName());
else if (bt instanceof DUInt32)
return new AggSDUInt32(bt.getName());
else if (bt instanceof DUInt16)
return new AggSDUInt16(bt.getName());
else if (bt instanceof DByte)
return new AggSDByte(bt.getName());
else if (bt instanceof DBoolean)
return new AggSDBoolean(bt.getName());
else if (bt instanceof DString)
return new AggSDString(bt.getName());
else
throw new UnsupportedOperationException("ProxySDArray assignBaseType = " + bt.getName());
}
/////////////////////
// these are all dummys, used only to assign a variable type
// these apparently have to be concrete SD subclasses
// LOOK: how come we cant use Proxy<type> instead ?
static class AggSDFloat64 extends SDFloat64 {
AggSDFloat64( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDFloat32 extends SDFloat32 {
AggSDFloat32( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDInt32 extends SDInt32 {
AggSDInt32( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDInt16 extends SDInt16 {
AggSDInt16( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDUInt32 extends SDUInt32 {
AggSDUInt32( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDUInt16 extends SDUInt16 {
AggSDUInt16( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDByte extends SDByte {
AggSDByte( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDBoolean extends SDBoolean {
AggSDBoolean( String name) { super(name); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
static class AggSDString extends SDString {
AggSDString( String name) { super(name); }
AggSDString( String name, String val) {
super(name);
setValue( val);
}
AggSDString( DString val) { setValue( val.getValue()); }
public boolean read(String datasetName, Object specialO) throws IOException {
setRead(true);
return (false);
}
}
}
/* Change History:
$Log: not supported by cvs2svn $
Revision 1.3 2004/02/06 15:23:49 donm
update to 1.1.4
Revision 1.2 2002/02/25 15:45:16 caron
cache 1D arrays; efficient Coord vars
Revision 1.1.1.1 2001/09/26 15:36:47 caron
checkin beta1
*/