NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDFJava #ISE-243086]: NetCDF-Java failing to read OPeNDAP Sequences



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;
    }

}