// $Id: AggDDS.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.servers.netcdf.NcDataset; import thredds.catalog.*; import dods.dap.*; import dods.dap.Server.*; import dods.dap.parser.ParseException; import java.io.*; import java.util.*; import java.text.SimpleDateFormat; public class AggDDS extends ServerDDS { private static boolean debug = false, debug2 = false; private AggDataset aggDataset; private DAS das; // type 1 constructor AggDDS( AggDataset aggDataset, String datasetName, Dataset defaultDataset ) { super( datasetName); this.aggDataset = aggDataset; das = (DAS) defaultDataset.getDAS().clone(); // create the connector coordinate variable String coordName = aggDataset.getVariableName(); String dateFormat = aggDataset.getDateFormat(); ArrayList aggFiles = aggDataset.getAggFiles(); // String defaults int size = aggFiles.size(); String[] coords = new String[ size]; for (int i=0; i<size; i++) { AggDataset.AggFile af = (AggDataset.AggFile) aggFiles.get(i); coords[i] = af.getCoord(); } // make dates if possible int[] coordVals = null; if (dateFormat != null) { coordVals = new int[size]; SimpleDateFormat parser = new SimpleDateFormat(dateFormat); for (int i=0; i<size; i++) { try { Date d = parser.parse(coords[i]); coordVals[i] = (int) (d.getTime()/1000); } catch (java.text.ParseException e) { System.out.println(" ERROR parsing date <"+coords[i]+">"); } } // add units to DAS AttributeTable at = new AttributeTable(); try { at.appendAttribute("units", Attribute.STRING, "\"secs since 1970-01-01 00:00:00\""); } catch (Exception e) {} das.addAttributeTable( coordName, at); } // the coordinate array on the new dimension ArrayList dims = new ArrayList(1); dims.add( new DArrayDimension( size, coordName)); Object data; if (coordVals == null) data = coords; else data = coordVals; // bug in Jbuilder SDArray connectCoord = new MemSDArray( coordName, dims, data); // add it to DDS addVariable( connectCoord); // now loop through orginal DDS and construct new DDS boolean isRemote = (defaultDataset instanceof DODSDataset); DDS orgDDS = defaultDataset.getClientDDS(); Enumeration dodsVars = orgDDS.getVariables(); while (dodsVars.hasMoreElements()) { dods.dap.BaseType bt = (dods.dap.BaseType) dodsVars.nextElement(); // only DGrids are joined if (bt instanceof DGrid) { addVariable( new AggSDGrid( (DGrid) bt, connectCoord, aggDataset, defaultDataset)); } else if (bt instanceof DArray) { if (isRemote) addVariable( new ProxySDArray( (DODSDataset) defaultDataset, (DArray) bt)); else addVariable( (SDArray) bt); // cast here so bombs early if problem } else { // scalar addScalar( defaultDataset, bt, isRemote); } } // hasMore } // type 2 Constructor AggDDS( AggDataset aggDataset, String datasetName) { super( datasetName); this.aggDataset = aggDataset; if (debug2) System.out.println(" AggDDS Type 2 "+datasetName); HashSet varNames = new HashSet(); das = new DAS(); // loop through datasets Iterator aggFiles = aggDataset.getAggFiles().iterator(); while (aggFiles.hasNext()) { AggDataset.AggFile af = (AggDataset.AggFile) aggFiles.next(); try { Dataset ds = af.acquire(true); //ds.setDebug(true); DDS dds = ds.getClientDDS(); boolean isRemote = (ds instanceof DODSDataset); if (debug2) System.out.println(" Dataset "+ds.getInternalPath()); // extract the variables from each dataset to make the DDS // assume that names that match are identical DDS orgDDS = ds.getClientDDS(); Enumeration dodsVars = orgDDS.getVariables(); while (dodsVars.hasMoreElements()) { dods.dap.BaseType bt = (dods.dap.BaseType) dodsVars.nextElement(); if (varNames.contains( bt.getName())) continue; // already got it !! //add it varNames.add( bt.getName()); aggDataset.mapVarToFile( bt.getName(), af); if (debug2) System.out.println(" adding "+bt.getName()+" "+bt.getClass().getName()); if (bt instanceof DGrid) { if (isRemote) addVariable( new ProxySDGrid( (DODSDataset) ds, (DGrid) bt)); else // if from netcdf file, can use directly addVariable( (SDGrid) bt); // cast here so bombs early if problem } else if (bt instanceof DArray) { if (isRemote) addVariable( new ProxySDArray( (DODSDataset) ds, (DArray) bt)); else // if from netcdf file, can use directly addVariable( (SDArray) bt); // cast here so bombs early if problem } else { // scalar addScalar( ds, bt, isRemote); } } // hasMore dods variables in orgDDS // while we're at it, construct the DAS also DAS orgDAS = ds.getDAS(); java.util.Enumeration enumx = orgDAS.getNames(); while (enumx.hasMoreElements()) { String attTableName = (String) enumx.nextElement(); if (null != das.getAttributeTable(attTableName)) continue; // already got it. AttributeTable oldAT = orgDAS.getAttributeTable(attTableName); das.addAttributeTable(attTableName, (AttributeTable) oldAT.clone()); //addAttributeTable( newAT, oldAT); } // hasMore attributes in orgDAS } catch (IOException ioe) { System.out.println("ERROR AggDDS: Failed to open Dataset "+af.getName()+" \n"); ioe.printStackTrace(); } finally { af.release(); } } // loop over datasets } // type 3 constructor AggDDS( AggDataset aggDataset, String datasetName, Dataset defaultDataset, DArray oldConnectVar, int nelems) { super( datasetName); this.aggDataset = aggDataset; das = defaultDataset.getDAS(); // first make the new connector dimension DArrayDimension oldConnectDim = oldConnectVar.getFirstDimension(); DArrayDimension newConnectDim = new DArrayDimension( nelems, oldConnectDim.getName()); // now loop through orginal DDS and construct new DDS boolean isRemote = (defaultDataset instanceof DODSDataset); DDS orgDDS = defaultDataset.getClientDDS(); Enumeration dodsVars = orgDDS.getVariables(); while (dodsVars.hasMoreElements()) { dods.dap.BaseType bt = (dods.dap.BaseType) dodsVars.nextElement(); if (bt instanceof DGrid) { DGrid grid = (DGrid) bt; DArray da; try { da = (DArray) grid.getVar(0); } catch (NoSuchVariableException e) { throw new IllegalStateException(e.getMessage()); } // create a different class for joined and unjoined case if (isJoinedArray(da, newConnectDim)) addVariable( new AggSDGrid( grid, newConnectDim, aggDataset, defaultDataset)); else if (isRemote) addVariable( new ProxySDGrid( (DODSDataset) defaultDataset, grid)); else addVariable( (SDGrid) grid); // cast here so bombs early if problem } else if (bt instanceof DArray) { // create a different class for joined and unjoined case if (isJoinedArray((DArray) bt, newConnectDim)) addVariable( new Agg3SDArray( (DArray) bt, newConnectDim, aggDataset)); else if (isRemote) addVariable( new ProxySDArray( (DODSDataset) defaultDataset, (DArray) bt)); else addVariable( (SDArray) bt); // cast here so bombs early if problem } else { // scalar addScalar( defaultDataset, bt, isRemote); } } // hasMore } public DAS getDAS() { return das; } // see if this array has the connector dimension private boolean isJoinedArray( DArray org, DArrayDimension joinedDD) { java.util.Enumeration dims = org.getDimensions(); while (dims.hasMoreElements()) { DArrayDimension dd = (DArrayDimension) dims.nextElement(); if (dd.getName().equals(joinedDD.getName())) return true; } return false; } private void addScalar( Dataset ds, dods.dap.BaseType bt, boolean isRemote) { if (bt instanceof DFloat64) { if (isRemote) addVariable (new ProxySDFloat64((DODSDataset) ds, bt.getName())); else addVariable ( (SDFloat64) bt); } else if (bt instanceof DFloat32) { if (isRemote) addVariable (new ProxySDFloat32((DODSDataset) ds, bt.getName())); else addVariable ( (SDFloat32) bt); } else if (bt instanceof DInt32) { if (isRemote) addVariable (new ProxySDInt32((DODSDataset) ds, bt.getName())); else addVariable ( (SDInt32) bt); } else if (bt instanceof DInt16) { if (isRemote) addVariable (new ProxySDInt16((DODSDataset) ds, bt.getName())); else addVariable ( (SDInt16) bt); } else if (bt instanceof DUInt32) { if (isRemote) addVariable (new ProxySDUInt32((DODSDataset) ds, bt.getName())); else addVariable ( (SDUInt32) bt); } else if (bt instanceof DUInt16) { if (isRemote) addVariable (new ProxySDUInt16((DODSDataset) ds, bt.getName())); else addVariable ( (SDUInt16) bt); } else if (bt instanceof DByte) { if (isRemote) addVariable (new ProxySDByte((DODSDataset) ds, bt.getName())); else addVariable ( (SDByte) bt); } else if (bt instanceof DBoolean) { if (isRemote) addVariable (new ProxySDBoolean((DODSDataset) ds, bt.getName())); else addVariable ( (SDBoolean) bt); } else if (bt instanceof DString) { if (isRemote) addVariable (new ProxySDString((DODSDataset) ds, bt.getName())); else addVariable ( (SDString) bt); } } // We need to reset the DDS to the correct underlying datasets void reset() throws java.io.IOException { Enumeration dodsVars = getVariables(); while (dodsVars.hasMoreElements()) { dods.dap.BaseType bt = (dods.dap.BaseType) dodsVars.nextElement(); AggDataset.AggFile af = aggDataset.getFileForVar( bt.getName()); Dataset ds = af.acquire(true); resetVar( bt, ds, ds.getClientDDS()); } } // We need to reset the DDS to the correct underlying datasets void reset(Dataset ds, DDS defaultDataset) { Enumeration dodsVars = getVariables(); while (dodsVars.hasMoreElements()) { dods.dap.BaseType bt = (dods.dap.BaseType) dodsVars.nextElement(); resetVar( bt, ds, defaultDataset); } // hasMore DODS Variables } private void resetVar( BaseType bt, Dataset ds, DDS dds) { // the non-aggregation variables must be reset to the defaultDatset if (bt instanceof DGrid) { DGrid grid = (DGrid) bt; java.util.Enumeration vars = grid.getVariables(); while (vars.hasMoreElements()) { SDArray dodsArray = (SDArray) vars.nextElement(); if (dodsArray instanceof HasProxyObject) { HasProxyObject po = (HasProxyObject) dodsArray; po.setProxy( getProxyObject(ds, dds, dodsArray.getName())); } } } else if (bt instanceof HasProxyObject) { HasProxyObject po = (HasProxyObject) bt; po.setProxy( getProxyObject(ds, dds, bt.getName())); } } private Object getProxyObject(Dataset ds, DDS defDDS, String name) { BaseType bt; try { bt = defDDS.getVariable(name); } catch (NoSuchVariableException e) { throw new IllegalStateException("AggDDS.getProxyObject failed "+e.getMessage()); } if (bt instanceof DGrid) { DGrid grid = (DGrid) bt; try { bt = grid.getVar(0); } catch (dods.dap.NoSuchVariableException e) { // will throw te following exception } } if (bt instanceof HasProxyObject) { HasProxyObject po = (HasProxyObject) bt; return po.getProxy(); } if (ds instanceof DODSDataset) { return ds; } throw new IllegalStateException("AggDDS.getProxyObject not HasProxyObject =" +name+" "+bt.getClass().getName()+" "+ds.getClass().getName()); } } /* private void addAttributeTable( AttributeTable newAT, AttributeTable oldAT) { java.util.Enumeration enum = oldAT.getNames(); while (enum.hasMoreElements()) { String attName = (String) enum.nextElement(); Attribute att = oldAT.getAttribute(attName); if (att.isContainer()) { AttributeTable oldt = att.getContainer(); AttributeTable newt = newAT.appendContainer(attName); addAttributeTable( newt, oldt); } else { try { // lousy interface newAT.appendAttribute(attName, att.getType(), att.getValueAt(0)); Attribute newAtt = newAT.getAttribute(attName); java.util.Enumeration values = att.getValues(); values.nextElement(); // throw first away while (values.hasMoreElements()) newAtt.appendValue((String) values.nextElement()); } catch (AttributeExistsException e) { System.out.println("AggDDS addAttributeTable "+attName+" "+e.getMessage()); } catch (AttributeBadValueException e) { System.out.println("AggDDS addAttributeTable "+attName+" "+e.getMessage()); } // try } // not a container } // loop over atts } */ /* Change History: $Log: not supported by cvs2svn $ Revision 1.3 2004/02/06 15:23:49 donm update to 1.1.4 Revision 1.3 2002/02/25 15:50:12 caron byte array padding Revision 1.2 2001/10/26 19:07:10 caron getClientDDS() Revision 1.1.1.1 2001/09/26 15:36:47 caron checkin beta1 */