opendap/src/main/java/ucar/nc2/dods/ConvertD2N.java
private Array convertStringArray(Array data, Variable ncVar) {
    String[] storage = (String[]) data.getStorage();
    int max_len = 0;
    for (String s : storage) {
      max_len = Math.max(max_len, s.length());
    }
    if (max_len > 1) return data;

    // below is the length=1 barfalloney
    int count = 0;
    int n = (int) data.getSize();
    char[] charStorage = new char[n];
    for (String s : storage) {
      if (s.length() > 0)
        charStorage[count++] = s.charAt(0);
    }

    // change it to a char (!!). Since its no longer a String, this code wont get called again for this variable.
    ncVar.setDataType( DataType.CHAR);

    // return data thats been changed to chars
    return Array.factory( DataType.CHAR, data.getShape(), charStorage);

    /* if (section == null)
      section = ncVar.getRanges();

    // add the strLen dimension back to the array
    int[] varShape = ncVar.getShape();
    int strLen = varShape[ ncVar.getRank()-1];
    int total = (int) Range.computeSize(section);
    int newSize = total/strLen;
    String[] newStorage = new String[newSize];

    // merge last dimension
    StringBuffer sbuff = new StringBuffer();
    int newCount = 0;
    while (newCount < newSize) {
      int mergeCount = 0;
      sbuff.setLength(0);
      while (mergeCount < strLen) {
        String s = storage[strLen * newCount + mergeCount];
        if (s.length() == 0) break;
        sbuff.append( s);
        mergeCount++;
      }
      newStorage[ newCount++] = sbuff.toString();
    }


    /* List dims = ncVar.getDimensions();
    ncVar.setDimensions( dims.subList(0, ncVar.getRank()-1)); // LOOK is this dangerous or what ???
    int[] newShape = ncVar.getShape();
    return Array.factory( DataType.STRING.getPrimitiveClassType(), newShape, newStorage); */
  }
private Array convertStringArray(Array data, Variable ncVar) {
    String[] storage = (String[]) data.getStorage();
    int max_len = 0;
    for (String s : storage) {
      max_len = Math.max(max_len, s.length());
    }
    if (max_len > 1) return data;

    // below is the length=1 barfalloney
    int count = 0;
    int n = (int) data.getSize();
    char[] charStorage = new char[n];
    for (String s : storage) {
      if (s.length() > 0)
        charStorage[count++] = s.charAt(0);
    }

    // change it to a char (!!). Since its no longer a String, this code wont get called again for this variable.
    ncVar.setDataType( DataType.CHAR);

    // return data thats been changed to chars
    return Array.factory( DataType.CHAR, data.getShape(), charStorage);

    /* if (section == null)
      section = ncVar.getRanges();

    // add the strLen dimension back to the array
    int[] varShape = ncVar.getShape();
    int strLen = varShape[ ncVar.getRank()-1];
    int total = (int) Range.computeSize(section);
    int newSize = total/strLen;
    String[] newStorage = new String[newSize];

    // merge last dimension
    StringBuffer sbuff = new StringBuffer();
    int newCount = 0;
    while (newCount < newSize) {
      int mergeCount = 0;
      sbuff.setLength(0);
      while (mergeCount < strLen) {
        String s = storage[strLen * newCount + mergeCount];
        if (s.length() == 0) break;
        sbuff.append( s);
        mergeCount++;
      }
      newStorage[ newCount++] = sbuff.toString();
    }


    /* List dims = ncVar.getDimensions();
    ncVar.setDimensions( dims.subList(0, ncVar.getRank()-1)); // LOOK is this dangerous or what ???
    int[] newShape = ncVar.getShape();
    return Array.factory( DataType.STRING.getPrimitiveClassType(), newShape, newStorage); */
  }
older opendap servers send netcdf char data as Strings of length 1 (!!)