indent,
taggedIndent,
   protected String basicXMLWriter (                                Writer outputWriter,                                String strIndent,                                boolean dontCloseNode,                                String newNodeNameString,                                String noChildObjectNodeName                             )   throws java.io.IOException   {      // init some internals      boolean writeHrefAttribute = false;      OutputStream dataOutputStream = null;      Writer dataOutputWriter = null;      boolean niceOutput = Specification.getInstance().isPrettyXDFOutput();      String indent = "";      // get the node name      String nodeName = getClassXDFNodeName();      if (newNodeNameString != null) nodeName = newNodeNameString;        // indent up one       indent = indent + strIndent;        //open node      if (niceOutput)        outputWriter.write( indent);        outputWriter.write("<" + nodeName );        Entity hrefObj = getHref();        XMLDataIOStyle readObj = parentArray.getXMLDataIOStyle();        // Well here decide if we need to write out to another file,      // In practice the systemId may correspond to an internet URI,      // and we cant always write to that (!). Its not clear under which      // situations we do want to do so. :P For the time being we just      // take the following 'dumb' approach.      if (hrefObj != null) {          String fileName = hrefObj.getSystemId();        String hrefName = hrefObj.getName();          // Some parsers return systemId with the 'file:' prefix. Java        // doenst currently understand this so we need to peal it off.        int index = fileName.indexOf("file:");        if (index == 0)           fileName = fileName.substring(5);        if(hrefName == null)         {          Log.errorln("Error: href object in dataCube lacks name. Data being written into metadata instead.\n");        }         else if (fileName != null)        {           writeHrefAttribute = true;           try {              dataOutputStream = new FileOutputStream(fileName);           }           catch (IOException e) {              //oops, something. is wrong, writ out to the passed in OutputStream              Log.warnln("Error: cannot open file:"+fileName+" for writing. Data being written into metadata.\n");              writeHrefAttribute = false;           }        }         else         {              Log.warnln("Error: href:"+hrefName+" lacks systemId, cannot write data to a separate file.");              Log.warnln("Data are being written into metadata instead.\n");              writeHrefAttribute = false;        }      }        // write data node attributes      if (writeHrefAttribute) {         outputWriter.write( " "+HREF_XML_ATTRIBUTE_NAME+"=\"");         writeOutAttribute(outputWriter, hrefObj.getName());         outputWriter.write( "\"");      }        String checksum = getChecksum();      if (checksum != null) {           outputWriter.write( " "+CHECKSUM_XML_ATTRIBUTE_NAME+"=\"");         writeOutAttribute(outputWriter, checksum.toString());         outputWriter.write( "\"");      }  /*      String encoding = getEncoding();      if (encoding != null) {           outputWriter.write( " "+ENCODING_XML_ATTRIBUTE_NAME+"=\"");         writeOutAttribute(outputWriter, encoding.toString());         outputWriter.write( "\"");      }*/          String compress = getCompression();      if (compress != null && dataOutputStream != null ) {            outputWriter.write( " "+COMPRESSION_TYPE_XML_ATTRIBUTE_NAME+"=\"");          writeOutAttribute(outputWriter, compress.toString());          outputWriter.write( "\"");           if (hrefObj == null) {             Log.errorln("Cant write compressed data within the XML file (use href instead for an external file). Aborting write.");             return nodeName;          }          // change the data outputWriter to match          if (compress.equals(Constants.DATA_COMPRESSION_GZIP)) {             try {                dataOutputStream = new GZIPOutputStream(dataOutputStream);             } catch (java.io.IOException e) {                Log.errorln("Cant open compressed (GZIP) outputstream to write to an href. Aborting.");                return nodeName;             }          } else if (compress.equals(Constants.DATA_COMPRESSION_ZIP)) {             dataOutputStream = new ZipOutputStream(dataOutputStream);             try {                ((ZipOutputStream) dataOutputStream).putNextEntry(new ZipEntry(hrefObj.getSystemId())); // write only to the first entry for now              } catch (java.io.IOException e) {                Log.errorln("Cant open compressed (ZIP) outputstream to write to an href. Aborting.");                return nodeName;             }          } else {             Log.errorln("Error: cant write data with compression type:"+compress+". Ignoring request.");             return nodeName;          }      }        if (writeHrefAttribute)           outputWriter.write("/>");  //we just close the data node now      else           outputWriter.write(">");  //end of opening code        // Locator currentLocator = parentArray.createLocator();      // List axisList = parentArray.getAxes();      List axisList = readObj.getIOAxesOrder();      if (axisList == null || axisList.size() == 0) {          // we dont have axes to direct the write?!?. Well, then, we           // wont be writing Data to either the XML file or an Href         Log.errorln("No axes defined! Cannot write data. Ignoring request.");      } else {          // writing Data to either the XML file or an Href         //         // Init important dataFormat information into arrays, this          // will help speed up long writes. Each entry corresponds to          // cached information about a particular dataFormat object. In         // the case where no FieldAxis (e.g. Fields) exist within the array,         // then we only have 1 entry in each of these arrays.          String[] noDataValues; //stores the NoDataValues for the parentArray,                                //used in writing out when NoDataException is caught         String[] formatPattern;      // cache of Java Formatter patterns for correct                                 // formatting of output values.         String[] negExponentialPattern; // Stupid Java DecimalFormatter cant work properly                                         // on exponential data, so we compensate with this.         String[] intFlag;      // Integer format flag          int[] numOfBytes;      // number of bytes each data format has.          DataFormat dataFormat[] = parentArray.getDataFormatList();         if (parentArray.hasFieldAxis()) {            // If we have field axis then prepare to init multiple size arrays            List fields = parentArray.getFieldAxis().getFields();            int nrofDataFormats = fields.size();            noDataValues  = new String[nrofDataFormats];            formatPattern = new String[nrofDataFormats];            intFlag       = new String[nrofDataFormats];            negExponentialPattern = new String[nrofDataFormats];            numOfBytes = new int[nrofDataFormats];            // now assign values             for (int i = 0; i < nrofDataFormats; i++) {               formatPattern[i] = dataFormat[i].getFormatPattern();               numOfBytes[i]    = dataFormat[i].numOfBytes();               Field field = (Field) fields.get(i);               if (field != null && field.getNoDataValue() != null)                    noDataValues[i] = field.getNoDataValue().toString();               if (dataFormat[i] instanceof FloatDataFormat)                  negExponentialPattern[i] = ((FloatDataFormat) dataFormat[i]).getNegativeExponentFormatPattern();               else                  negExponentialPattern[i] = null;               if (dataFormat[i] instanceof IntegerDataFormat)                  intFlag[i] = ((IntegerDataFormat) dataFormat[i]).getType();               else                  intFlag[i] = null;            }         } else {            // no field axis? then only one dataFormat and we get it from the Array            // init single size arrays            noDataValues  = new String[1];            formatPattern = new String[1];            negExponentialPattern = new String[1];            intFlag       = new String[1];            numOfBytes = new int[1];            // assign values             formatPattern[0] = dataFormat[0].getFormatPattern();            numOfBytes[0]    = dataFormat[0].numOfBytes();            String value = (String) null;            if (parentArray.getNoDataValue() != null) {               value = parentArray.getNoDataValue().toString(); // this is a HACK             }            noDataValues[0] = value;            if (dataFormat[0] instanceof FloatDataFormat)               negExponentialPattern[0] = ((FloatDataFormat) dataFormat[0]).getNegativeExponentFormatPattern();            else               negExponentialPattern[0] = null;            if (dataFormat[0] instanceof IntegerDataFormat)               intFlag[0] = ((IntegerDataFormat) dataFormat[0]).getType();            else               intFlag[0] = null;         }              // init the dataOutputWriter properly. To a file or to the same writer as the         // rest of the XML metadata?         if (dataOutputStream != null) {             // if this exists, then we are re-directing to an outside file.            // wrap the outputstream (compressed or otherwise) with bufferedWriter            dataOutputWriter = new BufferedWriter(new OutputStreamWriter(dataOutputStream));         } else {            // goes to same spot as meta-data, e.g. just use the XML output writer              dataOutputWriter = outputWriter;         }         // some info about the format Object         String endian = readObj.getEndian();         // now, based on outputstyle, write out the data         if (readObj instanceof TaggedXMLDataIOStyle)          {            String[] tags = ((TaggedXMLDataIOStyle)readObj).getAxisTags();            int[] axes = getMaxDataIndex(readObj);            int stop = axes.length;            int[] axisLength = new int[stop];            for (int i = 0; i < stop; i++) {               axisLength[i] = axes[stop - 1 - i];            }                    int whichTagIsFieldAxis = -1;            if (parentArray.hasFieldAxis()) {               for (int i = 0; i < stop; i++) {                  whichTagIsFieldAxis = i;                  AxisInterface axisObj = ((TaggedXMLDataIOStyle) readObj).getAxisByTag("d" + i);                  if (axisObj instanceof FieldAxis) {                     break;                  }               }            }            Locator taggedLocator = parentArray.createLocator();            AxisInterface fastestAxis = (AxisInterface) axisList.get(0);            int nrofDataFormats = dataFormat.length;            writeTaggedData( dataOutputWriter,                             taggedLocator,                             indent,                             axisLength,                             tags,                             0,                             0,                             fastestAxis,                             noDataValues,                             nrofDataFormats,                             dataFormat,                             numOfBytes,                             formatPattern,                             negExponentialPattern,                             endian,                             intFlag,                              whichTagIsFieldAxis                           );               // this *shouldnt* be needed, but tests with both Java 1.2.2 and 1.3.0            // on SUN and Linux platforms show that it is. Hopefully we can remove            // this in the future.            dataOutputWriter.flush();                 }  //done dealing with with TaggedXMLDataIOSytle         else          {               if (readObj instanceof DelimitedXMLDataIOStyle) {               AxisInterface fastestAxis = (AxisInterface) axisList.get(0);               writeDelimitedData( dataOutputWriter,                                   (DelimitedXMLDataIOStyle) readObj,                                   fastestAxis, noDataValues,                                   dataFormat,                                   numOfBytes,                                   formatPattern,                                   negExponentialPattern,                                   endian,                                   intFlag,                                   writeHrefAttribute ? false : true                                 );                 } else {               writeFormattedData( dataOutputWriter,                                   (FormattedXMLDataIOStyle) readObj,                                   noDataValues,                                   dataFormat,                                   numOfBytes,                                   formatPattern,                                   negExponentialPattern,                                   endian,                                   intFlag,                                    writeHrefAttribute ? false : true                                 );            }               if (writeHrefAttribute) {               try {                  // should work as flush() too, so no call needed here.                   dataOutputWriter.close();               } catch (java.io.IOException e) {                  Log.errorln("Cant close dataOuputStream! Aborting.");                  return nodeName;               }            }            }      } // finish writing data to XML/Href         //close the data section appropriately      if (!writeHrefAttribute && niceOutput) {        outputWriter.write( Constants.NEW_LINE+indent);      }        // If we didnt write Href attribute, then means that data      // were put into document. We need to close the open data      // node appropriately.      if (!writeHrefAttribute)         outputWriter.write( "</" + nodeName + ">");   //     if (niceOutput) //       outputWriter.write( Constants.NEW_LINE);      return nodeName;   }