Input:
Extract data for one member over all structures . [CODESPLIT] public Array extractMemberArray ( StructureMembers . Member m ) throws IOException { if ( m . getDataArray ( ) != null ) return m . getDataArray ( ) ; DataType dataType = m . getDataType ( ) ; /* special handling for sequences
    if (dataType == DataType.SEQUENCE) {
      List<StructureData> sdataList = new ArrayList<StructureData>();
      for (int recno=0; recno<getSize(); recno++) {
        ArraySequence2 seq = getArraySequence(recno, m);
        StructureDataIterator iter = seq.getStructureDataIterator();
        while (iter.hasNext())
          sdataList.add( iter.next());
      }
      ArraySequence2 seq = getArraySequence(0, m);
      int size = sdataList.size();
      StructureData[] sdataArray = sdataList.toArray( new StructureData[size]);
      return new ArrayStructureW( seq.getStructureMembers(), new int[] {size}, sdataArray);
   } */ // combine the shapes
 int [ ] mshape = m . getShape ( ) ; int rrank = rank + mshape . length ; int [ ] rshape = new int [ rrank ] ; System . arraycopy ( getShape ( ) , 0 , rshape , 0 , rank ) ; System . arraycopy ( mshape , 0 , rshape , rank , mshape . length ) ; // create an empty array to hold the result
 Array result ; if ( dataType == DataType . STRUCTURE ) { StructureMembers membersw = new StructureMembers ( m . getStructureMembers ( ) ) ; // no data arrays get propagated
 result = new ArrayStructureW ( membersw , rshape ) ; } else if ( dataType == DataType . OPAQUE ) { result = Array . factory ( DataType . OPAQUE , rshape ) ; } else { result = Array . factory ( dataType , rshape ) ; } IndexIterator resultIter = result . getIndexIterator ( ) ; if ( dataType == DataType . DOUBLE ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyDoubles ( recno , m , resultIter ) ; } else if ( dataType == DataType . FLOAT ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyFloats ( recno , m , resultIter ) ; } else if ( dataType . getPrimitiveClassType ( ) == byte . class ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyBytes ( recno , m , resultIter ) ; } else if ( dataType . getPrimitiveClassType ( ) == short . class ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyShorts ( recno , m , resultIter ) ; } else if ( dataType . getPrimitiveClassType ( ) == int . class ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyInts ( recno , m , resultIter ) ; } else if ( dataType . getPrimitiveClassType ( ) == long . class ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyLongs ( recno , m , resultIter ) ; } else if ( dataType == DataType . CHAR ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyChars ( recno , m , resultIter ) ; } else if ( ( dataType == DataType . STRING ) || ( dataType == DataType . OPAQUE ) ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyObjects ( recno , m , resultIter ) ; } else if ( dataType == DataType . STRUCTURE ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copyStructures ( recno , m , resultIter ) ; } else if ( dataType == DataType . SEQUENCE ) { for ( int recno = 0 ; recno < getSize ( ) ; recno ++ ) copySequences ( recno , m , resultIter ) ; } return result ; }


Input: member data is itself a structure and may be an array of structures . [CODESPLIT] protected void copyStructures ( int recnum , StructureMembers . Member m , IndexIterator result ) { Array data = getArray ( recnum , m ) ; IndexIterator dataIter = data . getIndexIterator ( ) ; while ( dataIter . hasNext ( ) ) result . setObjectNext ( dataIter . getObjectNext ( ) ) ; }


Input:
Get member data array of any type as an Object eg Float Double String StructureData etc . [CODESPLIT] public Object getScalarObject ( int recno , StructureMembers . Member m ) { DataType dataType = m . getDataType ( ) ; if ( dataType == DataType . DOUBLE ) { return getScalarDouble ( recno , m ) ; } else if ( dataType == DataType . FLOAT ) { return getScalarFloat ( recno , m ) ; } else if ( dataType . getPrimitiveClassType ( ) == byte . class ) { return getScalarByte ( recno , m ) ; } else if ( dataType . getPrimitiveClassType ( ) == short . class ) { return getScalarShort ( recno , m ) ; } else if ( dataType . getPrimitiveClassType ( ) == int . class ) { return getScalarInt ( recno , m ) ; } else if ( dataType . getPrimitiveClassType ( ) == long . class ) { return getScalarLong ( recno , m ) ; } else if ( dataType == DataType . CHAR ) { return getScalarString ( recno , m ) ; } else if ( dataType == DataType . STRING ) { return getScalarString ( recno , m ) ; } else if ( dataType == DataType . STRUCTURE ) { return getScalarStructure ( recno , m ) ; } else if ( dataType == DataType . OPAQUE ) { ArrayObject data = ( ArrayObject ) m . getDataArray ( ) ; return data . getObject ( recno * m . getSize ( ) ) ; // LOOK ??
 } throw new RuntimeException ( "Dont have implementation for " + dataType ) ; }


Input: Get scalar value as a float with conversion as needed . Underlying type must be convertible to float . [CODESPLIT] public float convertScalarFloat ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) == DataType . FLOAT ) return getScalarFloat ( recnum , m ) ; if ( m . getDataType ( ) == DataType . DOUBLE ) return ( float ) getScalarDouble ( recnum , m ) ; Object o = getScalarObject ( recnum , m ) ; if ( o instanceof Number ) return ( ( Number ) o ) . floatValue ( ) ; throw new ForbiddenConversionException ( "Type is " + m . getDataType ( ) + ", not convertible to float" ) ; }


Input: Get scalar value as a double with conversion as needed . Underlying type must be convertible to double . [CODESPLIT] public double convertScalarDouble ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) == DataType . DOUBLE ) return getScalarDouble ( recnum , m ) ; if ( m . getDataType ( ) == DataType . FLOAT ) return ( double ) getScalarFloat ( recnum , m ) ; Object o = getScalarObject ( recnum , m ) ; if ( o instanceof Number ) return ( ( Number ) o ) . doubleValue ( ) ; throw new ForbiddenConversionException ( "Type is " + m . getDataType ( ) + ", not convertible to double" ) ; }


Input: Get scalar value as an int with conversion as needed . Underlying type must be convertible to int . [CODESPLIT] public int convertScalarInt ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) == DataType . INT || m . getDataType ( ) == DataType . UINT ) return getScalarInt ( recnum , m ) ; if ( m . getDataType ( ) == DataType . SHORT ) return ( int ) getScalarShort ( recnum , m ) ; if ( m . getDataType ( ) == DataType . USHORT ) return DataType . unsignedShortToInt ( getScalarShort ( recnum , m ) ) ; if ( m . getDataType ( ) == DataType . BYTE ) return ( int ) getScalarByte ( recnum , m ) ; if ( m . getDataType ( ) == DataType . UBYTE ) return ( int ) DataType . unsignedByteToShort ( getScalarByte ( recnum , m ) ) ; if ( m . getDataType ( ) == DataType . LONG || m . getDataType ( ) == DataType . ULONG ) return ( int ) getScalarLong ( recnum , m ) ; Object o = getScalarObject ( recnum , m ) ; if ( o instanceof Number ) return ( ( Number ) o ) . intValue ( ) ; throw new ForbiddenConversionException ( "Type is " + m . getDataType ( ) + ", not convertible to int" ) ; }


Input:
Get scalar member data of type float . [CODESPLIT] public float getScalarFloat ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) != DataType . FLOAT ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be float" ) ; Array data = m . getDataArray ( ) ; return data . getFloat ( recnum * m . getSize ( ) ) ; // gets first one in the array
 }


Input:
Get scalar member data of type byte . [CODESPLIT] public byte getScalarByte ( int recnum , StructureMembers . Member m ) { if ( ! ( m . getDataType ( ) . getPrimitiveClassType ( ) == byte . class ) ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be byte" ) ; Array data = m . getDataArray ( ) ; return data . getByte ( recnum * m . getSize ( ) ) ; // gets first one in the array
 }


Input:
Get scalar member data of type short . [CODESPLIT] public short getScalarShort ( int recnum , StructureMembers . Member m ) { if ( ! ( m . getDataType ( ) . getPrimitiveClassType ( ) == short . class ) ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be short" ) ; Array data = m . getDataArray ( ) ; return data . getShort ( recnum * m . getSize ( ) ) ; // gets first one in the array
 }


Input:
Get scalar member data of type char . [CODESPLIT] public char getScalarChar ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) != DataType . CHAR ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be char" ) ; Array data = m . getDataArray ( ) ; return data . getChar ( recnum * m . getSize ( ) ) ; // gets first one in the array
 }


Input: Get member data of type String or char . [CODESPLIT] public String getScalarString ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) == DataType . CHAR ) { ArrayChar data = ( ArrayChar ) m . getDataArray ( ) ; return data . getString ( recnum ) ; } if ( m . getDataType ( ) == DataType . STRING ) { Array data = m . getDataArray ( ) ; return ( String ) data . getObject ( recnum ) ; } throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be String or char" ) ; }


Input:
Get member data of type Structure . [CODESPLIT] public StructureData getScalarStructure ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) != DataType . STRUCTURE ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be Structure" ) ; ArrayStructure data = ( ArrayStructure ) m . getDataArray ( ) ; return data . getStructureData ( recnum * m . getSize ( ) ) ; // gets first in the array
 }


Input:
Get member data of type array of Structure . [CODESPLIT] public ArrayStructure getArrayStructure ( int recnum , StructureMembers . Member m ) { if ( ( m . getDataType ( ) != DataType . STRUCTURE ) && ( m . getDataType ( ) != DataType . SEQUENCE ) ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be Structure or Sequence" ) ; if ( m . getDataType ( ) == DataType . SEQUENCE ) return getArraySequence ( recnum , m ) ; ArrayStructure array = ( ArrayStructure ) m . getDataArray ( ) ; int count = m . getSize ( ) ; StructureData [ ] this_sdata = new StructureData [ count ] ; for ( int i = 0 ; i < count ; i ++ ) this_sdata [ i ] = array . getStructureData ( recnum * count + i ) ; // make a copy of the members, but remove the data arrays, since the structureData must be used instead
 StructureMembers membersw = new StructureMembers ( array . getStructureMembers ( ) ) ; return new ArrayStructureW ( membersw , m . getShape ( ) , this_sdata ) ; }


Input:
Get member data of type ArraySequence [CODESPLIT] public ArraySequence getArraySequence ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) != DataType . SEQUENCE ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be Sequence" ) ; // should store sequences as ArrayObject of ArraySequence objects
 ArrayObject array = ( ArrayObject ) m . getDataArray ( ) ; return ( ArraySequence ) array . getObject ( recnum ) ; }


Input:
Get member data of type ArrayObject [CODESPLIT] public ArrayObject getArrayObject ( int recnum , StructureMembers . Member m ) { if ( m . getDataType ( ) != DataType . OPAQUE ) throw new IllegalArgumentException ( "Type is " + m . getDataType ( ) + ", must be Sequence" ) ; ArrayObject array = ( ArrayObject ) m . getDataArray ( ) ; return ( ArrayObject ) array . getObject ( recnum ) ; // LOOK ??
 }


Input: experimental [CODESPLIT] int setDirect ( int v0 , int v1 , int v2 ) { if ( v0 < 0 || v0 >= shape0 ) throw new ArrayIndexOutOfBoundsException ( ) ; if ( v1 < 0 || v1 >= shape1 ) throw new ArrayIndexOutOfBoundsException ( ) ; if ( v2 < 0 || v2 >= shape2 ) throw new ArrayIndexOutOfBoundsException ( ) ; return offset + v0 * stride0 + v1 * stride1 + v2 * stride2 ; }


Input: Precalculate some stuff [CODESPLIT] private void precalculate ( ) { sinLat0 = Math . sin ( lat0 ) ; cosLat0 = Math . cos ( lat0 ) ; lon0Degrees = Math . toDegrees ( lon0 ) ; }


Input:
This returns true when the line between pt1 and pt2 crosses the seam . When the cone is flattened the seam is lon0 + - 180 . [CODESPLIT] public boolean crossSeam ( ProjectionPoint pt1 , ProjectionPoint pt2 ) { // either point is infinite
 if ( ProjectionPointImpl . isInfinite ( pt1 ) || ProjectionPointImpl . isInfinite ( pt2 ) ) return true ; // opposite signed X values, larger then 5000 km
 return ( pt1 . getX ( ) * pt2 . getX ( ) < 0 ) && ( Math . abs ( pt1 . getX ( ) - pt2 . getX ( ) ) > 5000.0 ) ; }


Input: Force an attribute value ( typically string ) to match a given basetype [CODESPLIT] static public Object attributeConvert ( DapType type , Object value ) { if ( value == null ) return value ; if ( type . isEnumType ( ) ) { if ( value instanceof String ) { // See if the constant is an int vs enum const name try { int ival = Integer . parseInt ( value . toString ( ) ) ; return ival ; } catch ( NumberFormatException nfe ) { // Assume it is an econst name; try to locate it DapEnumConst dec = ( ( DapEnumeration ) type ) . lookup ( value . toString ( ) ) ; if ( dec == null ) return value ; return dec . getValue ( ) ; } } else if ( value instanceof Long ) { return ( Long ) value ; } } else if ( value instanceof Long ) { return ( Long ) value ; } else if ( value instanceof Float ) { return ( Float ) value ; } else if ( value instanceof Double ) { return ( Double ) value ; } else if ( value instanceof Character ) { return ( ( Character ) value ) ; } return value ; }


Input: / * Get the size of an equivalent java object ; zero if not defined [CODESPLIT] static public int getJavaSize ( TypeSort atomtype ) { switch ( atomtype ) { case Char : case Int8 : case UInt8 : return 1 ; case Int16 : case UInt16 : return 2 ; case Int32 : case UInt32 : return 4 ; case Int64 : case UInt64 : return 8 ; case Float32 : return 4 ; case Float64 : return 8 ; default : break ; } return 0 ; }


Input: Force a numeric value to be in a specified range Only defined for simple integers ( ValueClass LONG ) WARNING : unsigned values are forced into the signed size but the proper bit pattern is maintained . The term force means that if the value is outside the typed min / max values it is pegged to the min or max value depending on the sign . Note that truncation is not used . [CODESPLIT] static public long forceRange ( TypeSort basetype , long value ) { assert basetype . isIntegerType ( ) : "Internal error" ; switch ( basetype ) { case Char : value = minmax ( value , 0 , 255 ) ; break ; case Int8 : value = minmax ( value , ( long ) Byte . MIN_VALUE , ( long ) Byte . MAX_VALUE ) ; break ; case UInt8 : value = value & 0xFF L ; break ; case Int16 : value = minmax ( value , ( long ) Short . MIN_VALUE , ( long ) Short . MAX_VALUE ) ; break ; case UInt16 : value = value & 0xFFFF L ; break ; case Int32 : value = minmax ( value , ( long ) Integer . MIN_VALUE , ( long ) Integer . MAX_VALUE ) ; break ; case UInt32 : value = value & 0xFFFFFFFF L ; break ; case Int64 : case UInt64 : break ; // value = value case Int64: default : } return value ; }


Input: Peg a value to either the min or max depending on sign . [CODESPLIT] static protected long minmax ( long value , long min , long max ) { if ( value < min ) return min ; if ( value > max ) return max ; return value ; }


Input: For removePrefix / path style servlet mappings . [CODESPLIT] public static String extractPath ( HttpServletRequest req , String removePrefix ) { // may be in pathInfo (Servlet) or servletPath (Controller) String dataPath = req . getPathInfo ( ) ; if ( dataPath == null ) { dataPath = req . getServletPath ( ) ; } if ( dataPath == null ) // not sure if this is possible return "" ; // removePrefix or "/"+removePrefix if ( removePrefix != null ) { if ( dataPath . startsWith ( removePrefix ) ) { dataPath = dataPath . substring ( removePrefix . length ( ) ) ; } else if ( dataPath . startsWith ( "/" ) ) { dataPath = dataPath . substring ( 1 ) ; if ( dataPath . startsWith ( removePrefix ) ) dataPath = dataPath . substring ( removePrefix . length ( ) ) ; } } if ( dataPath . startsWith ( "/" ) ) dataPath = dataPath . substring ( 1 ) ; if ( dataPath . contains ( ".." ) ) // LOOK what about escapes ?? throw new IllegalArgumentException ( "path cannot contain '..'" ) ; return dataPath ; }


Input: ///////////////////////////////////////////////// [CODESPLIT] public static String getFileNameForResponse ( String pathInfo , NetcdfFileWriter . Version version ) { Preconditions . checkNotNull ( version , "version == null" ) ; return getFileNameForResponse ( pathInfo , version . getSuffix ( ) ) ; }


Input: _more_ [CODESPLIT] public static void printProjArgs ( int Projection , double [ ] projargs ) { double NorthBound ; double SouthBound ; double WestBound ; double EastBound ; double RowInc ; double ColInc ; double Lat1 ; double Lat2 ; double PoleRow ; double PoleCol ; double CentralLat ; double CentralLon ; double CentralRow ; double CentralCol ; double Rotation ; /* radians */ double Cone ; double Hemisphere ; double ConeFactor ; double CosCentralLat ; double SinCentralLat ; double StereoScale ; double InvScale ; double CylinderScale ; switch ( Projection ) { case PROJ_GENERIC : case PROJ_LINEAR : case PROJ_CYLINDRICAL : case PROJ_SPHERICAL : NorthBound = projargs [ 0 ] ; WestBound = projargs [ 1 ] ; RowInc = projargs [ 2 ] ; ColInc = projargs [ 3 ] ; System . out . println ( "Generic, Linear, Cylindrical, Spherical:" ) ; System . out . println ( "NB: " + NorthBound + ", WB: " + WestBound + ", rowInc: " + RowInc + ", colInc: " + ColInc ) ; break ; case PROJ_ROTATED : NorthBound = projargs [ 0 ] ; WestBound = projargs [ 1 ] ; RowInc = projargs [ 2 ] ; ColInc = projargs [ 3 ] ; CentralLat = projargs [ 4 ] ; CentralLon = projargs [ 5 ] ; Rotation = projargs [ 6 ] ; System . out . println ( "Rotated:" ) ; System . out . println ( "NB: " + NorthBound + ", WB: " + WestBound + ", rowInc: " + RowInc + ", colInc: " + ColInc + ", clat: " + CentralLat + ", clon: " + CentralLon + ", rotation: " + Rotation ) ; break ; case PROJ_LAMBERT : Lat1 = projargs [ 0 ] ; Lat2 = projargs [ 1 ] ; PoleRow = projargs [ 2 ] ; PoleCol = projargs [ 3 ] ; CentralLon = projargs [ 4 ] ; ColInc = projargs [ 5 ] ; System . out . println ( "Lambert: " ) ; System . out . println ( "lat1: " + Lat1 + ", lat2: " + Lat2 + ", poleRow: " + PoleRow + ", PoleCol: " + PoleCol + ", clon: " + CentralLon + ", colInc: " + ColInc ) ; break ; case PROJ_STEREO : CentralLat = projargs [ 0 ] ; CentralLon = projargs [ 1 ] ; CentralRow = projargs [ 2 ] ; CentralCol = projargs [ 3 ] ; ColInc = projargs [ 4 ] ; System . out . println ( "Stereo: " ) ; System . out . println ( "clat: " + CentralLat + ", clon: " + CentralLon + ", cRow: " + CentralRow + ", cCol: " + CentralCol + ", colInc: " + ColInc ) ; break ; default : System . out . println ( "Projection unknown" ) ; } }


Input: Evaluate a filter with respect to a Sequence record . Assumes the filter has been canonicalized so that the lhs is a variable . [CODESPLIT] protected Object eval ( DapVariable var , DapSequence seq , DataCursor record , CEAST expr ) throws DapException { switch ( expr . sort ) { case CONSTANT : return expr . value ; case SEGMENT : return fieldValue ( var , seq , record , expr . name ) ; case EXPR : Object lhs = eval ( var , seq , record , expr . lhs ) ; Object rhs = ( expr . rhs == null ? null : eval ( var , seq , record , expr . rhs ) ) ; if ( rhs != null ) switch ( expr . op ) { case LT : return compare ( lhs , rhs ) < 0 ; case LE : return compare ( lhs , rhs ) <= 0 ; case GT : return compare ( lhs , rhs ) > 0 ; case GE : return compare ( lhs , rhs ) >= 0 ; case EQ : return lhs . equals ( rhs ) ; case NEQ : return ! lhs . equals ( rhs ) ; case REQ : return lhs . toString ( ) . matches ( rhs . toString ( ) ) ; case AND : return ( ( Boolean ) lhs ) && ( ( Boolean ) rhs ) ; } else switch ( expr . op ) { case NOT : return ! ( ( Boolean ) lhs ) ; } } throw new DapException ( "Malformed Filter" ) ; }


Input: Convert the view to a constraint string suitable for use in a URL except not URL encoded . [CODESPLIT] public String toConstraintString ( ) { StringBuilder buf = new StringBuilder ( ) ; boolean first = true ; for ( int i = 0 ; i < segments . size ( ) ; i ++ ) { Segment seg = segments . get ( i ) ; if ( ! seg . var . isTopLevel ( ) ) continue ; if ( ! first ) buf . append ( ";" ) ; first = false ; dumpvar ( seg , buf , true ) ; } return buf . toString ( ) ; }


Input: Recursive helper for tostring / toConstraintString [CODESPLIT] protected void dumpvar ( Segment seg , StringBuilder buf , boolean forconstraint ) { if ( seg . var . isTopLevel ( ) ) buf . append ( seg . var . getFQN ( ) ) ; else buf . append ( seg . var . getShortName ( ) ) ; List < DapDimension > dimset = seg . var . getDimensions ( ) ; // Add any slices List < Slice > slices = seg . slices ; if ( slices == null ) dimset = new ArrayList < DapDimension > ( ) ; else assert ( dimset . size ( ) == 0 && DapUtil . isScalarSlices ( slices ) ) || ( dimset . size ( ) == slices . size ( ) ) ; for ( int i = 0 ; i < dimset . size ( ) ; i ++ ) { Slice slice = slices . get ( i ) ; DapDimension dim = dimset . get ( i ) ; try { buf . append ( forconstraint ? slice . toConstraintString ( ) : slice . toString ( ) ) ; } catch ( DapException de ) { } } DapType basetype = seg . var . getBaseType ( ) ; // if the var is atomic, then we are done if ( basetype . isAtomic ( ) ) return ; // If structure and all fields are in the view, then done if ( basetype . getTypeSort ( ) . isCompound ( ) ) { DapStructure struct = ( DapStructure ) basetype ; if ( ! isWholeCompound ( struct ) ) { // Need to insert {...} and recurse buf . append ( LBRACE ) ; boolean first = true ; for ( DapVariable field : struct . getFields ( ) ) { if ( ! first ) buf . append ( ";" ) ; first = false ; Segment fseg = findSegment ( field ) ; dumpvar ( fseg , buf , forconstraint ) ; } buf . append ( RBRACE ) ; } if ( basetype . getTypeSort ( ) . isSeqType ( ) && seg . filter != null ) { buf . append ( "|" ) ; buf . append ( seg . filter . toString ( ) ) ; } } }


Input: Reference X match [CODESPLIT] public boolean references ( DapNode node ) { boolean isref = false ; switch ( node . getSort ( ) ) { case DIMENSION : DapDimension dim = this . redef . get ( ( DapDimension ) node ) ; if ( dim == null ) dim = ( DapDimension ) node ; isref = this . dimrefs . contains ( dim ) ; break ; case ENUMERATION : isref = ( this . enums . contains ( ( DapEnumeration ) node ) ) ; break ; case VARIABLE : isref = ( findVariableIndex ( ( DapVariable ) node ) >= 0 ) ; break ; case GROUP : case DATASET : isref = ( this . groups . contains ( ( DapGroup ) node ) ) ; break ; default : break ; } return isref ; }


Input: Selection X match <p > Evaluate a filter with respect to a Sequence record . Assumes the filter has been canonicalized . [CODESPLIT] public boolean match ( DapVariable sqvar , DapSequence seq , DataCursor rec ) throws DapException { Segment sseq = findSegment ( sqvar ) ; if ( sseq == null ) return false ; CEAST filter = sseq . filter ; if ( filter == null ) return true ; return matches ( sqvar , seq , rec , filter ) ; }


Input: Evaluate a filter with respect to a Sequence record . [CODESPLIT] protected boolean matches ( DapVariable var , DapSequence seq , DataCursor rec , CEAST filter ) throws DapException { Object value = eval ( var , seq , rec , filter ) ; return ( ( Boolean ) value ) ; }


Input: / * Search the set of variables [CODESPLIT] protected int findVariableIndex ( DapVariable var ) { for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { if ( variables . get ( i ) == var ) return i ; } return - 1 ; }


Input: Locate each unexpanded Structure|Sequence and : 1 . check that none of its fields is referenced = > do not expand 2 . add all of its fields as leaves Note that #2 may end up adding additional leaf structs & / or seqs [CODESPLIT] public void expand ( ) { // Create a queue of unprocessed leaf compounds Queue < DapVariable > queue = new ArrayDeque < DapVariable > ( ) ; for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( ! var . isTopLevel ( ) ) continue ; // prime the queue DapType base = var . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { DapStructure struct = ( DapStructure ) base ; // remember Sequence subclass Structure if ( expansionCount ( struct ) == 0 ) queue . add ( var ) ; } } // Process the queue in prefix order while ( queue . size ( ) > 0 ) { DapVariable vvstruct = queue . remove ( ) ; DapStructure dstruct = ( DapStructure ) vvstruct . getBaseType ( ) ; for ( DapVariable field : dstruct . getFields ( ) ) { if ( findVariableIndex ( field ) < 0 ) { // Add field as leaf this . segments . add ( new Segment ( field ) ) ; this . variables . add ( field ) ; } DapType fbase = field . getBaseType ( ) ; if ( fbase . getTypeSort ( ) . isCompound ( ) ) { if ( expansionCount ( ( DapStructure ) fbase ) == 0 ) queue . add ( field ) ; } } } this . expansion = Expand . EXPANDED ; }


Input: Locate each Structure|Sequence and : 1 . check that all of its fields are referenced recursively and not constrained otherwise ignore 2 . contract by removing all of the fields of the Structure or Sequence . This is intended to be ( not quite ) the dual of expand () ; [CODESPLIT] public void contract ( ) { // Create a set of contracted compounds Set < DapStructure > contracted = new HashSet <> ( ) ; for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( var . isTopLevel ( ) ) { DapType base = var . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { contractR ( ( DapStructure ) base , contracted ) ; } } } this . expansion = Expand . CONTRACTED ; }


Input: Recursive helper [CODESPLIT] protected boolean contractR ( DapStructure dstruct , Set < DapStructure > contracted ) { if ( contracted . contains ( dstruct ) ) return true ; int processed = 0 ; List < DapVariable > fields = dstruct . getFields ( ) ; for ( DapVariable field : fields ) { if ( findVariableIndex ( field ) < 0 ) break ; // this compound cannot be contracted DapType base = field . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) && ! contracted . contains ( ( field ) ) ) { if ( ! contractR ( ( DapStructure ) base , contracted ) ) break ; // this compound cannot be contracted } processed ++ ; } if ( processed < fields . size ( ) ) return false ; contracted . add ( dstruct ) ; // all compound fields were successfully contracted. return true ; }


Input: Count the number of fields of a structure that already in this view . [CODESPLIT] protected int expansionCount ( DapStructure struct ) { int count = 0 ; for ( DapVariable field : struct . getFields ( ) ) { if ( findVariableIndex ( field ) >= 0 ) count ++ ; } return count ; }


Input: See if a structure is whole which means that none of its fields is missing from the constraint all of fields use default ( non - constrained ) dimension ) and all of its fields are also whole . This must be done recursively . [CODESPLIT] protected boolean isWholeCompound ( DapStructure dstruct ) { int processed = 0 ; List < DapVariable > fields = dstruct . getFields ( ) ; for ( DapVariable field : fields ) { // not contractable if this field has non-original dimensions Segment seg = findSegment ( field ) ; if ( seg == null ) break ; // this compound is not whole List < Slice > slices = seg . slices ; if ( slices != null ) { for ( Slice slice : slices ) { if ( slice . isConstrained ( ) ) break ; } } DapType base = field . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { if ( ! isWholeCompound ( ( DapStructure ) base ) ) break ; // this compound is not whole } processed ++ ; } return ( processed == fields . size ( ) ) ; }


Input: Compute dimension related information using slicing and redef info . In effect this is where projection constraints are applied <p > Assume that the constraint compiler has given us the following info : <ol > <li > A list of the variables to include . <li > A pair ( DapDimension Slice ) for each redef <li > For each variable in #1 a list of slices taken from the constraint expression < / ol > <p > Two products will be produced . <ol > <li > The variables map will be modified so that the slices properly reflect any original or redef dimensions . <li > A set dimrefs of all referenced original dimensions . < / ol > <p > The processing is as follows <ol > <li > For each redef create a new redef dimension <li > For each variable : <ol > <li > if the variable is scalar do nothing . <li > if the variable has no associated slices then make its new dimensions be the original dimensions . <li > otherwise walk the slices and create new dimensions from them ; use redefs where indicated <li > < / ol > < / ol > [CODESPLIT] protected void computedimensions ( ) throws DapException { // Build the redefmap for ( DapDimension key : redefslice . keySet ( ) ) { Slice slice = redefslice . get ( key ) ; DapDimension newdim = ( DapDimension ) key . clone ( ) ; newdim . setSize ( slice . getCount ( ) ) ; redef . put ( key , newdim ) ; } // Process each variable for ( int i = 0 ; i < segments . size ( ) ; i ++ ) { Segment seg = segments . get ( i ) ; if ( seg . var . getRank ( ) == 0 ) continue ; List < Slice > slices = seg . slices ; List < DapDimension > orig = seg . var . getDimensions ( ) ; List < DapDimension > newdims = new ArrayList <> ( ) ; // If the slice list is short then pad it with // default slices if ( slices == null ) slices = new ArrayList < Slice > ( ) ; while ( slices . size ( ) < orig . size ( ) ) // pad { slices . add ( new Slice ( ) . setConstrained ( false ) ) ; } assert ( slices != null && slices . size ( ) == orig . size ( ) ) ; for ( int j = 0 ; j < slices . size ( ) ; j ++ ) { Slice slice = slices . get ( j ) ; DapDimension dim0 = orig . get ( j ) ; DapDimension newdim = redef . get ( dim0 ) ; if ( newdim == null ) newdim = dim0 ; // fill in the undefined last value slice . setMaxSize ( newdim . getSize ( ) ) ; slice . finish ( ) ; Slice newslice = null ; if ( slice . isConstrained ( ) ) { // Construct an anonymous dimension for this slice newdim = new DapDimension ( slice . getCount ( ) ) ; } else { // replace with a new slice from the dim newslice = new Slice ( newdim ) ; if ( newslice != null ) { // track set of referenced non-anonymous dimensions if ( ! dimrefs . contains ( dim0 ) ) dimrefs . add ( dim0 ) ; slices . set ( j , newslice ) ; } } // record the dimension per variable newdims . add ( newdim ) ; } seg . setDimset ( newdims ) ; } }


Input: Walk all the included variables and accumulate the referenced enums [CODESPLIT] protected void computeenums ( ) { for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( var . getSort ( ) != DapSort . VARIABLE ) continue ; DapType daptype = var . getBaseType ( ) ; if ( ! daptype . isEnumType ( ) ) continue ; if ( ! this . enums . contains ( ( DapEnumeration ) daptype ) ) this . enums . add ( ( DapEnumeration ) daptype ) ; } }


Input: Walk all the included declarations and accumulate the set of referenced groups [CODESPLIT] protected void computegroups ( ) { // 1. variables for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; List < DapGroup > path = var . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } } // 2. Dimensions for ( DapDimension dim : this . dimrefs ) { if ( ! dim . isShared ( ) ) continue ; List < DapGroup > path = dim . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } } // 2. enumerations for ( DapEnumeration en : this . enums ) { List < DapGroup > path = en . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } } }


Input: Static Utility for compiling a constraint string [CODESPLIT] static public CEConstraint compile ( String sce , DapDataset dmr ) throws DapException { // Process any constraint if ( sce == null || sce . length ( ) == 0 ) return CEConstraint . getUniversal ( dmr ) ; CEParserImpl ceparser = new CEParserImpl ( dmr ) ; if ( PARSEDEBUG ) ceparser . setDebugLevel ( 1 ) ; if ( DEBUG ) { System . err . println ( "Dap4Servlet: parsing constraint: |" + sce + "|" ) ; } boolean ok ; try { ok = ceparser . parse ( sce ) ; } catch ( ParseException pe ) { ok = false ; } if ( ! ok ) throw new DapException ( "Constraint parse failed: " + sce ) ; CEAST root = ceparser . getCEAST ( ) ; CECompiler compiler = new CECompiler ( ) ; CEConstraint ce = compiler . compile ( dmr , root ) ; ce . expand ( ) ; ce . finish ( ) ; return ce ; }


Input: Write the variable s declaration in a C - style syntax . This method is used to create textual representation of the Data Descriptor Structure ( DDS ) . [CODESPLIT] public final void printDecl ( PrintWriter os , String space , boolean print_semi ) { printDecl ( os , space , print_semi , false ) ; }


Input: Returns a clone of this <code > PrimitiveVector< / code > . See DAPNode . cloneDag () [CODESPLIT] public DAPNode cloneDAG ( CloneMap map ) throws CloneNotSupportedException { PrimitiveVector v = ( PrimitiveVector ) super . cloneDAG ( map ) ; v . var = ( BaseType ) cloneDAG ( map , var ) ; return v ; }


Input:
/ * 1 ) single runtime 1a timeOffset 1b time or timeRange 1c none = constant runtime dataset 2 ) multiple runtimes 2a timeOffset = constant offset dataset 2b time ( not range ) = constant forecast dataset [CODESPLIT] public Optional < List < CoverageCoordAxis > > subset ( SubsetParams params , AtomicBoolean isConstantForcast , boolean makeCFcompliant ) { return Optional . empty ( "not implemented by " + getClass ( ) . getName ( ) ) ; /* List<CoverageCoordAxis> result = new ArrayList<>();

    Optional<CoverageCoordAxis> axiso = runAxis.subset(params);
    if (!axiso.isPresent())
      return Optional.empty(axiso.getErrorMessage());
    CoverageCoordAxis1D runAxisSubset = (CoverageCoordAxis1D) axiso.get();
    result.add(runAxisSubset);

    // subset on timeOffset (1a, 1c, 2a)
    if (params.hasTimeOffsetParam() || !params.hasTimeParam()) {
      axiso = timeAxis2D.subset(params);
      if (!axiso.isPresent())
        return Optional.empty(axiso.getErrorMessage());
      CoverageCoordAxis timeOffsetSubset = axiso.get();
      result.add(timeOffsetSubset);

      if (makeCFcompliant)
        result.add(makeCFTimeCoord(runAxisSubset, (CoverageCoordAxis1D) timeOffsetSubset)); // possible the twoD time case, if nruns > 1
      return Optional.of(result);
    }

    // subset on time, # runtimes = 1 (1b)
    if (runAxisSubset.getNcoords() == 1) {
      double val = runAxisSubset.getCoord(0);   // not sure runAxis is needed. maybe use runtimeSubset
      CalendarDate runDate = runAxisSubset.makeDate(val);
      Optional<TimeOffsetAxis> too = timeAxis2D.subsetFromTime(params, runDate);
      if (!too.isPresent())
        return Optional.empty(too.getErrorMessage());
      TimeOffsetAxis timeOffsetSubset =  too.get();
      result.add(timeOffsetSubset);

      if (makeCFcompliant)
        result.add(makeCFTimeCoord(runAxisSubset, timeOffsetSubset));
      return Optional.of(result);
    }

    // tricky case 2b time (point only not range) = constant forecast dataset
    // data reader has to skip around the 2D times
    // 1) the runtimes may be subset by whats available
    // 2) timeOffset could become an aux coordinate
    // 3) time coordinate becomes a scalar,
    isConstantForcast.set(true);

    CalendarDate dateWanted;
    if (params.isTrue(SubsetParams.timePresent))
      dateWanted = CalendarDate.present();
    else
      dateWanted = (CalendarDate) params.get(SubsetParams.time);
    if (dateWanted == null)
      throw new IllegalStateException("Must have time parameter");

    double wantOffset = runAxisSubset.convert(dateWanted); // forecastDate offset from refdate
    double start = timeAxis.getStartValue();
    double end = timeAxis.getEndValue();
    CoordAxisHelper helper = new CoordAxisHelper(timeOffset);

    // brute force search LOOK specialize for regular ?
    List<Integer> runtimeIdx = new ArrayList<>();  // list of runtime indexes that have this forecast
    // List<Integer> offsetIdx = new ArrayList<>();  // list of offset indexes that have this forecast
    List<Double> offset = new ArrayList<>();      // corresponding offset from start of run
    for (int i=0; i<runAxisSubset.getNcoords(); i++) {
      // public double getOffsetInTimeUnits(CalendarDate convertFrom, CalendarDate convertTo);
      double runOffset = runAxisSubset.getCoord(i);
      if (end + runOffset < wantOffset) continue;
      if (wantOffset < start + runOffset) break;
      int idx = helper.search(wantOffset - runOffset);
      if (idx >= 0) {
        runtimeIdx.add(i);  // the ith runtime
        // offsetIdx.add(idx);   // the idx time offset
        offset.add(wantOffset - runOffset);   // the offset from the runtime
      }
    }

    // here are the runtimes
    int ncoords = runtimeIdx.size();
    double[] runValues = new double[ncoords];
    double[] offsetValues = new double[ncoords];
    int count = 0;
    for (int k=0; k<ncoords; k++) {
      offsetValues[count] = offset.get(k);
      runValues[count++] = runAxisSubset.getCoord( runtimeIdx.get(k));
    }

    CoverageCoordAxisBuilder runbuilder = new CoverageCoordAxisBuilder(runAxisSubset)
            .subset(null, CoverageCoordAxis.Spacing.irregularPoint, ncoords, runValues); // LOOK check for regular (in CovCoordAxis ?)
    CoverageCoordAxis1D runAxisSubset2 = new CoverageCoordAxis1D(runbuilder);

    CoverageCoordAxisBuilder timebuilder = new CoverageCoordAxisBuilder(timeOffset)
            .subset(runAxisSubset2.getName(), CoverageCoordAxis.Spacing.irregularPoint, ncoords, offsetValues); // aux coord (LOOK interval) ??
    CoverageCoordAxis1D timeOffsetSubset = new TimeOffsetAxis(timebuilder);

    CoverageCoordAxis scalarTimeCoord = makeScalarTimeCoord(wantOffset, runAxisSubset);

    // nothing needed for CF, the run coordinate acts as the CF time independent coord. timeOffset is aux, forecastTime is scalar
    return Optional.of(Lists.newArrayList(runAxisSubset2, timeOffsetSubset, scalarTimeCoord)); // */ }


Input: accept grib2 or ncx files [CODESPLIT] @ Override public boolean isValidFile ( RandomAccessFile raf ) throws IOException { if ( raf instanceof HTTPRandomAccessFile ) { // only do remote if memory resident if ( raf . length ( ) > raf . getBufferSize ( ) ) return false ; } else { // wont accept remote index GribCdmIndex . GribCollectionType type = GribCdmIndex . getType ( raf ) ; if ( type == GribCdmIndex . GribCollectionType . GRIB2 ) return true ; if ( type == GribCdmIndex . GribCollectionType . Partition2 ) return true ; } // check for GRIB2 data file return Grib2RecordScanner . isValidFile ( raf ) ; }


Input:
save all data in the PersistentStore [CODESPLIT] public void storePersistentData ( ) { store . putBeanObject ( VIEWER_SIZE , getSize ( ) ) ; store . putBeanObject ( SOURCE_WINDOW_SIZE , ( Rectangle ) sourceWindow . getBounds ( ) ) ; if ( fileChooser != null ) fileChooser . save ( ) ; if ( datasetChooser != null ) datasetChooser . save ( ) ; if ( sourcePane != null ) sourcePane . save ( ) ; /* if (catEditor != null) catEditor.save();
    if (catCrawler != null) catCrawler.save();
    if (serverConfigure != null) serverConfigure.save();
    if (catCopier != null) catCopier.save();   */ }


Input:
actions that are system - wide [CODESPLIT] private void makeActionsSystem ( ) { /* aboutAction = new AbstractAction() {
      public void actionPerformed(ActionEvent evt) {
        new AboutWindow();
      }
    };
    BAMutil.setActionProperties( aboutAction, null, "About", false, 'A', 0); */ /* printAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        PrinterJob printJob = PrinterJob.getPrinterJob();
        PageFormat pf = printJob.defaultPage();

        // do we need to rotate ??
        if (panz.wantRotate( pf.getImageableWidth(), pf.getImageableHeight()))
          pf.setOrientation( PageFormat.LANDSCAPE);
        else
          pf.setOrientation(PageFormat.PORTRAIT);

        printJob.setPrintable(controller.getPrintable(), pf);
        if (printJob.printDialog()) {
          try {
            if (Debug.isSet("print.job")) System.out.println("call printJob.print");
            printJob.print();
            if (Debug.isSet("print.job")) System.out.println(" printJob done");
          } catch (Exception PrintException) {
            PrintException.printStackTrace();
          }
        }
      }
    };
    BAMutil.setActionProperties( printAction, "Print", "Print...", false, 'P', KeyEvent.VK_P);

    sysConfigAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        if (sysConfigDialog == null)
          makeSysConfigWindow();
        sysConfigDialog.show();
      }
    };
    BAMutil.setActionProperties( sysConfigAction, "Preferences", "Configure...", false, 'C', -1);

    clearDebugFlagsAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) { Debug.clear(); }
    };
    BAMutil.setActionProperties( clearDebugFlagsAction, null, "Clear DebugFlags", false, 'D', -1);

    clearRecentAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        recentDatasetList = new ArrayList();
      }
    };
    BAMutil.setActionProperties( clearRecentAction, null, "Clear Recent Datasets", false, 'R', -1);
    */ AbstractAction clearDebugFlagsAction = new AbstractAction ( ) { public void actionPerformed ( ActionEvent e ) { /* Debug.clear(); */ } } ; BAMutil . setActionProperties ( clearDebugFlagsAction , null , "Clear Debug Flags" , false , ' ' , - 1 ) ; /* AbstractAction setDebugFlagsAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        // LOOK set netcdf debug flags

        InvCatalogFactory.debugURL = Debug.isSet("InvCatalogFactory/debugURL");
        InvCatalogFactory.debugOpen = Debug.isSet("InvCatalogFactory/debugOpen");
        InvCatalogFactory.debugVersion = Debug.isSet("InvCatalogFactory/debugVersion");
        InvCatalogFactory.showParsedXML = Debug.isSet("InvCatalogFactory/showParsedXML");
        InvCatalogFactory.showStackTrace = Debug.isSet("InvCatalogFactory/showStackTrace");
        InvCatalogFactory.debugXML = Debug.isSet("InvCatalogFactory/debugXML");
        InvCatalogFactory.debugDBurl = Debug.isSet("InvCatalogFactory/debugDBurl");
        InvCatalogFactory.debugXMLopen = Debug.isSet("InvCatalogFactory/debugXMLopen");
        InvCatalogFactory.showCatalogXML = Debug.isSet("InvCatalogFactory/showCatalogXML");
      }
    };
    BAMutil.setActionProperties(setDebugFlagsAction, null, "Set Debug Flags", false, 'S', -1);  */ /* exitAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        topLevel.close();
      }
    };
    BAMutil.setActionProperties( exitAction, "Exit", "Exit", false, 'X', -1); */ }


Input: ////////////////////////////////////////////////////////////////// [CODESPLIT] boolean init ( ) { System . setProperty ( "tds.log.dir" , contentTdmDir . toString ( ) ) ; if ( ! Files . exists ( threddsConfig ) ) { log . error ( "config file {} does not exist, set -Dtds.content.root.path=<dir>" , threddsConfig ) ; System . out . printf ( "threddsConfig does not exist=%s%n" , threddsConfig ) ; return false ; } ThreddsConfigReader reader = new ThreddsConfigReader ( threddsConfig . toString ( ) , log ) ; for ( String location : reader . getRootList ( "catalogRoot" ) ) { Resource r = new FileSystemResource ( contentThreddsDir . toString ( ) + "/" + location ) ; catalogRoots . add ( r ) ; } // LOOK check TdsInit /* 4.3.15: grib index file placement, using DiskCache2  */ String gribIndexDir = reader . get ( "GribIndex.dir" , new File ( contentThreddsDir . toString ( ) , "cache/grib/" ) . getPath ( ) ) ; Boolean gribIndexAlwaysUse = reader . getBoolean ( "GribIndex.alwaysUse" , false ) ; Boolean gribIndexNeverUse = reader . getBoolean ( "GribIndex.neverUse" , false ) ; String gribIndexPolicy = reader . get ( "GribIndex.policy" , null ) ; DiskCache2 gribCache = gribIndexNeverUse ? DiskCache2 . getNoop ( ) : new DiskCache2 ( gribIndexDir , false , - 1 , - 1 ) ; gribCache . setPolicy ( gribIndexPolicy ) ; gribCache . setAlwaysUseCache ( gribIndexAlwaysUse ) ; gribCache . setNeverUseCache ( gribIndexNeverUse ) ; GribIndexCache . setDiskCache2 ( gribCache ) ; log . info ( "TDM set " + gribCache ) ; return true ; }


Input: Initialize the file read in all the metadata ( ala DM_OPEN ) [CODESPLIT] public static GempakFileReader getInstance ( RandomAccessFile raf , boolean fullCheck ) throws IOException { GempakFileReader gfr = new GempakFileReader ( ) ; gfr . init ( raf , fullCheck ) ; return gfr ; }


Input: Initialize the file read in all the metadata ( ala DM_OPEN ) [CODESPLIT] public boolean init ( RandomAccessFile raf , boolean fullCheck ) throws IOException { setByteOrder ( ) ; rf = raf ; fileSize = rf . length ( ) ; raf . seek ( 0 ) ; return init ( fullCheck ) ; }


Input: Initialize the file read in all the metadata ( ala DM_OPEN ) [CODESPLIT] protected boolean init ( boolean fullCheck ) throws IOException { if ( rf == null ) { throw new IOException ( "file has not been set" ) ; } dmLabel = new DMLabel ( ) ; boolean labelOk = dmLabel . init ( ) ; if ( ! labelOk ) { logError ( "not a GEMPAK file" ) ; return false ; } // Read the keys  (DM_RKEY) readKeys ( ) ; if ( keys == null ) { logError ( "Couldn't read keys" ) ; return false ; } // Read the headers (DM_RHDA) readHeaders ( ) ; if ( headers == null ) { logError ( "Couldn't read headers" ) ; return false ; } // Read the parts (DM_RPRT) readParts ( ) ; if ( parts == null ) { logError ( "Couldn't read parts" ) ; return false ; } // Read the file header info (DM_RFIL) readFileHeaderInfo ( ) ; if ( fileHeaderInfo == null ) { logError ( "Couldn't read file header info" ) ; return false ; } return true ; }


Input: Get the byte order for the machine type . [CODESPLIT] public int getByteOrder ( int kmachn ) { if ( ( kmachn == MTVAX ) || ( kmachn == MTULTX ) || ( kmachn == MTALPH ) || ( kmachn == MTLNUX ) || ( kmachn == MTIGPH ) ) { return RandomAccessFile . LITTLE_ENDIAN ; } return RandomAccessFile . BIG_ENDIAN ; }


Input: LOOK WTF ?? Set the machine type for this system . [CODESPLIT] void setByteOrder ( ) { String arch = System . getProperty ( "os.arch" ) ; if ( arch . equals ( "x86" ) || // Windows, Linux arch . equals ( "arm" ) || // Window CE arch . equals ( "x86_64" ) || // Windows64, Mac OS-X arch . equals ( "amd64" ) || // Linux64? arch . equals ( "alpha" ) ) { // Utrix, VAX, DECOS MTMACH = RandomAccessFile . LITTLE_ENDIAN ; } else { MTMACH = RandomAccessFile . BIG_ENDIAN ; } }


Input: Read the file header info ( DM_RFIL ) [CODESPLIT] protected void readFileHeaderInfo ( ) throws IOException { if ( dmLabel == null ) { return ; } int iread = dmLabel . kpfile ; int numheaders = dmLabel . kfhdrs ; String [ ] names = new String [ numheaders ] ; int [ ] lens = new int [ numheaders ] ; int [ ] types = new int [ numheaders ] ; for ( int i = 0 ; i < numheaders ; i ++ ) { names [ i ] = DM_RSTR ( iread ++ ) ; } for ( int i = 0 ; i < numheaders ; i ++ ) { lens [ i ] = DM_RINT ( iread ++ ) ; } for ( int i = 0 ; i < numheaders ; i ++ ) { types [ i ] = DM_RINT ( iread ++ ) ; } fileHeaderInfo = new ArrayList <> ( ) ; for ( int i = 0 ; i < numheaders ; i ++ ) { DMFileHeaderInfo ghi = new DMFileHeaderInfo ( ) ; ghi . kfhnam = names [ i ] ; ghi . kfhlen = lens [ i ] ; ghi . kfhtyp = types [ i ] ; fileHeaderInfo . add ( ghi ) ; } }


Input: Read in the row and column keys ( DM_KEY ) [CODESPLIT] protected void readKeys ( ) throws IOException { if ( dmLabel == null ) { return ; } keys = new DMKeys ( ) ; // read the row keys int num = dmLabel . krkeys ; List < Key > rkeys = new ArrayList <> ( num ) ; for ( int i = 0 ; i < num ; i ++ ) { String key = DM_RSTR ( dmLabel . kprkey + i ) ; rkeys . add ( new Key ( key , i , ROW ) ) ; } keys . kkrow = rkeys ; num = dmLabel . kckeys ; List < Key > ckeys = new ArrayList <> ( num ) ; for ( int i = 0 ; i < num ; i ++ ) { String key = DM_RSTR ( dmLabel . kpckey + i ) ; ckeys . add ( new Key ( key , i , COL ) ) ; } keys . kkcol = ckeys ; }


Input: Read the headers ( DM_RHDA ) [CODESPLIT] protected void readHeaders ( ) throws IOException { if ( dmLabel == null ) { return ; } headers = new DMHeaders ( ) ; List < int [ ] > rowHeaders = new ArrayList <> ( dmLabel . krow ) ; int istart = dmLabel . kprowh ; // first word is a valid flag so we have to add 1 to size int [ ] header ; for ( int i = 0 ; i < dmLabel . krow ; i ++ ) { header = new int [ dmLabel . krkeys + 1 ] ; DM_RINT ( istart , header ) ; if ( header [ 0 ] != IMISSD ) { headers . lstrw = i ; } rowHeaders . add ( header ) ; istart += header . length ; } headers . rowHeaders = rowHeaders ; List < int [ ] > colHeaders = new ArrayList <> ( dmLabel . kcol ) ; istart = dmLabel . kpcolh ; for ( int i = 0 ; i < dmLabel . kcol ; i ++ ) { header = new int [ dmLabel . kckeys + 1 ] ; DM_RINT ( istart , header ) ; if ( header [ 0 ] != IMISSD ) { headers . lstcl = i ; } colHeaders . add ( header ) ; istart += header . length ; } headers . colHeaders = colHeaders ; // some of the words are characters if ( needToSwap ) { int [ ] keyLoc = new int [ swapKeys . length ] ; String [ ] keyType = new String [ swapKeys . length ] ; boolean haveRow = false ; boolean haveCol = false ; for ( int i = 0 ; i < swapKeys . length ; i ++ ) { Key key = findKey ( swapKeys [ i ] ) ; keyLoc [ i ] = ( key != null ) ? key . loc + 1 : 0 ; keyType [ i ] = ( key != null ) ? key . type : "" ; if ( keyType [ i ] . equals ( ROW ) ) { haveRow = true ; } if ( keyType [ i ] . equals ( COL ) ) { haveCol = true ; } } if ( haveRow ) { for ( int [ ] toCheck : headers . rowHeaders ) { for ( int j = 0 ; j < swapKeys . length ; j ++ ) { if ( keyType [ j ] . equals ( ROW ) ) { if ( swapKeys [ j ] . equals ( "GVCD" ) && ! ( toCheck [ keyLoc [ j ] ] > GempakUtil . vertCoords . length ) ) { continue ; } GempakUtil . swp4 ( toCheck , keyLoc [ j ] , swapNum [ j ] ) ; } } } } if ( haveCol ) { for ( int [ ] toCheck : headers . colHeaders ) { for ( int j = 0 ; j < swapKeys . length ; j ++ ) { if ( keyType [ j ] . equals ( COL ) ) { if ( swapKeys [ j ] . equals ( "GVCD" ) && ! ( toCheck [ keyLoc [ j ] ] > GempakUtil . vertCoords . length ) ) { continue ; } GempakUtil . swp4 ( toCheck , keyLoc [ j ] , swapNum [ j ] ) ; } } } } } }


Input: Read the parts ( DM_RPRT ) [CODESPLIT] protected void readParts ( ) throws IOException { if ( dmLabel == null ) { return ; } int iread = dmLabel . kppart ; int numParts = dmLabel . kprt ; DMPart [ ] partArray = new DMPart [ numParts ] ; // read the part names for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] = new DMPart ( ) ; partArray [ i ] . kprtnm = DM_RSTR ( iread ++ ) ; } // read the part header lengths for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . klnhdr = DM_RINT ( iread ++ ) ; } // read the part types for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . ktyprt = DM_RINT ( iread ++ ) ; } // get number of parameters/per part. for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . kparms = DM_RINT ( iread ++ ) ; } // read parameter names for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List < DMParam > parms = new ArrayList <> ( numParms ) ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = new DMParam ( ) ; parms . add ( dmp ) ; dmp . kprmnm = DM_RSTR ( iread ++ ) ; } partArray [ i ] . params = parms ; } // read the scale for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . kscale = DM_RINT ( iread ++ ) ; } } // read the offset for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . koffst = DM_RINT ( iread ++ ) ; } } // read the nbits for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . kbits = DM_RINT ( iread ++ ) ; } } parts = new ArrayList <> ( numParts ) ; parts . addAll ( Arrays . asList ( partArray ) . subList ( 0 , numParts ) ) ; for ( DMPart part : parts ) { if ( part . ktyprt == MDRPCK ) { part . packInfo = new PackingInfo ( part ) ; } } }


Input: Run the program [CODESPLIT] public static void main ( String [ ] args ) throws IOException { if ( args . length == 0 ) { System . out . println ( "need to supply a GEMPAK grid file name" ) ; System . exit ( 1 ) ; } GempakFileReader gfr = getInstance ( getFile ( args [ 0 ] ) , true ) ; gfr . printFileLabel ( ) ; gfr . printKeys ( ) ; gfr . printHeaders ( ) ; gfr . printParts ( ) ; }


Input: Find a key with the given name [CODESPLIT] public Key findKey ( String name ) { if ( keys == null ) { return null ; } // search rows for ( Key key : keys . kkrow ) { if ( key . name . equals ( name ) ) { return key ; } } // search columns for ( Key key : keys . kkcol ) { if ( key . name . equals ( name ) ) { return key ; } } return null ; }


Input: Find the file header with this name [CODESPLIT] public DMFileHeaderInfo findFileHeader ( String name ) { if ( ( fileHeaderInfo == null ) || fileHeaderInfo . isEmpty ( ) ) { return null ; } for ( DMFileHeaderInfo fhi : fileHeaderInfo ) { if ( name . equals ( fhi . kfhnam ) ) { return fhi ; } } return null ; }


Input: Read in the values for the file header [CODESPLIT] public float [ ] getFileHeader ( String name ) throws IOException { DMFileHeaderInfo fh = findFileHeader ( name ) ; if ( ( fh == null ) || ( fh . kfhtyp != MDREAL ) ) { return null ; } int knt = fileHeaderInfo . indexOf ( fh ) ; // 0 based int iread = dmLabel . kpfile + 3 * dmLabel . kfhdrs ; for ( int i = 0 ; i < knt ; i ++ ) { DMFileHeaderInfo fhi = fileHeaderInfo . get ( i ) ; iread = iread + fhi . kfhlen + 1 ; } int nword = DM_RINT ( iread ) ; if ( nword <= 0 ) { logError ( "Invalid header length for " + name ) ; return null ; } iread ++ ; float [ ] rheader = new float [ nword ] ; if ( name . equals ( "NAVB" ) && needToSwap ) { DM_RFLT ( iread , 1 , rheader , 0 ) ; needToSwap = false ; iread ++ ; DM_RFLT ( iread , 1 , rheader , 1 ) ; needToSwap = true ; iread ++ ; DM_RFLT ( iread , nword - 2 , rheader , 2 ) ; } else { DM_RFLT ( iread , rheader ) ; } return rheader ; }


Input: Print the part information [CODESPLIT] public void printParts ( ) { if ( parts == null ) { return ; } for ( int i = 0 ; i < parts . size ( ) ; i ++ ) { System . out . println ( "\nParts[" + i + "]:" ) ; System . out . println ( parts . get ( i ) ) ; } }


Input: Find the part with the particular name . [CODESPLIT] public int getPartNumber ( String name ) { int part = 0 ; if ( ( parts != null ) && ! parts . isEmpty ( ) ) { for ( int i = 0 ; i < parts . size ( ) ; i ++ ) { String partName = parts . get ( i ) . kprtnm ; if ( partName . equals ( name ) ) { // gotta add 1 because parts are 1 based part = i + 1 ; break ; } } } return part ; }


Input: Find the part with the particular name . [CODESPLIT] public DMPart getPart ( String name ) { if ( ( parts != null ) && ! parts . isEmpty ( ) ) { for ( DMPart part : parts ) { String partName = part . kprtnm ; if ( partName . equals ( name ) ) { return part ; } } } return null ; }


Input: Get the pointer to the data . Taken from DM_RDTR [CODESPLIT] public int getDataPointer ( int irow , int icol , String partName ) { int ipoint = - 1 ; if ( ( irow < 1 ) || ( irow > dmLabel . krow ) || ( icol < 1 ) || ( icol > dmLabel . kcol ) ) { System . out . println ( "bad row or column number: " + irow + "/" + icol ) ; return ipoint ; } int iprt = getPartNumber ( partName ) ; if ( iprt == 0 ) { System . out . println ( "couldn't find part" ) ; return ipoint ; } // gotta subtract 1 because parts are 1 but List is 0 based DMPart part = parts . get ( iprt - 1 ) ; // check for valid data type if ( ( part . ktyprt != MDREAL ) && ( part . ktyprt != MDGRID ) && ( part . ktyprt != MDRPCK ) ) { System . out . println ( "Not a valid type" ) ; return ipoint ; } int ilenhd = part . klnhdr ; ipoint = dmLabel . kpdata + ( irow - 1 ) * dmLabel . kcol * dmLabel . kprt + ( icol - 1 ) * dmLabel . kprt + ( iprt - 1 ) ; return ipoint ; }


Input: Read an integer [CODESPLIT] public int DM_RINT ( int word ) throws IOException { if ( rf == null ) { throw new IOException ( "DM_RINT: no file to read from" ) ; } if ( dmLabel == null ) { throw new IOException ( "DM_RINT: reader not initialized" ) ; } rf . seek ( getOffset ( word ) ) ; // set the order if ( needToSwap ) { //if ((dmLabel.kmachn != MTMACH) && //   ((dmLabel.kvmst && ! mvmst) || //   (mvmst && !dmLabel.kvmst))) { rf . order ( RandomAccessFile . LITTLE_ENDIAN ) ; // swap } else { rf . order ( RandomAccessFile . BIG_ENDIAN ) ; } int idata = rf . readInt ( ) ; if ( IMISSD != dmLabel . kmissd ) { if ( idata == dmLabel . kmissd ) { idata = IMISSD ; } } rf . order ( RandomAccessFile . BIG_ENDIAN ) ; return idata ; }


Input: Read into an array of ints . [CODESPLIT] public void DM_RINT ( int word , int num , int [ ] iarray , int start ) throws IOException { for ( int i = 0 ; i < num ; i ++ ) { if ( start + i > iarray . length ) { throw new IOException ( "DM_RINT: start+num exceeds iarray length" ) ; } iarray [ start + i ] = DM_RINT ( word + i ) ; } }


Input: Read a float [CODESPLIT] public float DM_RFLT ( int word ) throws IOException { if ( rf == null ) { throw new IOException ( "DM_RFLT: no file to read from" ) ; } if ( dmLabel == null ) { throw new IOException ( "DM_RFLT: reader not initialized" ) ; } rf . seek ( getOffset ( word ) ) ; if ( needToSwap ) { // set the order //if ((dmLabel.kmachn != MTMACH) && //   ((dmLabel.kvmst && ! mvmst) || //   (mvmst && !dmLabel.kvmst))) { rf . order ( RandomAccessFile . LITTLE_ENDIAN ) ; // swap } else { rf . order ( RandomAccessFile . BIG_ENDIAN ) ; } float rdata = rf . readFloat ( ) ; if ( RMISSD != dmLabel . smissd ) { if ( Math . abs ( rdata - dmLabel . smissd ) < RDIFFD ) { rdata = RMISSD ; } } // reset to read normally rf . order ( RandomAccessFile . BIG_ENDIAN ) ; return rdata ; }


Input: Read into an array of ints . [CODESPLIT] public void DM_RFLT ( int word , int num , float [ ] rarray , int start ) throws IOException { for ( int i = 0 ; i < num ; i ++ ) { if ( start + i > rarray . length ) { throw new IOException ( "DM_RFLT: start+num exceeds rarray length" ) ; } rarray [ start + i ] = DM_RFLT ( word + i ) ; } }


Input: Read a String [CODESPLIT] public String DM_RSTR ( int isword , int nchar ) throws IOException { if ( rf == null ) { throw new IOException ( "DM_RSTR: no file to read from" ) ; } rf . seek ( getOffset ( isword ) ) ; return rf . readString ( nchar ) ; }


Input: Read the data [CODESPLIT] public RData DM_RDTR ( int irow , int icol , String partName ) throws IOException { return DM_RDTR ( irow , icol , partName , 1 ) ; }


Input: Read the real ( float ) data [CODESPLIT] public RData DM_RDTR ( int irow , int icol , String partName , int decimalScale ) throws IOException { int ipoint = - 1 ; if ( ( irow < 1 ) || ( irow > dmLabel . krow ) || ( icol < 1 ) || ( icol > dmLabel . kcol ) ) { System . out . println ( "bad row/column number " + irow + "/" + icol ) ; return null ; } //System.out.println("reading row " + irow + ", column " + icol); int iprt = getPartNumber ( partName ) ; if ( iprt == 0 ) { System . out . println ( "couldn't find part: " + partName ) ; return null ; } // gotta subtract 1 because parts are 1 but List is 0 based DMPart part = parts . get ( iprt - 1 ) ; // check for valid real data type if ( ( part . ktyprt != MDREAL ) && ( part . ktyprt != MDGRID ) && ( part . ktyprt != MDRPCK ) ) { System . out . println ( "Not a valid type" ) ; return null ; } int ilenhd = part . klnhdr ; ipoint = dmLabel . kpdata + ( irow - 1 ) * dmLabel . kcol * dmLabel . kprt + ( icol - 1 ) * dmLabel . kprt + ( iprt - 1 ) ; float [ ] rdata ; int [ ] header = null ; int istart = DM_RINT ( ipoint ) ; if ( istart == 0 ) { return null ; } // start catching up here because some files are incorrectly written try { int length = DM_RINT ( istart ) ; int isword = istart + 1 ; if ( length <= ilenhd ) { //System.out.println("length (" + length //                   + ") is less than header length (" + ilenhd //                   + ")"); return null ; } else if ( Math . abs ( length ) > 10000000 ) { //System.out.println("length is huge"); return null ; } header = new int [ ilenhd ] ; DM_RINT ( isword , header ) ; int nword = length - ilenhd ; isword += header . length ; if ( part . ktyprt == MDREAL ) { rdata = new float [ nword ] ; DM_RFLT ( isword , rdata ) ; } else if ( part . ktyprt == MDGRID ) { rdata = DM_RPKG ( isword , nword , decimalScale ) ; } else { //  packed ints int [ ] idata = new int [ nword ] ; DM_RINT ( isword , idata ) ; rdata = DM_UNPK ( part , idata ) ; } } catch ( EOFException eof ) { //System.err.println("reading off end of file"); rdata = null ; } RData rd = null ; if ( rdata != null ) { rd = new RData ( header , rdata ) ; } return rd ; }


Input: Unpack an array of packed integers . [CODESPLIT] public float [ ] DM_UNPK ( DMPart part , int [ ] ibitst ) { int nparms = part . kparms ; int nwordp = part . kwordp ; int npack = ( ibitst . length - 1 ) / nwordp + 1 ; if ( npack * nwordp != ibitst . length ) { //logError("number of packed records not correct"); // System.out.println("number of packed records not correct: " //                   + npack * nwordp + " vs. " + ibitst.length); return null ; } float [ ] data = new float [ nparms * npack ] ; PackingInfo pkinf = part . packInfo ; int ir = 0 ; int ii = 0 ; for ( int pack = 0 ; pack < npack ; pack ++ ) { // //  Move bitstring into internal words.  TODO: necessary? // int [ ] jdata = new int [ nwordp ] ; System . arraycopy ( ibitst , ii , jdata , 0 , nwordp ) ; // //  Extract each data value. // for ( int idata = 0 ; idata < nparms ; idata ++ ) { // //  Extract correct bits from words using shift and mask //  operations. // int jbit = pkinf . nbitsc [ idata ] ; int jsbit = pkinf . isbitc [ idata ] ; int jshift = 1 - jsbit ; int jsword = pkinf . iswrdc [ idata ] ; int jword = jdata [ jsword ] ; // use >>> to shift avoid carrying sign along int mask = mskpat >>> ( 32 - jbit ) ; int ifield = jword >>> Math . abs ( jshift ) ; ifield = ifield & mask ; if ( ( jsbit + jbit - 1 ) > 32 ) { jword = jdata [ jsword + 1 ] ; jshift = jshift + 32 ; int iword = jword << jshift ; iword = iword & mask ; ifield = ifield | iword ; } // //  The integer data is now in ifield.  Use the scaling and //  offset terms to convert to REAL data. // if ( ifield == pkinf . imissc [ idata ] ) { data [ ir + idata ] = RMISSD ; } else { data [ ir + idata ] = ( ifield + pkinf . koffst [ idata ] ) * ( float ) pkinf . scalec [ idata ] ; } } ir += nparms ; ii += nwordp ; } return data ; }


Input: Get a bit string for an integer [CODESPLIT] protected static String getBits ( int b ) { Formatter s = new Formatter ( ) ; for ( int i = 31 ; i >= 0 ; i -- ) { if ( ( b & ( 1 << i ) ) != 0 ) { s . format ( "1" ) ; } else { s . format ( "0" ) ; } if ( i % 8 == 0 ) { s . format ( "|" ) ; } } return s . toString ( ) ; }


Input: ////////////////////////////////////////////////////////////////////////////////////////////// [CODESPLIT] public void writeDataAll ( WritableByteChannel channel ) throws IOException , InvalidRangeException { for ( Vinfo vinfo : vinfoList ) { if ( ! vinfo . isRecord ) { Variable v = vinfo . v ; // assert filePos == vinfo.offset; //if (debugPos) System.out.println(" writing at "+filePos+" should be "+vinfo.offset+" "+v.getFullName()); int nbytes = ( int ) v . readToByteChannel ( v . getShapeAsSection ( ) , channel ) ; filePos += nbytes ; filePos += pad ( channel , nbytes ) ; if ( debugPos ) System . out . printf ( " read=%d vinfo=%s%n" , nbytes , vinfo ) ; } } // must use record dimension if it exists+ boolean useRecordDimension = ncfile . hasUnlimitedDimension ( ) ; if ( useRecordDimension ) { ncfile . sendIospMessage ( NetcdfFile . IOSP_MESSAGE_ADD_RECORD_STRUCTURE ) ; Structure recordVar = ( Structure ) ncfile . findVariable ( "record" ) ; Section section = new Section ( ) . appendRange ( null ) ; long bytesDone = 0 ; long done = 0 ; long nrecs = ( int ) recordVar . getSize ( ) ; int structureSize = recordVar . getElementSize ( ) ; int readAtaTime = Math . max ( 10 , buffer_size / structureSize ) ; for ( int count = 0 ; count < nrecs ; count += readAtaTime ) { long last = Math . min ( nrecs , done + readAtaTime ) ; // dont go over nrecs int need = ( int ) ( last - done ) ; // how many to read this time section . setRange ( 0 , new Range ( count , count + need - 1 ) ) ; try { bytesDone += recordVar . readToByteChannel ( section , channel ) ; done += need ; } catch ( InvalidRangeException e ) { e . printStackTrace ( ) ; break ; } } assert done == nrecs ; bytesDone /= 1000 * 1000 ; if ( debugWrite ) System . out . println ( "write record var; total = " + bytesDone + " Mbytes # recs=" + done ) ; // remove the record structure this is rather fishy, perhaps better to leave it ncfile . sendIospMessage ( NetcdfFile . IOSP_MESSAGE_REMOVE_RECORD_STRUCTURE ) ; ncfile . finish ( ) ; } }


Input: ////////////////////////////////////// [CODESPLIT] public static void writeFromFile ( NetcdfFile fileIn , String fileOutName ) throws IOException , InvalidRangeException { try ( FileOutputStream stream = new FileOutputStream ( fileOutName ) ) { WritableByteChannel channel = stream . getChannel ( ) ; DataOutputStream dout = new DataOutputStream ( Channels . newOutputStream ( channel ) ) ; N3channelWriter writer = new N3channelWriter ( fileIn ) ; int numrec = fileIn . getUnlimitedDimension ( ) == null ? 0 : fileIn . getUnlimitedDimension ( ) . getLength ( ) ; writer . writeHeader ( dout , numrec ) ; dout . flush ( ) ; writer . writeDataAll ( channel ) ; } }


Input: Write ncfile to a WritableByteChannel . [CODESPLIT] public static void writeToChannel ( NetcdfFile ncfile , WritableByteChannel wbc ) throws IOException , InvalidRangeException { DataOutputStream stream = new DataOutputStream ( new BufferedOutputStream ( Channels . newOutputStream ( wbc ) , 8000 ) ) ; //DataOutputStream stream = new DataOutputStream(Channels.newOutputStream(wbc));  // buffering seems to improve by 5% N3channelWriter writer = new N3channelWriter ( ncfile ) ; int numrec = ncfile . getUnlimitedDimension ( ) == null ? 0 : ncfile . getUnlimitedDimension ( ) . getLength ( ) ; writer . writeHeader ( stream , numrec ) ; stream . flush ( ) ; writer . writeDataAll ( wbc ) ; }


Input:
Parse the DDX waiting in the <code > InputStream< / code > and instantiate all of the member <code > BaseType< / code > variables and their associated <code > Attributes < / code > into a <code > DDS< / code > using the passed <code > BaseTypeFactory< / code > [CODESPLIT] public void parse ( Document ddx , DDS targetDDS , BaseTypeFactory fac , boolean validation ) throws DAP2Exception { dds = targetDDS ; factory = fac ; // Build up the OPeNDAP data objects rpresented by the XML document.
 // Additional validation will take place  during this process.
 Element root = ddx . getRootElement ( ) ; lastDoc = ddx ; // This is just a little tracker to help with debugging.
 parseLevel = 0 ; // Make sure the root element is in fact a Dataset.
 // Trying to enforce this in the schema would create a
 // contrived and difficult to interpret schema design.
 String type = root . getName ( ) ; if ( ! ( type . equals ( "Dataset" ) ) ) { throw new NoSuchTypeException ( "Root Element MUST be <Dataset>. Found: " + type ) ; } String name = root . getAttribute ( "name" ) . getValue ( ) ; //System.out.println("DDS should be named: "+name);
 dds . setClearName ( name ) ; parentDC = dds ; currentBT = dds ; // Parse any Attributes (or AttributeTables/containers) at the
 // top level in the Dataset.
 parseAttributes ( root , "-- " ) ; // Parse any Aliases at the
 // top level in the Dataset.
 parseAliases ( root , "++ " ) ; // Parse all of the child elements (which would be OPeNDAP
 // BaseType variables) in the Dataset.
 Iterator ci = root . getChildren ( ) . iterator ( ) ; while ( ci . hasNext ( ) ) { Element child = ( Element ) ci . next ( ) ; parseBase ( child , "    " ) ; } //	catch(Exception e) {
 //	    throw new DAP2Exception("PARSER ERROR! \n"+
 //	                            e.getClass().getName()+ ": "+e.getMessage());
 //	}
 }


Input:
Parse the DDX waiting in the <code > InputStream< / code > and instantiate all of the member <code > BaseType< / code > variables and their associated <code > Attributes < / code > into a <code > DDS< / code > using the passed <code > BaseTypeFactory< / code > [CODESPLIT] public void parse ( InputStream is , DDS targetDDS , BaseTypeFactory fac , boolean validation ) throws DAP2Exception { try { // get a jdom parser to parse and validate the XML document.
 SAXBuilder parser = new SAXBuilder ( ) ; // optionally turn on validation
 parser . setFeature ( "http://apache.org/xml/features/validation/schema" , validation ) ; // parse the document into a hierarchical document
 Document doc = parser . build ( is ) ; if ( _Debug ) System . out . println ( "Document is " + ( validation ? "valid and " : "" ) + "well-formed.\nContent: " + doc ) ; parse ( doc , targetDDS , fac , validation ) ; } catch ( JDOMException jde ) { throw new DAP2Exception ( jde ) ; } catch ( IOException ioe ) { throw new DAP2Exception ( ioe ) ; } }


Input:
This method recursively travels through the DOM tree locating BaseType derived nodes and placing them in the DDS . The structure of the BaseType derived elements in the XML instance document is captured in the DOM object that is being parsed . This structure again reflected in the resulting DDS . [CODESPLIT] private void parseBase ( Element e , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { parseLevel ++ ; String type = e . getName ( ) ; if ( type . equals ( "Attribute" ) ) { // Do nothing here, the Attributes get parsed when the BaseType's
 // get built. This conditional basically serves as a "trap" to
 // ignore the <Attribute> tag.
 } else if ( type . equals ( "Alias" ) ) { // Do nothing here, the Aliases get parsed when the BaseType's
 // get built. This conditional basically serves as a "trap" to
 // ignore the <Alias> tag.
 } else if ( type . equals ( "dataBLOB" ) ) { // dataBLOB?
 // The schema says that the href attribute is
 // required for the dataBLOB element.
 org . jdom2 . Attribute hrefAttr = e . getAttribute ( "href" ) ; // Since it's required we know that the getAttribute()
 // method is not going to return null.
 String contentID = hrefAttr . getValue ( ) ; if ( _Debug ) System . out . println ( "Found dataBLOB element. contentID=\"" + contentID + "\"" ) ; dds . setBlobContentID ( contentID ) ; } else { // What's left must be a OPeNDAP BaseType
 if ( _Debug ) System . out . println ( "Parsing new BaseType element. Parse level: " + parseLevel ) ; if ( _Debug ) showXMLElement ( e , indent ) ; // Go get a new BaseType formed from this element
 BaseType bt = newBaseType ( e ) ; // Set it's parent.
 // bt.setParent(parentDC);
 // Add it to it's parent (container)
 parentDC . addVariable ( bt ) ; // Now we need to make sure this particular BaseType
 // derived element isn't some special type that needs
 // additional parsing:
 // Is it a container?
 if ( bt instanceof DConstructor ) { // Up date the parsers state, (cache my parent)
 DConstructor myParentDC = parentDC ; parentDC = ( DConstructor ) bt ; try { // Grids are special containers, handle them
 if ( bt instanceof DGrid ) { parseGrid ( e , indent ) ; } else { // Otherwise, recurse on the children
 for ( Element child : e . getChildren ( ) ) { parseBase ( child , indent + "    " ) ; } } } finally { // restore my parent
 parentDC = myParentDC ; } } else if ( bt instanceof DArray ) { // Array's are special, better build it if it is one
 if ( _Debug ) System . out . println ( "Parsing Array instance.  Array name: '" + bt . getClearName ( ) + "'" ) ; parseArray ( e , ( DArray ) bt , indent ) ; } } parseLevel -- ; }


Input:
Arrays have special parsing need as their syntax is different from that of a typical BaseType derived type or a container type . The array is based on a template variable that can have ANY structure that can be represented by the OPeNDAP data model . With the exception of ( you knew this was comming right? ) of other arrays . IE You can t have Arrays of Arrays . This caveat is enforced by the XML schema . [CODESPLIT] private void parseArray ( Element ArrayElement , DArray da , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { int countTemplateVars = 0 ; int numDims = 0 ; for ( Element e : ArrayElement . getChildren ( ) ) { if ( _Debug ) System . out . println ( indent + "Working on Array element: " + e . getName ( ) ) ; // Is this element an Attribute of the Array?
 if ( e . getName ( ) . equals ( "Attribute" ) ) { //Then ignore it!
 } // Is this element an Attribute of the Alias?
 else if ( e . getName ( ) . equals ( "Alias" ) ) { //Then ignore it!
 } // Is this element an array dimension?
 else if ( e . getName ( ) . equals ( "dimension" ) ) { // Then count it,
 numDims ++ ; // And now let's add it to the array...
 // Array dimension are not required to have names, so
 // the schema does not enforce the use of the name attribute.
 // try to get the dimension's name, and use it id it's there.
 String name = null ; Attribute nameAttr = e . getAttribute ( "name" ) ; if ( nameAttr != null ) name = nameAttr . getValue ( ) ; // The presence of the 'size' attribute is enforeced by the schema.
 // get it, parse it, use it.
 int size = Integer . parseInt ( e . getAttribute ( "size" ) . getValue ( ) ) ; // add the dimension to the array.
 da . appendDim ( size , ( name ) ) ; } else { // otherwise, it must be THE template element.
 // Just to make sure the schema validation didn't fail (because
 // I am basically paranoid about software) count the number of
 // template candidates we find and throw an Exception later
 // if there was more than one.
 countTemplateVars ++ ; // The template element is just another BaseType
 // derived element. So, let's go build it!
 BaseType template = buildArrayTemplate ( e , indent ) ; // Oddly, in the OPeNDAP implementation of Array, the Array variable
 // takes it's name from it's (internal) template variable. This
 // is probably an artifact of the original DDSParser.
 // So, set the name of the template variable to the name of the Array.
 template . setClearName ( da . getClearName ( ) ) ; // Add the template variable to the Array
 da . addVariable ( template ) ; } } if ( _Debug ) { System . out . println ( indent + "Built Array: " ) ; da . printDecl ( System . out , indent ) ; System . out . println ( indent + "dimensions: " + numDims + "  templates: " + countTemplateVars ) ; } if ( countTemplateVars != 1 ) { throw new NoSuchTypeException ( "ONLY ONE (1) TEMPLATE VARIABLE ALLOWED PER ARRAY!" ) ; } }


Input:
Builds the template variable for an array . The logic here has a lot in common with the logic in parseBase . I considered trying to refactor the code so that the two methods could utilize the same logic but I bagged it . Cie la vie . <p / > Arrays of arrays are not allowed this rule should is enforced through the schema validation process . [CODESPLIT] private BaseType buildArrayTemplate ( Element template , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { BaseType bt = null ; if ( _Debug ) showXMLElement ( template , indent + "...:" ) ; // Get all of the Attribute elements (tagged <Attribute>)
 Iterator attrElements = template . getChildren ( "Attribute" , opendapNameSpace ) . iterator ( ) ; if ( attrElements . hasNext ( ) ) throw new BadSemanticsException ( "Array Template Variables MAY NOT have Attributes" ) ; // Build the appropriate BaseType from the tag.
 bt = newBaseType ( template ) ; if ( _Debug ) System . out . println ( "Got template: " + bt . getTypeName ( ) + "   " + bt . getClearName ( ) ) ; // Now we need to make sure this particular BaseType
 // derived element isn't some special type that needs
 // additional parsing:
 // Is it a container?
 if ( bt instanceof DConstructor ) { // Up date the parsers state, (cache my parent)
 DConstructor myParentDC = parentDC ; parentDC = ( DConstructor ) bt ; try { // Grids are special containers, handle them
 if ( bt instanceof DGrid ) { parseGrid ( template , indent ) ; } else { // Otherwise, recurse on the children
 for ( Element child : template . getChildren ( ) ) { parseBase ( child , indent + "    " ) ; } } } finally { // restore my parent
 parentDC = myParentDC ; } } return ( bt ) ; }


Input:
Grids are unusual examples of DConstructor and require special handling when parsing . [CODESPLIT] private void parseGrid ( Element gridElement , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { parseLevel ++ ; // Grab the parent object (which better be a Grid!)
 // just to elminate the hassle of casting everytime...
 DGrid myGrid = ( DGrid ) parentDC ; if ( _Debug ) { System . out . println ( "Parsing Grid Element: " + gridElement ) ; System . out . println ( "Grid Elements: " ) ; //showXMLElement(gridElement, indent);
 for ( Element element : gridElement . getChildren ( ) ) System . out . println ( element ) ; } // Get and parse the grid's Array element.
 String eName = "Array" ; if ( _Debug ) { System . out . println ( "Parsing Array element." ) ; System . out . println ( "Asking for element: '" + eName + "' in namespace: '" + opendapNameSpace + "'" ) ; } Element arrayElement = gridElement . getChild ( eName , opendapNameSpace ) ; if ( _Debug ) System . out . println ( "Got Array element: " + arrayElement ) ; DArray gridArray = ( DArray ) newBaseType ( arrayElement ) ; parseArray ( arrayElement , gridArray , indent + "    " ) ; // Add it to the Grid
 myGrid . addVariable ( gridArray , DGrid . ARRAY ) ; // Get the Map elements
 eName = "Map" ; if ( _Debug ) { System . out . println ( "Parsing Map elements." ) ; System . out . println ( "Asking for element: '" + eName + "' in namespace: '" + opendapNameSpace + "'" ) ; } List < Element > mapElements = gridElement . getChildren ( "Map" , opendapNameSpace ) ; // Make sure the number of Map elements matches the dimension of the Grid Array.
 if ( mapElements . size ( ) != gridArray . numDimensions ( ) ) throw new BadSemanticsException ( "Error in Grid syntax: " + "The number of Map arrays must " + "equal the number of dimensions " + "of the data array." ) ; // Parse each Map element and poke it into the Grid.
 for ( Element mapElement : mapElements ) { DArray thisMap = ( DArray ) newBaseType ( mapElement ) ; parseArray ( mapElement , thisMap , indent + "    " ) ; if ( thisMap . numDimensions ( ) != 1 ) throw new BadSemanticsException ( "Error in Grid syntax: " + "Maps may have only one dimension." ) ; myGrid . addVariable ( thisMap , DGrid . MAPS ) ; } parseLevel -- ; }


Input:
A convienience function used for displaying information in _Debug mode . Prints an XML element s name content ( if any ) and Attributes to System . out [CODESPLIT] private void showXMLElement ( Element e , String indent ) { System . out . print ( parseLevel + indent + "Element: " + e . getName ( ) + "  " ) ; String text = e . getTextNormalize ( ) ; if ( ! text . equals ( "" ) ) System . out . print ( " = " + text + "   " ) ; //System.out.println("");
 for ( Attribute att : e . getAttributes ( ) ) { //System.out.print(parseLevel + indent + "    ");
 System . out . print ( att . getName ( ) + ": " + att . getValue ( ) + "  " ) ; } System . out . println ( "" ) ; for ( Element kid : e . getChildren ( ) ) { showXMLElement ( kid , indent + "    " ) ; } }


Input:
/ * Builds a new BaseType derived type from the passed XML element . <p > This happens in 4 steps : <ul > <li > 1 ) Determine the OPeNDAP type and vairiable name < / li > <li > 2 ) Get an new one of the thing in ( 1 ) < / li > <li > 3 ) Parse any Attribute tags associated with this OPeNDAP type . ( They appear as children of the XML element ) < / li > <li > 4 ) Parse any Alias tags associated with this OPeNDAP type . ( They appear as children of the XML element ) < / li > < / ul > [CODESPLIT] private BaseType newBaseType ( Element e ) throws DASException , NoSuchTypeException { if ( _Debug ) System . out . println ( "Getting new BaseType() from: " + e ) ; // What's the Element Name? This IS the OPeNDAP typename.
 String type = e . getName ( ) ; // What is the name of this variable? Since BaseType derived types
 // are not required to have names we have to do this carefully.
 String name = null ; org . jdom2 . Attribute nameAttr = e . getAttribute ( "name" ) ; if ( nameAttr != null ) name = nameAttr . getValue ( ) ; if ( _Debug ) System . out . println ( "    type: " + type + "   name: '" + name + "'" ) ; // GO get a fresh new OPeNDAP variable (BaseType derived type)
 currentBT = newBaseTypeFactory ( type , name ) ; //Parse any Attribute tagged child elements for this variable.
 parseAttributes ( e , "--- " ) ; //Parse any Alias tagged child elements for this variable.
 parseAliases ( e , "+++ " ) ; return ( currentBT ) ; }


Input: The name of this method might be a bit misleading . This method is basically a wrapper for the BaseTypeFactory associated with the DDS that we are building . <p / > I think it should really be a method of BaseTypeFactory . <p / > Something like : <p / > BaseTypeFactory . getNewVariable ( String typeString String name ) <p / > But well BaseTypeFactory is an interface so that s a crappy idea . * sigh * [CODESPLIT] private BaseType newBaseTypeFactory ( String typeString , String name ) throws NoSuchTypeException { BaseType bt ; if ( typeString . equals ( "Array" ) || typeString . equals ( "Map" ) ) { bt = factory . newDArray ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Grid" ) ) { bt = factory . newDGrid ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Structure" ) ) { bt = factory . newDStructure ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Sequence" ) ) { bt = factory . newDSequence ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Int16" ) ) { bt = factory . newDInt16 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "UInt16" ) ) { bt = factory . newDUInt16 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Int32" ) ) { bt = factory . newDInt32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "UInt32" ) ) { bt = factory . newDUInt32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Float32" ) ) { bt = factory . newDFloat32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Float64" ) ) { bt = factory . newDFloat64 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Byte" ) ) { bt = factory . newDByte ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "String" ) ) { bt = factory . newDString ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Url" ) ) { bt = factory . newDURL ( ) ; bt . setClearName ( name ) ; } else throw new NoSuchTypeException ( "Unknown Type: " + typeString ) ; return bt ; }


Input:
Parse the Attribute tags for a given variable element in the XML document . Build the appropriate Attributes and AttributeTables and add them to the the current variable s ( currentBT s ) AttributeTable . [CODESPLIT] private void parseAttributes ( Element e , String indent ) throws DASException , NoSuchTypeException { parseLevel ++ ; String subIndent = indent + "    " ; if ( _Debug ) System . out . println ( indent + "Parsing Attributes: " ) ; if ( _Debug ) System . out . println ( subIndent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; // Get all of the Attribute elements (tagged <Attribute>)
 for ( Element attrElement : e . getChildren ( "Attribute" , opendapNameSpace ) ) { String name = null ; Attribute nameAttr = attrElement . getAttribute ( "name" ) ; // no need to check that the getAttribute call worked because the Schema enforces
 // the presence of the "name" attribute for the <Attribute> tag in the OPeNDAP namespace
 name = nameAttr . getValue ( ) ; String typeName = null ; Attribute typeAttr = attrElement . getAttribute ( "type" ) ; // no need to check that the getAttribute call worked because the Schema enforces
 // the presence of the "type" attribute for the <Attribute> tag in the OPeNDAP namespace
 typeName = typeAttr . getValue ( ) ; // Is this Attribute a container??
 if ( typeName . equals ( "Container" ) ) { // Make sure that the document is valid for Attribute Containers and Values
 Iterator valueChildren = attrElement . getChildren ( "value" , opendapNameSpace ) . iterator ( ) ; if ( valueChildren . hasNext ( ) ) throw new AttributeBadValueException ( "Container Attributes may " + "contain only other Attributes.\n" + "Container Attributes may NOT " + "contain values." ) ; // Cache the currentAT (AttributeTable), this might be a null
 // in which case the the container should be added to the currentBT.
 AttributeTable cacheAttributeTable = currentAT ; if ( _Debug ) System . out . println ( indent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; if ( _Debug ) System . out . println ( indent + "Attribute '" + name + "' is type " + typeName ) ; // Add the Attribute container to the appropriate object.
 // If the currentAT is null, this indicates that we are working
 // on the top level attributes for the currentBT, if it's not
 // then we are working on the Attributes for some AttributeTable
 // contained within the top level Attributes in the currentBT.
 // Set the currentAT to the newly built (and returned) AttributeTable
 if ( currentAT == null ) currentAT = currentBT . appendAttributeContainer ( name ) ; else currentAT = currentAT . appendContainer ( name ) ; // Go parse the child Attributes of this Attribute table.
 // Note that this is a recursive call.
 parseAttributes ( attrElement , indent + "    " ) ; // Now parse all of the Aliases that exist in this Attribute table.
 parseAliases ( attrElement , "+++ " ) ; // restore the currentAT from the cached one, thus regaining the
 // the state that we entered this method with.
 currentAT = cacheAttributeTable ; } else { // Make sure that the document is valid for Attribute Containers and Values
 Iterator attrChildren = attrElement . getChildren ( "Attribute" , opendapNameSpace ) . iterator ( ) ; if ( attrChildren . hasNext ( ) ) throw new AttributeBadValueException ( "Attributes must be of type Container " + "in order to contain other Attributes.\n" + "Attributes of types other than Container " + "must contain values." ) ; // Walk through the <value> elements
 for ( Element valueChild : attrElement . getChildren ( "value" , opendapNameSpace ) ) { // Get the content of the value.
 // There are several methods for getting this content in the
 // org.jdom2.Element object. The method getText() makes no effort
 // to "normalize" the white space content. IE tabs, spaces,
 // carriage return, newlines are all preserved. This might not
 // be the right thing to do, but only time will tell.
 String value = valueChild . getText ( ) ; if ( _Debug ) { System . out . println ( subIndent + "Attribute '" + name + "' of " + currentBT . getClearName ( ) + " is type " + typeName + " and has value: " + value ) ; } // get the Attribute value type code.
 int typeVal = opendap . dap . Attribute . getTypeVal ( typeName ) ; // Add the attribute and it's value to the appropriat
 // container. Note that the interface for appending
 // values to opendap.dap.Attributes is built such that
 // the Attribute must be named each time. If the Attribte
 // name already exists, then the value is added to the list
 // of values for the Attribute. If the Attribute name does not
 // already exist, a new Attribute is made to hold the value.
 if ( currentAT == null ) currentBT . appendAttribute ( name , typeVal , value , true ) ; else currentAT . appendAttribute ( name , typeVal , value , true ) ; } } } parseLevel -- ; }


Input:
Parse all of the Alias tags in this element of the XML document . Add each one to the correct Attribute Table . [CODESPLIT] private void parseAliases ( Element e , String indent ) throws DASException { parseLevel ++ ; String subIndent = indent + "    " ; if ( _Debug ) System . out . println ( indent + "Parsing Aliases: " ) ; if ( _Debug ) System . out . println ( subIndent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; // Get the Alias elements
 for ( Element aliasElement : e . getChildren ( "Alias" , opendapNameSpace ) ) { String name = null ; Attribute nameAttr = aliasElement . getAttribute ( "name" ) ; // no need to check that the getAttribute call worked because the Schema enforces
 // the presence of the "name" attribute for the <Alias> tag in the OPeNDAP namespace
 name = nameAttr . getValue ( ) ; String attributeName = null ; Attribute attributeAttr = aliasElement . getAttribute ( "Attribute" ) ; // no need to check that the getAttribute call worked because the Schema enforces
 // the presence of the "Attribute" attribute for the <Alias> tag in the OPeNDAP namespace
 attributeName = attributeAttr . getValue ( ) ; if ( _Debug ) { System . out . println ( subIndent + "The name '" + name + "' is aliased to dds attribute: '" + attributeName + "'" ) ; } // Add the Alias to the appropriate container.
 if ( currentAT == null ) currentBT . addAttributeAlias ( name , attributeName ) ; else currentAT . addAlias ( name , attributeName ) ; } parseLevel -- ; }


Input:
This method is used to normalize strings prior to their inclusion in XML documents . XML has certain parsing requirements around reserved characters . These reserved characters must be replaced with symbols recognized by the XML parser as place holder for the actual symbol . <p / > The rule for this normalization is as follows : <p / > <ul > <li > The &lt ; ( less than ) character is replaced with &amp ; lt ; <li > The &gt ; ( greater than ) character is replaced with &amp ; gt ; <li > The &amp ; ( ampersand ) character is replaced with &amp ; amp ; <li > The ( apostrophe ) character is replaced with &amp ; apos ; <li > The &quot ; ( double quote ) character is replaced with &amp ; quot ; < / ul > [CODESPLIT] public static String normalizeToXML ( String s ) { // Some handy definitons.
 String xmlGT = ">" ; String xmlLT = "<" ; String xmlAmp = "&" ; String xmlApos = "'" ; String xmlQuote = """ ; boolean Debug = false ; StringBuilder sb = new StringBuilder ( s ) ; for ( int offset = 0 ; offset < sb . length ( ) ; offset ++ ) { char c = sb . charAt ( offset ) ; switch ( c ) { case ' ' : // GreaterThan
 sb . replace ( offset , offset + 1 , xmlGT ) ; break ; case ' ' : // Less Than
 sb . replace ( offset , offset + 1 , xmlLT ) ; break ; case ' ' : // Ampersand
 sb . replace ( offset , offset + 1 , xmlAmp ) ; break ; case ' ' : // Single Quote
 sb . replace ( offset , offset + 1 , xmlApos ) ; break ; case ' ' : // Double Quote
 sb . replace ( offset , offset + 1 , xmlQuote ) ; break ; default : break ; } } //Coverity[DEADCODE]
 if ( Debug ) System . out . println ( "String: `" + s + "` normalized to: `" + sb + "`" ) ; return ( sb . toString ( ) ) ; }


Input: wml2 : Collection / wml2 : observationMember / om : OM_Observation / om : featureOfInterest [CODESPLIT] public static FeaturePropertyType initFeatureOfInterest ( FeaturePropertyType featureOfInterest , StationTimeSeriesFeature stationFeat ) { // wml2:MonitoringPoint MonitoringPointDocument monitoringPointDoc = MonitoringPointDocument . Factory . newInstance ( ) ; NcMonitoringPointType . initMonitoringPointType ( monitoringPointDoc . addNewMonitoringPoint ( ) , stationFeat ) ; featureOfInterest . set ( monitoringPointDoc ) ; return featureOfInterest ; }


Input: convert ids to DataDescriptors expand table D [CODESPLIT] private List < DataDescriptor > decode ( List < Short > keyDesc , BufrTableLookup lookup ) { if ( keyDesc == null ) return null ; List < DataDescriptor > keys = new ArrayList < DataDescriptor > ( ) ; for ( short id : keyDesc ) { DataDescriptor dd = new DataDescriptor ( id , lookup ) ; keys . add ( dd ) ; if ( dd . f == 3 ) { TableD . Descriptor tdd = lookup . getDescriptorTableD ( dd . fxy ) ; if ( tdd == null || tdd . getSequence ( ) == null ) { dd . bad = true ; } else { dd . name = tdd . getName ( ) ; dd . subKeys = decode ( tdd . getSequence ( ) , lookup ) ; } } } return keys ; }


Input:
look for replication move replicated items into subtree [CODESPLIT] private List < DataDescriptor > replicate ( List < DataDescriptor > keys ) { List < DataDescriptor > tree = new ArrayList < DataDescriptor > ( ) ; Iterator < DataDescriptor > dkIter = keys . iterator ( ) ; while ( dkIter . hasNext ( ) ) { DataDescriptor dk = dkIter . next ( ) ; if ( dk . f == 1 ) { dk . subKeys = new ArrayList < DataDescriptor > ( ) ; dk . replication = dk . y ; // replication count
 if ( dk . replication == 0 ) { // delayed replication
 root . isVarLength = true ; // variable sized data == deferred replication == sequence data
 // the next one is the replication count size : does not count in field count (x)
 DataDescriptor replication = dkIter . next ( ) ; if ( replication . y == 0 ) dk . replicationCountSize = 1 ; // ??
 else if ( replication . y == 1 ) dk . replicationCountSize = 8 ; else if ( replication . y == 2 ) dk . replicationCountSize = 16 ; else if ( replication . y == 11 ) dk . repetitionCountSize = 8 ; else if ( replication . y == 12 ) dk . repetitionCountSize = 16 ; else log . error ( "Unknown replication type= " + replication ) ; } // transfer to the subKey list
 for ( int j = 0 ; j < dk . x && dkIter . hasNext ( ) ; j ++ ) { dk . subKeys . add ( dkIter . next ( ) ) ; } // recurse
 dk . subKeys = replicate ( dk . subKeys ) ; } else if ( ( dk . f == 3 ) && ( dk . subKeys != null ) ) { dk . subKeys = replicate ( dk . subKeys ) ; // do at all levels
 } tree . add ( dk ) ; } return tree ; }


Input:
/ * try to grab names of compounds ( structs ) if f = 1 is followed by f = 3 eg : 0 - 40 - 20 : GQisFlagQualDetailed - Quality flag for the system 1 - 01 - 010 : replication 3 - 40 - 2 : ( IASI Level 1c band description ) 0 - 25 - 140 : Start channel 0 - 25 - 141 : End channel 0 - 25 - 142 : Channel scale factor 1 - 01 - 087 : replication 3 - 40 - 3 : ( IASI Level 1c 100 channels ) 1 - 04 - 100 : replication 2 - 01 - 136 : Operator = change data width 0 - 5 - 42 : Channel number 2 - 01 - 000 : Operator = change data width 0 - 14 - 46 : Scaled IASI radiance 0 - 2 - 19 : Satellite instruments 0 - 25 - 51 : AVHRR channel combination 1 - 01 - 007 : replication 3 - 40 - 4 : ( IASI Level 1c AVHRR single scene ) 0 - 5 - 60 : Y angular position from centre of gravity 0 - 5 - 61 : Z angular position from centre of gravity 0 - 25 - 85 : Fraction of clear pixels in HIRS FOV ... [CODESPLIT] private void grabCompoundNames ( List < DataDescriptor > tree ) { for ( int i = 0 ; i < tree . size ( ) ; i ++ ) { DataDescriptor key = tree . get ( i ) ; if ( key . bad ) continue ; if ( ( key . f == 3 ) && ( key . subKeys != null ) ) { grabCompoundNames ( key . subKeys ) ; } else if ( key . f == 1 && key . x == 1 && i < tree . size ( ) - 1 ) { // replicator with 1 element
 DataDescriptor nextKey = tree . get ( i + 1 ) ; if ( nextKey . f == 3 ) { // the one element is a compound
 if ( nextKey . name != null && ! nextKey . name . isEmpty ( ) ) key . name = nextKey . name ; } else if ( key . y == 0 && i < tree . size ( ) - 2 ) { // seq has an extra key before the 3
 DataDescriptor nnKey = tree . get ( i + 2 ) ; if ( nnKey . f == 3 ) if ( nnKey . name != null && ! nnKey . name . isEmpty ( ) ) key . name = nnKey . name ; } } } }


Input:
flatten the compounds ( type 3 ) ; but dont remove bad ones [CODESPLIT] private void flatten ( List < DataDescriptor > result , List < DataDescriptor > tree ) { for ( DataDescriptor key : tree ) { if ( key . bad ) { root . isBad = true ; result . add ( key ) ; // add it anyway so we can see it in debug
 continue ; } if ( ( key . f == 3 ) && ( key . subKeys != null ) ) { flatten ( result , key . subKeys ) ; } else if ( key . f == 1 ) { // flatten the subtrees
 List < DataDescriptor > subTree = new ArrayList < DataDescriptor > ( ) ; flatten ( subTree , key . subKeys ) ; key . subKeys = subTree ; result . add ( key ) ; } else { result . add ( key ) ; } } }