public void
    dataset(DapDataset dmr)
            throws DapException
    {
        // Iterate over the variables in order
        for(DapVariable var : this.dmr.getTopVariables()) {
            if(!this.ce.references(var))
                continue;
            variable(var);
        }
    }

public
void
dataset
(
DapDataset
dmr
)
throws
DapException
{
// Iterate over the variables in order
for
(
DapVariable
var
:
this
.
dmr
.
getTopVariables
(
)
)
{
if
(
!
this
.
ce
.
references
(
var
)
)
continue
;
variable
(
var
)
;
}
}


public static void returnFile(HttpServlet servlet, String contentPath, String path,
                                HttpServletRequest req, HttpServletResponse res, String contentType) throws IOException {

    String filename = ServletUtil.formFilename(contentPath, path);

    log.debug("returnFile(): returning file <" + filename + ">.");
    // No file, nothing to view
    if (filename == null) {
      res.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    // dontallow ..
    if (filename.contains("..")) {
      res.sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }

    // dont allow access to WEB-INF or META-INF
    String upper = filename.toUpperCase();
    if (upper.contains("WEB-INF") || upper.contains("META-INF")) {
      res.sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }

    returnFile(servlet, req, res, new File(filename), contentType);
  }

Write a file to the response stream.

@param servlet     called from this servlet, may be null
@param contentPath file root path
@param path        file path reletive to the root
@param req         the request
@param res         the response
@param contentType content type, or null
@throws IOException on write error


public static void returnString(String contents, HttpServletResponse res)
          throws IOException {

    try {
      ServletOutputStream out = res.getOutputStream();
      IO.copy(new ByteArrayInputStream(contents.getBytes(CDM.utf8Charset)), out);
    } catch (IOException e) {
      log.error(" IOException sending string: ", e);
      res.sendError(HttpServletResponse.SC_NOT_FOUND, "Problem sending string: " + e.getMessage());
    }
  }

public
static
void
returnString
(
String
contents
,
HttpServletResponse
res
)
throws
IOException
{
try
{
ServletOutputStream
out
=
res
.
getOutputStream
(
)
;
IO
.
copy
(
new
ByteArrayInputStream
(
contents
.
getBytes
(
CDM
.
utf8Charset
)
)
,
out
)
;
}
catch
(
IOException
e
)
{
log
.
error
(
" IOException sending string: "
,
e
)
;
res
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
,
"Problem sending string: "
+
e
.
getMessage
(
)
)
;
}
}

Send given content string as the HTTP response.

@param contents the string to return as the HTTP response.
@param res      the HttpServletResponse
@throws IOException if an I/O error occurs while writing the response.

Send given content string as the HTTP response .


public static int setResponseContentLength(HttpServletResponse response, String s) throws UnsupportedEncodingException {
    int length = s.getBytes(response.getCharacterEncoding()).length;
    response.setContentLength(length);
    return length;
  }

public static int setResponseContentLength ( HttpServletResponse response , String s ) throws UnsupportedEncodingException { int length = s . getBytes ( response . getCharacterEncoding ( ) ) . length ; response . setContentLength ( length ) ; return length ; }

Set the proper content length for the string

@param response the HttpServletResponse to act upon
@param s the string that will be returned
@return the number of bytes
@throws UnsupportedEncodingException on bad character encoding


public static URI getRequestURI(HttpServletRequest req) {
    try {
      return new URI(getRequestBase(req));
    } catch (URISyntaxException e) {
      e.printStackTrace();
      return null;
    }
  }

public static URI getRequestURI ( HttpServletRequest req ) { try { return new URI ( getRequestBase ( req ) ) ; } catch ( URISyntaxException e ) { e . printStackTrace ( ) ; return null ; } }

The request base as a URI

@param req the HttpServletRequest
@return parsed request as a URI


public static String getRequestPath(HttpServletRequest req) {
    StringBuilder buff = new StringBuilder();
    if (req.getServletPath() != null)
      buff.append(req.getServletPath());
    if (req.getPathInfo() != null)
      buff.append(req.getPathInfo());
    return buff.toString();
  }

public static String getRequestPath ( HttpServletRequest req ) { StringBuilder buff = new StringBuilder ( ) ; if ( req . getServletPath ( ) != null ) buff . append ( req . getServletPath ( ) ) ; if ( req . getPathInfo ( ) != null ) buff . append ( req . getPathInfo ( ) ) ; return buff . toString ( ) ; }

servletPath + pathInfo

@param req the HttpServletRequest
@return parsed request servletPath + pathInfo


public static String getRequest(HttpServletRequest req) {
    String query = req.getQueryString();
    return getRequestBase(req) + (query == null ? "" : "?" + query);
  }

public static String getRequest ( HttpServletRequest req ) { String query = req . getQueryString ( ) ; return getRequestBase ( req ) + ( query == null ? "" : "?" + query ) ; }

The entire request including query string

@param req the HttpServletRequest
@return entire parsed request


public static String getParameterIgnoreCase(HttpServletRequest req, String paramName) {
    Enumeration e = req.getParameterNames();
    while (e.hasMoreElements()) {
      String s = (String) e.nextElement();
      if (s.equalsIgnoreCase(paramName))
        return req.getParameter(s);
    }
    return null;
  }

public static String getParameterIgnoreCase ( HttpServletRequest req , String paramName ) { Enumeration e = req . getParameterNames ( ) ; while ( e . hasMoreElements ( ) ) { String s = ( String ) e . nextElement ( ) ; if ( s . equalsIgnoreCase ( paramName ) ) return req . getParameter ( s ) ; } return null ; }

Return the value of the given parameter for the given request. Should
only be used if the parameter is known to only have one value. If used
on a multi-valued parameter, the first value is returned.

@param req       the HttpServletRequest
@param paramName the name of the parameter to find.
@return the value of the given parameter for the given request.

Return the value of the given parameter for the given request . Should only be used if the parameter is known to only have one value . If used on a multi - valued parameter the first value is returned .


public void save() {
    if (catListBox != null) catListBox.save();

    if (prefs != null) {
      if (fileChooser != null)
        fileChooser.save();
      if (catgenFileChooser != null)
        catgenFileChooser.save();
      prefs.putInt(HDIVIDER, split.getDividerLocation());
    }
  }

public void save ( ) { if ( catListBox != null ) catListBox . save ( ) ; if ( prefs != null ) { if ( fileChooser != null ) fileChooser . save ( ) ; if ( catgenFileChooser != null ) catgenFileChooser . save ( ) ; prefs . putInt ( HDIVIDER , split . getDividerLocation ( ) ) ; } }


public int writeDirectory(HttpServletResponse res, File dir, String path) throws IOException {
    // error checking
    if (dir == null) {
      res.sendError(HttpServletResponse.SC_NOT_FOUND);
      return 0;
    }

    if (!dir.exists() || !dir.isDirectory()) {
      res.sendError(HttpServletResponse.SC_NOT_FOUND);
      return 0;
    }

    // Get directory as HTML
    String dirHtmlString = getDirectory(path, dir);

    thredds.servlet.ServletUtil.setResponseContentLength(res, dirHtmlString);
    res.setContentType(ContentType.html.getContentHeader());
    PrintWriter writer = res.getWriter();
    writer.write(dirHtmlString);
    writer.flush();

    return dirHtmlString.length();
  }

public
int
writeDirectory
(
HttpServletResponse
res
,
File
dir
,
String
path
)
throws
IOException
{
// error checking
if
(
dir
==
)
{
res
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
)
;
return
0
;
}
if
(
!
dir
.
exists
(
)
||
!
dir
.
isDirectory
(
)
)
{
res
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
)
;
return
0
;
}
// Get directory as HTML
String
dirHtmlString
=
getDirectory
(
path
,
dir
)
;
thredds
.
servlet
.
ServletUtil
.
setResponseContentLength
(
res
,
dirHtmlString
)
;
res
.
setContentType
(
ContentType
.
html
.
getContentHeader
(
)
)
;
PrintWriter
writer
=
res
.
getWriter
(
)
;
writer
.
write
(
dirHtmlString
)
;
writer
.
flush
(
)
;
return
dirHtmlString
.
length
(
)
;
}

Write a file directory.

@param res  the HttpServletResponse on which to write the file directory response.
@param dir  directory
@param path the URL path reletive to the base
@return the number of characters (Unicode code units) in the response.
@throws java.io.IOException if an I/O exception occurs.


public void setBitOffset(DataDescriptor dkey) {
    if (bitPosition == null)
      bitPosition = new HashMap<DataDescriptor, Integer>(2 * parent.getSubKeys().size());
    bitPosition.put(dkey, bitOffset);
    bitOffset += dkey.getBitWidth();
  }

public void setBitOffset ( DataDescriptor dkey ) { if ( bitPosition == null ) bitPosition = new HashMap < DataDescriptor , Integer > ( 2 * parent . getSubKeys ( ) . size ( ) ) ; bitPosition . put ( dkey , bitOffset ) ; bitOffset += dkey . getBitWidth ( ) ; }


public BitCounterUncompressed makeNested(DataDescriptor subKey, int n, int row, int replicationCountSize) {
    if (subCounters == null)
      subCounters = new HashMap<DataDescriptor, BitCounterUncompressed[]>(5); // assumes DataDescriptor.equals is ==

    BitCounterUncompressed[] subCounter = subCounters.get(subKey);
    if (subCounter == null) {
      subCounter = new BitCounterUncompressed[nrows]; // one for each row in this table
      subCounters.put(subKey, subCounter);
    }

    BitCounterUncompressed rc = new BitCounterUncompressed(subKey, n, replicationCountSize);
    subCounter[row] = rc;

    return rc;
  }

public
BitCounterUncompressed
makeNested
(
DataDescriptor
subKey
,
int
n
,
int
row
,
int
replicationCountSize
)
{
if
(
subCounters
==
)
subCounters
=
new
HashMap
<
DataDescriptor
,
BitCounterUncompressed
[
]
>
(
5
)
;
// assumes DataDescriptor.equals is ==
BitCounterUncompressed
[
]
subCounter
=
subCounters
.
get
(
subKey
)
;
if
(
subCounter
==
)
{
subCounter
=
new
BitCounterUncompressed
[
nrows
]
;
// one for each row in this table
subCounters
.
put
(
subKey
,
subCounter
)
;
}
BitCounterUncompressed
rc
=
new
BitCounterUncompressed
(
subKey
,
n
,
replicationCountSize
)
;
subCounter
[
row
]
=
rc
;
return
rc
;
}

Track nested Tables.
@param subKey  subKey is a structure or a sequence - so itself has subKeys
@param n numbers of rows in the nested table
@param row which row in the parent Table this belongs to
@param replicationCountSize number of bits taken up by the count (non-zero for sequences)
@return  nested ReplicationCounter


int countBits(int startBit) {
    countBits = replicationCountSize;
    this.startBit = new int[nrows];

    for (int i=0; i<nrows; i++) {
      this.startBit[i] = startBit + countBits;
      if (debug) System.out.println(" BitCounterUncompressed row "+i+" startBit="+ this.startBit[i]);

      for (DataDescriptor nd : parent.subKeys) {
        BitCounterUncompressed[] bitCounter = (subCounters == null) ? null : subCounters.get(nd);
        if (bitCounter == null) // a regular field
          countBits += nd.getBitWidth();
        else {
          if (debug) System.out.println(" ---------> nested "+nd.getFxyName()+" starts at ="+ (startBit + countBits));
          countBits += bitCounter[i].countBits(startBit + countBits);
          if (debug) System.out.println(" <--------- nested "+nd.getFxyName()+" ends at ="+ (startBit + countBits));
        }
      }
    }
    return countBits;
  }

int
countBits
(
int
startBit
)
{
countBits
=
replicationCountSize
;
this
.
startBit
=
new
int
[
nrows
]
;
for
(
int
i
=
0
;
i
<
nrows
;
i
++
)
{
this
.
startBit
[
i
]
=
startBit
+
countBits
;
if
(
debug
)
System
.
out
.
println
(
" BitCounterUncompressed row "
+
i
+
" startBit="
+
this
.
startBit
[
i
]
)
;
for
(
DataDescriptor
nd
:
parent
.
subKeys
)
{
BitCounterUncompressed
[
]
bitCounter
=
(
subCounters
==
)
:
subCounters
.
get
(
nd
)
;
if
(
bitCounter
==
)
// a regular field
countBits
+=
nd
.
getBitWidth
(
)
;
else
{
if
(
debug
)
System
.
out
.
println
(
" ---------> nested "
+
nd
.
getFxyName
(
)
+
" starts at ="
+
(
startBit
+
countBits
)
)
;
countBits
+=
bitCounter
[
i
]
.
countBits
(
startBit
+
countBits
)
;
if
(
debug
)
System
.
out
.
println
(
" <--------- nested "
+
nd
.
getFxyName
(
)
+
" ends at ="
+
(
startBit
+
countBits
)
)
;
}
}
}
return
countBits
;
}

total bits of this table and all subtables


public void appendLine( String line) {

    if (count >= nlines) {
      try {
        int remove = Math.max(removeIncr, count - nlines); // nlines may have changed
        int offset = ta.getLineEndOffset( remove);
        ta.replaceRange( "", 0, offset);
      } catch (Exception e) {
        log.error("Problem in TextHistoryPane", e);
      }
      count = nlines - removeIncr;
    }
    ta.append(line);
    ta.append("\n");
    count++;

    // scroll to end
    ta.setCaretPosition(ta.getText().length());
  }

public
void
appendLine
(
String
line
)
{
if
(
count
>=
nlines
)
{
try
{
int
remove
=
Math
.
max
(
removeIncr
,
count
nlines
)
;
// nlines may have changed
int
offset
=
ta
.
getLineEndOffset
(
remove
)
;
ta
.
replaceRange
(
""
,
0
,
offset
)
;
}
catch
(
Exception
e
)
{
log
.
error
(
"Problem in TextHistoryPane"
,
e
)
;
}
count
=
nlines
removeIncr
;
}
ta
.
append
(
line
)
;
ta
.
append
(
"\n"
)
;
count
++
;
// scroll to end
ta
.
setCaretPosition
(
ta
.
getText
(
)
.
length
(
)
)
;
}

Append this line to the bottom of the JTextArea.
A newline is added and JTextArea is scrolled to bottom;
remove lines at top if needed.
@param line append this line. Ok to have multiple lines (ie embedded newlines)
but not too many.

Append this line to the bottom of the JTextArea . A newline is added and JTextArea is scrolled to bottom ; remove lines at top if needed .


public Document makeStationCollectionDocument(LatLonRect bb, String[] names) throws IOException {

    List<DsgFeatureCollection> list = fdp.getPointFeatureCollectionList();
    DsgFeatureCollection fc = list.get(0); // LOOK maybe should pass in the dsg?

    if (!(fc instanceof StationTimeSeriesFeatureCollection)) {
      throw new UnsupportedOperationException(fc.getClass().getName() + " not a StationTimeSeriesFeatureCollection");
    }
    StationTimeSeriesFeatureCollection sobs = (StationTimeSeriesFeatureCollection) fc;

    Element rootElem = new Element("stationCollection");
    Document doc = new Document(rootElem);

    List<StationFeature> stations;
    if (bb != null)
      stations = sobs.getStationFeatures(bb);
    else if (names != null)
      stations = sobs.getStationFeatures(Arrays.asList(names));
    else
      stations = sobs.getStationFeatures();

    for (Station s : stations) {
      Element sElem = new Element("station");
      sElem.setAttribute("name", s.getName());
      if (s.getWmoId() != null)
        sElem.setAttribute("wmo_id", s.getWmoId());
      if ((s.getDescription() != null) && (s.getDescription().length() > 0))
        sElem.addContent(new Element("description").addContent(s.getDescription()));

      sElem.addContent(new Element("longitude").addContent(Double.toString(s.getLongitude())));
      sElem.addContent(new Element("latitide").addContent(Double.toString(s.getLatitude())));
      if (!Double.isNaN(s.getAltitude()))
        sElem.addContent(new Element("altitude").addContent(Double.toString(s.getAltitude())));
      rootElem.addContent(sElem);
    }

    return doc;
  }

Create an XML document for the stations in this dataset, possible subsetted by bb.
Must be a station dataset.

@param bb    restrict stations to this bounding box, may be null
@param names restrict stations to these names, may be null
@return XML document for the stations
@throws IOException on read error

Create an XML document for the stations in this dataset possible subsetted by bb . Must be a station dataset .


public Document getCapabilitiesDocument() {
    Element rootElem = new Element("capabilities");
    Document doc = new Document(rootElem);
    if (null != path) {
      rootElem.setAttribute("location", path);
      Element elem = new Element("featureDataset");
      FeatureType ft = fdp.getFeatureType();
      elem.setAttribute("type", ft.toString().toLowerCase());
      String url = path.replace("dataset.xml", ft.toString().toLowerCase() + ".xml");
      elem.setAttribute("url", url);
      rootElem.addContent(elem);
    }

    List<DsgFeatureCollection> list = fdp.getPointFeatureCollectionList();
    DsgFeatureCollection fc = list.get(0); // LOOK maybe should pass in the dsg?

    rootElem.addContent(writeTimeUnit(fc.getTimeUnit()));
    rootElem.addContent(new Element("AltitudeUnits").addContent(fc.getAltUnits()));

    // data variables
    List<? extends VariableSimpleIF> vars = fdp.getDataVariables();
    Collections.sort(vars);
    for (VariableSimpleIF v : vars) {
      rootElem.addContent(writeVariable(v));
    }

    /* CollectionInfo info;
    try {
      info = new DsgCollectionHelper(fc).calcBounds();
    } catch (IOException e) {
      throw new RuntimeException(e);
    } */

    LatLonRect bb = fc.getBoundingBox();
    if (bb != null)
      rootElem.addContent(writeBoundingBox(bb));

    // add date range
    CalendarDateRange dateRange = fc.getCalendarDateRange();
    if (dateRange != null) {
      Element drElem = new Element("TimeSpan"); // from KML
      drElem.addContent(new Element("begin").addContent(dateRange.getStart().toString()));
      drElem.addContent(new Element("end").addContent(dateRange.getEnd().toString()));
      if (dateRange.getResolution() != null)
        drElem.addContent(new Element("resolution").addContent(dateRange.getResolution().toString()));

      rootElem.addContent(drElem);
    }

    /* add accept list
    Element elem = new Element("AcceptList");
    //elem.addContent(new Element("accept").addContent("raw"));
    elem.addContent(new Element("accept").addContent("csv").setAttribute("displayName", "csv"));
    elem.addContent(new Element("accept").addContent("text/csv").setAttribute("displayName", "csv (file)"));
    elem.addContent(new Element("accept").addContent("xml").setAttribute("displayName", "xml"));
    elem.addContent(new Element("accept").addContent("text/xml").setAttribute("displayName", "xml (file)"));
    elem.addContent(new Element("accept").addContent("waterml2").setAttribute("displayName", "WaterML 2.0"));
    elem.addContent(new Element("accept").addContent("netcdf").setAttribute("displayName", "CF/NetCDF-3"));
    //elem.addContent(new Element("accept").addContent("ncstream"));
    rootElem.addContent(elem); */

    return doc;
  }

Create the capabilities XML document for this dataset

@return capabilities XML document


@Nullable
    synchronized Record getRecordAt(SubsetParams coords) {
      int[] want = new int[getRank()];
      int count = 0;
      int runIdx = -1;
      for (Coordinate coord : getCoordinates()) {
        int idx = -1;
        switch (coord.getType()) {
          case runtime:
            CalendarDate runtimeCooord = coords.getRunTime();
            idx = coord.getIndex(runtimeCooord);
            runIdx = idx;
            break;

          case timeIntv:
            double[] timeIntv = coords.getTimeOffsetIntv();
            idx = coord.getIndex(new TimeCoordIntvValue((int) timeIntv[0], (int) timeIntv[1]));
            break;

          case time:
            Double timeOffset = coords.getTimeOffset(); // Double
            int coordInt = timeOffset.intValue();
            idx = coord.getIndex(coordInt);
            break;

          case time2D:
            timeIntv = coords.getTimeOffsetIntv();
            if (timeIntv != null) {
              TimeCoordIntvValue coordTinv = new TimeCoordIntvValue((int) timeIntv[0], (int) timeIntv[1]);
              idx = ((CoordinateTime2D) coord).findTimeIndexFromVal(runIdx, coordTinv); // LOOK can only use if orthogonal
              break;
            }
            Double timeCoord = coords.getTimeOffset();
            if (timeCoord != null) {
              coordInt = timeCoord.intValue();
              idx = ((CoordinateTime2D) coord).findTimeIndexFromVal(runIdx, coordInt);
              break;
            }

          // the OneTime case
          CoordinateTime2D coord2D = (CoordinateTime2D) coord;
          if (coord2D.getNtimes() == 1) {
            idx = 0;
            break;
          }
          throw new IllegalStateException("time2D must have timeOffset ot timeOffsetIntv coordinare");

          case vert:
            double[] vertIntv = coords.getVertCoordIntv();
            if (vertIntv != null) {
              VertCoordValue coordVert = new VertCoordValue(vertIntv[0], vertIntv[1]);
              idx = coord.getIndex(coordVert);
              break;
            }
            Double vertCoord = coords.getVertCoord();
            if (vertCoord != null) {
              VertCoordValue coordVert = new VertCoordValue(vertCoord);
              idx = coord.getIndex(coordVert);
            }
            break;

          case ens:
            Double ensVal = coords.getEnsCoord();
            idx = ((CoordinateEns) coord).getIndexByMember(ensVal);
            break;

          default:
            logger.warn("GribCollectionImmutable: missing CoordVal for {}%n", coord.getName());
        }

        if (idx < 0) {
          logger.debug("Cant find index for value in axis {} in variable {}", coord.getName(), name);
          return null;
        }

        want[count++] = idx;
      }
      return sa.getContent(want);
    }

coord based record finding. note only one record at a time

coord based record finding . note only one record at a time


public Coordinate getCoordinate(int index) {
      int grpIndex = coordIndex.get(index);
      return group.coords.get(grpIndex);
    }

public Coordinate getCoordinate ( int index ) { int grpIndex = coordIndex . get ( index ) ; return group . coords . get ( grpIndex ) ; }


public void addItem( Object item) {
    if (item == null) return;
    for (int i=0; i<getItemCount(); i++) {
      if (item.equals( getItemAt(i))) {
        if (i == 0) {
          setSelectedIndex(0);
          return; // already there
        }
        removeItemAt(i);
      }
    }

    // add as first in the list
    insertItemAt( item, 0);
    setSelectedIndex(0);
  }

public
void
addItem
(
Object
item
)
{
if
(
item
==
)
return
;
for
(
int
i
=
0
;
i
<
getItemCount
(
)
;
i
++
)
{
if
(
item
.
equals
(
getItemAt
(
i
)
)
)
{
if
(
i
==
0
)
{
setSelectedIndex
(
0
)
;
return
;
// already there
}
removeItemAt
(
i
)
;
}
}
// add as first in the list
insertItemAt
(
item
,
0
)
;
setSelectedIndex
(
0
)
;
}

Add the item to the top of the list. If it already exists, move it to the top.
@param item to be added.

Add the item to the top of the list . If it already exists move it to the top .


@ExceptionHandler(Throwable.class)
  public ResponseEntity<String> handle(Throwable ex) throws Throwable {
    // If the exception is annotated with @ResponseStatus rethrow it and let
    // the framework handle it - like the OrderNotFoundException example
    // at the start of this post.
    // AnnotationUtils is a Spring Framework utility class.
    // see https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
    if (AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class) != null)
      throw ex;

    logger.error("uncaught exception", ex);
    // ex.printStackTrace(); // temporary - remove in production

    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.TEXT_PLAIN);
    String msg = ex.getMessage();
      StringWriter sw = new StringWriter();
      PrintWriter p = new PrintWriter(sw);
      ex.printStackTrace(p);
      p.close();
      sw.close();
      msg = sw.toString();
    return new ResponseEntity<>("Throwable exception handled : " + htmlEscape(msg), responseHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
  }


public Slice
    slice(int i)
    {
        if(i < 0 || i >= this.rank)
            throw new IllegalArgumentException();
        return this.slices.get(i);
    }

public Slice slice ( int i ) { if ( i < 0 || i >= this . rank ) throw new IllegalArgumentException ( ) ; return this . slices . get ( i ) ; }


public int
    step(int firstpos, int lastpos)
    {
        for(int i = lastpos - 1; i >= firstpos; i--) { // walk backwards
            if(this.index.indices[i] > this.endpoint[i])
                this.index.indices[i] = this.slices.get(i).getFirst(); // reset this position
            else {
                this.index.indices[i] += this.slices.get(i).getStride();  // move to next indices
                return i;
            }
        }
        return -1;
    }

public
int
step
(
int
firstpos
,
int
lastpos
)
{
for
(
int
i
=
lastpos
1
;
i
>=
firstpos
;
i
)
{
// walk backwards
if
(
this
.
index
.
indices
[
i
]
>
this
.
endpoint
[
i
]
)
this
.
index
.
indices
[
i
]
=
this
.
slices
.
get
(
i
)
.
getFirst
(
)
;
// reset this position
else
{
this
.
index
.
indices
[
i
]
+=
this
.
slices
.
get
(
i
)
.
getStride
(
)
;
// move to next indices
return
i
;
}
}
return
1
;
}


@Nullable
  public static Map<Integer, String> getNcepGenProcess() {
    if (genProcessMap != null) return genProcessMap;
    String path = "resources/grib1/ncep/ncepTableA.xml";
    try (InputStream is = GribResourceReader.getInputStream(path)) {
      SAXBuilder builder = new SAXBuilder();
      org.jdom2.Document doc = builder.build(is);
      Element root = doc.getRootElement();

      HashMap<Integer, String> result = new HashMap<>(200);
      List<Element> params = root.getChildren("parameter");
      for (Element elem1 : params) {
        int code = Integer.parseInt(elem1.getAttributeValue("code"));
        String desc = elem1.getChildText("description");
        result.put(code, desc);
      }
      return Collections.unmodifiableMap(result);  // all at once - thread safe

    } catch (IOException | JDOMException ioe) {
      logger.error("Cant read NCEP Table 1 = " + path, ioe);
      return null;
    }
  }

@
Nullable
public
static
Map
<
Integer
,
String
>
getNcepGenProcess
(
)
{
if
(
genProcessMap
!=
)
return
genProcessMap
;
String
path
=
"resources/grib1/ncep/ncepTableA.xml"
;
try
(
InputStream
is
=
GribResourceReader
.
getInputStream
(
path
)
)
{
SAXBuilder
builder
=
new
SAXBuilder
(
)
;
org
.
jdom2
.
Document
doc
=
builder
.
build
(
is
)
;
Element
root
=
doc
.
getRootElement
(
)
;
HashMap
<
Integer
,
String
>
result
=
new
HashMap
<>
(
200
)
;
List
<
Element
>
params
=
root
.
getChildren
(
"parameter"
)
;
for
(
Element
elem1
:
params
)
{
int
code
=
Integer
.
parseInt
(
elem1
.
getAttributeValue
(
"code"
)
)
;
String
desc
=
elem1
.
getChildText
(
"description"
)
;
result
.
put
(
code
,
desc
)
;
}
return
Collections
.
unmodifiableMap
(
result
)
;
// all at once - thread safe
}
catch
(
IOException
|
JDOMException
ioe
)
{
logger
.
error
(
"Cant read NCEP Table 1 = "
+
path
,
ioe
)
;
return
;
}
}


public static FeatureType isCdmrfEndpoint(String endpoint) throws IOException {

    HTTPSession httpClient = HTTPFactory.newSession(endpoint);
    String url = endpoint + "?req=featureType";

    // get the header
    try (HTTPMethod method = HTTPFactory.Get(httpClient, url)) {
      method.setFollowRedirects(true);
      int statusCode = method.execute();
      if (statusCode != 200) return null;
      String content = method.getResponseAsString();
      return FeatureType.getType(content);

    } catch (Throwable t) {
      t.printStackTrace();
      return null;
    }
  }

public
static
FeatureType
isCdmrfEndpoint
(
String
endpoint
)
throws
IOException
{
HTTPSession
httpClient
=
HTTPFactory
.
newSession
(
endpoint
)
;
String
url
=
endpoint
+
"?req=featureType"
;
// get the header
try
(
HTTPMethod
method
=
HTTPFactory
.
Get
(
httpClient
,
url
)
)
{
method
.
setFollowRedirects
(
true
)
;
int
statusCode
=
method
.
execute
(
)
;
if
(
statusCode
!=
200
)
return
;
String
content
=
method
.
getResponseAsString
(
)
;
return
FeatureType
.
getType
(
content
)
;
}
catch
(
Throwable
t
)
{
t
.
printStackTrace
(
)
;
return
;
}
}

all CdmrFeatureDatasets must return their featureType - use as a fail-fast test of the endpoint

all CdmrFeatureDatasets must return their featureType - use as a fail - fast test of the endpoint


public void SetHasValue(int type) {
        this.type = type;
        if (debug) {
            System.out.println("sw = " + (char) sw + "; type = " + type +
                    "; set = " + set + "; val = " + val);
        }
    }

public
void
SetHasValue
(
int
type
)
{
this
.
type
=
type
;
if
(
debug
)
{
System
.
out
.
println
(
"sw = "
+
(
char
)
sw
+
"; type = "
+
type
+
"; set = "
+
set
+
"; val = "
+
val
)
;
}
}

Set the value type of the option switch to the type passed

@param    type    type of value that switch may accept or be


public static Grib1Gds factory(int center, int gridNumber) {
    if (center == 7) {
      return factoryNCEP(gridNumber);
    } else
      throw new IllegalArgumentException("Dont have predefined GDS " + gridNumber + " from " + center);
  }

public
static
Grib1Gds
factory
(
int
center
,
int
gridNumber
)
{
if
(
center
==
7
)
{
return
factoryNCEP
(
gridNumber
)
;
}
else
throw
new
IllegalArgumentException
(
"Dont have predefined GDS "
+
gridNumber
+
" from "
+
center
)
;
}

Constructs a Grib1Gds object from a pds and predefined tables.

@param center center id
@param gridNumber from pds (octet 7)
@return predefined GDS

Constructs a Grib1Gds object from a pds and predefined tables .


static public long copyB(InputStream in, OutputStream out, int bufferSize) throws IOException {
    long totalBytesRead = 0;
    int done = 0, next = 1;

    byte[] buffer = new byte[bufferSize];
    while (true) {
      int n = in.read(buffer);
      if (n == -1) break;
      out.write(buffer, 0, n);
      totalBytesRead += n;

      if (showCopy) {
        done += n;
        if (done > 1000 * 1000 * next) {
          System.out.println(next + " Mb");
          next++;
        }
      }
    }
    out.flush();
    return totalBytesRead;
  }

static
public
long
copyB
(
InputStream
in
,
OutputStream
out
,
int
bufferSize
)
throws
IOException
{
long
totalBytesRead
=
0
;
int
done
=
0
,
next
=
1
;
byte
[
]
buffer
=
new
byte
[
bufferSize
]
;
while
(
true
)
{
int
n
=
in
.
read
(
buffer
)
;
if
(
n
==
1
)
break
;
out
.
write
(
buffer
,
0
,
n
)
;
totalBytesRead
+=
n
;
if
(
showCopy
)
{
done
+=
n
;
if
(
done
>
1000
*
1000
*
next
)
{
System
.
out
.
println
(
next
+
" Mb"
)
;
next
++
;
}
}
}
out
.
flush
(
)
;
return
totalBytesRead
;
}

copy all bytes from in to out, specify buffer size

@param in         InputStream
@param out        OutputStream
@param bufferSize : internal buffer size.
@return number of bytes copied
@throws java.io.IOException on io error

copy all bytes from in to out specify buffer size


static public String readContents(InputStream is, String charset) throws IOException {
    ByteArrayOutputStream bout = new ByteArrayOutputStream(10 * default_file_buffersize);
    IO.copy(is, bout);
    return bout.toString(charset);
  }

static public String readContents ( InputStream is , String charset ) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream ( 10 * default_file_buffersize ) ; IO . copy ( is , bout ) ; return bout . toString ( charset ) ; }

Read the contents from the inputStream and place into a String,
with any error messages  put in the return String.

@param is the inputStream to read from.
@return String holding the contents, or an error message.
@throws java.io.IOException on io error

Read the contents from the inputStream and place into a String with any error messages put in the return String .


static public byte[] readContentsToByteArray(InputStream is) throws IOException {
    ByteArrayOutputStream bout = new ByteArrayOutputStream(10 * default_file_buffersize);
    IO.copy(is, bout);
    return bout.toByteArray();
  }

static public byte [ ] readContentsToByteArray ( InputStream is ) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream ( 10 * default_file_buffersize ) ; IO . copy ( is , bout ) ; return bout . toByteArray ( ) ; }

Read the contents from the inputStream and place into a byte array,
with any error messages  put in the return String.

@param is the inputStream to read from.
@return byte[] holding the contents, or an error message.
@throws java.io.IOException on io error

Read the contents from the inputStream and place into a byte array with any error messages put in the return String .


static public void writeContents(String contents, OutputStream os) throws IOException {
    ByteArrayInputStream bin = new ByteArrayInputStream(contents.getBytes(CDM.utf8Charset));
    IO.copy(bin, os);
  }

static public void writeContents ( String contents , OutputStream os ) throws IOException { ByteArrayInputStream bin = new ByteArrayInputStream ( contents . getBytes ( CDM . utf8Charset ) ) ; IO . copy ( bin , os ) ; }

Wite the contents from the String to a Stream,

@param contents String holding the contents.
@param os       write to this OutputStream
@throws java.io.IOException on io error


static public void copyFileB(File fileIn, OutputStream out, int bufferSize) throws IOException {
    try (FileInputStream fin = new FileInputStream(fileIn)) {
      InputStream in = new BufferedInputStream(fin);
      IO.copyB(in, out, bufferSize);
    }
  }

static public void copyFileB ( File fileIn , OutputStream out , int bufferSize ) throws IOException { try ( FileInputStream fin = new FileInputStream ( fileIn ) ) { InputStream in = new BufferedInputStream ( fin ) ; IO . copyB ( in , out , bufferSize ) ; } }

copy file to output stream, specify internal buffer size

@param fileIn     copy this file
@param out        copy to this stream
@param bufferSize internal buffer size.
@throws java.io.IOException on io error

copy file to output stream specify internal buffer size


static public long copyRafB(ucar.unidata.io.RandomAccessFile raf, long offset, long length, OutputStream out, byte[] buffer) throws IOException {
    int bufferSize = buffer.length;
    long want = length;
    raf.seek(offset);
    while (want > 0) {
      int len = (int) Math.min(want, bufferSize);
      int bytesRead = raf.read(buffer, 0, len);
      if (bytesRead <= 0) break;
      out.write(buffer, 0, bytesRead);
      want -= bytesRead;
    }
    out.flush();
    return length - want;
  }

static public long copyRafB ( ucar . unidata . io . RandomAccessFile raf , long offset , long length , OutputStream out , byte [ ] buffer ) throws IOException { int bufferSize = buffer . length ; long want = length ; raf . seek ( offset ) ; while ( want > 0 ) { int len = ( int ) Math . min ( want , bufferSize ) ; int bytesRead = raf . read ( buffer , 0 , len ) ; if ( bytesRead <= 0 ) break ; out . write ( buffer , 0 , bytesRead ) ; want -= bytesRead ; } out . flush ( ) ; return length - want ; }

Copy part of a RandomAccessFile to output stream, specify internal buffer size

@param raf    copy this file
@param offset start here (byte offset)
@param length number of bytes to copy
@param out    copy to this stream
@param buffer use this buffer.
@return number of bytes copied
@throws java.io.IOException on io error

Copy part of a RandomAccessFile to output stream specify internal buffer size


static public void copyDirTree(String fromDirName, String toDirName) throws IOException {
    File fromDir = new File(fromDirName);
    File toDir = new File(toDirName);

    if (!fromDir.exists())
      return;

    if (!toDir.exists()) {
      if (!toDir.mkdirs()) {
        throw new IOException("Could not create directory: " + toDir);
      }
    }

    File[] files = fromDir.listFiles();
    if (files != null)
      for (File f : files) {
        if (f.isDirectory())
          copyDirTree(f.getAbsolutePath(), toDir.getAbsolutePath() + "/" + f.getName());
        else
          copyFile(f.getAbsolutePath(), toDir.getAbsolutePath() + "/" + f.getName());
      }
  }

static
public
void
copyDirTree
(
String
fromDirName
,
String
toDirName
)
throws
IOException
{
File
fromDir
=
new
File
(
fromDirName
)
;
File
toDir
=
new
File
(
toDirName
)
;
if
(
!
fromDir
.
exists
(
)
)
return
;
if
(
!
toDir
.
exists
(
)
)
{
if
(
!
toDir
.
mkdirs
(
)
)
{
throw
new
IOException
(
"Could not create directory: "
+
toDir
)
;
}
}
File
[
]
files
=
fromDir
.
listFiles
(
)
;
if
(
files
!=
)
for
(
File
f
:
files
)
{
if
(
f
.
isDirectory
(
)
)
copyDirTree
(
f
.
getAbsolutePath
(
)
,
toDir
.
getAbsolutePath
(
)
+
"/"
+
f
.
getName
(
)
)
;
else
copyFile
(
f
.
getAbsolutePath
(
)
,
toDir
.
getAbsolutePath
(
)
+
"/"
+
f
.
getName
(
)
)
;
}
}

Copy an entire directory tree.

@param fromDirName from this directory (do nothing if not exist)
@param toDirName   to this directory (will create if not exist)
@throws java.io.IOException on io error


static public byte[] readFileToByteArray(String filename) throws IOException {
    try (FileInputStream fin = new FileInputStream(filename)) {
      InputStream in = new BufferedInputStream(fin);
      return readContentsToByteArray(in);
    }
  }

static public byte [ ] readFileToByteArray ( String filename ) throws IOException { try ( FileInputStream fin = new FileInputStream ( filename ) ) { InputStream in = new BufferedInputStream ( fin ) ; return readContentsToByteArray ( in ) ; } }

Read the file and place contents into a byte array,
with any error messages  put in the return String.

@param filename the file to read from.
@return byte[] holding the contents, or an error message.
@throws java.io.IOException on io error

Read the file and place contents into a byte array with any error messages put in the return String .


static public String readFile(String filename) throws IOException {
    try (FileInputStream fin = new FileInputStream(filename)) {
      InputStreamReader reader = new InputStreamReader(fin, CDM.utf8Charset);
      StringWriter swriter = new StringWriter(50000);
      UnsynchronizedBufferedWriter writer = new UnsynchronizedBufferedWriter(swriter);
      writer.write(reader);
      return swriter.toString();
    }
  }

static public String readFile ( String filename ) throws IOException { try ( FileInputStream fin = new FileInputStream ( filename ) ) { InputStreamReader reader = new InputStreamReader ( fin , CDM . utf8Charset ) ; StringWriter swriter = new StringWriter ( 50000 ) ; UnsynchronizedBufferedWriter writer = new UnsynchronizedBufferedWriter ( swriter ) ; writer . write ( reader ) ; return swriter . toString ( ) ; } }

Read the contents from the named file and place into a String, assuming UTF-8 encoding.

@param filename the URL to read from.
@return String holding the file contents
@throws java.io.IOException on io error

Read the contents from the named file and place into a String assuming UTF - 8 encoding .


static public void writeToFile(String contents, File file) throws IOException {
    try (FileOutputStream fout = new FileOutputStream(file)) {
      OutputStreamWriter fw = new OutputStreamWriter(fout, CDM.utf8Charset);
      UnsynchronizedBufferedWriter writer = new UnsynchronizedBufferedWriter(fw);
      writer.write(contents);
      writer.flush();
    }
  }

static public void writeToFile ( String contents , File file ) throws IOException { try ( FileOutputStream fout = new FileOutputStream ( file ) ) { OutputStreamWriter fw = new OutputStreamWriter ( fout , CDM . utf8Charset ) ; UnsynchronizedBufferedWriter writer = new UnsynchronizedBufferedWriter ( fw ) ; writer . write ( contents ) ; writer . flush ( ) ; } }

Write String contents to a file, using UTF-8 encoding.

@param contents String holding the contents
@param file     write to this file (overwrite if exists)
@throws java.io.IOException on io error

Write String contents to a file using UTF - 8 encoding .


static public void writeToFile(String contents, String fileOutName) throws IOException {
    writeToFile(contents, new File(fileOutName));
  }

static public void writeToFile ( String contents , String fileOutName ) throws IOException { writeToFile ( contents , new File ( fileOutName ) ) ; }

Write contents to a file, using UTF-8 encoding.

@param contents    String holding the contents
@param fileOutName write to this file (overwrite if exists)
@throws java.io.IOException on io error

Write contents to a file using UTF - 8 encoding .


static public long writeToFile(InputStream in, String fileOutName) throws IOException {
    try (FileOutputStream fout = new FileOutputStream( fileOutName)) {
      OutputStream out = new BufferedOutputStream(fout);
      return IO.copy(in, out);
    } finally {
      if (null != in) in.close();
    }
  }

static public long writeToFile ( InputStream in , String fileOutName ) throws IOException { try ( FileOutputStream fout = new FileOutputStream ( fileOutName ) ) { OutputStream out = new BufferedOutputStream ( fout ) ; return IO . copy ( in , out ) ; } finally { if ( null != in ) in . close ( ) ; } }

copy input stream to file. close input stream when done.

@param in          copy from here
@param fileOutName open this file (overwrite) and copy to it.
@return number of bytes copied
@throws java.io.IOException on io error

copy input stream to file . close input stream when done .


public void parseExceptionHandler(ParseException pe, HttpServletResponse response)
    {
        //log.error("DODSServlet.parseExceptionHandler", pe);

        if(Debug.isSet("showException")) {
            log.error(pe.toString());
            printThrowable(pe);
        }

        try {
            BufferedOutputStream eOut = new BufferedOutputStream(response.getOutputStream());
            response.setHeader("Content-Description", "dods-error");

            // This should probably be set to "plain" but this works, the
            // C++ slients don't barf as they would if I sent "plain" AND
            // the C++ don't expect compressed data if I do this...
            response.setHeader("Content-Encoding", "");
            // response.setContentType("text/plain");

            // Strip any double quotes out of the parser error message.
            // These get stuck in auto-magically by the javacc generated parser
            // code and they break our error parser (bummer!)
            String msg = pe.getMessage().replace('\"', '\'');

            DAP2Exception de2 = new DAP2Exception(opendap.dap.DAP2Exception.CANNOT_READ_FILE, msg);
            de2.print(eOut);
        } catch (IOException ioe) {
            log.error("Cannot respond to client! IO Error: " + ioe.getMessage());
        }

    }

Turns a ParseException into a OPeNDAP DAP2 error and sends it to the client.

@param pe       The ParseException that caused the problem.
@param response The HttpServletResponse for the client.

Turns a ParseException into a OPeNDAP DAP2 error and sends it to the client .


public void dap2ExceptionHandler(DAP2Exception de, HttpServletResponse response)
    {
        //log.info("DODSServlet.dodsExceptionHandler (" + de.getErrorCode() + ") " + de.getErrorMessage());

        if(Debug.isSet("showException")) {
            log.error(de.toString());
            de.printStackTrace();
            printDODSException(de);
        }

        // Convert Dap2Excaption code to an HttpCode
        switch (de.getErrorCode()) {
        case DAP2Exception.NO_SUCH_FILE:
        case DAP2Exception.CANNOT_READ_FILE:
            response.setStatus(HttpStatus.SC_NOT_FOUND);
            break;
        case DAP2Exception.NO_AUTHORIZATION:
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            break;
        case DAP2Exception.NO_SUCH_VARIABLE:
        case DAP2Exception.MALFORMED_EXPR:
        case DAP2Exception.UNKNOWN_ERROR: // fall thru
        default:
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            break;
        }

        try {
            BufferedOutputStream eOut = new BufferedOutputStream(response.getOutputStream());

            response.setHeader("Content-Description", "dods-error");

            // This should probably be set to "plain" but this works, the
            // C++ slients don't barf as they would if I sent "plain" AND
            // the C++ don't expect compressed data if I do this...
            response.setHeader("Content-Encoding", "");

            de.print(eOut);

        } catch (IOException ioe) {
            log.error("Cannot respond to client! IO Error: " + ioe.getMessage());
        }

    }

Sends a OPeNDAP DAP2 error to the client.

@param de       The OPeNDAP DAP2 exception that caused the problem.
@param response The HttpServletResponse for the client.

Sends a OPeNDAP DAP2 error to the client .


public void badURL(HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        if(Debug.isSet("showResponse")) {
            log.debug("Sending Bad URL Page.");
        }

        //log.info("DODSServlet.badURL " + rs.getRequest().getRequestURI());

        response.setContentType("text/html");
        response.setHeader("XDODS-Server", getServerVersion());
        response.setHeader("Content-Description", "dods-error");
        // Commented because of a bug in the OPeNDAP C++ stuff...
        //rs.getResponse().setHeader("Content-Encoding", "plain");

        PrintWriter pw = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), Util.UTF8));

        printBadURLPage(pw);
        printHelpPage(pw);
        pw.flush();

        response.setStatus(HttpServletResponse.SC_OK);

    }

Sends an html document to the client explaining that they have used a
poorly formed URL and then the help page...

@param request  The client's  request
@param response The client response

Sends an html document to the client explaining that they have used a poorly formed URL and then the help page ...


public void doGetCatalog(ReqState rs)
            throws Exception
    {
        rs.getResponse().setHeader("XDODS-Server", getServerVersion());
        rs.getResponse().setContentType("text/xml");
        rs.getResponse().setHeader("Content-Description", "dods-catalog");

        PrintWriter pw = new PrintWriter(new OutputStreamWriter(rs.getResponse().getOutputStream(), Util.UTF8));
        printCatalog(rs, pw);
        pw.flush();
        rs.getResponse().setStatus(HttpServletResponse.SC_OK);

    }

public void doGetCatalog ( ReqState rs ) throws Exception { rs . getResponse ( ) . setHeader ( "XDODS-Server" , getServerVersion ( ) ) ; rs . getResponse ( ) . setContentType ( "text/xml" ) ; rs . getResponse ( ) . setHeader ( "Content-Description" , "dods-catalog" ) ; PrintWriter pw = new PrintWriter ( new OutputStreamWriter ( rs . getResponse ( ) . getOutputStream ( ) , Util . UTF8 ) ) ; printCatalog ( rs , pw ) ; pw . flush ( ) ; rs . getResponse ( ) . setStatus ( HttpServletResponse . SC_OK ) ; }

Handler for OPeNDAP catalog.xml requests.

@param rs The client's <code> ReqState </code>
@see GetHTMLInterfaceHandler

Handler for OPeNDAP catalog . xml requests .


protected void printCatalog(ReqState rs, PrintWriter os)
            throws IOException
    {
        os.println("Catalog not available for this server");
        os.println("Server version = " + getServerVersion());
    }

protected
void
printCatalog
(
ReqState
rs
,
PrintWriter
os
)
throws
IOException
{
os
.
println
(
"Catalog not available for this server"
)
;
os
.
println
(
"Server version = "
+
getServerVersion
(
)
)
;
}

to be overridden by servers that implement catalogs


protected void printStatus(PrintWriter os)
    {
        os.println("
Server version = " + getServerVersion() + "
");
        os.println("
Number of Requests Received = " + HitCounter + "
");
        if(track) {
            int n = prArr.size();
            int pending = 0;
            StringBuilder preqs = new StringBuilder();
            for(int i = 0; i < n; i++) {
                ReqState rs = (ReqState) prArr.get(i);
                RequestDebug reqD = (RequestDebug) rs.getUserObject();
                if(!reqD.done) {
                    preqs.append("
-----------------------\n");
                    preqs.append("Request[");
                    preqs.append(reqD.reqno);
                    preqs.append("](");
                    preqs.append(reqD.threadDesc);
                    preqs.append(") is pending.\n");
                    preqs.append(rs.toString());
                    preqs.append("
");
                    pending++;
                }
            }
            os.println("
" + pending + " Pending Request(s)
");
            os.println(preqs.toString());
        }
    }

protected
void
printStatus
(
PrintWriter
os
)
{
os
.
println
(
"
Server version = "
+
getServerVersion
(
)
+
"
"
)
;
os
.
println
(
"
Number of Requests Received = "
+
HitCounter
+
"
"
)
;
if
(
track
)
{
int
n
=
prArr
.
size
(
)
;
int
pending
=
0
;
StringBuilder
preqs
=
new
StringBuilder
(
)
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
ReqState
rs
=
(
ReqState
)
prArr
.
get
(
i
)
;
RequestDebug
reqD
=
(
RequestDebug
)
rs
.
getUserObject
(
)
;
if
(
!
reqD
.
done
)
{
preqs
.
append
(
"
-----------------------\n"
)
;
preqs
.
append
(
"Request["
)
;
preqs
.
append
(
reqD
.
reqno
)
;
preqs
.
append
(
"]("
)
;
preqs
.
append
(
reqD
.
threadDesc
)
;
preqs
.
append
(
") is pending.\n"
)
;
preqs
.
append
(
rs
.
toString
(
)
)
;
preqs
.
append
(
"
"
)
;
pending
++
;
}
}
os
.
println
(
"
"
+
pending
+
" Pending Request(s)
"
)
;
os
.
println
(
preqs
.
toString
(
)
)
;
}
}

to be overridden by servers that implement status report


private void printBadURLPage(PrintWriter pw)
    {
        pw.println("
Error in URL
");
        pw.println("The URL extension did not match any that are known by this");
        pw.println("server. Below is a list of the five extensions that are be recognized by");
        pw.println("all OPeNDAP servers. If you think that the server is broken (that the URL you");
        pw.println("submitted should have worked), then please contact the");
        pw.println("OPeNDAP user support coordinator at: ");
        pw.println("support@unidata.ucar.edu
");

    }

Prints the Bad URL Page page to the passed PrintWriter

@param pw PrintWriter stream to which to dump the bad URL page.


public CalendarDate getReferenceDate() {
    return CalendarDate.of(null, year, month, day, hour, minute, second);
  }

public CalendarDate getReferenceDate ( ) { return CalendarDate . of ( null , year , month , day , hour , minute , second ) ; }

reference reference or base time as Dare.

@return baseTime

reference reference or base time as Dare .


private Array readVlenData(Variable v, Section section, DataStorage dataStorage) throws IOException, InvalidRangeException {
    raf.seek(dataStorage.filePos);
    int nelems = readVInt(raf);
    Array[] result = new Array[nelems];

    for (int elem = 0; elem < nelems; elem++) {
      int dsize = readVInt(raf);
      byte[] data = new byte[dsize];
      raf.readFully(data);
      Array dataArray = Array.factory(v.getDataType(), (int[]) null, ByteBuffer.wrap(data));
      result[elem] = dataArray;
    }
    // return Array.makeObjectArray(v.getDataType(), result[0].getClass(), new int[]{nelems}, result);
    return Array.makeVlenArray(new int[]{nelems}, result);
    //return dataArray.section(section.getRanges());
  }


static public NcmlCollectionReader readNcML(String ncmlString, Formatter errlog) throws IOException {
      StringReader reader = new StringReader(ncmlString);

      org.jdom2.Document doc;
      try {
        SAXBuilder builder = new SAXBuilder();
        if (debugURL) System.out.println(" NetcdfDataset NcML String = <" + ncmlString + ">");
        doc = builder.build(new StringReader(ncmlString));
      } catch (JDOMException e) {
        throw new IOException(e.getMessage());
      }
      if (debugXML) System.out.println(" SAXBuilder done");

      return readXML(doc, errlog, null);
  }

static
public
NcmlCollectionReader
readNcML
(
String
ncmlString
,
Formatter
errlog
)
throws
IOException
{
StringReader
reader
=
new
StringReader
(
ncmlString
)
;
org
.
jdom2
.
Document
doc
;
try
{
SAXBuilder
builder
=
new
SAXBuilder
(
)
;
if
(
debugURL
)
System
.
out
.
println
(
" NetcdfDataset NcML String = <"
+
ncmlString
+
">"
)
;
doc
=
builder
.
build
(
new
StringReader
(
ncmlString
)
)
;
}
catch
(
JDOMException
e
)
{
throw
new
IOException
(
e
.
getMessage
(
)
)
;
}
if
(
debugXML
)
System
.
out
.
println
(
" SAXBuilder done"
)
;
return
readXML
(
doc
,
errlog
,
)
;
}

Read an NcML file from a String, and construct a NcmlCollectionReader from its scan or scanFmrc element.

@param ncmlString the NcML to construct the reader from
@param errlog put error messages here
@return the resulting NetcdfDataset
@throws IOException on read error, or bad referencedDatasetUri URI

Read an NcML file from a String and construct a NcmlCollectionReader from its scan or scanFmrc element .


static public NcmlCollectionReader open(String ncmlLocation, Formatter errlog) throws IOException {
    if (!ncmlLocation.startsWith("http:") && !ncmlLocation.startsWith("file:"))
      ncmlLocation = "file:" + ncmlLocation;

    URL url = new URL(ncmlLocation);

    org.jdom2.Document doc;
    try {
      SAXBuilder builder = new SAXBuilder();
      if (debugURL) System.out.println(" NetcdfDataset URL = <" + url + ">");
      doc = builder.build(url);
    } catch (JDOMException e) {
      throw new IOException(e.getMessage());
    }
    if (debugXML) System.out.println(" SAXBuilder done");

    return readXML(doc, errlog, ncmlLocation);
  }

static
public
NcmlCollectionReader
open
(
String
ncmlLocation
,
Formatter
errlog
)
throws
IOException
{
if
(
!
ncmlLocation
.
startsWith
(
"http:"
)
&&
!
ncmlLocation
.
startsWith
(
"file:"
)
)
ncmlLocation
=
"file:"
+
ncmlLocation
;
URL
url
=
new
URL
(
ncmlLocation
)
;
org
.
jdom2
.
Document
doc
;
try
{
SAXBuilder
builder
=
new
SAXBuilder
(
)
;
if
(
debugURL
)
System
.
out
.
println
(
" NetcdfDataset URL = <"
+
url
+
">"
)
;
doc
=
builder
.
build
(
url
)
;
}
catch
(
JDOMException
e
)
{
throw
new
IOException
(
e
.
getMessage
(
)
)
;
}
if
(
debugXML
)
System
.
out
.
println
(
" SAXBuilder done"
)
;
return
readXML
(
doc
,
errlog
,
ncmlLocation
)
;
}

Read an NcML file from a URL location, and construct a NcmlCollectionReader from its scan or scanFmrc element.

@param ncmlLocation the URL location string of the NcML document
@param errlog put error messages here
@return the resulting NetcdfDataset
@throws IOException on read error, or bad referencedDatasetUri URI

Read an NcML file from a URL location and construct a NcmlCollectionReader from its scan or scanFmrc element .


static public String allow(String x, String allowChars, char replaceChar) {
    boolean ok = true;
    for (int pos = 0; pos < x.length(); pos++) {
      char c = x.charAt(pos);
      if (!(Character.isLetterOrDigit(c) || (0 <= allowChars.indexOf(c)))) {
        ok = false;
        break;
      }
    }
    if (ok)
      return x;

    // gotta do it
    StringBuilder sb = new StringBuilder(x);
    for (int pos = 0; pos < sb.length(); pos++) {
      char c = sb.charAt(pos);
      if (Character.isLetterOrDigit(c) || (0 <= allowChars.indexOf(c))) {
        continue;
      }

      sb.setCharAt(pos, replaceChar);
    }

    return sb.toString();
  }

static
public
String
allow
(
String
x
,
String
allowChars
,
char
replaceChar
)
{
boolean
ok
=
true
;
for
(
int
pos
=
0
;
pos
<
x
.
length
(
)
;
pos
++
)
{
char
c
=
x
.
charAt
(
pos
)
;
if
(
!
(
Character
.
isLetterOrDigit
(
c
)
||
(
0
<=
allowChars
.
indexOf
(
c
)
)
)
)
{
ok
=
false
;
break
;
}
}
if
(
ok
)
return
x
;
// gotta do it
StringBuilder
sb
=
new
StringBuilder
(
x
)
;
for
(
int
pos
=
0
;
pos
<
sb
.
length
(
)
;
pos
++
)
{
char
c
=
sb
.
charAt
(
pos
)
;
if
(
Character
.
isLetterOrDigit
(
c
)
||
(
0
<=
allowChars
.
indexOf
(
c
)
)
)
{
continue
;
}
sb
.
setCharAt
(
pos
,
replaceChar
)
;
}
return
sb
.
toString
(
)
;
}

Replace any char not alphanumeric or in allowChars by replaceChar.

@param x           operate on this string
@param allowChars  these are ok.
@param replaceChar thar char to replace
@return resulting string.

Replace any char not alphanumeric or in allowChars by replaceChar .


public static String cleanup(byte[] h) {
    byte[] bb = new byte[h.length];
    int count = 0;
    for (byte b : h) {
      if (b >= 32 && b < 127)
        bb[count++] = b;
    }
    return new String(bb, 0, count, CDM.utf8Charset);
  }

public static String cleanup ( byte [ ] h ) { byte [ ] bb = new byte [ h . length ] ; int count = 0 ; for ( byte b : h ) { if ( b >= 32 && b < 127 ) bb [ count ++ ] = b ; } return new String ( bb , 0 , count , CDM . utf8Charset ) ; }

Delete any non-printable characters

@param h byte array
@return cleaned up string


static public String filter(String x, String okChars) {
    boolean ok = true;
    for (int pos = 0; pos < x.length(); pos++) {
      char c = x.charAt(pos);
      if (!(Character.isLetterOrDigit(c) || (0 <= okChars.indexOf(c)))) {
        ok = false;
        break;
      }
    }
    if (ok) {
      return x;
    }

    // gotta do it
    StringBuilder sb = new StringBuilder(x.length());
    for (int pos = 0; pos < x.length(); pos++) {
      char c = x.charAt(pos);
      if (Character.isLetterOrDigit(c) || (0 <= okChars.indexOf(c))) {
        sb.append(c);
      }
    }

    return sb.toString();
  }

static
public
String
filter
(
String
x
,
String
okChars
)
{
boolean
ok
=
true
;
for
(
int
pos
=
0
;
pos
<
x
.
length
(
)
;
pos
++
)
{
char
c
=
x
.
charAt
(
pos
)
;
if
(
!
(
Character
.
isLetterOrDigit
(
c
)
||
(
0
<=
okChars
.
indexOf
(
c
)
)
)
)
{
ok
=
false
;
break
;
}
}
if
(
ok
)
{
return
x
;
}
// gotta do it
StringBuilder
sb
=
new
StringBuilder
(
x
.
length
(
)
)
;
for
(
int
pos
=
0
;
pos
<
x
.
length
(
)
;
pos
++
)
{
char
c
=
x
.
charAt
(
pos
)
;
if
(
Character
.
isLetterOrDigit
(
c
)
||
(
0
<=
okChars
.
indexOf
(
c
)
)
)
{
sb
.
append
(
c
)
;
}
}
return
sb
.
toString
(
)
;
}

Remove any char not alphanumeric or in okChars.

@param x       filter this string
@param okChars these are ok.
@return filtered string.

Remove any char not alphanumeric or in okChars .


static public String filter7bits(String s) {
    if (s == null) return null;
    char[] bo = new char[s.length()];
    int count = 0;
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if ((c < 128) && (c > 31) || ((c == '\n') || (c == '\t'))) {
        bo[count++] = c;
      }
    }

    return new String(bo, 0, count);
  }

static public String filter7bits ( String s ) { if ( s == null ) return null ; char [ ] bo = new char [ s . length ( ) ] ; int count = 0 ; for ( int i = 0 ; i < s . length ( ) ; i ++ ) { char c = s . charAt ( i ) ; if ( ( c < 128 ) && ( c > 31 ) || ( ( c == ' ' ) || ( c == ' ' ) ) ) { bo [ count ++ ] = c ; } } return new String ( bo , 0 , count ) ; }

Remove all but printable ascii

@param s filter this string
@return filtered string.


static public String makeValidCdmObjectName(String name) {
    name = name.trim();
    // common case no change
    boolean ok = true;
    for (int i = 0; i < name.length(); i++) {
      int c = name.charAt(i);
      if (c < 0x20) ok = false;
      if (c == '/') ok = false;
      if (c == ' ') ok = false;
      if (!ok) break;
    }
    if (ok) return name;

    StringBuilder sbuff = new StringBuilder(name.length());
    for (int i = 0, len = name.length(); i < len; i++) {
      int c = name.charAt(i);
      if ((c == '/') || (c == ' '))
        sbuff.append('_');
      else if (c >= 0x20)
        sbuff.append((char) c);
    }
    return sbuff.toString();
  }

static
public
String
makeValidCdmObjectName
(
String
name
)
{
name
=
name
.
trim
(
)
;
// common case no change
boolean
ok
=
true
;
for
(
int
i
=
0
;
i
<
name
.
length
(
)
;
i
++
)
{
int
c
=
name
.
charAt
(
i
)
;
if
(
c
<
0x20
)
ok
=
false
;
if
(
c
==
'
'
)
ok
=
false
;
if
(
c
==
'
'
)
ok
=
false
;
if
(
!
ok
)
break
;
}
if
(
ok
)
return
name
;
StringBuilder
sbuff
=
new
StringBuilder
(
name
.
length
(
)
)
;
for
(
int
i
=
0
,
len
=
name
.
length
(
)
;
i
<
len
;
i
++
)
{
int
c
=
name
.
charAt
(
i
)
;
if
(
(
c
==
'
'
)
||
(
c
==
'
'
)
)
sbuff
.
append
(
'
'
)
;
else
if
(
c
>=
0x20
)
sbuff
.
append
(
(
char
)
c
)
;
}
return
sbuff
.
toString
(
)
;
}


static public int match(String s1, String s2) {
    int i = 0;
    while ((i < s1.length()) && (i < s2.length())) {
      if (s1.charAt(i) != s2.charAt(i)) {
        break;
      }
      i++;
    }
    return i;
  }

static public int match ( String s1 , String s2 ) { int i = 0 ; while ( ( i < s1 . length ( ) ) && ( i < s2 . length ( ) ) ) { if ( s1 . charAt ( i ) != s2 . charAt ( i ) ) { break ; } i ++ ; } return i ; }

Count number of chars that match in two strings, starting from front.

@param s1 compare this string
@param s2 compare this string
@return number of matching chars, starting from first char

Count number of chars that match in two strings starting from front .


public static String padLeft(String s, int desiredLength,
                               String padString) {
    while (s.length() < desiredLength) {
      s = padString + s;
    }
    return s;
  }

public static String padLeft ( String s , int desiredLength , String padString ) { while ( s . length ( ) < desiredLength ) { s = padString + s ; } return s ; }

Pad the given string with padString on the left up to the given length.

@param s             String to pad
@param desiredLength ending length
@param padString     String to pad with (e.g, " ")
@return padded String

Pad the given string with padString on the left up to the given length .


public static String padRight(String s, int desiredLength,
                                String padString) {
    StringBuilder ret = new StringBuilder(s);
    while (ret.length() < desiredLength) {
      ret.append(padString);
    }
    return ret.toString();
  }

public static String padRight ( String s , int desiredLength , String padString ) { StringBuilder ret = new StringBuilder ( s ) ; while ( ret . length ( ) < desiredLength ) { ret . append ( padString ) ; } return ret . toString ( ) ; }

Pad the given string with padString on the right up to the given length.

@param s             String to pad
@param desiredLength ending length
@param padString     String to pad with (e.g, " ")
@return padded String

Pad the given string with padString on the right up to the given length .


static public String remove(String s, String sub) {
    int len = sub.length();
    int pos;
    while (0 <= (pos = s.indexOf(sub))) {
      s = s.substring(0, pos) + s.substring(pos + len);
    }
    return s;
  }

static public String remove ( String s , String sub ) { int len = sub . length ( ) ; int pos ; while ( 0 <= ( pos = s . indexOf ( sub ) ) ) { s = s . substring ( 0 , pos ) + s . substring ( pos + len ) ; } return s ; }

Remove all occurrences of the substring sub in the string s.

@param s   operate on this string
@param sub remove all occurrences of this substring.
@return result with substrings removed

Remove all occurrences of the substring sub in the string s .


static public String remove(String s, int c) {
    if (0 > s.indexOf(c)) {  // none
      return s;
    }

    StringBuilder buff = new StringBuilder(s);
    int i = 0;
    while (i < buff.length()) {
      if (buff.charAt(i) == c) {
        buff.deleteCharAt(i);
      } else {
        i++;
      }
    }
    return buff.toString();
  }

static
public
String
remove
(
String
s
,
int
c
)
{
if
(
0
>
s
.
indexOf
(
c
)
)
{
// none
return
s
;
}
StringBuilder
buff
=
new
StringBuilder
(
s
)
;
int
i
=
0
;
while
(
i
<
buff
.
length
(
)
)
{
if
(
buff
.
charAt
(
i
)
==
c
)
{
buff
.
deleteCharAt
(
i
)
;
}
else
{
i
++
;
}
}
return
buff
.
toString
(
)
;
}

Remove all occurrences of the character c in the string s.

@param s operate on this string
@param c remove all occurrences of this character.
@return result with any character c removed

Remove all occurrences of the character c in the string s .


static public String removeFromEnd(String s, int c) {
    if (0 > s.indexOf(c))   // none
      return s;

    int len = s.length();
    while ((s.charAt(len - 1) == c) && (len > 0))
      len--;

    if (len == s.length())
      return s;
    return s.substring(0, len);
  }

static
public
String
removeFromEnd
(
String
s
,
int
c
)
{
if
(
0
>
s
.
indexOf
(
c
)
)
// none
return
s
;
int
len
=
s
.
length
(
)
;
while
(
(
s
.
charAt
(
len
1
)
==
c
)
&&
(
len
>
0
)
)
len
;
if
(
len
==
s
.
length
(
)
)
return
s
;
return
s
.
substring
(
0
,
len
)
;
}

Remove all occurrences of the character c at the end of s.

@param s operate on this string
@param c remove all occurrences of this character that are at the end of the string.
@return result with any character c removed

Remove all occurrences of the character c at the end of s .


static public String collapseWhitespace(String s) {
    int len = s.length();
    StringBuilder b = new StringBuilder(len);
    for (int i = 0; i < len; i++) {
      char c = s.charAt(i);
      if (!Character.isWhitespace(c)) {
        b.append(c);
      } else {
        b.append(' ');
        while ((i + 1 < len) && Character.isWhitespace(s.charAt(i + 1))) {
          i++;  /// skip further whitespace
        }
      }
    }
    return b.toString();
  }

static
public
String
collapseWhitespace
(
String
s
)
{
int
len
=
s
.
length
(
)
;
StringBuilder
b
=
new
StringBuilder
(
len
)
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
char
c
=
s
.
charAt
(
i
)
;
if
(
!
Character
.
isWhitespace
(
c
)
)
{
b
.
append
(
c
)
;
}
else
{
b
.
append
(
'
'
)
;
while
(
(
i
+
1
<
len
)
&&
Character
.
isWhitespace
(
s
.
charAt
(
i
+
1
)
)
)
{
i
++
;
/// skip further whitespace
}
}
}
return
b
.
toString
(
)
;
}

Collapse continuous whitespace into one single " ".

@param s operate on this string
@return result with collapsed whitespace

Collapse continuous whitespace into one single .


static public String replace(String s, char out, String in) {
    if (s.indexOf(out) < 0) {
      return s;
    }

    // gotta do it
    StringBuilder sb = new StringBuilder(s);
    replace(sb, out, in);
    return sb.toString();
  }

static
public
String
replace
(
String
s
,
char
out
,
String
in
)
{
if
(
s
.
indexOf
(
out
)
<
0
)
{
return
s
;
}
// gotta do it
StringBuilder
sb
=
new
StringBuilder
(
s
)
;
replace
(
sb
,
out
,
in
)
;
return
sb
.
toString
(
)
;
}

Replace any char "out" in s with "in".

@param s   string to replace
@param out replace this character
@param in  with this string
@return modified string if needed


static public String replace(String x, char[] replaceChar, String[] replaceWith) {
    // common case no replacement
    boolean ok = true;
    for (char aReplaceChar : replaceChar) {
      int pos = x.indexOf(aReplaceChar);
      ok = (pos < 0);
      if (!ok)
        break;
    }
    if (ok)
      return x;

    // gotta do it
    StringBuilder sb = new StringBuilder(x);
    for (int i = 0; i < replaceChar.length; i++) {
      int pos = x.indexOf(replaceChar[i]);
      if (pos >= 0) {
        replace(sb, replaceChar[i], replaceWith[i]);
      }
    }

    return sb.toString();
  }

static
public
String
replace
(
String
x
,
char
[
]
replaceChar
,
String
[
]
replaceWith
)
{
// common case no replacement
boolean
ok
=
true
;
for
(
char
aReplaceChar
:
replaceChar
)
{
int
pos
=
x
.
indexOf
(
aReplaceChar
)
;
ok
=
(
pos
<
0
)
;
if
(
!
ok
)
break
;
}
if
(
ok
)
return
x
;
// gotta do it
StringBuilder
sb
=
new
StringBuilder
(
x
)
;
for
(
int
i
=
0
;
i
<
replaceChar
.
length
;
i
++
)
{
int
pos
=
x
.
indexOf
(
replaceChar
[
i
]
)
;
if
(
pos
>=
0
)
{
replace
(
sb
,
replaceChar
[
i
]
,
replaceWith
[
i
]
)
;
}
}
return
sb
.
toString
(
)
;
}

Replace all occurrences of any char in replaceChar with corresponding String in replaceWith

@param x           operate on this string
@param replaceChar get rid of these
@param replaceWith replace with these
@return resulting string


public static String replace(String string, String pattern, String value) {
    if (pattern.length() == 0)
      return string;

    if (!string.contains(pattern)) return string;

    // ok gotta do it
    StringBuilder returnValue = new StringBuilder();
    int patternLength = pattern.length();
    while (true) {
      int idx = string.indexOf(pattern);
      if (idx < 0)
        break;

      returnValue.append(string.substring(0, idx));
      if (value != null)
        returnValue.append(value);

      string = string.substring(idx + patternLength);
    }
    returnValue.append(string);
    return returnValue.toString();
  }

public
static
String
replace
(
String
string
,
String
pattern
,
String
value
)
{
if
(
pattern
.
length
(
)
==
0
)
return
string
;
if
(
!
string
.
contains
(
pattern
)
)
return
string
;
// ok gotta do it
StringBuilder
returnValue
=
new
StringBuilder
(
)
;
int
patternLength
=
pattern
.
length
(
)
;
while
(
true
)
{
int
idx
=
string
.
indexOf
(
pattern
)
;
if
(
idx
<
0
)
break
;
returnValue
.
append
(
string
.
substring
(
0
,
idx
)
)
;
if
(
value
!=
)
returnValue
.
append
(
value
)
;
string
=
string
.
substring
(
idx
+
patternLength
)
;
}
returnValue
.
append
(
string
)
;
return
returnValue
.
toString
(
)
;
}

Replaces all occurrences of "pattern" in "string" with "value"

@param string  string to munge
@param pattern pattern to replace
@param value   replacement value
@return munged string

Replaces all occurrences of pattern in string with value


static public String substitute(String original, String match, String subst) {
    String s = original;
    int pos;
    while (0 <= (pos = s.indexOf(match))) {
      StringBuilder sb = new StringBuilder(s);
      s = sb.replace(pos, pos + match.length(), subst).toString();
    }
    return s;
  }

static public String substitute ( String original , String match , String subst ) { String s = original ; int pos ; while ( 0 <= ( pos = s . indexOf ( match ) ) ) { StringBuilder sb = new StringBuilder ( s ) ; s = sb . replace ( pos , pos + match . length ( ) , subst ) . toString ( ) ; } return s ; }

Find all occurrences of the "match" in original, and substitute the "subst" string.

@param original starting string
@param match    string to match
@param subst    string to substitute
@return a new string with substitutions

Find all occurrences of the match in original and substitute the subst string .


static public String substitute(String original, String[] match, String[] subst) {

    boolean ok = true;
    for (String aMatch : match) {
      if (original.contains(aMatch)) {
        ok = false;
        break;
      }
    }
    if (ok) {
      return original;
    }

    // gotta do it;
    StringBuilder sb = new StringBuilder(original);
    for (int i = 0; i < match.length; i++) {
      substitute(sb, match[i], subst[i]);
    }
    return sb.toString();
  }

static
public
String
substitute
(
String
original
,
String
[
]
match
,
String
[
]
subst
)
{
boolean
ok
=
true
;
for
(
String
aMatch
:
match
)
{
if
(
original
.
contains
(
aMatch
)
)
{
ok
=
false
;
break
;
}
}
if
(
ok
)
{
return
original
;
}
// gotta do it;
StringBuilder
sb
=
new
StringBuilder
(
original
)
;
for
(
int
i
=
0
;
i
<
match
.
length
;
i
++
)
{
substitute
(
sb
,
match
[
i
]
,
subst
[
i
]
)
;
}
return
sb
.
toString
(
)
;
}

Find all occurences of match strings in original, and substitute the corresponding
subst string.

@param original starting string
@param match    array of strings to match
@param subst    array of strings to substitute
@return a new string with substitutions

Find all occurences of match strings in original and substitute the corresponding subst string .


static public void remove(StringBuilder sb, String out) {
    int i = 0;
    while (i < sb.length()) {
      int c = sb.charAt(i);
      boolean ok = true;
      for (int j = 0; j < out.length(); j++) {
        if (out.charAt(j) == c) {
          sb.delete(i, i + 1);
          ok = false;
          break;
        }
      }
      if (ok) i++;
    }
  }

static public void remove ( StringBuilder sb , String out ) { int i = 0 ; while ( i < sb . length ( ) ) { int c = sb . charAt ( i ) ; boolean ok = true ; for ( int j = 0 ; j < out . length ( ) ; j ++ ) { if ( out . charAt ( j ) == c ) { sb . delete ( i , i + 1 ) ; ok = false ; break ; } } if ( ok ) i ++ ; } }

Remove any of the characters in out from sb

@param sb  the StringBuilder
@param out get rid of any of these characters


static public void unreplace(StringBuilder sb, String out, char in) {
    int pos;
    while (0 <= (pos = sb.indexOf(out))) {
      sb.setCharAt(pos, in);
      sb.delete(pos + 1, pos + out.length());
    }
  }

static public void unreplace ( StringBuilder sb , String out , char in ) { int pos ; while ( 0 <= ( pos = sb . indexOf ( out ) ) ) { sb . setCharAt ( pos , in ) ; sb . delete ( pos + 1 , pos + out . length ( ) ) ; } }

Replace any String "out" in sb with char "in".

@param sb  StringBuilder to replace
@param out repalce this String
@param in  with this char

Replace any String out in sb with char in .


static public void replace(StringBuilder sb, String out, String in) {
    for (int i = 0; i < sb.length(); i++) {
      int c = sb.charAt(i);
      for (int j = 0; j < out.length(); j++) {
        if (out.charAt(j) == c)
          sb.setCharAt(i, in.charAt(j));
      }
    }
  }

static public void replace ( StringBuilder sb , String out , String in ) { for ( int i = 0 ; i < sb . length ( ) ; i ++ ) { int c = sb . charAt ( i ) ; for ( int j = 0 ; j < out . length ( ) ; j ++ ) { if ( out . charAt ( j ) == c ) sb . setCharAt ( i , in . charAt ( j ) ) ; } } }

Replace any of the characters from out with corresponding character from in

@param sb  the StringBuilder
@param out get rid of any of these characters
@param in  replacing with the character at same index


static public void substitute(StringBuilder sbuff, String match, String subst) {
    int pos, fromIndex = 0;
    int substLen = subst.length();
    int matchLen = match.length();
    while (0 <= (pos = sbuff.indexOf(match, fromIndex))) {
      sbuff.replace(pos, pos + matchLen, subst);
      fromIndex = pos + substLen;  // make sure dont get into an infinite loop
    }
  }

Find all occurences of the "match" in original, and substitute the "subst" string,
directly into the original.

@param sbuff starting string buffer
@param match string to match
@param subst string to substitute

Find all occurences of the match in original and substitute the subst string directly into the original .


static public String trim(String s, int bad) {
    int len = s.length();
    int st = 0;

    while ((st < len) && (s.charAt(st) == bad)) {
      st++;
    }
    while ((st < len) && (s.charAt(len - 1) == bad)) {
      len--;
    }
    return ((st > 0) || (len < s.length())) ? s.substring(st, len) : s;
  }

static public String trim ( String s , int bad ) { int len = s . length ( ) ; int st = 0 ; while ( ( st < len ) && ( s . charAt ( st ) == bad ) ) { st ++ ; } while ( ( st < len ) && ( s . charAt ( len - 1 ) == bad ) ) { len -- ; } return ( ( st > 0 ) || ( len < s . length ( ) ) ) ? s . substring ( st , len ) : s ; }

Remove bad char from beginning or end of string

@param s operate on this
@return trimmed string


@Subscribe
  public void processEvent(CollectionUpdateEvent event) {
    if (!config.collectionName.equals(event.getCollectionName())) return; // not for me

    try {
      update(event.getType());
    } catch (IOException e) {
      logger.error("Error processing event", e);
    }
  }

@
Subscribe
public
void
processEvent
(
CollectionUpdateEvent
event
)
{
if
(
!
config
.
collectionName
.
equals
(
event
.
getCollectionName
(
)
)
)
return
;
// not for me
try
{
update
(
event
.
getType
(
)
)
;
}
catch
(
IOException
e
)
{
logger
.
error
(
"Error processing event"
,
e
)
;
}
}

called by eventBus, this is where the trigger comes in

called by eventBus this is where the trigger comes in


protected State checkState() throws IOException {
    State localState;

    synchronized (lock) {
      if (first) {
        firstInit();
        updateCollection(state, config.updateConfig.updateType);
        // makeDatasetTop(state);
        first = false;
      }
      localState = state.copy();
    }

    return localState;
  }

protected
State
checkState
(
)
throws
IOException
{
State
localState
;
synchronized
(
lock
)
{
if
(
first
)
{
firstInit
(
)
;
updateCollection
(
state
,
config
.
updateConfig
.
updateType
)
;
// makeDatasetTop(state);
first
=
false
;
}
localState
=
state
.
copy
(
)
;
}
return
localState
;
}

A request has come in, check that the state has been initialized.
this is called from the request thread.

@return a copy of the State

A request has come in check that the state has been initialized . this is called from the request thread .


protected void update(CollectionUpdateType force) throws IOException {  // this may be called from a background thread, or from checkState() request thread
    State localState;

    synchronized (lock) {
      if (first) {
        state = checkState();
        state.lastInvChange = System.currentTimeMillis();
        return;
      }
      // do the update in a local object
      localState = state.copy();
    }

    updateCollection(localState, force);
    // makeDatasetTop(localState);
    localState.lastInvChange = System.currentTimeMillis();

    // switch to live
    synchronized (lock) {
      state = localState;
    }

  }

Collection was changed, update internal objects.
called by CollectionUpdater, trigger via handleCollectionEvent, so in a quartz scheduler thread

@param force update type

Collection was changed update internal objects . called by CollectionUpdater trigger via handleCollectionEvent so in a quartz scheduler thread


private void doUniqueTemplates(Formatter f, MCollection dcm, boolean useIndex) throws IOException {
    f.format("Show Unique GDS and PDS templates%n");

    Map<Integer, FileList> gdsSet = new HashMap<>();
    Map<Integer, FileList> pdsSet = new HashMap<>();
    Map<Integer, FileList> drsSet = new HashMap<>();
    for (MFile mfile : dcm.getFilesSorted()) {
      f.format(" %s%n", mfile.getPath());
      doUniqueTemplates(mfile, gdsSet, pdsSet, drsSet, f);
    }

    List<FileList> sorted = new ArrayList<>(gdsSet.values());
    Collections.sort(sorted);
    for (FileList gdsl : sorted) {
      f.format("%nGDS %s template= %d %n", gdsl.name, gdsl.template);
      for (FileCount fc : gdsl.fileList) {
        f.format("  %5d %s %n", fc.countRecords, fc.f.getPath());
      }
    }

    List<FileList> sortedPds = new ArrayList<>(pdsSet.values());
    Collections.sort(sortedPds);
    for (FileList pdsl : sortedPds) {
      f.format("%n===================================================%n");
      f.format("%nPDS %s template= %d %n", pdsl.name, pdsl.template);
      for (FileCount fc : pdsl.fileList) {
        f.format("  %5d %s %n", fc.countRecords, fc.f.getPath());
      }
    }

    List<FileList> sortedDrs = new ArrayList<>(drsSet.values());
    Collections.sort(sortedDrs);
    for (FileList pdsl : sortedDrs) {
      f.format("%n===================================================%n");
      f.format("%nDRS %s template= %d %n", pdsl.name, pdsl.template);
      for (FileCount fc : pdsl.fileList) {
        f.format("  %5d %s %n", fc.countRecords, fc.f.getPath());
      }
    }
  }

Look through the collection and find what GDS and PDS templates are used.

Look through the collection and find what GDS and PDS templates are used .


@Override
  public java.util.List<InvDataset> getDatasets() {
    read();
    return useProxy ? proxy.getDatasets() : super.getDatasets();
  }

@ Override public java . util . List < InvDataset > getDatasets ( ) { read ( ) ; return useProxy ? proxy . getDatasets ( ) : super . getDatasets ( ) ; }

Get a list of all the nested datasets.
@return Datasets. This triggers a read of the referenced catalog the first time its called.


public void release() {
    datasets = new java.util.ArrayList<>();
    proxy = null;
    useProxy = false;
    init = false;
  }

public void release ( ) { datasets = new java . util . ArrayList <> ( ) ; proxy = null ; useProxy = false ; init = false ; }

Release resources - undo the read of the catalog. This is needed when crawling large catalogs.
For modest catalogs that you will repeatedly examine, do not use this method.

Release resources - undo the read of the catalog . This is needed when crawling large catalogs . For modest catalogs that you will repeatedly examine do not use this method .


static public StructureDataDeep copy(StructureData sdata, StructureMembers members) {
    ArrayStructureBB abb = copyToArrayBB(sdata, members, ByteOrder.BIG_ENDIAN);
    return new StructureDataDeep(abb);
  }

static public StructureDataDeep copy ( StructureData sdata , StructureMembers members ) { ArrayStructureBB abb = copyToArrayBB ( sdata , members , ByteOrder . BIG_ENDIAN ) ; return new StructureDataDeep ( abb ) ; }

Make deep copy from sdata to another StructureData object whose data is self contained
@param sdata    original sdata
@param members  the StructureData members. a reference is kept to this object
@return StructureData with all data self contained


static public ArrayStructureBB copyToArrayBB(ArrayStructure as, ByteOrder bo, boolean canonical) throws IOException {
    if (!canonical && as.getClass().equals(ArrayStructureBB.class)) { // no subclasses, LOOK detect already canonical later
      ArrayStructureBB abb = (ArrayStructureBB) as;
      ByteBuffer bb = abb.getByteBuffer();
      if (bo == null || bo.equals(bb.order()))
        return abb;
    }

    StructureMembers smo = as.getStructureMembers();
    StructureMembers sm = new StructureMembers(smo);
    ArrayStructureBB abb = new ArrayStructureBB(sm, as.getShape());
    ArrayStructureBB.setOffsets(sm);  // this makes the packing canonical
    if (bo != null) {
      ByteBuffer bb = abb.getByteBuffer();
      bb.order(bo);
    }

    try (StructureDataIterator iter = as.getStructureDataIterator()) {
      while (iter.hasNext())
        copyToArrayBB(iter.next(), abb);
    }
    return abb;
  }

Make deep copy from an ArrayStructure to a ArrayStructureBB whose data is contained in a ByteBuffer
@param as    original ArrayStructure
@param bo    what byte order to use ? (null for any)
@param canonical  packing must be canonical
@return ArrayStructureBB with all data self contained


static public ArrayStructureBB copyToArrayBB(Structure s, ArrayStructure as, ByteOrder bo) throws IOException {
    StructureMembers sm = s.makeStructureMembers();
    ArrayStructureBB abb = new ArrayStructureBB(sm, as.getShape());
    ArrayStructureBB.setOffsets(sm);
    if (bo != null) {
      ByteBuffer bb = abb.getByteBuffer();
      bb.order(bo);
    }

    try (StructureDataIterator iter = as.getStructureDataIterator()) {
      while (iter.hasNext())
        copyToArrayBB(iter.next(), abb);
    }
    return abb;
  }

static public ArrayStructureBB copyToArrayBB ( Structure s , ArrayStructure as , ByteOrder bo ) throws IOException { StructureMembers sm = s . makeStructureMembers ( ) ; ArrayStructureBB abb = new ArrayStructureBB ( sm , as . getShape ( ) ) ; ArrayStructureBB . setOffsets ( sm ) ; if ( bo != null ) { ByteBuffer bb = abb . getByteBuffer ( ) ; bb . order ( bo ) ; } try ( StructureDataIterator iter = as . getStructureDataIterator ( ) ) { while ( iter . hasNext ( ) ) copyToArrayBB ( iter . next ( ) , abb ) ; } return abb ; }

Make deep copy to an ArrayStructureBB whose data is contained in a ByteBuffer.
Use the order of the members in the given Structure; skip copying any not in the Structure
@param s     list of structure members come from here; must be compatible with ArrayStructure's data
@param as    original ArrayStructure
@param bo    what byte order to use ? (null for default)
@return ArrayStructureBB with all data self contained

Make deep copy to an ArrayStructureBB whose data is contained in a ByteBuffer . Use the order of the members in the given Structure ; skip copying any not in the Structure


static public ArrayStructureBB copyToArrayBB(StructureData sdata) {
    return copyToArrayBB(sdata, new StructureMembers(sdata.getStructureMembers()), ByteOrder.BIG_ENDIAN);
  }

static public ArrayStructureBB copyToArrayBB ( StructureData sdata ) { return copyToArrayBB ( sdata , new StructureMembers ( sdata . getStructureMembers ( ) ) , ByteOrder . BIG_ENDIAN ) ; }

Make deep copy from a StructureData to a ArrayStructureBB whose data is contained in a ByteBuffer.
@param sdata  original ArrayStructure.
@return ArrayStructureBB with all data self contained

Make deep copy from a StructureData to a ArrayStructureBB whose data is contained in a ByteBuffer .


static public ArrayStructureBB copyToArrayBB(StructureData sdata, StructureMembers sm, ByteOrder bo) {
    int size = sm.getStructureSize();
    ByteBuffer bb = ByteBuffer.allocate(size); // default is big endian
    bb.order(bo);
    ArrayStructureBB abb = new ArrayStructureBB(sm, new int[]{1}, bb, 0);
    ArrayStructureBB.setOffsets(sm);
    copyToArrayBB(sdata, abb);
    return abb;
  }

static
public
ArrayStructureBB
copyToArrayBB
(
StructureData
sdata
,
StructureMembers
sm
,
ByteOrder
bo
)
{
int
size
=
sm
.
getStructureSize
(
)
;
ByteBuffer
bb
=
ByteBuffer
.
allocate
(
size
)
;
// default is big endian
bb
.
order
(
bo
)
;
ArrayStructureBB
abb
=
new
ArrayStructureBB
(
sm
,
new
int
[
]
{
1
}
,
bb
,
0
)
;
ArrayStructureBB
.
setOffsets
(
sm
)
;
copyToArrayBB
(
sdata
,
abb
)
;
return
abb
;
}

Make deep copy from a StructureData to a ArrayStructureBB whose data is contained in a ByteBuffer
@param sdata    original ArrayStructure
@param sm       the StructureData members. a reference is kept to this object
@param bo       Byte Order of the ByteBuffer
@return ArrayStructureBB with all data self contained


@Override
  public double getForecastTimeIntervalSizeInHours(Grib2Pds pds) {
    Grib2Pds.PdsInterval pdsIntv = (Grib2Pds.PdsInterval) pds;

    // override here only if timeRangeUnit = 255
    boolean needOverride = false;
    for (Grib2Pds.TimeInterval ti : pdsIntv.getTimeIntervals()) {
      needOverride = (ti.timeRangeUnit == 255);
    }
    if (!needOverride)
      return super.getForecastTimeIntervalSizeInHours(pds);

    return 12.0;
  }

Only use in GribVariable to decide on variable identity when intvMerge = false.
By returning a constant, we dont intvMerge = false.
Problem is we cant reconstruct interval length without reference time, which is not in the pds.

Only use in GribVariable to decide on variable identity when intvMerge = false . By returning a constant we dont intvMerge = false . Problem is we cant reconstruct interval length without reference time which is not in the pds .


public CoordinateAxis1D section(Range r) throws InvalidRangeException {
    Section section = new Section().appendRange(r);
    CoordinateAxis1D result = (CoordinateAxis1D) section(section);
    int len = r.length();

    // deal with the midpoints, bounds
    if (isNumeric()) {
      double[] new_mids = new double[len];
      for (int idx = 0; idx < len; idx++) {
        int old_idx = r.element(idx);
        new_mids[idx] = coords[old_idx];
      }
      result.coords = new_mids;

      if (isInterval) {
        double[] new_bound1 = new double[len];
        double[] new_bound2 = new double[len];
        double[] new_edge = new double[len + 1];
        for (int idx = 0; idx < len; idx++) {
          int old_idx = r.element(idx);
          new_bound1[idx] = bound1[old_idx];
          new_bound2[idx] = bound2[old_idx];
          new_edge[idx] = bound1[old_idx];
          new_edge[idx + 1] = bound2[old_idx]; // all but last are overwritten
        }
        result.bound1 = new_bound1;
        result.bound2 = new_bound2;
        result.edge = new_edge;

      } else {
        double[] new_edge = new double[len + 1];
        for (int idx = 0; idx < len; idx++) {
          int old_idx = r.element(idx);
          new_edge[idx] = edge[old_idx];
          new_edge[idx + 1] = edge[old_idx + 1]; // all but last are overwritten
        }
        result.edge = new_edge;
      }
    }

    if (names != null) {
      String[] new_names = new String[len];
      for (int idx = 0; idx < len; idx++) {
        int old_idx = r.element(idx);
        new_names[idx] = names[old_idx];
      }
      result.names = new_names;
    }

    result.wasCalcRegular = false;
    result.calcIsRegular();

    return result;
  }

public
CoordinateAxis1D
section
(
Range
r
)
throws
InvalidRangeException
{
Section
section
=
new
Section
(
)
.
appendRange
(
r
)
;
CoordinateAxis1D
result
=
(
CoordinateAxis1D
)
section
(
section
)
;
int
len
=
r
.
length
(
)
;
// deal with the midpoints, bounds
if
(
isNumeric
(
)
)
{
double
[
]
new_mids
=
new
double
[
len
]
;
for
(
int
idx
=
0
;
idx
<
len
;
idx
++
)
{
int
old_idx
=
r
.
element
(
idx
)
;
new_mids
[
idx
]
=
coords
[
old_idx
]
;
}
result
.
coords
=
new_mids
;
if
(
isInterval
)
{
double
[
]
new_bound1
=
new
double
[
len
]
;
double
[
]
new_bound2
=
new
double
[
len
]
;
double
[
]
new_edge
=
new
double
[
len
+
1
]
;
for
(
int
idx
=
0
;
idx
<
len
;
idx
++
)
{
int
old_idx
=
r
.
element
(
idx
)
;
new_bound1
[
idx
]
=
bound1
[
old_idx
]
;
new_bound2
[
idx
]
=
bound2
[
old_idx
]
;
new_edge
[
idx
]
=
bound1
[
old_idx
]
;
new_edge
[
idx
+
1
]
=
bound2
[
old_idx
]
;
// all but last are overwritten
}
result
.
bound1
=
new_bound1
;
result
.
bound2
=
new_bound2
;
result
.
edge
=
new_edge
;
}
else
{
double
[
]
new_edge
=
new
double
[
len
+
1
]
;
for
(
int
idx
=
0
;
idx
<
len
;
idx
++
)
{
int
old_idx
=
r
.
element
(
idx
)
;
new_edge
[
idx
]
=
edge
[
old_idx
]
;
new_edge
[
idx
+
1
]
=
edge
[
old_idx
+
1
]
;
// all but last are overwritten
}
result
.
edge
=
new_edge
;
}
}
if
(
names
!=
)
{
String
[
]
new_names
=
new
String
[
len
]
;
for
(
int
idx
=
0
;
idx
<
len
;
idx
++
)
{
int
old_idx
=
r
.
element
(
idx
)
;
new_names
[
idx
]
=
names
[
old_idx
]
;
}
result
.
names
=
new_names
;
}
result
.
wasCalcRegular
=
false
;
result
.
calcIsRegular
(
)
;
return
result
;
}

Create a new CoordinateAxis1D as a section of this CoordinateAxis1D.

@param r the section range
@return a new CoordinateAxis1D as a section of this CoordinateAxis1D
@throws InvalidRangeException if IllegalRange

Create a new CoordinateAxis1D as a section of this CoordinateAxis1D .


static public TableAnalyzer factory(TableConfigurer tc, FeatureType wantFeatureType, NetcdfDataset ds) throws IOException {

    // Create a TableAnalyzer with this TableConfigurer (may be null)
    TableAnalyzer analyzer = new TableAnalyzer(ds, tc);

    if (tc != null) {
      if (tc.getConvName() == null)
        analyzer.userAdvice.format(" No 'Conventions' global attribute.%n");
      else
        analyzer.userAdvice.format(" Conventions global attribute = %s %n", tc.getConvName());

      // add the convention name used
      if (tc.getConvUsed() != null) {
        analyzer.setConventionUsed(tc.getConvUsed());
        if (!tc.getConvUsed().equals(tc.getConvName()))
          analyzer.userAdvice.format(" TableConfigurer used = "+tc.getConvUsed()+".%n");
      }

    } else {
      analyzer.userAdvice.format(" No TableConfigurer found, using default analysis.%n");

    }

    // construct the nested table object
    analyzer.analyze(wantFeatureType);
    return analyzer;
  }

Create a TableAnalyser for this dataset with the given TableConfigurer

@param tc TableConfigurer, may be null.
@param wantFeatureType want this FeatureType
@param ds for this dataset
@return TableAnalyser
@throws IOException on read error


public FeatureType getFirstFeatureType() {
    for (NestedTable nt : leaves) {
      if (nt.hasCoords())
        return nt.getFeatureType();
    }
    return null;
  }

public FeatureType getFirstFeatureType ( ) { for ( NestedTable nt : leaves ) { if ( nt . hasCoords ( ) ) return nt . getFeatureType ( ) ; } return null ; }


private void analyze(FeatureType wantFeatureType) throws IOException {
    // for netcdf-3 files, convert record dimension to structure
    // LOOK may be problems when served via opendap
    boolean structAdded = (Boolean) ds.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE);

    if (tc == null) {
      makeTablesDefault(structAdded);
      makeNestedTables();

    } else {
      configResult = tc.getConfig(wantFeatureType, ds, errlog);
      if (configResult != null)
        addTableRecurse( configResult); // kinda stupid
      else { // use default
        makeTablesDefault(structAdded);
        makeNestedTables();
      }
    }

    // find the leaves
    for (TableConfig config : tableSet) {
      if (config.children == null) { // its a leaf
        NestedTable flatTable = new NestedTable(ds, config, errlog);
        leaves.add(flatTable);
      }
    }

    if (PointDatasetStandardFactory.showTables)
      getDetailInfo( new Formatter( System.out));
  }

Make a NestedTable object for the dataset.
@param wantFeatureType want this FeatureType
@throws IOException on read error

Make a NestedTable object for the dataset .


public boolean sync() {
    try {
      if (!mcGridReader.init()) {
        return false;
      }
      GridIndex index = mcGridReader.getGridIndex();
      // reconstruct the ncfile objects
      ncfile.empty();
      open(index, null);
      return true;

    } catch (IOException ioe) {
      return false;
    }
  }

public
boolean
sync
(
)
{
try
{
if
(
!
mcGridReader
.
init
(
)
)
{
return
false
;
}
GridIndex
index
=
mcGridReader
.
getGridIndex
(
)
;
// reconstruct the ncfile objects
ncfile
.
empty
(
)
;
open
(
index
,
)
;
return
true
;
}
catch
(
IOException
ioe
)
{
return
false
;
}
}


public static double[] getGaussianLatitudes(String type, int start,
            int num)
            throws IllegalArgumentException {
        double[] baseArray = null;
        start--;  // it's one based
        if (type.equalsIgnoreCase(GAUST62)) {
            baseArray = gltst62;
        } else if (type.equalsIgnoreCase(GAUSR15)) {
            baseArray = glts15;
        } else if (type.equalsIgnoreCase(GAUSR20)) {
            baseArray = glts20;
        } else if (type.equalsIgnoreCase(GAUSR30)) {
            baseArray = glts30;
        } else if (type.equalsIgnoreCase(GAUSR40)) {
            baseArray = glats;
        } else {
            throw new IllegalArgumentException("Unsupported type: " + type);
        }
        if (start + num > baseArray.length) {
            throw new IllegalArgumentException("Maximum " + baseArray.length
                    + " latitudes exceeded");
        }
        double[] retVals = new double[num];
        for (int i = 0; i < num; i++) {
            retVals[i] = baseArray[start + i];
        }
        return retVals;
    }

public
static
double
[
]
getGaussianLatitudes
(
String
type
,
int
start
,
int
num
)
throws
IllegalArgumentException
{
double
[
]
baseArray
=
;
start
;
// it's one based
if
(
type
.
equalsIgnoreCase
(
GAUST62
)
)
{
baseArray
=
gltst62
;
}
else
if
(
type
.
equalsIgnoreCase
(
GAUSR15
)
)
{
baseArray
=
glts15
;
}
else
if
(
type
.
equalsIgnoreCase
(
GAUSR20
)
)
{
baseArray
=
glts20
;
}
else
if
(
type
.
equalsIgnoreCase
(
GAUSR30
)
)
{
baseArray
=
glts30
;
}
else
if
(
type
.
equalsIgnoreCase
(
GAUSR40
)
)
{
baseArray
=
glats
;
}
else
{
throw
new
IllegalArgumentException
(
"Unsupported type: "
+
type
)
;
}
if
(
start
+
num
>
baseArray
.
length
)
{
throw
new
IllegalArgumentException
(
"Maximum "
+
baseArray
.
length
+
" latitudes exceeded"
)
;
}
double
[
]
retVals
=
new
double
[
num
]
;
for
(
int
i
=
0
;
i
<
num
;
i
++
)
{
retVals
[
i
]
=
baseArray
[
start
+
i
]
;
}
return
retVals
;
}

Get the latitude values for the given type.

@param type gaussian type
@param start  starting index (1 based)
@param num  number of values

@return the values

@throws IllegalArgumentException  invalid or unsupported type

Get the latitude values for the given type .


static public long swapLong(byte[] b, int offset) {
    // 8 bytes
    long accum = 0;
    long shiftedval;
    for (int shiftBy = 0, i = offset; shiftBy < 64; shiftBy += 8, i++) {
      shiftedval = ((long) (b[i] & 0xff)) << shiftBy;
      accum |= shiftedval;
    }
    return accum;
  }

static
public
long
swapLong
(
byte
[
]
b
,
int
offset
)
{
// 8 bytes
long
accum
=
0
;
long
shiftedval
;
for
(
int
shiftBy
=
0
,
i
=
offset
;
shiftBy
<
64
;
shiftBy
+=
8
,
i
++
)
{
shiftedval
=
(
(
long
)
(
b
[
i
]
&
0xff
)
)
<<
shiftBy
;
accum
|=
shiftedval
;
}
return
accum
;
}

Returns the long resulting from reversing 8 bytes at a specified
offset in a byte array.

@param b      the byte array
@param offset the offset of the first byte
@return the long represented by the bytes
b[offset+7], b[offset+6], ..., b[offset]

Returns the long resulting from reversing 8 bytes at a specified offset in a byte array .


static public float swapFloat(byte[] b, int offset) {
    int accum = 0;
    for (int shiftBy = 0, i = offset; shiftBy < 32; shiftBy += 8, i++)
      accum |= (b[i] & 0xff) << shiftBy;
    return Float.intBitsToFloat(accum);
  }

static public float swapFloat ( byte [ ] b , int offset ) { int accum = 0 ; for ( int shiftBy = 0 , i = offset ; shiftBy < 32 ; shiftBy += 8 , i ++ ) accum |= ( [ i ] & 0xff ) << shiftBy ; return Float . intBitsToFloat ( accum ) ; }

Returns the float resulting from reversing 4 bytes at a specified
offset in a byte array.

@param b      the byte array
@param offset the offset of the first byte
@return the float represented by the bytes
b[offset+3], b[offset+2], ..., b[offset]

Returns the float resulting from reversing 4 bytes at a specified offset in a byte array .


static public char swapChar(byte[] b, int offset) {
    // 2 bytes
    int low = b[offset] & 0xff;
    int high = b[offset + 1] & 0xff;
    return (char) (high << 8 | low);
  }

static
public
char
swapChar
(
byte
[
]
b
,
int
offset
)
{
// 2 bytes
int
low
=
b
[
offset
]
&
0xff
;
int
high
=
b
[
offset
+
1
]
&
0xff
;
return
(
char
)
(
high
<<
8
|
low
)
;
}

Returns the char resulting from swapping 2 bytes at a specified
offset in a byte array.

@param b      the byte array
@param offset the offset of the first byte
@return the char represented by the bytes
b[offset+1], b[offset]

Returns the char resulting from swapping 2 bytes at a specified offset in a byte array .


protected void findCoordinateAxes(NetcdfDataset ds) {

    // coordinates is an alias for _CoordinateAxes
    for (VarProcess vp : varList) {
      if (vp.coordAxes == null) { // dont override if already set
        String coordsString = ds.findAttValueIgnoreCase(vp.v, CF.COORDINATES, null);
        if (coordsString != null) {
          vp.coordinates = coordsString;
        }
      }
    }

    super.findCoordinateAxes(ds);
  }

The attribute "coordinates" is an alias for _CoordinateAxes.

The attribute coordinates is an alias for _CoordinateAxes .