This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
Doug- Thanks for the test program. Problem is fixed. I am attaching the file DAPNode.java which contains the fix. Also, you test program loop should use the arr.hasNext() function to ensure that the iterator is properly created, otherwise you will get a nullpointer exception. =Dennis Heimbigner Unidata Ticket Details =================== Ticket ID: ISE-243086 Department: Support netCDF Java Priority: Urgent Status: Closed
///////////////////////////////////////////////////////////////////////////// // This file is part of the "Java-DAP" project, a Java implementation // of the OPeNDAP Data Access Protocol. // // Copyright (c) 2010, OPeNDAP, Inc. // Copyright (c) 2002,2003 OPeNDAP, Inc. // // Author: James Gallagher <address@hidden> // // All rights reserved. // // Redistribution and use in source and binary forms, // with or without modification, are permitted provided // that the following conditions are met: // // - Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // - Neither the name of the OPeNDAP nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ///////////////////////////////////////////////////////////////////////////// package opendap.dap; import ucar.nc2.util.net.EscapeStrings; import java.io.Serializable; import java.util.HashMap; import java.util.Map; /** * The DAPNode class is the common parent type for * all nodes in the DDS and the DAS. It is used to manage * the following elements. * 1. Names - both encoded and clear * 2. Cloning - it implements the single clone procedure * and converts it to calls to cloneDAG. * 3. Parent - this was moved here from BaseType * because it (should) represent the only cyclic pointer * in the tree. * 4. projection - this really only for server nodes. * it should be removed when we quit using cloning. * * @author dmh (Dennis Heimbigner, Unidata) * @version $Revision: 22951 $ */ public class DAPNode implements Cloneable, Serializable { static final long serialVersionUID = 1; // Define a singleton value for which we can test with == static DAPNode NULLNODE = new DAPNode("null"); /** * The name of this variable - not www enccoded */ protected String _name; /* With disallowed characters unescaped */ protected String _nameEncoded; // www encoded form of name /** * The parent (container class) of this object, if one exists */ private DAPNode _myParent; /** * Track if this variable is being used as part of a projection. */ private boolean projected = false; /** * The Attribute Table used to contain attributes specific to this * instance of a BaseType variable. This is the repository for * "Semantic Metadata" */ private Attribute _attr; private AttributeTable _attrTbl; /** * Constructs a new <code>DAPNode</code> with no name. */ public DAPNode() { this(null); } /** * Constructs a new <code>DAPNode</code> with name <code>n</code>. * Name is assumed to never be DAP encoded * @param n the name of the variable. */ public DAPNode(String n) { _myParent = null; setClearName(n); } public void setProjected(boolean tf) { projected = tf; } /** * Check the projection state of this variable. * Is the given variable marked as projected? If the variable is listed * in the projection part of a constraint expression, then the CE parser * should mark it as <em>projected</em>. When this method is called on * such a variable it should return <code>true</code>, otherwise it * should return <code>false</code>. * * @return <code>true</code> if the variable is part of the current * projections, <code>false</code> otherwise. * @see opendap.servers.CEEvaluator */ public boolean isProject() { return (projected); } /** * Set the state of this variable's projection. <code>true</code> means * that this variable is part of the current projection as defined by * the current constraint expression, otherwise the current projection * for this variable should be <code>false</code>. * * @param state <code>true</code> if the variable is part of the current * projection, <code>false</code> otherwise. * @param all If <code>true</code>, set the Project property of all the * members (and their children, and so on). * @see opendap.servers.CEEvaluator */ public void setProject(boolean state, boolean all) { setProjected(state); } /** * Set the state of this variable's projection. <code>true</code> means * that this variable is part of the current projection as defined by * the current constraint expression, otherwise the current projection * for this variable should be <code>false</code>. <p> * This is equivalent to setProjection(<code>state</code>, * <code>true</code>). * * @param state <code>true</code> if the variable is part of the current * projection, <code>false</code> otherwise. * @see opendap.servers.CEEvaluator */ public void setProject(boolean state) { setProject(state, true); } public void setParent(DAPNode bt) { _myParent = bt; } public DAPNode getParent() { return (_myParent); } /** * Returns the unencoded name of the class instance. * * @return the name of the class instance. */ public final String getClearName() { return _name; } /** * Returns the WWW encoded name of the class instance. * * @return the name of the class instance. */ public final String getEncodedName() { return _nameEncoded; } /** * Sets the name of the class instance. * * @param n the name of the class instance; with escapes */ public final void setEncodedName(String n) { _nameEncoded = n; _name = EscapeStrings.unEscapeDAPIdentifier(n); //setClearName(EscapeStrings.www2id(n)); } /** * Sets the unencoded name of the class instance. * * @param n the unencoded name of the class instance. */ public void setClearName(String n) { _name = n; _nameEncoded = EscapeStrings.escapeDAPIdentifier(n); if(_attr != null) _attr.setClearName(n); if(_attrTbl != null) _attrTbl.setClearName(n); } /** * Clone interface. Note that in order to do this properly, * we need to be prepared to clone a DAG rather than just * a tree. This means we need two additional procedures: cloneDAG(CloneMap, DAPNode) * and cloneDAG(CloneMap). These functions carry along a map of already cloned * nodes in order to avoid re-cloning. */ // Define a class for holding all the clone mapping information. // Members are kept public for direct access. static public class CloneMap { Map<DAPNode,DAPNode> nodes = new HashMap<DAPNode,DAPNode>(); // map base object to clone DAPNode root = null; // initial cloned object } /** * Returns a clone of this <code>DAPNode</code>. A deep copy is performed * on all data inside the variable. * * @return a clone of this <code>DAPNode</code>. */ public Object clone() { try { CloneMap map = new CloneMap(); map.root = this; map.nodes.put(NULLNODE,NULLNODE); return cloneDAG(map); } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * Returns a clone of this <code>DAPNode</code>. * on all data inside the variable. Uses a set of already * cloned nodes to avoid re-cloning. All sub classes of DAPNode * should implement and invoke cloneDAG, not clone. * * @param map The set of already cloned nodes. * @return a clone of this <code>DAPNode</code>. */ /** * This version of cloneDAG() is the primary * point of cloning. If the src is already cloned, * then that existing clone is immediately returned. * Otherwise cloneDAG(map) is called to have the object * clone itself. Note this is static because it uses no * existing state. * @param map list of previously cloned nodes * @return the clone of the src node * @throws CloneNotSupportedException */ static public DAPNode cloneDAG(CloneMap map, DAPNode src) throws CloneNotSupportedException { DAPNode bt = map.nodes.get(src); if(bt == null) bt = src.cloneDAG(map); return bt; } /** * This procedure does the actual recursive clone. * @param map list of previously cloned nodes * @return clone of this node * @throws CloneNotSupportedException */ public DAPNode cloneDAG(CloneMap map) throws CloneNotSupportedException { DAPNode node = (DAPNode)super.clone(); // Object.clone map.nodes.put(this,node); DAPNode tmp = map.nodes.get(_myParent); if(tmp != node) _myParent = tmp; return node; } }