Input: Add listener : ListSelectionEvent sent when a new row is selected [CODESPLIT] public void addListSelectionListener ( ListSelectionListener l ) { listenerList . add ( javax . swing . event . ListSelectionListener . class , l ) ; }


Input: Remove listener [CODESPLIT] public void removeListSelectionListener ( ListSelectionListener l ) { listenerList . remove ( javax . swing . event . ListSelectionListener . class , l ) ; }


Input: Get the currently selected bean or null if none selected . [CODESPLIT] public Object getSelectedBean ( ) { int viewRowIndex = jtable . getSelectedRow ( ) ; if ( viewRowIndex < 0 ) return null ; int modelRowIndex = jtable . convertRowIndexToModel ( viewRowIndex ) ; return ( modelRowIndex < 0 ) || ( modelRowIndex >= beans . size ( ) ) ? null : beans . get ( modelRowIndex ) ; }


Input: Get the currently selected beans . Use this for multiple selection [CODESPLIT] public List getSelectedBeans ( ) { ArrayList < Object > list = new ArrayList <> ( ) ; int [ ] viewRowIndices = jtable . getSelectedRows ( ) ; for ( int viewRowIndex : viewRowIndices ) { int modelRowIndex = jtable . convertRowIndexToModel ( viewRowIndex ) ; list . add ( beans . get ( modelRowIndex ) ) ; if ( debugSelected ) System . out . println ( " bean selected= " + modelRowIndex + " " + beans . get ( modelRowIndex ) ) ; } return list ; }


Input: Get the currently selected cells . Use this for multiple row selection when columnSelection is on [CODESPLIT] public ArrayList < Object > getSelectedCells ( ) { ArrayList < Object > list = new ArrayList <> ( ) ; int [ ] viewRowIndices = jtable . getSelectedRows ( ) ; int [ ] viewColumnIndices = jtable . getSelectedColumns ( ) ; for ( int i = 0 ; i < viewRowIndices . length ; i ++ ) for ( int j = 0 ; i < viewColumnIndices . length ; j ++ ) { int modelRowIndex = jtable . convertRowIndexToModel ( viewRowIndices [ i ] ) ; int modelColumnIndex = jtable . convertColumnIndexToModel ( viewColumnIndices [ j ] ) ; list . add ( model . getValueAt ( modelRowIndex , modelColumnIndex ) ) ; } return list ; }


Input: Set the currently selected cells ( 0 false or null ) . Use this for multiple row selection when columnSelection is on [CODESPLIT] public void clearSelectedCells ( ) { int [ ] viewRowIndices = jtable . getSelectedRows ( ) ; int [ ] viewColumnIndices = jtable . getSelectedColumns ( ) ; TableColumnModel tcm = jtable . getColumnModel ( ) ; for ( int viewColumnIndex : viewColumnIndices ) { TableColumn tc = tcm . getColumn ( viewColumnIndex ) ; int modelColumnIndex = tc . getModelIndex ( ) ; Class colClass = jtable . getColumnClass ( viewColumnIndex ) ; Object zeroValue = model . zeroValue ( colClass ) ; for ( int viewRowIndex : viewRowIndices ) { int modelRowIndex = jtable . convertRowIndexToModel ( viewRowIndex ) ; model . setValueAt ( zeroValue , modelRowIndex , modelColumnIndex ) ; } } }


Input: Set which row is selected . [CODESPLIT] public void setSelectedBean ( Object bean ) { if ( bean == null ) return ; int modelRowIndex = beans . indexOf ( bean ) ; int viewRowIndex = jtable . convertRowIndexToView ( modelRowIndex ) ; if ( viewRowIndex >= 0 ) jtable . getSelectionModel ( ) . setSelectionInterval ( viewRowIndex , viewRowIndex ) ; makeRowVisible ( viewRowIndex ) ; }


Input: Set which rows are selected . must also call setSelectionMode ( ListSelectionModel . MULTIPLE_INTERVAL_SELECTION ) ; [CODESPLIT] public void setSelectedBeans ( List want ) { jtable . getSelectionModel ( ) . clearSelection ( ) ; for ( Object bean : want ) { int modelRowIndex = beans . indexOf ( bean ) ; int viewRowIndex = jtable . convertRowIndexToView ( modelRowIndex ) ; if ( viewRowIndex >= 0 ) { jtable . getSelectionModel ( ) . addSelectionInterval ( viewRowIndex , viewRowIndex ) ; } } }


Input: Save state to the PreferencesExt . [CODESPLIT] public void saveState ( boolean saveData ) { if ( store == null ) return ; try { // save data if ( saveData ) { store . putBeanCollection ( "beanList" , beans ) ; } } catch ( Exception e ) { e . printStackTrace ( ) ; } List < PropertyCol > propCols = new ArrayList <> ( ) ; HidableTableColumnModel tableColumnModel = ( HidableTableColumnModel ) jtable . getColumnModel ( ) ; Enumeration < TableColumn > columns = tableColumnModel . getColumns ( false ) ; while ( columns . hasMoreElements ( ) ) { PropertyCol propCol = new PropertyCol ( ) ; TableColumn column = columns . nextElement ( ) ; propCol . setName ( column . getIdentifier ( ) . toString ( ) ) ; propCol . setWidth ( column . getWidth ( ) ) ; propCol . setVisible ( tableColumnModel . isColumnVisible ( column ) ) ; propCols . add ( propCol ) ; } store . putBeanCollection ( "propertyCol" , propCols ) ; }


Input: Notifies the TableModel that the data in the specified bean has changed . The TableModel will then fire an event of its own which its listeners will hear ( usually a JTable ) . [CODESPLIT] public void fireBeanDataChanged ( Object bean ) { int row = beans . indexOf ( bean ) ; if ( row >= 0 ) { model . fireTableRowsUpdated ( row , row ) ; } }


Input: Restore state from PreferencesExt [CODESPLIT] protected void restoreState ( ) { if ( store == null ) { return ; } ArrayList propColObjs = ( ArrayList ) store . getBean ( "propertyCol" , new ArrayList ( ) ) ; HidableTableColumnModel tableColumnModel = ( HidableTableColumnModel ) jtable . getColumnModel ( ) ; int newViewIndex = 0 ; for ( Object propColObj : propColObjs ) { PropertyCol propCol = ( PropertyCol ) propColObj ; try { int currentViewIndex = tableColumnModel . getColumnIndex ( propCol . getName ( ) ) ; // May throw IAE. TableColumn column = tableColumnModel . getColumn ( currentViewIndex ) ; column . setPreferredWidth ( propCol . getWidth ( ) ) ; tableColumnModel . moveColumn ( currentViewIndex , newViewIndex ) ; assert tableColumnModel . getColumn ( newViewIndex ) == column : "tableColumn wasn't successfully moved." ; // We must do this last, since moveColumn() only works on visible columns. tableColumnModel . setColumnVisible ( column , propCol . isVisible ( ) ) ; if ( propCol . isVisible ( ) ) { ++ newViewIndex ; // Don't increment for hidden columns. } } catch ( IllegalArgumentException e ) { logger . debug ( String . format ( "Column named \"%s\" was present in the preferences file but not the dataset." , propCol . getName ( ) ) , e ) ; } } }


Input: / * Needed to implement Array . getElement () [CODESPLIT] static public Class cdmElementClass ( DataType dt ) { switch ( dt ) { case BOOLEAN : return boolean . class ; case ENUM1 : case BYTE : return byte . class ; case CHAR : return char . class ; case ENUM2 : case SHORT : return short . class ; case ENUM4 : case INT : return int . class ; case LONG : return long . class ; case FLOAT : return float . class ; case DOUBLE : return double . class ; case STRING : return String . class ; case OPAQUE : return ByteBuffer . class ; case UBYTE : return byte . class ; case USHORT : return short . class ; case UINT : return int . class ; case ULONG : return long . class ; default : break ; } return null ; }


Input: convert a string to a specified cdmtype Note that if en is defined then we attempt to convert the string as enum const [CODESPLIT] static public Object attributeParse ( DataType cdmtype , EnumTypedef en , Object o ) { String so = o . toString ( ) ; if ( en != null ) { switch ( cdmtype ) { case ENUM1 : case ENUM2 : case ENUM4 : if ( ! ( o instanceof Integer ) ) throw new ConversionException ( o . toString ( ) ) ; int eval = ( Integer ) o ; String econst = en . lookupEnumString ( eval ) ; if ( econst == null ) throw new ConversionException ( o . toString ( ) ) ; return econst ; default : throw new ConversionException ( o . toString ( ) ) ; } } long lval = 0 ; double dval = 0.0 ; boolean islong = true ; boolean isdouble = true ; // Do a quick conversion checks try { lval = Long . parseLong ( so ) ; } catch ( NumberFormatException nfe ) { islong = false ; } try { dval = Double . parseDouble ( so ) ; } catch ( NumberFormatException nfe ) { isdouble = false ; } o = null ; // default is not convertible switch ( cdmtype ) { case BOOLEAN : if ( so . equalsIgnoreCase ( "false" ) || ( islong && lval == 0 ) ) o = Boolean . FALSE ; else o = Boolean . TRUE ; break ; case BYTE : if ( islong ) o = Byte . valueOf ( ( byte ) lval ) ; break ; case SHORT : if ( islong ) o = Short . valueOf ( ( short ) lval ) ; break ; case INT : if ( islong ) o = Integer . valueOf ( ( int ) lval ) ; break ; case LONG : if ( islong ) o = Long . valueOf ( lval ) ; break ; case UBYTE : // Keep the proper bit pattern if ( islong ) o = Byte . valueOf ( ( byte ) ( lval & 0xFF L ) ) ; break ; case USHORT : if ( islong ) o = Short . valueOf ( ( short ) ( lval & 0xFFFF L ) ) ; break ; case UINT : if ( islong ) o = Integer . valueOf ( ( int ) ( lval & 0xFFFFFFFF L ) ) ; break ; case ULONG : //Need to resort to BigInteger BigInteger bi = new BigInteger ( so ) ; bi = bi . and ( LONGMASK ) ; o = ( Long ) bi . longValue ( ) ; break ; case FLOAT : if ( islong && ! isdouble ) { dval = ( double ) lval ; isdouble = true ; } if ( isdouble ) o = ( Float ) ( ( float ) dval ) ; break ; case DOUBLE : if ( islong && ! isdouble ) { dval = ( double ) lval ; isdouble = true ; } if ( isdouble ) o = ( Double ) ( dval ) ; break ; case STRING : return so ; case OPAQUE : // Big Integer then ByteBuffer if ( so . startsWith ( "0x" ) || so . startsWith ( "0X" ) ) so = so . substring ( 2 ) ; bi = new BigInteger ( so , 16 ) ; // Now extract bytes byte [ ] bb = bi . toByteArray ( ) ; o = ByteBuffer . wrap ( bb ) ; break ; default : throw new ConversionException ( o . toString ( ) ) ; } if ( o == null ) throw new ConversionException ( o . toString ( ) ) ; return o ; }


Input: Factory method for constructing an unknown unit from a name . [CODESPLIT] public static UnknownUnit create ( String name ) throws NameException { UnknownUnit unit ; name = name . toLowerCase ( ) ; synchronized ( map ) { unit = map . get ( name ) ; if ( unit == null ) { unit = new UnknownUnit ( name ) ; map . put ( unit . getName ( ) , unit ) ; map . put ( unit . getPlural ( ) , unit ) ; } } return unit ; }


Input: Closes this input stream and releases any system resources associated with the stream ; closes the method also . [CODESPLIT] @ Override public void close ( ) throws IOException { if ( closed ) return ; /* Allow multiple close calls */ closed = true ; try { consume ( ) ; } finally { super . close ( ) ; } if ( method != null ) method . close ( ) ; }


Input: Has v already been added to the set of extra variables? [CODESPLIT] private boolean isExtra ( Variable v ) { return v != null && extras != null && extras . contains ( v ) ; }


Input: Is v a coordinate axis for this feature type? [CODESPLIT] private boolean isCoordinate ( Variable v ) { if ( v == null ) return false ; String name = v . getShortName ( ) ; return ( latVE != null && latVE . axisName . equals ( name ) ) || ( lonVE != null && lonVE . axisName . equals ( name ) ) || ( altVE != null && altVE . axisName . equals ( name ) ) || ( stnAltVE != null && stnAltVE . axisName . equals ( name ) ) || ( timeVE != null && timeVE . axisName . equals ( name ) ) || ( nomTimeVE != null && nomTimeVE . axisName . equals ( name ) ) ; }


Input: find a coord axis of the given type in the table and its parents [CODESPLIT] private CoordVarExtractor findCoordinateAxis ( Table . CoordName coordName , Table t , int nestingLevel ) { if ( t == null ) return null ; String axisName = t . findCoordinateVariableName ( coordName ) ; if ( axisName != null ) { VariableDS v = t . findVariable ( axisName ) ; if ( v != null ) return new CoordVarExtractorVariable ( v , axisName , nestingLevel ) ; if ( t . extraJoins != null ) { for ( Join j : t . extraJoins ) { v = j . findVariable ( axisName ) ; if ( v != null ) return new CoordVarExtractorVariable ( v , axisName , nestingLevel ) ; } } // see if its in the StructureData if ( t instanceof Table . TableSingleton ) { Table . TableSingleton ts = ( Table . TableSingleton ) t ; return new CoordVarStructureData ( axisName , ts . sdata ) ; } // see if its at the top level if ( t instanceof Table . TableTop ) { v = ( VariableDS ) ds . findVariable ( axisName ) ; if ( v != null ) return new CoordVarTop ( v ) ; else return new CoordVarConstant ( coordName . toString ( ) , "" , axisName ) ; // assume its the actual value } errlog . format ( "NestedTable: cant find variable '%s' for coordinate type %s %n" , axisName , coordName ) ; } // check the parent return findCoordinateAxis ( coordName , t . parent , nestingLevel + 1 ) ; }


Input: use recursion so that parent variables come first [CODESPLIT] private void addDataVariables ( List < VariableSimpleIF > list , Table t ) { if ( t . parent != null ) addDataVariables ( list , t . parent ) ; for ( VariableSimpleIF col : t . cols . values ( ) ) { if ( t . nondataVars . contains ( col . getFullName ( ) ) ) continue ; if ( t . nondataVars . contains ( col . getShortName ( ) ) ) continue ; // fishy list . add ( col ) ; } }


Input: add table join to this cursor level [CODESPLIT] void addParentJoin ( Cursor cursor ) throws IOException { int level = cursor . currentIndex ; Table t = getTable ( level ) ; if ( t . extraJoins != null ) { List < StructureData > sdata = new ArrayList <> ( 3 ) ; sdata . add ( cursor . tableData [ level ] ) ; for ( Join j : t . extraJoins ) { sdata . add ( j . getJoinData ( cursor ) ) ; } cursor . tableData [ level ] = StructureDataFactory . make ( sdata . toArray ( new StructureData [ sdata . size ( ) ] ) ) ; // LOOK should try to consolidate } }


Input: // Station or Station_Profile [CODESPLIT] public StructureDataIterator getStationDataIterator ( ) throws IOException { Table stationTable = root ; StructureDataIterator siter = stationTable . getStructureDataIterator ( null ) ; if ( stationTable . limit != null ) { Variable limitV = ds . findVariable ( stationTable . limit ) ; int limit = limitV . readScalarInt ( ) ; return new StructureDataIteratorLimited ( siter , limit ) ; } return siter ; }


Input: also called from StandardPointFeatureIterator [CODESPLIT] StationFeature makeStation ( StructureData stationData ) { if ( stnVE . isMissing ( stationData ) ) return null ; String stationName = stnVE . getCoordValueAsString ( stationData ) ; String stationDesc = ( stnDescVE == null ) ? "" : stnDescVE . getCoordValueAsString ( stationData ) ; String stnWmoId = ( wmoVE == null ) ? "" : wmoVE . getCoordValueAsString ( stationData ) ; double lat = latVE . getCoordValue ( stationData ) ; double lon = lonVE . getCoordValue ( stationData ) ; double elev = ( stnAltVE == null ) ? Double . NaN : stnAltVE . getCoordValue ( stationData ) ; // missing lat, lon means skip this station if ( Double . isNaN ( lat ) || Double . isNaN ( lon ) ) return null ; return new StationFeatureImpl ( stationName , stationDesc , stnWmoId , lat , lon , elev , - 1 , stationData ) ; }


Input: Do the conversion and return a NodeMap representing the conversion . [CODESPLIT] public NodeMap < CDMNode , DapNode > create ( ) throws DapException { // Netcdf Dataset will already have a root group Group cdmroot = ncfile . getRootGroup ( ) ; this . nodemap . put ( cdmroot , this . dmr ) ; fillGroup ( cdmroot , this . dmr , ncfile ) ; return this . nodemap ; }


Input: Create a variable or field [CODESPLIT] protected void createVar ( DapVariable dapvar , NetcdfFile ncfile , Group cdmgroup , Structure cdmparentstruct ) throws DapException { Variable cdmvar = null ; DapType basetype = dapvar . getBaseType ( ) ; if ( basetype . isAtomic ( ) ) { DapVariable atomvar = ( DapVariable ) dapvar ; cdmvar = new Variable ( ncfile , cdmgroup , cdmparentstruct , atomvar . getShortName ( ) ) ; DataType cdmbasetype ; if ( basetype . isEnumType ( ) ) cdmbasetype = CDMTypeFcns . enumTypeFor ( basetype ) ; else cdmbasetype = CDMTypeFcns . daptype2cdmtype ( basetype ) ; if ( cdmbasetype == null ) throw new DapException ( "Unknown basetype:" + basetype ) ; cdmvar . setDataType ( cdmbasetype ) ; if ( basetype . isEnumType ( ) ) { EnumTypedef cdmenum = ( EnumTypedef ) this . nodemap . get ( basetype ) ; if ( cdmenum == null ) throw new DapException ( "Unknown enumeration type:" + basetype . toString ( ) ) ; cdmvar . setEnumTypedef ( cdmenum ) ; } this . nodemap . put ( cdmvar , dapvar ) ; } else if ( basetype . isStructType ( ) ) { DapStructure dapstruct = ( DapStructure ) basetype ; Structure cdmstruct = new Structure ( ncfile , cdmgroup , cdmparentstruct , dapstruct . getShortName ( ) ) ; cdmvar = cdmstruct ; this . nodemap . put ( cdmvar , dapvar ) ; // Add the fields for ( DapVariable field : dapstruct . getFields ( ) ) { createVar ( field , ncfile , cdmgroup , cdmstruct ) ; } } else if ( basetype . isSeqType ( ) ) { DapSequence dapseq = ( DapSequence ) basetype ; // In general one would convert the sequence // to a CDM sequence with vlen // so Sequence {...} s[d1]...[dn] // => Sequence {...} s[d1]...[dn] Sequence cdmseq = new Sequence ( ncfile , cdmgroup , cdmparentstruct , dapseq . getShortName ( ) ) ; cdmvar = cdmseq ; this . nodemap . put ( cdmvar , dapvar ) ; // Add the fields for ( DapVariable field : dapseq . getFields ( ) ) { createVar ( field , ncfile , cdmgroup , cdmseq ) ; } // If the rank > 0, then add warning attribute if ( dapvar . getRank ( ) > 0 ) { List value = new ArrayList ( ) ; value . add ( "CDM does not support Sequences with rank > 0" ) ; Attribute warning = new Attribute ( "_WARNING:" , value ) ; cdmvar . addAttribute ( warning ) ; } } else assert ( false ) : "Unknown variable sort: " + dapvar . getSort ( ) ; int rank = dapvar . getRank ( ) ; List < Dimension > cdmdims = new ArrayList < Dimension > ( rank + 1 ) ; // +1 for vlen for ( int i = 0 ; i < rank ; i ++ ) { DapDimension dim = dapvar . getDimension ( i ) ; Dimension cdmdim = createDimensionRef ( dim , cdmgroup ) ; cdmdims . add ( cdmdim ) ; } if ( basetype . isSeqType ( ) ) { // Add the final vlen cdmdims . add ( Dimension . VLEN ) ; } cdmvar . setDimensions ( cdmdims ) ; // Create variable's attributes for ( String key : dapvar . getAttributes ( ) . keySet ( ) ) { DapAttribute attr = dapvar . getAttributes ( ) . get ( key ) ; Attribute cdmattr = createAttribute ( attr ) ; cdmvar . addAttribute ( cdmattr ) ; } if ( cdmparentstruct != null ) cdmparentstruct . addMemberVariable ( cdmvar ) ; else if ( cdmgroup != null ) cdmgroup . addVariable ( cdmvar ) ; }


Input: / * package [CODESPLIT] void note ( Notes note ) { assert ( this . allnotes != null ) ; int gid = note . gid ; int id = note . id ; NoteSort sort = note . getSort ( ) ; Map < Long , Notes > sortnotes = this . allnotes . get ( sort ) ; assert sortnotes != null ; switch ( sort ) { case TYPE : case GROUP : case DIM : assert sortnotes . get ( id ) == null ; sortnotes . put ( ( long ) id , note ) ; break ; case VAR : long gv = Nc4Notes . getVarId ( ( VarNotes ) note ) ; assert sortnotes . get ( gv ) == null ; sortnotes . put ( gv , note ) ; break ; } }


Input: / * package [CODESPLIT] VarNotes findVar ( int gid , int varid ) { long gv = Nc4Notes . getVarId ( gid , varid , - 1 ) ; return ( VarNotes ) find ( gv , NoteSort . VAR ) ; }


Input: / * package [CODESPLIT] VarNotes findField ( int gid , int varid , int fid ) { long gv = Nc4Notes . getVarId ( gid , varid , fid ) ; return ( VarNotes ) find ( gv , NoteSort . VAR ) ; }


Input: / * package [CODESPLIT] Notes find ( DapNode node ) { NoteSort sort = noteSortFor ( node ) ; assert ( this . allnotes != null ) ; Map < Long , Notes > sortnotes = this . allnotes . get ( sort ) ; assert sortnotes != null ; for ( Map . Entry < Long , Notes > entries : sortnotes . entrySet ( ) ) { Notes note = entries . getValue ( ) ; if ( note . get ( ) == node ) return note ; } return null ; }


Input: DSP API [CODESPLIT] @ Override public Nc4DSP open ( String filepath ) throws DapException { if ( filepath . startsWith ( "file:" ) ) try { XURI xuri = new XURI ( filepath ) ; filepath = xuri . getPath ( ) ; } catch ( URISyntaxException use ) { throw new DapException ( "Malformed filepath: " + filepath ) . setCode ( DapCodes . SC_NOT_FOUND ) ; } int ret , mode ; IntByReference ncidp = new IntByReference ( ) ; this . filepath = filepath ; try { mode = NC_NOWRITE ; Nc4Cursor . errcheck ( nc4 , ret = nc4 . nc_open ( this . filepath , mode , ncidp ) ) ; this . ncid = ncidp . getValue ( ) ; // Figure out what kind of file IntByReference formatp = new IntByReference ( ) ; Nc4Cursor . errcheck ( nc4 , ret = nc4 . nc_inq_format ( ncid , formatp ) ) ; this . format = formatp . getValue ( ) ; if ( DEBUG ) System . out . printf ( "TestNetcdf: open: %s; ncid=%d; format=%d%n" , this . filepath , ncid , this . format ) ; // Compile the DMR Nc4DMRCompiler dmrcompiler = new Nc4DMRCompiler ( this , ncid , dmrfactory ) ; setDMR ( dmrcompiler . compile ( ) ) ; if ( DEBUG || DUMPDMR ) { System . err . println ( "+++++++++++++++++++++" ) ; System . err . println ( printDMR ( getDMR ( ) ) ) ; System . err . println ( "+++++++++++++++++++++" ) ; } return this ; } catch ( Exception t ) { t . printStackTrace ( ) ; } return null ; }


Input: Utilities [CODESPLIT] static public String makeString ( byte [ ] b ) { // null terminates int count ; for ( count = 0 ; ( count < b . length && b [ count ] != 0 ) ; count ++ ) { ; } return new String ( b , 0 , count , DapUtil . UTF8 ) ; }


Input: Create a SimpleUnit from the given name catch Exceptions . [CODESPLIT] static public SimpleUnit factory ( String name ) { try { return factoryWithExceptions ( name ) ; } catch ( Exception e ) { if ( debugParse ) System . out . println ( "Parse " + name + " got Exception " + e ) ; return null ; } }


Input: Create a SimpleUnit from the given name allow Exceptions . [CODESPLIT] static public SimpleUnit factoryWithExceptions ( String name ) throws UnitException { UnitFormat format = UnitFormatManager . instance ( ) ; Unit uu = format . parse ( name ) ; //if (isDateUnit(uu)) return new DateUnit(name); if ( isTimeUnit ( uu ) ) return new TimeUnit ( name ) ; return new SimpleUnit ( uu ) ; }


Input: need subclass access [CODESPLIT] static protected Unit makeUnit ( String name ) throws UnitException { UnitFormat format = UnitFormatManager . instance ( ) ; return format . parse ( name ) ; }


Input: Return true if unitString1 is compatible to unitString2 meaning one can be converted to the other . If either unit string is illegal return false . [CODESPLIT] static public boolean isCompatible ( String unitString1 , String unitString2 ) { Unit uu1 , uu2 ; try { UnitFormat format = UnitFormatManager . instance ( ) ; uu1 = format . parse ( unitString1 ) ; } catch ( Exception e ) { if ( debugParse ) System . out . println ( "Parse " + unitString1 + " got Exception1 " + e ) ; return false ; } try { UnitFormat format = UnitFormatManager . instance ( ) ; uu2 = format . parse ( unitString2 ) ; } catch ( Exception e ) { if ( debugParse ) System . out . println ( "Parse " + unitString2 + " got Exception2 " + e ) ; return false ; } //System.out.println("udunits isCompatible "+ uu1+ " "+ uu2); return uu1 . isCompatible ( uu2 ) ; }


Input: Return true if unitString1 is convertible to unitString2 [CODESPLIT] static public boolean isCompatibleWithExceptions ( String unitString1 , String unitString2 ) throws UnitException { UnitFormat format = UnitFormatManager . instance ( ) ; Unit uu1 = format . parse ( unitString1 ) ; Unit uu2 = format . parse ( unitString2 ) ; return uu1 . isCompatible ( uu2 ) ; }


Input: Return true if this ucar . units . Unit is a Date . [CODESPLIT] static public boolean isDateUnit ( ucar . units . Unit uu ) { boolean ok = uu . isCompatible ( dateReferenceUnit ) ; if ( ! ok ) return false ; try { uu . getConverterTo ( dateReferenceUnit ) ; return true ; } catch ( ConversionException e ) { return false ; } }


Input: Return true if the given unit is convertible to a date Unit . allowed format is something like : <pre > [ - ] Y [ Y [ Y [ Y ]]] - MM - DD [ ( T| ) hh [ : mm [ : ss [ . sss * ]]] [ [ + | - ] hh [[ : ] mm ]]] < / pre > [CODESPLIT] static public boolean isDateUnit ( String unitString ) { SimpleUnit su = factory ( unitString ) ; return su != null && isDateUnit ( su . getUnit ( ) ) ; }


Input: Return true if the given unit is a time Unit eg seconds . [CODESPLIT] static public boolean isTimeUnit ( String unitString ) { SimpleUnit su = factory ( unitString ) ; return su != null && isTimeUnit ( su . getUnit ( ) ) ; }


Input: Get the conversion factor to convert inputUnit to outputUnit . [CODESPLIT] static public double getConversionFactor ( String inputUnitString , String outputUnitString ) throws IllegalArgumentException { SimpleUnit inputUnit = SimpleUnit . factory ( inputUnitString ) ; SimpleUnit outputUnit = SimpleUnit . factory ( outputUnitString ) ; return inputUnit . convertTo ( 1.0 , outputUnit ) ; }


Input: Convert given value of this unit to the new unit . [CODESPLIT] public double convertTo ( double value , SimpleUnit outputUnit ) throws IllegalArgumentException { try { return uu . convertTo ( value , outputUnit . getUnit ( ) ) ; } catch ( ConversionException e ) { throw new IllegalArgumentException ( e . getMessage ( ) ) ; } }


Input: Return true if unitString1 is compatible to unitString2 meaning one can be converted to the other . If either unit string is illegal return false . [CODESPLIT] public boolean isCompatible ( String unitString ) { Unit uuWant ; try { UnitFormat format = UnitFormatManager . instance ( ) ; uuWant = format . parse ( unitString ) ; } catch ( Exception e ) { if ( debugParse ) System . out . println ( "Parse " + unitString + " got Exception1 " + e ) ; return false ; } return uu . isCompatible ( uuWant ) ; }


Input: Is this an instance of an UnknownUnit? [CODESPLIT] public boolean isUnknownUnit ( ) { ucar . units . Unit uu = getUnit ( ) ; if ( uu instanceof ucar . units . UnknownUnit ) return true ; if ( uu instanceof ucar . units . DerivedUnit ) return isUnknownUnit ( ( ucar . units . DerivedUnit ) uu ) ; if ( uu instanceof ucar . units . ScaledUnit ) { ucar . units . ScaledUnit scu = ( ucar . units . ScaledUnit ) uu ; Unit u = scu . getUnit ( ) ; if ( u instanceof ucar . units . UnknownUnit ) return true ; if ( u instanceof ucar . units . DerivedUnit ) return isUnknownUnit ( ( ucar . units . DerivedUnit ) u ) ; } return false ; }


Input: Extract the value can only be called for ScaledUnit . [CODESPLIT] public double getValue ( ) { if ( ! ( uu instanceof ScaledUnit ) ) return Double . NaN ; ScaledUnit offset = ( ScaledUnit ) uu ; return offset . getScale ( ) ; }


Input: Generates a clause which which compares subclauses using one of the relative operators supported by the Operator class . [CODESPLIT] public TopLevelClause newRelOpClause ( int operator , SubClause lhs , List rhs ) throws DAP2ServerSideException { return new RelOpClause ( operator , lhs , rhs ) ; }


Input: Generates a clause which invokes a function that returns a boolean value . [CODESPLIT] public TopLevelClause newBoolFunctionClause ( String functionName , List children ) throws DAP2ServerSideException , NoSuchFunctionException { BoolFunction function = functionLibrary . getBoolFunction ( functionName ) ; if ( function == null ) { if ( functionLibrary . getBTFunction ( functionName ) != null ) { throw new NoSuchFunctionException ( "The function " + functionName + "() does not return a " + "boolean value, and must be used in a comparison or " + "as an argument to another function." ) ; } else { throw new NoSuchFunctionException ( "This server does not support a " + functionName + "() function" ) ; } } return new BoolFunctionClause ( function , children ) ; }


Input: Generates a clause which invokes a function that returns a BaseType . [CODESPLIT] public SubClause newBTFunctionClause ( String functionName , List children ) throws DAP2ServerSideException , NoSuchFunctionException { BTFunction function = functionLibrary . getBTFunction ( functionName ) ; if ( function == null ) { if ( functionLibrary . getBoolFunction ( functionName ) != null ) { throw new NoSuchFunctionException ( "The function " + functionName + "() cannot be used as a " + "sub-expression in a constraint clause" ) ; } else { throw new NoSuchFunctionException ( "This server does not support a " + functionName + "() function" ) ; } } return new BTFunctionClause ( function , children ) ; }


Input: / * private void writeDataFinish () throws IOException { ArrayInt . D1 nextChildArray = new ArrayInt . D1 ( recno ) ; [CODESPLIT] public void writeRecord ( StationObsDatatype sobs , StructureData sdata ) throws IOException { if ( debug ) System . out . println ( "sobs= " + sobs + "; station = " + sobs . getStation ( ) ) ; for ( Variable v : recordVars ) { if ( timeName . equals ( v . getShortName ( ) ) ) { Date d = sobs . getObservationTimeAsDate ( ) ; int secs = ( int ) ( d . getTime ( ) / 1000 ) ; timeArray . set ( 0 , secs ) ; } else if ( parentName . equals ( v . getShortName ( ) ) ) { int stationIndex = stnList . indexOf ( sobs . getStation ( ) ) ; parentArray . set ( 0 , stationIndex ) ; } else { v . setCachedData ( sdata . getArray ( v . getShortName ( ) ) , false ) ; } } ncfile . writeRecordData ( recordVars ) ; }


Input: //////////////////////////////////////////////////////////////////////////////// [CODESPLIT] public static void rewrite ( String fileIn , String fileOut , boolean inMemory , boolean sort ) throws IOException { System . out . println ( "Rewrite .nc files from " + fileIn + " to " + fileOut + "inMem= " + inMemory + " sort= " + sort ) ; long start = System . currentTimeMillis ( ) ; // do it in memory for speed NetcdfFile ncfile = inMemory ? NetcdfFile . openInMemory ( fileIn ) : NetcdfFile . open ( fileIn ) ; NetcdfDataset ncd = new NetcdfDataset ( ncfile ) ; StringBuilder errlog = new StringBuilder ( ) ; StationObsDataset sobs = ( StationObsDataset ) TypedDatasetFactory . open ( FeatureType . STATION , ncd , null , errlog ) ; List < ucar . unidata . geoloc . Station > stns = sobs . getStations ( ) ; List < VariableSimpleIF > vars = sobs . getDataVariables ( ) ; FileOutputStream fos = new FileOutputStream ( fileOut ) ; DataOutputStream out = new DataOutputStream ( fos ) ; WriterCFStationObsDataset writer = new WriterCFStationObsDataset ( out , "rewrite " + fileIn ) ; writer . writeHeader ( stns , vars , - 1 ) ; if ( sort ) { for ( ucar . unidata . geoloc . Station s : stns ) { DataIterator iter = sobs . getDataIterator ( s ) ; while ( iter . hasNext ( ) ) { StationObsDatatype sobsData = ( StationObsDatatype ) iter . nextData ( ) ; StructureData data = sobsData . getData ( ) ; writer . writeRecord ( sobsData , data ) ; } } } else { DataIterator iter = sobs . getDataIterator ( 1000 * 1000 ) ; while ( iter . hasNext ( ) ) { StationObsDatatype sobsData = ( StationObsDatatype ) iter . nextData ( ) ; StructureData data = sobsData . getData ( ) ; writer . writeRecord ( sobsData , data ) ; } } writer . finish ( ) ; long took = System . currentTimeMillis ( ) - start ; System . out . println ( "Rewrite " + fileIn + " to " + fileOut + " took = " + took ) ; }


Input: Adapt a rank 2 array into a java . awt . image . BufferedImage . If passed a rank 3 array take first 2D slice . [CODESPLIT] public static java . awt . image . BufferedImage makeGrayscaleImage ( Array ma , IsMissingEvaluator missEval ) { if ( ma . getRank ( ) < 2 ) return null ; if ( ma . getRank ( ) == 3 ) ma = ma . reduce ( ) ; if ( ma . getRank ( ) == 3 ) ma = ma . slice ( 0 , 0 ) ; // we need 2D int h = ma . getShape ( ) [ 0 ] ; int w = ma . getShape ( ) [ 1 ] ; DataBuffer dataBuffer = makeDataBuffer ( ma , missEval ) ; WritableRaster raster = WritableRaster . createInterleavedRaster ( dataBuffer , w , h , //   int w, int h, w , //   int scanlineStride, 1 , //    int pixelStride, new int [ ] { 0 } , //   int bandOffsets[], null ) ; //   Point location) ColorSpace cs = ColorSpace . getInstance ( ColorSpace . CS_GRAY ) ; ComponentColorModel colorModel = new ComponentColorModel ( cs , new int [ ] { 8 } , false , false , Transparency . OPAQUE , DataBuffer . TYPE_BYTE ) ; return new BufferedImage ( colorModel , raster , false , null ) ; }


Input: /////////////////////////////////////////////// [CODESPLIT] protected String translatePathToReletiveLocation ( String dsPath , String configPath ) { if ( dsPath == null ) return null ; if ( dsPath . length ( ) == 0 ) return null ; if ( dsPath . startsWith ( "/" ) ) dsPath = dsPath . substring ( 1 ) ; if ( ! dsPath . startsWith ( configPath ) ) return null ; // remove the matching part, the rest is the "reletive location" String dataDir = dsPath . substring ( configPath . length ( ) ) ; if ( dataDir . startsWith ( "/" ) ) dataDir = dataDir . substring ( 1 ) ; return dataDir ; }


Input: Open a catalog and crawl ( depth first ) all the datasets in it . Close catalogs and release their resources as you . [CODESPLIT] public int crawl ( String catUrl , CancelTask task , PrintWriter out , Object context ) { InvCatalogFactory catFactory = InvCatalogFactory . getDefaultFactory ( true ) ; InvCatalogImpl cat = catFactory . readXML ( catUrl ) ; StringBuilder buff = new StringBuilder ( ) ; boolean isValid = cat . check ( buff , false ) ; if ( out != null ) { out . println ( "catalog <" + cat . getName ( ) + "> " + ( isValid ? "is" : "is not" ) + " valid" ) ; out . println ( " validation output=\n" + buff ) ; } if ( isValid ) return crawl ( cat , task , out , context ) ; return 0 ; }


Input: Crawl a catalog thats already been opened . When you get to a dataset containing leaf datasets do all only the first or a randomly chosen one . [CODESPLIT] public int crawl ( InvCatalogImpl cat , CancelTask task , PrintWriter out , Object context ) { if ( out != null ) out . println ( "***CATALOG " + cat . getCreateFrom ( ) ) ; countCatrefs = 0 ; for ( InvDataset ds : cat . getDatasets ( ) ) { if ( type == Type . all ) crawlDataset ( ds , task , out , context , true ) ; else crawlDirectDatasets ( ds , task , out , context , true ) ; if ( ( task != null ) && task . isCancel ( ) ) break ; } return 1 + countCatrefs ; }


Input: Crawl this dataset recursively return all datasets [CODESPLIT] public void crawlDataset ( InvDataset ds , CancelTask task , PrintWriter out , Object context , boolean release ) { boolean isCatRef = ( ds instanceof InvCatalogRef ) ; if ( filter != null && filter . skipAll ( ds ) ) { if ( isCatRef && release ) ( ( InvCatalogRef ) ds ) . release ( ) ; return ; } boolean isDataScan = ds . findProperty ( "DatasetScan" ) != null ; if ( isCatRef ) { InvCatalogRef catref = ( InvCatalogRef ) ds ; if ( out != null ) out . println ( " **CATREF " + catref . getURI ( ) + " (" + ds . getName ( ) + ") " ) ; countCatrefs ++ ; if ( ! listen . getCatalogRef ( catref , context ) ) { if ( release ) catref . release ( ) ; return ; } } if ( ! isCatRef || isDataScan ) listen . getDataset ( ds , context ) ; // recurse - depth first List < InvDataset > dlist = ds . getDatasets ( ) ; if ( isCatRef ) { InvCatalogRef catref = ( InvCatalogRef ) ds ; if ( ! isDataScan ) { listen . getDataset ( catref . getProxyDataset ( ) , context ) ; // wait till a catref is read, so all metadata is there ! } } for ( InvDataset dds : dlist ) { crawlDataset ( dds , task , out , context , release ) ; if ( ( task != null ) && task . isCancel ( ) ) break ; } if ( isCatRef && release ) { InvCatalogRef catref = ( InvCatalogRef ) ds ; catref . release ( ) ; } }


Input:
Crawl this dataset recursively . Only send back direct datasets [CODESPLIT] public void crawlDirectDatasets ( InvDataset ds , CancelTask task , PrintWriter out , Object context , boolean release ) { boolean isCatRef = ( ds instanceof InvCatalogRef ) ; if ( filter != null && filter . skipAll ( ds ) ) { if ( isCatRef && release ) ( ( InvCatalogRef ) ds ) . release ( ) ; return ; } if ( isCatRef ) { InvCatalogRef catref = ( InvCatalogRef ) ds ; if ( out != null ) out . println ( " **CATREF " + catref . getURI ( ) + " (" + ds . getName ( ) + ") " ) ; countCatrefs ++ ; if ( ! listen . getCatalogRef ( catref , context ) ) { if ( release ) catref . release ( ) ; return ; } } // get datasets with data access ("leaves") List < InvDataset > dlist = ds . getDatasets ( ) ; List < InvDataset > leaves = new ArrayList < InvDataset > ( ) ; for ( InvDataset dds : dlist ) { if ( dds . hasAccess ( ) ) leaves . add ( dds ) ; } if ( leaves . size ( ) > 0 ) { if ( type == Type . first_direct ) { InvDataset dds = leaves . get ( 0 ) ; listen . getDataset ( dds , context ) ; } else if ( type == Type . random_direct ) { listen . getDataset ( chooseRandom ( leaves ) , context ) ; } else if ( type == Type . random_direct_middle ) { listen . getDataset ( chooseRandomNotFirstOrLast ( leaves ) , context ) ; } else { // do all of them for ( InvDataset dds : leaves ) { listen . getDataset ( dds , context ) ; if ( ( task != null ) && task . isCancel ( ) ) break ; } } } // recurse for ( InvDataset dds : dlist ) { if ( dds . hasNestedDatasets ( ) ) crawlDirectDatasets ( dds , task , out , context , release ) ; if ( ( task != null ) && task . isCancel ( ) ) break ; } /* if (out != null) {
     int took = (int) (System.currentTimeMillis() - start);
     out.println(" ** " + ds.getName() + " took " + took + " msecs\n");
   } */ if ( ds instanceof InvCatalogRef && release ) { InvCatalogRef catref = ( InvCatalogRef ) ds ; catref . release ( ) ; } }


Input: Get index file may be in cache directory may not exist [CODESPLIT] public static File getFileOrCache ( String fileLocation ) { File result = getExistingFileOrCache ( fileLocation ) ; if ( result != null ) return result ; return getDiskCache2 ( ) . getFile ( fileLocation ) ; }


Input: Looking for an existing file in cache or not [CODESPLIT] public static File getExistingFileOrCache ( String fileLocation ) { File result = getDiskCache2 ( ) . getExistingFileOrCache ( fileLocation ) ; if ( result == null && Grib . debugGbxIndexOnly && fileLocation . endsWith ( ".gbx9.ncx4" ) ) { // might create only from gbx9 for debugging int length = fileLocation . length ( ) ; String maybeIndexAlreadyExists = fileLocation . substring ( 0 , length - 10 ) + ".ncx4" ; result = getDiskCache2 ( ) . getExistingFileOrCache ( maybeIndexAlreadyExists ) ; } return result ; }


Input: gml : Point / gml : pos [CODESPLIT] public static DirectPositionType initPos ( DirectPositionType pos , StationTimeSeriesFeature stationFeat ) { // TEXT pos . setListValue ( Arrays . asList ( stationFeat . getLatitude ( ) , stationFeat . getLongitude ( ) , stationFeat . getAltitude ( ) ) ) ; return pos ; }


Input: java . net calls this : [CODESPLIT] protected PasswordAuthentication getPasswordAuthentication ( ) { if ( pwa == null ) throw new IllegalStateException ( ) ; if ( debug ) { System . out . println ( "site= " + getRequestingSite ( ) ) ; System . out . println ( "port= " + getRequestingPort ( ) ) ; System . out . println ( "protocol= " + getRequestingProtocol ( ) ) ; System . out . println ( "prompt= " + getRequestingPrompt ( ) ) ; System . out . println ( "scheme= " + getRequestingScheme ( ) ) ; } serverF . setText ( getRequestingHost ( ) + ":" + getRequestingPort ( ) ) ; realmF . setText ( getRequestingPrompt ( ) ) ; dialog . setVisible ( true ) ; if ( debug ) { System . out . println ( "user= (" + pwa . getUserName ( ) + ")" ) ; System . out . println ( "password= (" + pwa . getPassword ( ) + ")" ) ; } return new PasswordAuthentication ( pwa . getUserName ( ) , pwa . getPassword ( ) . toCharArray ( ) ) ; }


Input: http client calls this : [CODESPLIT] public Credentials getCredentials ( AuthScope scope ) { serverF . setText ( scope . getHost ( ) + ":" + scope . getPort ( ) ) ; String realmName = scope . getRealm ( ) ; if ( realmName == null ) { realmName = "THREDDS Data Server" ; } realmF . setText ( realmName ) ; dialog . setVisible ( true ) ; if ( pwa == null ) throw new IllegalStateException ( ) ; if ( debug ) { System . out . println ( "user= (" + pwa . getUserName ( ) + ")" ) ; System . out . println ( "password= (" + new String ( pwa . getPassword ( ) ) + ")" ) ; } // Is this really necessary? UsernamePasswordCredentials upc = new UsernamePasswordCredentials ( pwa . getUserName ( ) , new String ( pwa . getPassword ( ) ) ) ; return upc ; }


Input: Debugging do not use in production . Set counters to zero set debugging on [CODESPLIT] static public void setDebugLeaks ( boolean b ) { if ( b ) { count_openFiles . set ( 0 ) ; maxOpenFiles . set ( 0 ) ; allFiles = new HashSet <> ( 1000 ) ; } debugLeaks = b ; }


Input: Debugging do not use . [CODESPLIT] static public List < String > getAllFiles ( ) { if ( null == allFiles ) return null ; List < String > result = new ArrayList <> ( ) ; result . addAll ( allFiles ) ; Collections . sort ( result ) ; return result ; }


Input:
Close the file and release any associated system resources . [CODESPLIT] public synchronized void close ( ) throws IOException { if ( cache != null ) { if ( cacheState > 0 ) { if ( cacheState == 1 ) { cacheState = 2 ; if ( cache . release ( this ) ) // return true if in the cache, otherwise was opened regular, so must be closed regular
 return ; cacheState = 0 ; // release failed, bail out
 } else { return ; // close has been called more than once - ok
 } } } if ( debugLeaks ) { openFiles . remove ( location ) ; if ( showOpen ) System . out . println ( "  close " + location ) ; } if ( file == null ) return ; // If we are writing and the buffer has been modified, flush the contents of the buffer.
 flush ( ) ; // may need to extend file, in case no fill is being used
 // may need to truncate file in case overwriting a longer file
 // use only if minLength is set (by N3iosp)
 long fileSize = file . length ( ) ; if ( ! readonly && ( minLength != 0 ) && ( minLength != fileSize ) ) { file . setLength ( minLength ) ; // System.out.println("TRUNCATE!!! minlength="+minLength);
 } // Close the underlying file object.
 file . close ( ) ; file = null ; // help the gc
 }


Input:
Set the position in the file for the next read or write . [CODESPLIT] public void seek ( long pos ) throws IOException { if ( pos < 0 ) throw new java . io . IOException ( "Negative seek offset" ) ; // If the seek is into the buffer, just update the file pointer.
 if ( ( pos >= bufferStart ) && ( pos < dataEnd ) ) { filePosition = pos ; return ; } // need new buffer, starting at pos
 readBuffer ( pos ) ; }


Input:
Get the length of the file . The data in the buffer ( which may not have been written the disk yet ) is taken into account . [CODESPLIT] public long length ( ) throws IOException { long fileLength = ( file == null ) ? - 1L : file . length ( ) ; // GRIB has closed the data raf
 if ( fileLength < dataEnd ) { return dataEnd ; } else { return fileLength ; } }


Input:
Copy the contents of the buffer to the disk . [CODESPLIT] public void flush ( ) throws IOException { if ( bufferModified ) { file . seek ( bufferStart ) ; file . write ( buffer , 0 , dataSize ) ; //System.out.println("--flush at "+bufferStart+" dataSize= "+dataSize+ " filePosition= "+filePosition);
 bufferModified = false ; } /* check min length
    if (!readonly && (minLength != 0) && (minLength != file.length())) {
      file.setLength(minLength);
    } */ }


Input:
Read a byte of data from the file blocking until data is available . [CODESPLIT] public int read ( ) throws IOException { // If the file position is within the data, return the byte...
 if ( filePosition < dataEnd ) { int pos = ( int ) ( filePosition - bufferStart ) ; filePosition ++ ; return ( buffer [ pos ] & 0xff ) ; // ...or should we indicate EOF...
 } else if ( endOfFile ) { return - 1 ; // ...or seek to fill the buffer, and try again.
 } else { seek ( filePosition ) ; return read ( ) ; } }


Input:
Read up to <code > len< / code > bytes into an array at a specified offset . This will block until at least one byte has been read . [CODESPLIT] public int readBytes ( byte b [ ] , int off , int len ) throws IOException { // Check for end of file.
 if ( endOfFile ) { return - 1 ; } // See how many bytes are available in the buffer - if none,
 // seek to the file position to update the buffer and try again.
 int bytesAvailable = ( int ) ( dataEnd - filePosition ) ; if ( bytesAvailable < 1 ) { seek ( filePosition ) ; return readBytes ( b , off , len ) ; } // Copy as much as we can.
 int copyLength = ( bytesAvailable >= len ) ? len : bytesAvailable ; System . arraycopy ( buffer , ( int ) ( filePosition - bufferStart ) , b , off , copyLength ) ; filePosition += copyLength ; // If there is more to copy...
 if ( copyLength < len ) { int extraCopy = len - copyLength ; // If the amount remaining is more than a buffer's length, read it
 // directly from the file.
 if ( extraCopy > buffer . length ) { extraCopy = read_ ( filePosition , b , off + copyLength , len - copyLength ) ; // ...or read a new buffer full, and copy as much as possible...
 } else { seek ( filePosition ) ; if ( ! endOfFile ) { extraCopy = ( extraCopy > dataSize ) ? dataSize : extraCopy ; System . arraycopy ( buffer , 0 , b , off + copyLength , extraCopy ) ; } else { extraCopy = - 1 ; } } // If we did manage to copy any more, update the file position and
 // return the amount copied.
 if ( extraCopy > 0 ) { filePosition += extraCopy ; return copyLength + extraCopy ; } } // Return the amount copied.
 return copyLength ; }


Input:
Read <code > nbytes< / code > bytes at the specified file offset send to a WritableByteChannel . This will block until all bytes are read . This uses the underlying file channel directly bypassing all user buffers . [CODESPLIT] public long readToByteChannel ( WritableByteChannel dest , long offset , long nbytes ) throws IOException { if ( fileChannel == null ) fileChannel = file . getChannel ( ) ; long need = nbytes ; while ( need > 0 ) { long count = fileChannel . transferTo ( offset , need , dest ) ; //if (count == 0) break;  // LOOK not sure what the EOF condition is
 need -= count ; offset += count ; } return nbytes - need ; }


Input:
Read directly from file without going through the buffer . All reading goes through here or readToByteChannel ; [CODESPLIT] protected int read_ ( long pos , byte [ ] b , int offset , int len ) throws IOException { file . seek ( pos ) ; int n = file . read ( b , offset , len ) ; if ( debugAccess ) { if ( showRead ) System . out . println ( " **read_ " + location + " = " + len + " bytes at " + pos + "; block = " + ( pos / buffer . length ) ) ; debug_nseeks . incrementAndGet ( ) ; debug_nbytes . addAndGet ( len ) ; } if ( extendMode && ( n < len ) ) { //System.out.println(" read_ = "+len+" at "+pos+"; got = "+n);
 n = len ; } return n ; }


Input: Reads exactly <code > len< / code > bytes from this file into the byte array . This method reads repeatedly from the file until all the bytes are read . This method blocks until all the bytes are read the end of the stream is detected or an exception is thrown . [CODESPLIT] public final void readFully ( byte b [ ] , int off , int len ) throws IOException { int n = 0 ; while ( n < len ) { int count = this . read ( b , off + n , len - n ) ; if ( count < 0 ) { throw new EOFException ( "Reading " + location + " at " + filePosition + " file length = " + length ( ) ) ; } n += count ; } }


Input:
Write a byte to the file . If the file has not been opened for writing an IOException will be raised only when an attempt is made to write the buffer to the file . <p / > Caveat : the effects of seek ( ) ing beyond the end of the file are undefined . [CODESPLIT] public void write ( int b ) throws IOException { // If the file position is within the block of data...
 if ( filePosition < dataEnd ) { int pos = ( int ) ( filePosition - bufferStart ) ; buffer [ pos ] = ( byte ) b ; bufferModified = true ; filePosition ++ ; // ...or (assuming that seek will not allow the file pointer
 // to move beyond the end of the file) get the correct block of
 // data...
 } else { // If there is room in the buffer, expand it...
 if ( dataSize != buffer . length ) { int pos = ( int ) ( filePosition - bufferStart ) ; buffer [ pos ] = ( byte ) b ; bufferModified = true ; filePosition ++ ; dataSize ++ ; dataEnd ++ ; // ...or do another seek to get a new buffer, and start again...
 } else { seek ( filePosition ) ; write ( b ) ; } } }


Input:
Write <code > len< / code > bytes from an array to the file . [CODESPLIT] public void writeBytes ( byte b [ ] , int off , int len ) throws IOException { // If the amount of data is small (less than a full buffer)...
 if ( len < buffer . length ) { // If any of the data fits within the buffer...
 int spaceInBuffer = 0 ; int copyLength = 0 ; if ( filePosition >= bufferStart ) { spaceInBuffer = ( int ) ( ( bufferStart + buffer . length ) - filePosition ) ; } if ( spaceInBuffer > 0 ) { // Copy as much as possible to the buffer.
 copyLength = ( spaceInBuffer > len ) ? len : spaceInBuffer ; System . arraycopy ( b , off , buffer , ( int ) ( filePosition - bufferStart ) , copyLength ) ; bufferModified = true ; long myDataEnd = filePosition + copyLength ; dataEnd = ( myDataEnd > dataEnd ) ? myDataEnd : dataEnd ; dataSize = ( int ) ( dataEnd - bufferStart ) ; filePosition += copyLength ; ///System.out.println("--copy to buffer "+copyLength+" "+len);
 } // If there is any data remaining, move to the new position and copy to
 // the new buffer.
 if ( copyLength < len ) { //System.out.println("--need more "+copyLength+" "+len+" space= "+spaceInBuffer);
 seek ( filePosition ) ; // triggers a flush
 System . arraycopy ( b , off + copyLength , buffer , ( int ) ( filePosition - bufferStart ) , len - copyLength ) ; bufferModified = true ; long myDataEnd = filePosition + ( len - copyLength ) ; dataEnd = ( myDataEnd > dataEnd ) ? myDataEnd : dataEnd ; dataSize = ( int ) ( dataEnd - bufferStart ) ; filePosition += ( len - copyLength ) ; } // ...or write a lot of data...
 } else { // Flush the current buffer, and write this data to the file.
 if ( bufferModified ) { flush ( ) ; } file . seek ( filePosition ) ; // moved per Steve Cerruti; Jan 14, 2005
 file . write ( b , off , len ) ; //System.out.println("--write at "+filePosition+" "+len);
 filePosition += len ; bufferStart = filePosition ; // an empty buffer
 dataSize = 0 ; dataEnd = bufferStart + dataSize ; } }


Input: Read an array of shorts [CODESPLIT] public final void readShort ( short [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { pa [ start + i ] = readShort ( ) ; } }


Input: Read an integer at the given position bypassing all buffering . [CODESPLIT] public final int readIntUnbuffered ( long pos ) throws IOException { byte [ ] bb = new byte [ 4 ] ; read_ ( pos , bb , 0 , 4 ) ; int ch1 = bb [ 0 ] & 0xff ; int ch2 = bb [ 1 ] & 0xff ; int ch3 = bb [ 2 ] & 0xff ; int ch4 = bb [ 3 ] & 0xff ; if ( ( ch1 | ch2 | ch3 | ch4 ) < 0 ) { throw new EOFException ( ) ; } if ( bigEndian ) { return ( ( ch1 << 24 ) + ( ch2 << 16 ) + ( ch3 << 8 ) + ( ch4 ) ) ; } else { return ( ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 ) ) ; } }


Input: Read an array of ints [CODESPLIT] public final void readInt ( int [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { pa [ start + i ] = readInt ( ) ; } }


Input: Read an array of longs [CODESPLIT] public final void readLong ( long [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { pa [ start + i ] = readLong ( ) ; } }


Input: Read an array of floats [CODESPLIT] public final void readFloat ( float [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { pa [ start + i ] = Float . intBitsToFloat ( readInt ( ) ) ; } }


Input: Read an array of doubles [CODESPLIT] public final void readDouble ( double [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { pa [ start + i ] = Double . longBitsToDouble ( readLong ( ) ) ; } }


Input: Read a String of known length . [CODESPLIT] public String readString ( int nbytes ) throws IOException { byte [ ] data = new byte [ nbytes ] ; readFully ( data ) ; return new String ( data , CDM . utf8Charset ) ; }


Input: Read a String of max length zero terminate . [CODESPLIT] public String readStringMax ( int nbytes ) throws IOException { byte [ ] b = new byte [ nbytes ] ; readFully ( b ) ; int count ; for ( count = 0 ; count < nbytes ; count ++ ) if ( b [ count ] == 0 ) break ; return new String ( b , 0 , count , CDM . utf8Charset ) ; }


Input: Write an array of booleans [CODESPLIT] public final void writeBoolean ( boolean [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeBoolean ( pa [ start + i ] ) ; } }


Input: Write an array of shorts [CODESPLIT] public final void writeShort ( short [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeShort ( pa [ start + i ] ) ; } }


Input: Write an array of chars [CODESPLIT] public final void writeChar ( char [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeChar ( pa [ start + i ] ) ; } }


Input: Write an array of ints [CODESPLIT] public final void writeInt ( int [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeInt ( pa [ start + i ] ) ; } }


Input: Write an array of longs [CODESPLIT] public final void writeLong ( long [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeLong ( pa [ start + i ] ) ; } }


Input: Write an array of floats [CODESPLIT] public final void writeFloat ( float [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeFloat ( pa [ start + i ] ) ; } }


Input: Write an array of doubles [CODESPLIT] public final void writeDouble ( double [ ] pa , int start , int n ) throws IOException { for ( int i = 0 ; i < n ; i ++ ) { writeDouble ( pa [ start + i ] ) ; } }


Input: Writes the string to the file as a sequence of bytes . Each character in the string is written out in sequence by discarding its high eight bits . [CODESPLIT] public final void writeBytes ( String s ) throws IOException { int len = s . length ( ) ; for ( int i = 0 ; i < len ; i ++ ) { write ( ( byte ) s . charAt ( i ) ) ; } }


Input: Writes the character array to the file as a sequence of bytes . Each character in the string is written out in sequence by discarding its high eight bits . [CODESPLIT] public final void writeBytes ( char b [ ] , int off , int len ) throws IOException { for ( int i = off ; i < len ; i ++ ) { write ( ( byte ) b [ i ] ) ; } }


Input: Writes a string to the file as a sequence of characters . Each character is written to the data output stream as if by the <code > writeChar< / code > method . [CODESPLIT] public final void writeChars ( String s ) throws IOException { int len = s . length ( ) ; for ( int i = 0 ; i < len ; i ++ ) { int v = s . charAt ( i ) ; write ( ( v >>> 8 ) & 0xFF ) ; write ( ( v ) & 0xFF ) ; } }


Input: Writes a string to the file using UTF - 8 encoding in a machine - independent manner . <p / > First two bytes are written to the file as if by the <code > writeShort< / code > method giving the number of bytes to follow . This value is the number of bytes actually written out not the length of the string . Following the length each character of the string is output in sequence using the UTF - 8 encoding for each character . [CODESPLIT] public final void writeUTF ( String str ) throws IOException { int strlen = str . length ( ) ; int utflen = 0 ; for ( int i = 0 ; i < strlen ; i ++ ) { int c = str . charAt ( i ) ; if ( ( c >= 0x0001 ) && ( c <= 0x007F ) ) { utflen ++ ; } else if ( c > 0x07FF ) { utflen += 3 ; } else { utflen += 2 ; } } if ( utflen > 65535 ) { throw new UTFDataFormatException ( ) ; } write ( ( utflen >>> 8 ) & 0xFF ) ; write ( ( utflen ) & 0xFF ) ; for ( int i = 0 ; i < strlen ; i ++ ) { int c = str . charAt ( i ) ; if ( ( c >= 0x0001 ) && ( c <= 0x007F ) ) { write ( c ) ; } else if ( c > 0x07FF ) { write ( 0xE0 | ( ( c >> 12 ) & 0x0F ) ) ; write ( 0x80 | ( ( c >> 6 ) & 0x3F ) ) ; write ( 0x80 | ( ( c ) & 0x3F ) ) ; } else { write ( 0xC0 | ( ( c >> 6 ) & 0x1F ) ) ; write ( 0x80 | ( ( c ) & 0x3F ) ) ; } } }


Input:
Search forward from the current pos looking for a match . [CODESPLIT] public boolean searchForward ( KMPMatch match , int maxBytes ) throws IOException { long start = getFilePointer ( ) ; long last = ( maxBytes < 0 ) ? length ( ) : Math . min ( length ( ) , start + maxBytes ) ; long needToScan = last - start ; // check what ever is now in the buffer
 int bytesAvailable = ( int ) ( dataEnd - filePosition ) ; if ( bytesAvailable < 1 ) { seek ( filePosition ) ; // read a new buffer
 bytesAvailable = ( int ) ( dataEnd - filePosition ) ; } int bufStart = ( int ) ( filePosition - bufferStart ) ; int scanBytes = ( int ) Math . min ( bytesAvailable , needToScan ) ; int pos = match . indexOf ( buffer , bufStart , scanBytes ) ; if ( pos >= 0 ) { seek ( bufferStart + pos ) ; return true ; } int matchLen = match . getMatchLength ( ) ; needToScan -= scanBytes - matchLen ; while ( needToScan > matchLen ) { readBuffer ( dataEnd - matchLen ) ; // force new buffer
 scanBytes = ( int ) Math . min ( buffer . length , needToScan ) ; pos = match . indexOf ( buffer , 0 , scanBytes ) ; if ( pos > 0 ) { seek ( bufferStart + pos ) ; return true ; } needToScan -= scanBytes - matchLen ; } // failure
 seek ( last ) ; return false ; }


Input: Create the selector result string and append . [CODESPLIT] public void appendQuery ( StringBuffer sbuff , ArrayList values ) { if ( template != null ) appendQueryFromTemplate ( sbuff , values ) ; else appendQueryFromParamValue ( sbuff , values ) ; }


Input: / * since none of these are required can only do consistency checks [CODESPLIT] @ Override public boolean isValid ( NcssGridParamsBean params , ConstraintValidatorContext constraintValidatorContext ) { constraintValidatorContext . disableDefaultConstraintViolation ( ) ; boolean isValid = true ; // lat/lon point if ( params . getLatitude ( ) != null || params . getLongitude ( ) != null ) { if ( ! params . hasLatLonPoint ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.lat_or_lon_missing}" ) . addConstraintViolation ( ) ; } } // lat/lon bb if ( params . getNorth ( ) != null || params . getSouth ( ) != null || params . getEast ( ) != null || params . getWest ( ) != null ) { if ( ! params . hasLatLonBB ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.wrong_bbox}" ) . addConstraintViolation ( ) ; } if ( params . getNorth ( ) < params . getSouth ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.north_south}" ) . addConstraintViolation ( ) ; } if ( params . getEast ( ) < params . getWest ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.east_west}" ) . addConstraintViolation ( ) ; } } // proj bb if ( params . getMaxx ( ) != null || params . getMinx ( ) != null || params . getMaxy ( ) != null || params . getMiny ( ) != null ) { if ( ! params . hasProjectionBB ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.wrong_pbox}" ) . addConstraintViolation ( ) ; } if ( params . getMaxx ( ) < params . getMinx ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.rangex}" ) . addConstraintViolation ( ) ; } if ( params . getMaxy ( ) < params . getMiny ( ) ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.rangey}" ) . addConstraintViolation ( ) ; } } // runtime: latest, all, or time if ( params . getRuntime ( ) != null ) { if ( "latest" . equalsIgnoreCase ( params . getRuntime ( ) ) ) { params . setLatestRuntime ( true ) ; } else if ( "all" . equalsIgnoreCase ( params . getRuntime ( ) ) ) { params . setAllRuntime ( true ) ; } else { CalendarDate cd = TimeParamsValidator . validateISOString ( params . getRuntime ( ) , "{thredds.server.ncSubset.validation.param.runtime}" , constraintValidatorContext ) ; if ( cd != null ) params . setRuntimeDate ( cd ) ; } } // timeOffset: first or double if ( params . getTimeOffset ( ) != null ) { if ( "first" . equalsIgnoreCase ( params . getTimeOffset ( ) ) ) { params . setFirstTimeOffset ( true ) ; } else { try { double val = Double . parseDouble ( params . getTimeOffset ( ) ) ; params . setTimeOffsetVal ( val ) ; } catch ( NumberFormatException e ) { constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.param.time_offset}" ) . addConstraintViolation ( ) ; } } } return isValid ; }


Input: returns a DirectoryPartition or DirectoryCollection [CODESPLIT] static public MCollection factory ( FeatureCollectionConfig config , Path topDir , boolean isTop , IndexReader indexReader , String suffix , org . slf4j . Logger logger ) throws IOException { DirectoryBuilder builder = new DirectoryBuilder ( config . collectionName , topDir . toString ( ) , suffix ) ; DirectoryPartition dpart = new DirectoryPartition ( config , topDir , isTop , indexReader , suffix , logger ) ; if ( ! builder . isLeaf ( indexReader ) ) { // its a partition return dpart ; } // its a collection boolean hasIndex = builder . findIndex ( ) ; if ( hasIndex ) { return dpart . makeChildCollection ( builder ) ; } else { DirectoryCollection result = new DirectoryCollection ( config . collectionName , topDir , isTop , config . olderThan , logger ) ; // no index file return result ; } }


Input: Find the index file using its canonical name [CODESPLIT] public boolean findIndex ( ) throws IOException { Path indexPath = Paths . get ( dir . toString ( ) , partitionName + suffix ) ; if ( Files . exists ( indexPath ) ) { this . index = indexPath ; BasicFileAttributes attr = Files . readAttributes ( indexPath , BasicFileAttributes . class ) ; this . indexLastModified = attr . lastModifiedTime ( ) ; this . indexSize = attr . size ( ) ; return true ; } return false ; }


Input: Scans first 100 files to decide if its a leaf . If so it becomes a DirectoryCollection else a PartitionCollection . [CODESPLIT] private boolean isLeaf ( IndexReader indexReader ) throws IOException { if ( partitionStatus == PartitionStatus . unknown ) { int countDir = 0 , countFile = 0 , count = 0 ; try ( DirectoryStream < Path > dirStream = Files . newDirectoryStream ( dir ) ) { Iterator < Path > iterator = dirStream . iterator ( ) ; while ( iterator . hasNext ( ) && count ++ < 100 ) { Path p = iterator . next ( ) ; BasicFileAttributes attr = Files . readAttributes ( p , BasicFileAttributes . class ) ; if ( attr . isDirectory ( ) ) countDir ++ ; else countFile ++ ; } } partitionStatus = ( countFile > countDir ) ? PartitionStatus . isLeaf : PartitionStatus . isDirectoryPartition ; } return partitionStatus == PartitionStatus . isLeaf ; }


Input: Find all children directories . Does not recurse . We separate this from the constructor so it can be done on demand Public for debugging . [CODESPLIT] public List < DirectoryBuilder > constructChildren ( IndexReader indexReader , CollectionUpdateType forceCollection ) throws IOException { if ( childrenConstructed ) return children ; if ( index != null && forceCollection == CollectionUpdateType . nocheck ) { // use index if it exists constructChildrenFromIndex ( indexReader , false ) ; } else { scanForChildren ( ) ; } //once we have found children, we know that this is a time partition partitionStatus = ( children . size ( ) > 0 ) ? PartitionStatus . isDirectoryPartition : PartitionStatus . isLeaf ; childrenConstructed = true ; // otherwise we are good return children ; }


Input: Scan for subdirectories make each into a DirectoryBuilder and add as a child [CODESPLIT] private void scanForChildren ( ) { if ( debug ) System . out . printf ( "DirectoryBuilder.scanForChildren on %s " , dir ) ; int count = 0 ; try ( DirectoryStream < Path > ds = Files . newDirectoryStream ( dir ) ) { for ( Path p : ds ) { BasicFileAttributes attr = Files . readAttributes ( p , BasicFileAttributes . class ) ; if ( attr . isDirectory ( ) ) { children . add ( new DirectoryBuilder ( topCollectionName , p , attr , suffix ) ) ; if ( debug && ( ++ count % 10 == 0 ) ) System . out . printf ( "%d " , count ) ; } } } catch ( IOException e ) { e . printStackTrace ( ) ; } if ( debug ) System . out . printf ( "done=%d%n" , count ) ; childrenConstructed = true ; }


Input: read the list of files from the index [CODESPLIT] public List < MFile > readFilesFromIndex ( IndexReader indexReader ) throws IOException { List < MFile > result = new ArrayList <> ( 100 ) ; if ( index == null ) return result ; indexReader . readMFiles ( index , result ) ; return result ; }


Input: Open a netcdf dataset using NetcdfDataset . defaultEnhanceMode plus CoordSystems and turn into a GridDataset . [CODESPLIT] static public GridDataset open ( String location ) throws java . io . IOException { return open ( location , NetcdfDataset . getDefaultEnhanceMode ( ) ) ; }


Input: Open a netcdf dataset using NetcdfDataset . defaultEnhanceMode plus CoordSystems and turn into a GridDataset . [CODESPLIT] static public GridDataset open ( String location , Set < NetcdfDataset . Enhance > enhanceMode ) throws java . io . IOException { NetcdfDataset ds = ucar . nc2 . dataset . NetcdfDataset . acquireDataset ( null , DatasetUrl . findDatasetUrl ( location ) , enhanceMode , - 1 , null , null ) ; return new GridDataset ( ds , null ) ; }


Input: Return GridDatatype objects grouped by GridCoordSys . All GridDatatype in a Gridset have the same GridCoordSystem . [CODESPLIT] public List < ucar . nc2 . dt . GridDataset . Gridset > getGridsets ( ) { return new ArrayList < ucar . nc2 . dt . GridDataset . Gridset > ( gridsetHash . values ( ) ) ; }


Input: Show Grids and coordinate systems . [CODESPLIT] private void getInfo ( Formatter buf ) { int countGridset = 0 ; for ( Gridset gs : gridsetHash . values ( ) ) { GridCoordSystem gcs = gs . getGeoCoordSystem ( ) ; buf . format ( "%nGridset %d  coordSys=%s" , countGridset , gcs ) ; buf . format ( " LLbb=%s " , gcs . getLatLonBoundingBox ( ) ) ; if ( ( gcs . getProjection ( ) != null ) && ! gcs . getProjection ( ) . isLatLon ( ) ) buf . format ( " bb= %s" , gcs . getBoundingBox ( ) ) ; buf . format ( "%n" ) ; buf . format ( "Name__________________________Unit__________________________hasMissing_Description%n" ) ; for ( GridDatatype grid : gs . getGrids ( ) ) { buf . format ( "%s%n" , grid . getInfo ( ) ) ; } countGridset ++ ; buf . format ( "%n" ) ; } buf . format ( "%nGeoReferencing Coordinate Axes%n" ) ; buf . format ( "Name__________________________Units_______________Type______Description%n" ) ; for ( CoordinateAxis axis : ncd . getCoordinateAxes ( ) ) { if ( axis . getAxisType ( ) == null ) continue ; axis . getInfo ( buf ) ; buf . format ( "%n" ) ; } }


Input: FileCacheable [CODESPLIT] @ Override public synchronized void close ( ) throws java . io . IOException { if ( fileCache != null ) { if ( fileCache . release ( this ) ) return ; } try { if ( ncd != null ) ncd . close ( ) ; } finally { ncd = null ; } }


Input: You must call shutdown () to shut down the background threads in order to get a clean process shutdown . [CODESPLIT] public static synchronized void shutdown ( ) { if ( timer != null ) { timer . cancel ( ) ; System . out . printf ( "FileCache.shutdown called%n" ) ; } timer = null ; }


Input: Acquire a FileCacheable and lock it so no one else can use it . call FileCacheable . close when done . [CODESPLIT] public FileCacheable acquire ( FileFactory factory , DatasetUrl durl , ucar . nc2 . util . CancelTask cancelTask ) throws IOException { return acquire ( factory , durl . trueurl , durl , - 1 , cancelTask , null ) ; }


Input:
Acquire a FileCacheable from the cache and lock it so no one else can use it . If not already in cache open it the FileFactory and put in cache . <p / > App should call FileCacheable . close when done and the file is then released instead of closed . <p / > If cache size goes over maxElement then immediately ( actually in 100 msec ) schedule a cleanup in a background thread . This means that the cache should never get much larger than maxElement unless you have them all locked . [CODESPLIT] @ Override public FileCacheable acquire ( FileFactory factory , Object hashKey , DatasetUrl location , int buffer_size , CancelTask cancelTask , Object spiObject ) throws IOException { if ( null == hashKey ) hashKey = location . trueurl ; if ( null == hashKey ) throw new IllegalArgumentException ( ) ; Tracker t = null ; if ( trackAll ) { t = new Tracker ( hashKey ) ; Tracker prev = track . putIfAbsent ( hashKey , t ) ; if ( prev != null ) t = prev ; } FileCacheable ncfile = acquireCacheOnly ( hashKey ) ; if ( ncfile != null ) { hits . incrementAndGet ( ) ; if ( t != null ) t . hit ++ ; return ncfile ; } miss . incrementAndGet ( ) ; if ( t != null ) t . miss ++ ; // open the file
 ncfile = factory . open ( location , buffer_size , cancelTask , spiObject ) ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCache " + name + " acquire " + hashKey + " " + ncfile . getLocation ( ) ) ; if ( debugPrint ) System . out . println ( "  FileCache " + name + " acquire " + hashKey + " " + ncfile . getLocation ( ) ) ; // user may have canceled
 if ( ( cancelTask != null ) && ( cancelTask . isCancel ( ) ) ) { if ( ncfile != null ) ncfile . close ( ) ; // LOOK ??
 return null ; } if ( disabled . get ( ) ) return ncfile ; // see if cache element already exists
 // cant use putIfAbsent, because we cant create the CacheElement until we know if doesnt exist
 CacheElement elem ; synchronized ( cache ) { elem = cache . get ( hashKey ) ; if ( elem == null ) cache . put ( hashKey , new CacheElement ( ncfile , hashKey ) ) ; // new element
 } // already exists, add to list
 if ( elem != null ) { synchronized ( elem ) { elem . addFile ( ncfile ) ; // add to existing list
 } } // increment the number of files in the cache
 //int count = counter.incrementAndGet();
 // do we need a cleanup ??
 boolean needHard = false ; boolean needSoft = false ; synchronized ( hasScheduled ) { if ( ! hasScheduled . get ( ) ) { int count = files . size ( ) ; if ( ( count > hardLimit ) && ( hardLimit > 0 ) ) { needHard = true ; hasScheduled . getAndSet ( true ) ; // tell other threads not to schedule another cleanup
 } else if ( ( count > softLimit ) && ( softLimit > 0 ) ) { // && wantsCleanup) { //
 hasScheduled . getAndSet ( true ) ; // tell other threads not to schedule another cleanup
 needSoft = true ; } } } if ( needHard ) { if ( debugCleanup ) System . out . println ( "CleanupTask due to hard limit time=" + new Date ( ) . getTime ( ) ) ; // +" Thread="+Thread.currentThread().hashCode()
 cleanup ( hardLimit ) ; } else if ( needSoft ) { schedule ( new CleanupTask ( ) , 100 ) ; // immediate cleanup in 100 msec
 if ( debugCleanup ) System . out . println ( "CleanupTask scheduled due to soft limit time=" + new Date ( ) ) ; } return ncfile ; }


Input:
Try to find a file in the cache . [CODESPLIT] private FileCacheable acquireCacheOnly ( Object hashKey ) { if ( disabled . get ( ) ) return null ; // see if its in the cache
 CacheElement wantCacheElem = cache . get ( hashKey ) ; if ( wantCacheElem == null ) return null ; // not found in cache
 CacheElement . CacheFile want = null ; synchronized ( wantCacheElem ) { // synch in order to traverse the list
 for ( CacheElement . CacheFile file : wantCacheElem . list ) { if ( file . isLocked . compareAndSet ( false , true ) ) { want = file ; break ; } } } if ( want == null ) return null ; // no unlocked file in cache
 // check if modified, remove if so
 if ( want . ncfile != null ) { long lastModified = want . ncfile . getLastModified ( ) ; boolean changed = lastModified != want . lastModified ; if ( cacheLog . isDebugEnabled ( ) && changed ) cacheLog . debug ( "FileCache " + name + ": acquire from cache " + hashKey + " " + want . ncfile . getLocation ( ) + " was changed; discard" ) ; if ( changed ) { remove ( want ) ; } } if ( want . ncfile != null ) { try { want . ncfile . reacquire ( ) ; // rehydrate
 } catch ( IOException ioe ) { if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCache " + name + " acquire from cache " + hashKey + " " + want . ncfile . getLocation ( ) + " failed: " + ioe . getMessage ( ) ) ; remove ( want ) ; // failed
 } } if ( debugPrint && want . ncfile != null ) { System . out . printf ( "  FileCache %s found in cache %s (countLocks %d)%n" , name , hashKey , countLocked ( ) ) ; } return want . ncfile ; }


Input:
LOOK should you remove the entire CacheElement ? [CODESPLIT] private void remove ( CacheElement . CacheFile want ) { want . remove ( ) ; files . remove ( want . ncfile ) ; try { want . ncfile . setFileCache ( null ) ; // unhook the caching
 want . ncfile . close ( ) ; } catch ( IOException e ) { log . error ( "close failed on " + want . ncfile . getLocation ( ) , e ) ; } want . ncfile = null ; }


Input:
Remove all instances of object from the cache [CODESPLIT] @ Override public void eject ( Object hashKey ) { if ( disabled . get ( ) ) return ; // see if its in the cache
 CacheElement wantCacheElem = cache . get ( hashKey ) ; if ( wantCacheElem == null ) return ; synchronized ( wantCacheElem ) { // synch in order to traverse the list
 for ( CacheElement . CacheFile want : wantCacheElem . list ) { // LOOK can we use remove(want);  ??
 files . remove ( want . ncfile ) ; try { want . ncfile . setFileCache ( null ) ; // unhook the caching
 want . ncfile . close ( ) ; // really close the file
 log . debug ( "close " + want . ncfile . getLocation ( ) ) ; } catch ( IOException e ) { log . error ( "close failed on " + want . ncfile . getLocation ( ) , e ) ; } want . ncfile = null ; if ( debugPrint ) System . out . println ( "  FileCache " + name + " eject " + hashKey ) ; } wantCacheElem . list . clear ( ) ; } cache . remove ( hashKey ) ; }


Input:
Release the file . This unlocks it updates its lastAccessed date . Normally applications need not call this just close the file as usual . The FileCacheable has to do tricky stuff . [CODESPLIT] @ Override public boolean release ( FileCacheable ncfile ) throws IOException { if ( ncfile == null ) return false ; if ( disabled . get ( ) ) { ncfile . setFileCache ( null ) ; // prevent infinite loops
 ncfile . close ( ) ; return false ; } // find it in the file cache
 CacheElement . CacheFile file = files . get ( ncfile ) ; // using hashCode of the FileCacheable
 if ( file != null ) { if ( ! file . isLocked . get ( ) ) { cacheLog . warn ( "FileCache " + name + " release " + ncfile . getLocation ( ) + " not locked; hash= " + ncfile . hashCode ( ) ) ; } file . lastAccessed = System . currentTimeMillis ( ) ; file . countAccessed ++ ; file . isLocked . set ( false ) ; file . ncfile . release ( ) ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCache " + name + " release " + ncfile . getLocation ( ) + "; hash= " + ncfile . hashCode ( ) ) ; if ( debugPrint ) System . out . printf ( "  FileCache %s release %s lock=%s count=%d%n" , name , ncfile . getLocation ( ) , file . isLocked . get ( ) , countLocked ( ) ) ; return true ; } return false ; // throw new IOException("FileCache " + name + " release does not have file in cache = " + ncfile.getLocation());
 }


Input:
debug [CODESPLIT] public String getInfo ( FileCacheable ncfile ) throws IOException { if ( ncfile == null ) return "" ; // find it in the file cache
 CacheElement . CacheFile file = files . get ( ncfile ) ; if ( file != null ) { return "File is in cache= " + file ; } return "File not in cache" ; }


Input:
Show individual cache entries add to formatter . [CODESPLIT] @ Override public void showCache ( Formatter format ) { ArrayList < CacheElement . CacheFile > allFiles = new ArrayList <> ( files . size ( ) ) ; for ( CacheElement elem : cache . values ( ) ) { synchronized ( elem ) { allFiles . addAll ( elem . list ) ; } } Collections . sort ( allFiles ) ; // sort so oldest are on top
 format . format ( "%nFileCache %s (min=%d softLimit=%d hardLimit=%d scour=%d secs):%n" , name , minElements , softLimit , hardLimit , period / 1000 ) ; format . format ( " isLocked  accesses lastAccess                   location %n" ) ; for ( CacheElement . CacheFile file : allFiles ) { String loc = file . ncfile != null ? file . ncfile . getLocation ( ) : "null" ; format . format ( "%8s %9d %s == %s %n" , file . isLocked , file . countAccessed , CalendarDateFormatter . toDateTimeStringISO ( file . lastAccessed ) , loc ) ; } showStats ( format ) ; }


Input: Add stat report ( hits misses etc ) to formatter . [CODESPLIT] public void showStats ( Formatter format ) { format . format ( "  hits= %d miss= %d nfiles= %d elems= %d%n" , hits . get ( ) , miss . get ( ) , files . size ( ) , cache . values ( ) . size ( ) ) ; }


Input:
Cleanup the cache bringing it down to minimum number . Will close the LRU ( least recently used ) ones first . Will not close locked files . Normally this is done in a background thread you dont need to call . <p / > We have to synchronize because of clearCache () [CODESPLIT] synchronized void cleanup ( int maxElements ) { try { /* int size = counter.get();
      int fsize = files.size();
      if (debug && (size != fsize)) {
        log.warn("FileCache " + name + " counter " + size + " doesnt match files().size=" + fsize);
      } */ int size = files . size ( ) ; if ( size <= minElements ) return ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCache {} cleanup started at {} for maxElements={}" , name , CalendarDate . present ( ) , maxElements ) ; if ( debugCleanup ) System . out . printf ( " FileCache %s cleanup started at %s for maxElements=%d%n" , name , CalendarDate . present ( ) , maxElements ) ; cleanups . incrementAndGet ( ) ; // add unlocked files to the all list
 List < CacheElement . CacheFile > allFiles = new ArrayList <> ( size + 10 ) ; for ( CacheElement . CacheFile file : files . values ( ) ) { if ( ! file . isLocked . get ( ) ) allFiles . add ( file ) ; } Collections . sort ( allFiles ) ; // sort so oldest are on top
 // take oldest ones and put on delete list
 int need2delete = size - minElements ; int minDelete = size - maxElements ; List < CacheElement . CacheFile > deleteList = new ArrayList <> ( need2delete ) ; int count = 0 ; Iterator < CacheElement . CacheFile > iter = allFiles . iterator ( ) ; while ( iter . hasNext ( ) && ( count < need2delete ) ) { CacheElement . CacheFile file = iter . next ( ) ; if ( file . isLocked . compareAndSet ( false , true ) ) { // lock it so it isnt used anywhere else
 file . remove ( ) ; // remove from the containing element
 deleteList . add ( file ) ; count ++ ; } } if ( count < minDelete ) { cacheLog . warn ( "FileCache " + name + " cleanup couldnt remove enough to keep under the maximum= " + maxElements + " due to locked files; currently at = " + ( size - count ) ) ; if ( debugCleanup ) System . out . println ( "FileCache " + name + " cleanup couldnt remove enough to keep under the maximum= " + maxElements + " due to locked files; currently at = " + ( size - count ) ) ; } // remove empty cache elements
 synchronized ( cache ) { for ( CacheElement elem : cache . values ( ) ) { synchronized ( elem ) { if ( elem . list . size ( ) == 0 ) cache . remove ( elem . hashKey ) ; } } } // now actually close the files
 long start = System . currentTimeMillis ( ) ; for ( CacheElement . CacheFile file : deleteList ) { //counter.decrementAndGet();
 if ( null == files . remove ( file . ncfile ) ) { if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( " FileCache {} cleanup failed to remove {}%n" , name , file . ncfile . getLocation ( ) ) ; } try { file . ncfile . setFileCache ( null ) ; file . ncfile . close ( ) ; file . ncfile = null ; // help the gc
 } catch ( IOException e ) { log . error ( "FileCache " + name + " close failed on " + file . getCacheName ( ) ) ; } } long took = System . currentTimeMillis ( ) - start ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( " FileCache {} cleanup had={} removed={} took={} msecs%n" , name , size , deleteList . size ( ) , took ) ; if ( debugCleanup ) System . out . printf ( " FileCache %s cleanup had=%d removed=%d took=%d msecs%n" , name , size , deleteList . size ( ) , took ) ; } finally { // allow scheduling again
 hasScheduled . set ( false ) ; } }


Input:
Convert 4 bytes into a signed integer . [CODESPLIT] private static int int4 ( int a , int b , int c , int d ) { // all bits set to ones
 if ( a == 0xff && b == 0xff && c == 0xff && d == 0xff ) return UNDEFINED ; return ( 1 - ( ( a & 128 ) >> 6 ) ) * ( ( a & 127 ) << 24 | b << 16 | c << 8 | d ) ; }


Input: Acquire a FileCacheable and lock it so no one else can use it . call FileCacheable . close () when done . [CODESPLIT] @ Override public FileCacheable acquire ( FileFactory factory , DatasetUrl location ) throws IOException { return acquire ( factory , location . trueurl , location , - 1 , null , null ) ; }


Input: Acquire a FileCacheable from the cache and lock it so no one else can use it . If not already in cache open it with FileFactory and put in cache . <p / > Call FileCacheable . close () when done ( rather than FileCacheIF . release () directly ) and the file is then released instead of closed . <p / > If cache size goes over maxElement then immediately ( actually in 100 msec ) schedule a cleanup in a background thread . This means that the cache should never get much larger than maxElement unless you have them all locked . [CODESPLIT] @ Override public FileCacheable acquire ( FileFactory factory , Object hashKey , DatasetUrl location , int buffer_size , CancelTask cancelTask , Object spiObject ) throws IOException { if ( null == hashKey ) hashKey = location . trueurl ; if ( null == hashKey ) throw new IllegalArgumentException ( ) ; Tracker t = null ; if ( trackAll ) { t = new Tracker ( hashKey ) ; Tracker prev = track . putIfAbsent ( hashKey , t ) ; if ( prev != null ) t = prev ; } FileCacheable ncfile = acquireCacheOnly ( hashKey ) ; if ( ncfile != null ) { hits . incrementAndGet ( ) ; if ( t != null ) t . hit ++ ; return ncfile ; } miss . incrementAndGet ( ) ; if ( t != null ) t . miss ++ ; // open the file ncfile = factory . open ( location , buffer_size , cancelTask , spiObject ) ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCacheARC " + name + " acquire " + hashKey + " " + ncfile . getLocation ( ) ) ; if ( debugPrint ) System . out . println ( "  FileCacheARC " + name + " acquire " + hashKey + " " + ncfile . getLocation ( ) ) ; // user may have canceled if ( ( cancelTask != null ) && ( cancelTask . isCancel ( ) ) ) { if ( ncfile != null ) ncfile . close ( ) ; return null ; } if ( disabled . get ( ) ) return ncfile ; addToCache ( hashKey , ncfile ) ; return ncfile ; }


Input: Try to find a file in the cache . [CODESPLIT] private FileCacheable acquireCacheOnly ( Object hashKey ) { if ( disabled . get ( ) ) return null ; // see if its in the cache CacheElement wantCacheElem = cache . get ( hashKey ) ; if ( wantCacheElem == null ) return null ; // not found in cache CacheElement . CacheFile want = null ; for ( CacheElement . CacheFile file : wantCacheElem . list ) { if ( file . isLocked . compareAndSet ( false , true ) ) { want = file ; break ; } } if ( want == null ) return null ; // no unlocked file in cache // check if modified, remove if so if ( want . ncfile != null ) { long lastModified = want . ncfile . getLastModified ( ) ; boolean changed = lastModified != wantCacheElem . lastModified . get ( ) ; if ( changed ) { // underlying file was modified if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCacheARC " + name + ": acquire from cache " + hashKey + " " + want . ncfile . getLocation ( ) + " was changed; discard" ) ; expireFromCache ( wantCacheElem ) ; return null ; } } updateInCache ( wantCacheElem ) ; return want . ncfile ; }


Input: get CacheElement specified by hashKey . If found update lastUsed in shadowCache . [CODESPLIT] private CacheElement updateInCache ( CacheElement elem ) { if ( shadowCache . firstKey ( ) == elem ) return elem ; elem . updateAccessed ( ) ; CacheElement prev = shadowCache . put ( elem , elem ) ; // faster if we could just insert at the top of the list. maybe we need to use LinkedList ? if ( prev != null && ( elem != prev ) ) { CacheElementComparator cc = new CacheElementComparator ( ) ; System . out . printf ( "elem != prev compare=%d%n" , cc . compare ( elem , prev ) ) ; System . out . printf ( "hash elem =%d prev=%d%n" , elem . hashCode ( ) , prev . hashCode ( ) ) ; } return elem ; }


Input: / * if ( disabled . get () ) return ; [CODESPLIT] private void addToCache ( Object hashKey , FileCacheable ncfile ) { CacheElement newCacheElem = new CacheElement ( hashKey ) ; CacheElement previous = cache . putIfAbsent ( hashKey , newCacheElem ) ; // add new element if doesnt exist CacheElement elem = ( previous != null ) ? previous : newCacheElem ; // use previous if it exists elem . addFile ( ncfile ) ; // add to existing list shadowCache . put ( newCacheElem , newCacheElem ) ; int size = cacheSize . getAndIncrement ( ) ; if ( size > softLimit ) { removeFromCache ( size - softLimit ) ; } }


Input: Release the file . This unlocks it updates its lastAccessed date . FileCacheable . close () needs to call this instead of actually closing . [CODESPLIT] @ Override public boolean release ( FileCacheable ncfile ) throws IOException { if ( ncfile == null ) return false ; if ( disabled . get ( ) ) { ncfile . setFileCache ( null ) ; // prevent infinite loops ncfile . close ( ) ; return false ; } // find it in the file cache int hashcode = System . identityHashCode ( ncfile ) ; // using Object hashCode of the FileCacheable CacheElement . CacheFile file = files . get ( hashcode ) ; if ( file != null ) { if ( ! file . isLocked . get ( ) ) { Exception e = new Exception ( "Stack trace" ) ; cacheLog . warn ( "FileCacheARC " + name + " release " + ncfile . getLocation ( ) + " not locked; hash= " + ncfile . hashCode ( ) , e ) ; } //file.lastAccessed = System.currentTimeMillis(); //file.countAccessed++; file . isLocked . set ( false ) ; if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "FileCacheARC " + name + " release " + ncfile . getLocation ( ) + "; hash= " + ncfile . hashCode ( ) ) ; if ( debugPrint ) System . out . println ( "  FileCacheARC " + name + " release " + ncfile . getLocation ( ) ) ; return true ; } return false ; // throw new IOException("FileCacheARC " + name + " release does not have file in cache = " + ncfile.getLocation()); }


Input: debug [CODESPLIT] public String getInfo ( FileCacheable ncfile ) throws IOException { if ( ncfile == null ) return "" ; // find it in the file cache int hashcode = System . identityHashCode ( ncfile ) ; CacheElement . CacheFile file = files . get ( hashcode ) ; if ( file != null ) { return "File is in cache= " + file ; } return "File not in cache" ; }


Input: Remove all cache entries . [CODESPLIT] public synchronized void clearCache ( boolean force ) { List < CacheElement . CacheFile > deleteList = new ArrayList <> ( 2 * cache . size ( ) ) ; if ( force ) { cache . clear ( ) ; // deletes everything from the cache deleteList . addAll ( files . values ( ) ) ; // add everything to the delete list files . clear ( ) ; // counter.set(0); } else { // add unlocked files to the delete list, remove from files hash Iterator < CacheElement . CacheFile > iter = files . values ( ) . iterator ( ) ; while ( iter . hasNext ( ) ) { CacheElement . CacheFile file = iter . next ( ) ; if ( file . isLocked . compareAndSet ( false , true ) ) { file . remove ( ) ; // remove from the containing CacheElement deleteList . add ( file ) ; iter . remove ( ) ; } } // remove empty cache elements for ( CacheElement elem : cache . values ( ) ) { if ( elem . list . size ( ) == 0 ) cache . remove ( elem . hashKey ) ; } } // close all files in deleteList for ( CacheElement . CacheFile file : deleteList ) { if ( force && file . isLocked . get ( ) ) cacheLog . warn ( "FileCacheARC " + name + " force close locked file= " + file ) ; //counter.decrementAndGet(); if ( file . ncfile == null ) continue ; try { file . ncfile . setFileCache ( null ) ; file . ncfile . close ( ) ; file . ncfile = null ; // help the gc } catch ( IOException e ) { log . error ( "FileCacheARC " + name + " close failed on " + file ) ; } } if ( cacheLog . isDebugEnabled ( ) ) cacheLog . debug ( "*FileCacheARC " + name + " clearCache force= " + force + " deleted= " + deleteList . size ( ) + " left=" + files . size ( ) ) ; //System.out.println("\n*NetcdfFileCache.clearCache force= " + force + " deleted= " + deleteList.size() + " left=" + counter.get()); }


Input: Show individual cache entries add to formatter . [CODESPLIT] @ Override public void showCache ( Formatter format ) { ArrayList < CacheElement . CacheFile > allFiles = new ArrayList <> ( files . size ( ) ) ; for ( CacheElement elem : cache . values ( ) ) { allFiles . addAll ( elem . list ) ; } Collections . sort ( allFiles ) ; // sort so oldest are on top format . format ( "%nFileCacheARC %s (min=%d softLimit=%d hardLimit=%d scour=%d):%n" , name , minElements , softLimit , hardLimit , period ) ; format . format ( "isLocked  accesses lastAccess                   location %n" ) ; for ( CacheElement . CacheFile file : allFiles ) { String loc = file . ncfile != null ? file . ncfile . getLocation ( ) : "null" ; CalendarDate cd = CalendarDate . of ( file . getLastAccessed ( ) ) ; format . format ( "%8s %9d %s %s %n" , file . isLocked , file . getCountAccessed ( ) , CalendarDateFormatter . toTimeUnits ( cd ) , loc ) ; } showStats ( format ) ; }


Input: ///////////////////////////////////////////////////////////// [CODESPLIT] public void showTracking ( Formatter format ) { if ( track == null ) return ; List < Tracker > all = new ArrayList <> ( track . size ( ) ) ; for ( Tracker val : track . values ( ) ) all . ( val ) ; Collections . sort ( all ) ; // LOOK what should we sort by ?? int count = 0 ; int countAll = 0 ; format . format ( "%nTrack of all files in FileCacheARC%n" ) ; format . format ( "   seq  accum   hit   miss  file%n" ) ; for ( Tracker t : all ) { count ++ ; countAll += t . hit + t . miss ; format . format ( "%6d  %6d : %5d %5d %s%n" , count , countAll , t . hit , t . miss , t . key ) ; } format . format ( "%n" ) ; }


Input: / * the parse function allows the specification of a new stream in case one is reusing the parser [CODESPLIT] public boolean parse ( String input ) throws ParseException { ( ( Dap2Lex ) yylexer ) . reset ( parsestate ) ; ( ( Dap2Lex ) yylexer ) . setText ( input ) ; return parse ( ) ; }


Input:
Determine if this CoordinateSystem can be made into a GridCoordSys . Optionally for a given variable . This currently assumes that the CoordinateSystem : <ol > <li > is georeferencing ( cs . isGeoReferencing () ) <li > x y are 1 or 2 - dimensional axes . <li > z t if they exist are 1 - dimensional axes . <li > domain rank > 1 < / ol > [CODESPLIT] public static boolean isGridCoordSys ( Formatter sbuff , CoordinateSystem cs , VariableEnhanced v ) { // must be at least 2 axes
 if ( cs . getRankDomain ( ) < 2 ) { if ( sbuff != null ) { sbuff . format ( "%s: domain rank < 2%n" , cs . getName ( ) ) ; } return false ; } // must be lat/lon or have x,y and projecction
 if ( ! cs . isLatLon ( ) ) { // do check for GeoXY ourself
 if ( ( cs . getXaxis ( ) == null ) || ( cs . getYaxis ( ) == null ) ) { if ( sbuff != null ) { sbuff . format ( "%s: NO Lat,Lon or X,Y axis%n" , cs . getName ( ) ) ; } return false ; } if ( null == cs . getProjection ( ) ) { if ( sbuff != null ) { sbuff . format ( "%s: NO projection found%n" , cs . getName ( ) ) ; } return false ; } } // obtain the x,y or lat/lon axes. x,y normally must be convertible to km
 CoordinateAxis xaxis , yaxis ; if ( cs . isGeoXY ( ) ) { xaxis = cs . getXaxis ( ) ; yaxis = cs . getYaxis ( ) ; // change to warning
 ProjectionImpl p = cs . getProjection ( ) ; if ( ! ( p instanceof RotatedPole ) ) { if ( ! SimpleUnit . kmUnit . isCompatible ( xaxis . getUnitsString ( ) ) ) { if ( sbuff != null ) { sbuff . format ( "%s: X axis units are not convertible to km%n" , cs . getName ( ) ) ; } //return false;
 } if ( ! SimpleUnit . kmUnit . isCompatible ( yaxis . getUnitsString ( ) ) ) { if ( sbuff != null ) { sbuff . format ( "%s: Y axis units are not convertible to km%n" , cs . getName ( ) ) ; } //return false;
 } } } else { xaxis = cs . getLonAxis ( ) ; yaxis = cs . getLatAxis ( ) ; } // check x,y rank <= 2
 if ( ( xaxis . getRank ( ) > 2 ) || ( yaxis . getRank ( ) > 2 ) ) { if ( sbuff != null ) sbuff . format ( "%s: X or Y axis rank must be <= 2%n" , cs . getName ( ) ) ; return false ; } // check that the x,y have at least 2 dimensions between them ( this eliminates point data)
 int xyDomainSize = CoordinateSystem . countDomain ( new CoordinateAxis [ ] { xaxis , yaxis } ) ; if ( xyDomainSize < 2 ) { if ( sbuff != null ) sbuff . format ( "%s: X and Y axis must have 2 or more dimensions%n" , cs . getName ( ) ) ; return false ; } List < CoordinateAxis > testAxis = new ArrayList <> ( ) ; testAxis . add ( xaxis ) ; testAxis . add ( yaxis ) ; //int countRangeRank = 2;
 CoordinateAxis z = cs . getHeightAxis ( ) ; if ( ( z == null ) || ! ( z instanceof CoordinateAxis1D ) ) z = cs . getPressureAxis ( ) ; if ( ( z == null ) || ! ( z instanceof CoordinateAxis1D ) ) z = cs . getZaxis ( ) ; if ( ( z != null ) && ! ( z instanceof CoordinateAxis1D ) ) { if ( sbuff != null ) { sbuff . format ( "%s: Z axis must be 1D%n" , cs . getName ( ) ) ; } return false ; } if ( z != null ) testAxis . add ( z ) ; // tom margolis 3/2/2010
 // allow runtime independent of time
 CoordinateAxis t = cs . getTaxis ( ) ; CoordinateAxis rt = cs . findAxis ( AxisType . RunTime ) ; // A runtime axis must be scalar or one-dimensional
 if ( rt != null ) { if ( ! rt . isScalar ( ) && ! ( rt instanceof CoordinateAxis1D ) ) { if ( sbuff != null ) sbuff . format ( "%s: RunTime axis must be 1D%n" , cs . getName ( ) ) ; return false ; } } // If time axis is two-dimensional...
 if ( ( t != null ) && ! ( t instanceof CoordinateAxis1D ) && ( t . getRank ( ) != 0 ) ) { if ( rt != null ) { if ( rt . getRank ( ) != 1 ) { if ( sbuff != null ) sbuff . format ( "%s: Runtime axis must be 1D%n" , cs . getName ( ) ) ; return false ; } // time first dimension must agree with runtime
 if ( ! rt . getDimension ( 0 ) . equals ( t . getDimension ( 0 ) ) ) { if ( sbuff != null ) sbuff . format ( "%s: 2D Time axis first dimension must be runtime%n" , cs . getName ( ) ) ; return false ; } } } if ( t != null ) testAxis . add ( t ) ; if ( rt != null ) testAxis . add ( rt ) ; CoordinateAxis ens = cs . getEnsembleAxis ( ) ; if ( ens != null ) testAxis . add ( ens ) ; if ( v != null ) { // test to see that v doesnt have extra dimensions. LOOK RELAX THIS
 List < Dimension > testDomain = new ArrayList <> ( ) ; for ( CoordinateAxis axis : testAxis ) { for ( Dimension dim : axis . getDimensions ( ) ) { if ( ! testDomain . contains ( dim ) ) testDomain . add ( dim ) ; } } if ( ! CoordinateSystem . isSubset ( v . getDimensionsAll ( ) , testDomain ) ) { if ( sbuff != null ) sbuff . format ( " NOT complete%n" ) ; return false ; } } return true ; }


Input: Determine if the CoordinateSystem cs can be made into a GridCoordSys for the Variable v . [CODESPLIT] public static GridCoordSys makeGridCoordSys ( Formatter sbuff , CoordinateSystem cs , VariableEnhanced v ) { if ( sbuff != null ) { sbuff . format ( " " ) ; v . getNameAndDimensions ( sbuff , false , true ) ; sbuff . format ( " check CS %s: " , cs . getName ( ) ) ; } if ( isGridCoordSys ( sbuff , cs , v ) ) { GridCoordSys gcs = new GridCoordSys ( cs , sbuff ) ; if ( sbuff != null ) sbuff . format ( " OK%n" ) ; return gcs ; } return null ; }


Input:
we have to delay making these since we dont identify the dimensions specifically until now [CODESPLIT] void makeVerticalTransform ( GridDataset gds , Formatter parseInfo ) { if ( vt != null ) return ; // already done
 if ( vCT == null ) return ; // no vt
 vt = vCT . makeVerticalTransform ( gds . getNetcdfDataset ( ) , timeDim ) ; if ( vt == null ) { if ( parseInfo != null ) parseInfo . format ( "  - ERR can't make VerticalTransform = %s%n" , vCT . getVerticalTransformType ( ) ) ; } else { if ( parseInfo != null ) parseInfo . format ( "  - VerticalTransform = %s%n" , vCT . getVerticalTransformType ( ) ) ; } }


Input: Is this a global coverage over longitude ? [CODESPLIT] @ Override public boolean isGlobalLon ( ) { if ( ! isLatLon ) return false ; if ( ! ( horizXaxis instanceof CoordinateAxis1D ) ) return false ; CoordinateAxis1D lon = ( CoordinateAxis1D ) horizXaxis ; double first = lon . getCoordEdge ( 0 ) ; double last = lon . getCoordEdge ( ( int ) lon . getSize ( ) ) ; double min = Math . min ( first , last ) ; double max = Math . max ( first , last ) ; return ( max - min ) >= 360 ; }


Input: true if increasing z coordinate values means up in altitude [CODESPLIT] @ Override public boolean isZPositive ( ) { if ( vertZaxis == null ) return false ; if ( vertZaxis . getPositive ( ) != null ) { return vertZaxis . getPositive ( ) . equalsIgnoreCase ( ucar . nc2 . constants . CF . POSITIVE_UP ) ; } if ( vertZaxis . getAxisType ( ) == AxisType . Height ) return true ; return vertZaxis . getAxisType ( ) != AxisType . Pressure ; }


Input:
Given a point in x y coordinate space find the x y index in the coordinate system . [CODESPLIT] @ Override public int [ ] findXYindexFromCoord ( double x_coord , double y_coord , int [ ] result ) { if ( result == null ) result = new int [ 2 ] ; if ( ( horizXaxis instanceof CoordinateAxis1D ) && ( horizYaxis instanceof CoordinateAxis1D ) ) { result [ 0 ] = ( ( CoordinateAxis1D ) horizXaxis ) . findCoordElement ( x_coord ) ; result [ 1 ] = ( ( CoordinateAxis1D ) horizYaxis ) . findCoordElement ( y_coord ) ; return result ; } else if ( ( horizXaxis instanceof CoordinateAxis2D ) && ( horizYaxis instanceof CoordinateAxis2D ) ) { if ( g2d == null ) g2d = new GridCoordinate2D ( ( CoordinateAxis2D ) horizYaxis , ( CoordinateAxis2D ) horizXaxis ) ; int [ ] result2 = new int [ 2 ] ; boolean found = g2d . findCoordElement ( y_coord , x_coord , result2 ) ; if ( found ) { result [ 0 ] = result2 [ 1 ] ; result [ 1 ] = result2 [ 0 ] ; } else { result [ 0 ] = - 1 ; result [ 1 ] = - 1 ; } return result ; } // cant happen
 throw new IllegalStateException ( "GridCoordSystem.findXYindexFromCoord" ) ; }