/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
<<<<<<< Updated upstream
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
=======
 * 
 *     https://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.util;

import java.io.FileOutputStream;
import java.io.PrintWriter;

public class ClassGenerator {
  private final String[] fieldTypes = {
    "boolean",
    "byte",
    "short",
    "int",
    "long",
    "char",
    "float",
    "double",
    "Boolean",
    "Character",
    "Byte",
    "Short",
    "Integer",
    "Long",
    "Float",
    "Double",
    "String",
    "Locale",
    "Date",
    "BigDecimal",
    "BigInteger",
    "Object",
    "SimpleClass",
    "SimpleInterface"
  };
  // includes a place holder for default package access
  private final String[] accessSpecifiers = {"private ", "public ", "protected ", ""};

  private final String[] fieldModifiers = {
    "",
    "static ",
    "transient ",
    "final ",
    "volatile ",
    "static transient ",
    "static final ",
    "static volatile ",
    "transient final ",
    "transient volatile ",
    "static transient final ",
    "static transient volatile "
  };

  private final String[] xmlPersistenceModifiers = {
    "",
    "persistence-modifier=\"none\"",
    "persistence-modifier=\"persistent\"",
    "persistence-modifier=\"transactional\""
  };

  private final String[] xmlEmbeddedModifiers = {"", "embedded=\"true\"", "embedded=\"false\""};

  private final String[] collectionTypes = {
    "Collection",
    "Map",
    "Set",
    "List",
    "HashSet",
    "ArrayList",
    "HashMap",
    "Hashtable",
    "LinkedList",
    "TreeMap",
    "TreeSet",
    "Vector",
    "Array"
  };

  // Note: Any updates to elementtypes should include an update to elementsWithPackageInfo
  private final String[] elementTypes = {
    "Object",
    "SimpleClass",
    "SimpleInterface",
    "String",
    "Date",
    "Locale",
    "BigDecimal",
    "BigInteger",
    "Byte",
    "Double",
    "Float",
    "Integer",
    "Long",
    "Short"
  };

  private final String[] elementsWithPackageInfo = {
    "java.lang.Object",
    "org.apache.jdo.tck.pc.fieldtypes.SimpleClass",
    "org.apache.jdo.tck.pc.fieldtypes.SimpleInterface",
    "java.lang.String",
    "java.util.Date",
    "java.util.Locale",
    "java.math.BigDecimal",
    "java.math.BigInteger",
    "java.lang.Byte",
    "java.lang.Double",
    "java.lang.Float",
    "java.lang.Integer",
    "java.lang.Long",
    "java.lang.Short"
  };

  private StringBuffer fieldSpecs = new StringBuffer(2000);
  private StringBuffer isPersistent = new StringBuffer(200);
  private StringBuffer isStatic = new StringBuffer(200);
  private StringBuffer isFinalArray = new StringBuffer(2000);

  // can accomodate only 4000 fields, have to increase the capacity if the fields exceed 4000
  private static final boolean[] isFinal = new boolean[4000];

  void generate() throws Exception {
    final String twoSpaces = "  ";
    final String space = " ";

    for (String fieldType : fieldTypes) {
      String classFile = (isPrimitive(fieldType) ? "FieldsOfPrimitive" : "FieldsOf") + fieldType;

      FileOutputStream xmlFout = new FileOutputStream(classFile + ".jdo.n");
      PrintWriter xmlPw = new PrintWriter(xmlFout);
      FileOutputStream xmlFout1 = new FileOutputStream(classFile + ".jdo.a");
      PrintWriter xmlPw1 = new PrintWriter(xmlFout1);
      FileOutputStream xmlFout2 = new FileOutputStream(classFile + ".jdo.d");
      PrintWriter xmlPw2 = new PrintWriter(xmlFout2);
      startXmlMetaData(xmlPw);
      startXmlMetaData(xmlPw1);
      startXmlMetaData(xmlPw2);

      startXmlClass(xmlPw, classFile, 0);
      startXmlClass(xmlPw1, classFile, 1);
      startXmlClass(xmlPw2, classFile, 2);

      FileOutputStream fout = new FileOutputStream(classFile + ".java");
      PrintWriter pw = new PrintWriter(fout);
      startClass(pw, classFile);
      int fieldCounter = 0;
      for (String accessSpecifier : accessSpecifiers) {
        for (String fieldModifier : fieldModifiers) {
          for (String xmlPersistenceModifier : xmlPersistenceModifiers) {
            // do not generate persistence modifiers (persistent or transactional or none)
            // for fields that cannot be persisted

            if ((fieldModifier.indexOf("static") >= 0 || fieldModifier.indexOf("final") >= 0)
                && !xmlPersistenceModifier.equals("")) continue;

            /*        original code
                     if(!isPersistenceCapable(fieldModifiers[k])
                              && !xmlPersistenceModifiers[l].equals(""))
                            continue;
            */
            for (String xmlEmbeddedModifier : xmlEmbeddedModifiers) {
              // generate persistence modifiers (persistent or transactional or none)
              // only for fields that can be persisted
              // generate embedded modifiers only for persistent fields

              boolean fieldIsPersistent =
                  !(fieldModifier.indexOf("static") >= 0
                      || fieldModifier.indexOf("final") >= 0
                      || xmlPersistenceModifier.indexOf("none") >= 0
                      || xmlPersistenceModifier.indexOf("transactional") >= 0
                      || (fieldModifier.indexOf("transient") >= 0
                          && xmlPersistenceModifier.indexOf("persistent") == -1));

              if (!xmlEmbeddedModifier.equals("") && !fieldIsPersistent) continue;

              StringBuffer sb = new StringBuffer();
              sb.append(twoSpaces);
              sb.append(accessSpecifier);
              sb.append(fieldModifier);
              sb.append(fieldType);
              sb.append(space);
              String fieldName = (fieldType + fieldCounter++);
              // temporary fix to get around the bug in the enhancer code
              if (!(xmlEmbeddedModifier.equals("") && xmlPersistenceModifier.equals(""))) {
                printXmlField(
                    xmlPw,
                    "name=\""
                        + fieldName
                        + "\" "
                        + xmlPersistenceModifier
                        + " "
                        + xmlEmbeddedModifier);
                printXmlField(
                    xmlPw1,
                    "name=\""
                        + fieldName
                        + "\" "
                        + xmlPersistenceModifier
                        + " "
                        + xmlEmbeddedModifier);
                printXmlField(
                    xmlPw2,
                    "name=\""
                        + fieldName
                        + "\" "
                        + xmlPersistenceModifier
                        + " "
                        + xmlEmbeddedModifier);
              } // end temporary fix
              sb.append(fieldName);
              buildisPersistentArray(fieldIsPersistent); // add to isPersistentArray
              buildisStaticArray(isStatic(fieldModifier)); // add to isStaticArray
              buildFieldSpecs(
                  xmlPersistenceModifier.replace('"', ' ')
                      + " "
                      + xmlEmbeddedModifier.replace('"', ' ')
                      + sb); // add to the field specs array
              isFinal[fieldCounter - 1] = fieldModifier.indexOf("final") >= 0;
              if (isFinal[fieldCounter - 1]) sb.append(getInitializerForFinalTypes(fieldType));
              buildisFinalArray(isFinal[fieldCounter - 1]);
              sb.append(";");
              pw.println(sb);
            }
          }
        }
      }
      writeisPersistentArray(pw);
      writeisStaticArray(pw);
      writeisFinalArray(pw);
      writeFieldSpecs(pw);
      writeMethodGetLength(pw);
      writeMethodGet(pw, fieldType, fieldCounter);
      writeMethodSet(pw, fieldType, fieldCounter);
      endClass(pw);
      pw.close();
      fout.close();

      endXmlClass(xmlPw);
      endXmlClass(xmlPw1);
      endXmlClass(xmlPw2);
      endXmlMetaDeta(xmlPw);
      endXmlMetaDeta(xmlPw1);
      endXmlMetaDeta(xmlPw2);
      xmlPw.close();
      xmlFout.close();
      xmlPw1.close();
      xmlFout1.close();
      xmlPw2.close();
      xmlFout2.close();
    }
  }

  private void startClass(PrintWriter pw, String className) {
    pw.println("package org.apache.jdo.tck.pc.fieldtypes;");
    pw.println("");
    pw.println(getImportStatements(className));
    pw.println("public class " + className + " { ");
    pw.println("  public int identifier;");
  }

  private void endClass(PrintWriter pw) {
    pw.println("");
    pw.println("}");
  }

  private void startXmlMetaData(PrintWriter pw) {
    pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    pw.println("<!DOCTYPE jdo SYSTEM \"jdo.dtd\">");
    pw.println("<jdo>");
    pw.println("<package name=\"org.apache.jdo.tck.pc.fieldtypes\">");
  }

  private void endXmlMetaDeta(PrintWriter pw) {
    pw.println("</package>");
    pw.println("</jdo>");
  }

  private void startXmlClass(PrintWriter pw, String className, int type) {
    switch (type) {
      case (0):
        pw.println("<class name=\"" + className + "\">");
        break;
      case (1):
        pw.println("<class name=\"" + className + "\" identity-type=\"application\">");
        break;
      case (2):
        pw.println("<class name=\"" + className + "\" identity-type=\"datastore\">");
        break;
      default:
        System.out.println("Unsupported Type");
    }
  }

  private void endXmlClass(PrintWriter pw) {
    pw.println("</class>");
  }

  // need to check if we should support extents
  // fieldName includes modifiers
  private void printXmlField(PrintWriter pw, String fieldName) {
    pw.println("<field " + fieldName + ">");
    pw.println("</field>");
  }

  // fieldname does not include any modifiers.
  // element type includes package informaiton.
  private void printXmlCollectionFieldWithEmbeddedElement(
      PrintWriter pw, String fieldName, String elementType, String embeddedValue) {
    pw.println("<field name=\"" + fieldName + "\" " + ">");
    pw.print("<collection element-type=" + "\"" + elementType + "\"");
    if (!embeddedValue.equals("")) pw.print(" embedded-element=" + "\"" + embeddedValue + "\"");
    pw.println(">");
    pw.println("</collection>");
    pw.println("</field>");
  }

  private void printXmlArrayFieldWithEmbeddedElement(
      PrintWriter pw, String fieldName, String embeddedValue) {
    pw.println("<field name=\"" + fieldName + "\" " + ">");
    pw.println("<array embedded-element=" + "\"" + embeddedValue + "\"" + ">");
    pw.println("</array>");
    pw.println("</field>");
  }

  private void printXmlMapField(
      PrintWriter pw,
      String fieldName,
      String keyType,
      String embeddedKey,
      String valueType,
      String embeddedValue) {
    pw.println("<field name=\"" + fieldName + "\" " + ">");
    pw.print("<map ");
    if (!keyType.equals("")) pw.print(" key-type=" + "\"" + keyType + "\"");
    if (!embeddedKey.equals("")) pw.print(" embedded-key=" + "\"" + embeddedKey + "\"");
    if (!valueType.equals("")) pw.print(" value-type=" + "\"" + valueType + "\"");
    if (!embeddedValue.equals("")) pw.print(" embedded-value=" + "\"" + embeddedValue + "\"");
    pw.println(">");
    pw.println("</map>");
    pw.println("</field>");
  }

  private String getInitializerForFinalTypes(String fieldType) throws Exception {
    if (fieldType.equals("char")) return " = 'a'"; // primitive character, return 'a';
    else if (fieldType.equals("boolean")) return " = false"; // primitive boolean, return 'a';
    else if (Character.isLowerCase(fieldType.charAt(0)))
      return " = 5"; // return 0 for all other primitive types
    else if (fieldType.equals("Byte")) return " = Byte.valueOf((byte)5)";
    else if (fieldType.equals("Boolean")) return " = Boolean.FALSE";
    else if (fieldType.equals("Character")) return " = Character.valueOf('a')";
    else if (fieldType.equals("Short")) return " = Short.valueOf((short)5)";
    else if (fieldType.equals("Integer")) return " = Integer.valueOf((int)5)";
    else if (fieldType.equals("Long")) return " = Long.valueOf((long)5)";
    else if (fieldType.equals("Float")) return " = Float.valueOf((float)5)";
    else if (fieldType.equals("Double")) return " = Double.valueOf((double)5)";
    else if (fieldType.equals("String")) return " = new String(\"JDO TCK\")";
    else if (fieldType.equals("Locale")) return " = Locale.US";
    else if (fieldType.equals("BigDecimal")) return " = new BigDecimal(100.15)";
    else if (fieldType.equals("BigInteger")) return " = new BigInteger(\"100\")";
    else if (fieldType.equals("Collection")) return " = new HashSet()";
    else if (fieldType.equals("Set")) return " = new HashSet()";
    else if (fieldType.equals("HashSet")) return " = new HashSet()";
    else if (fieldType.equals("Object")) return " = new Object()";
    else if (fieldType.equals("SimpleClass")) return " = new SimpleClass()";
    else if (fieldType.equals("SimpleInterface")) return " = new SimpleClass()";
    else if (fieldType.equals("Date")) return " = new Date()";
    else throw new Exception("Unsupported FieldType " + fieldType);
  }

  private String getImportStatements(String fieldType) {
    if (fieldType.equals("FieldsOfLocale")) return "import java.util.*;";
    if (fieldType.equals("FieldsOfDate")) return "import java.util.*;";
    else if (fieldType.equals("FieldsOfBigDecimal")) return "import java.math.*;";
    else if (fieldType.equals("FieldsOfBigInteger")) return "import java.math.*;";
    else if (fieldType.equals("FieldsOfCollection")) return "import java.util.*;";
    else if (fieldType.equals("FieldsOfSet")) return "import java.util.*;";
    else if (fieldType.equals("FieldsOfHashSet")) return "import java.util.*;";
    else if (fieldType.indexOf("Collections") >= 0)
      return "import java.util.*;\r\nimport java.math.*;";
    else return "";
  }

  private boolean isPrimitive(String fieldType) {
    if (Character.isUpperCase(fieldType.charAt(0))) return false;
    else return true;
  }

  private boolean isPersistenceCapable(String fieldModifier) {
    if (fieldModifier.indexOf("static") >= 0
        || fieldModifier.indexOf("final") >= 0
        || fieldModifier.indexOf("transient") >= 0) return false;
    else return true;
  }

  private boolean isStatic(String fieldModifier) {
    if (fieldModifier.indexOf("static") >= 0) return true;
    else return false;
  }

  private boolean isFinal(String fieldModifier) {
    return fieldModifier.indexOf("final") >= 0;
  }

  private void buildisPersistentArray(boolean value) {
    if (isPersistent.length() != 0) isPersistent.append(",");
    if (value) isPersistent.append("true");
    else isPersistent.append("false");
  }

  private void buildisStaticArray(boolean value) {
    if (isStatic.length() != 0) isStatic.append(",");
    if (value) isStatic.append("true");
    else isStatic.append("false");
  }

  private void buildisFinalArray(boolean value) {
    if (isFinalArray.length() != 0) isFinalArray.append(",");
    if (value) isFinalArray.append("true");
    else isFinalArray.append("false");
  }

  private void writeisPersistentArray(PrintWriter pw) {
    // have to go through this hoopla because pw.println(fieldSpecs.toString()); outputs only
    // 1024 characters
    char[] charArray = new char[isPersistent.length()];
    isPersistent.getChars(0, isPersistent.length(), charArray, 0);
    pw.println("");
    pw.println("public static final boolean [] isPersistent = { ");

    int fieldCounter = 0;
    for (char c : charArray) {
      pw.print(c);
      if (c == ',') {
        fieldCounter++;
        if (fieldCounter == 10) {
          pw.println("");
          pw.flush();
          fieldCounter = 0;
        }
      }
    }
    pw.println("");
    pw.println(" };");
    isPersistent = new StringBuffer(2000);
  }

  private void writeisStaticArray(PrintWriter pw) {
    // have to go through this hoopla because pw.println(fieldSpecs.toString()); outputs only
    // 1024 characters
    char[] charArray = new char[isStatic.length()];
    isStatic.getChars(0, isStatic.length(), charArray, 0);
    pw.println("");
    pw.println("public static final boolean [] isStatic = { ");

    int fieldCounter = 0;
    for (char c : charArray) {
      pw.print(c);
      if (c == ',') {
        fieldCounter++;
        if (fieldCounter == 10) {
          pw.println("");
          pw.flush();
          fieldCounter = 0;
        }
      }
    }
    pw.println("");
    pw.println(" };");
    isStatic = new StringBuffer(2000);
  }

  private void writeisFinalArray(PrintWriter pw) {
    // have to go through this hoopla because pw.println(fieldSpecs.toString()); outputs only
    // 1024 characters
    char[] charArray = new char[isFinalArray.length()];
    isFinalArray.getChars(0, isFinalArray.length(), charArray, 0);
    pw.println("");
    pw.println("public static final boolean [] isFinal = { ");

    int fieldCounter = 0;
    for (char c : charArray) {
      pw.print(c);
      if (c == ',') {
        fieldCounter++;
        if (fieldCounter == 10) {
          pw.println("");
          pw.flush();
          fieldCounter = 0;
        }
      }
    }
    pw.println("");
    pw.println(" };");
    isFinalArray = new StringBuffer(2000);
  }

  private void buildFieldSpecs(String field) {
    if (fieldSpecs.length() != 0) fieldSpecs.append(",");

    fieldSpecs.append("\"");
    fieldSpecs.append(field.trim());
    fieldSpecs.append("\"");
  }

  private void writeFieldSpecs(PrintWriter pw) {
    // have to go through this hoopla because pw.println(fieldSpecs.toString()); outputs only
    // 1024 characters
    char[] charArray = new char[fieldSpecs.length()];
    fieldSpecs.getChars(0, fieldSpecs.length(), charArray, 0);
    pw.println("");
    pw.println("  public static final String [] fieldSpecs = { ");

    pw.print("  ");
    for (char c : charArray) {
      pw.print(c);
      if (c == ',') {
        pw.println("");
        pw.print("  ");
        pw.flush();
      }
    }
    pw.println("");
    pw.println("  };");
    fieldSpecs = new StringBuffer(2000);
  }

  private void writeMethodGetLength(PrintWriter pw) {
    pw.println("  public int getLength()");
    pw.println("  {");
    pw.println("    return fieldSpecs.length;");
    pw.println("  }");
  }

  private void writeMethodGet(PrintWriter pw, String fieldType, int numberOfFields) {
    pw.println("  public " + fieldType + " get(int index)");
    pw.println("  {");

    pw.println("    switch (index)");
    pw.println("    {");
    for (int i = 0; i < numberOfFields; i++) {
      pw.println("      case(" + i + "):");
      pw.println("        return " + fieldType + i + ";");
    }
    pw.println("      default:");
    pw.println("        throw new IndexOutOfBoundsException();");
    pw.println("    }");
    pw.println("  }");
  }

  private void writeMethodGet(
      PrintWriter pw, String fieldType, String[] fieldNames, int numFields) {
    pw.println("  public " + fieldType + " get(int index)");
    pw.println("  {");

    pw.println("    switch (index)");
    pw.println("    {");
    for (int i = 0; i < numFields; i++) {
      pw.println("      case(" + i + "):");
      pw.println("        return " + fieldNames[i] + ";");
    }
    pw.println("      default:");
    pw.println("        throw new IndexOutOfBoundsException();");
    pw.println("    }");
    pw.println("  }");
  }

  private void writeMethodSet(PrintWriter pw, String fieldType, int numberOfFields) {
    pw.println("  public boolean set(int index," + fieldType + " value" + ")");
    pw.println("  {");
    pw.println("    if(fieldSpecs[index].indexOf(\"final\") != -1)");
    pw.println("      return false;");

    pw.println("    switch (index)");
    pw.println("    {");
    for (int i = 0; i < numberOfFields; i++) {
      if (!isFinal[i]) {
        pw.println("      case(" + i + "):");
        pw.println("        " + fieldType + i + "= value" + ";");
        pw.println("         break;");
      }
    }
    pw.println("      default:");
    pw.println("        throw new IndexOutOfBoundsException();");
    pw.println("    }");
    pw.println("    return true;");
    pw.println("  }");
  }

  private void writeMethodSet(
      PrintWriter pw, String fieldType, String[] fieldNames, int numFields) {
    pw.println("  public boolean set(int index," + fieldType + " value" + ")");
    pw.println("  {");
    pw.println("    if(fieldSpecs[index].indexOf(\"final\") != -1)");
    pw.println("      return false;");

    pw.println("    switch (index)");
    pw.println("    {");
    for (int i = 0; i < numFields; i++) {
      //       if(!isFinal[i]) {
      pw.println("      case(" + i + "):");
      pw.println("        " + fieldNames[i] + "= value" + ";");
      pw.println("         break;");
      //       }
    }
    pw.println("      default:");
    pw.println("        throw new IndexOutOfBoundsException();");
    pw.println("    }");
    pw.println("    return true;");
    pw.println("  }");
  }

  private void writeMethodSetForArray(
      PrintWriter pw, String fieldType, String[] fieldNames, int numFields) {
    pw.println("  public boolean set(int index," + fieldType + " value" + ")");
    pw.println("  {");
    pw.println("    if(fieldSpecs[index].indexOf(\"final\") != -1)");
    pw.println("      return false;");

    pw.println("    switch (index)");
    pw.println("    {");
    for (int i = 0; i < numFields; i++) {
      //       if(!isFinal[i]) {
      String fieldName = fieldNames[i];
      String valueType;
      pw.println("      case(" + i + "):");
      int indexOfValueType = fieldName.indexOf("Of") + 2;
      String valueTypeWithNumber = fieldName.substring(indexOfValueType);
      int lastIndexOfValueType = 0;
      for (int j = valueTypeWithNumber.length() - 1; j >= 0; j--) {
        if (Character.isDigit(valueTypeWithNumber.charAt(j))) {
          continue;
        } else {
          lastIndexOfValueType = j;
          break;
        }
      }
      valueType = valueTypeWithNumber.substring(0, lastIndexOfValueType + 1);
      pw.println("        " + fieldNames[i] + "= (" + valueType + " []) value ;");
      pw.println("         break;");
      //       }
    }
    pw.println("      default:");
    pw.println("        throw new IndexOutOfBoundsException();");
    pw.println("    }");
    pw.println("    return true;");
    pw.println("  }");
  }

  // generates Collection files for the different collectionTypes
  // also, updates the corresponding xml files
  // called by generate, after it is done dealing with the generic field types
  void generateCollections() throws Exception {
    final String[] embeddedElements = {"", "true", "false"};
    final String[] embeddedElementsForFieldSpec = {
      "", "embedded-element=true", "embedded-element=false"
    };
    for (String collectionType : collectionTypes) {
      // Map has a lot of combinations, generate it separately
      if (collectionType.indexOf("Map") >= 0 || collectionType.equals("Hashtable")) {
        generateMapCollection(collectionType);
      } else // Array and the other collections
      {
        String classFile = collectionType + "Collections";
        FileOutputStream fout = new FileOutputStream(classFile + ".java");
        PrintWriter pw = new PrintWriter(fout);
        FileOutputStream xmlFout = new FileOutputStream(classFile + ".jdo.n");
        PrintWriter xmlPw = new PrintWriter(xmlFout);
        FileOutputStream xmlFout1 = new FileOutputStream(classFile + ".jdo.a");
        PrintWriter xmlPw1 = new PrintWriter(xmlFout1);
        FileOutputStream xmlFout2 = new FileOutputStream(classFile + ".jdo.d");
        PrintWriter xmlPw2 = new PrintWriter(xmlFout2);

        startClass(pw, classFile);
        startXmlMetaData(xmlPw);
        startXmlMetaData(xmlPw1);
        startXmlMetaData(xmlPw2);

        startXmlClass(xmlPw, classFile, 0);
        startXmlClass(xmlPw1, classFile, 1);
        startXmlClass(xmlPw2, classFile, 2);

        int fieldCounter = 0;
        String[] fieldNames = new String[elementTypes.length * embeddedElements.length];
        for (int j = 0; j < elementTypes.length; j++) {
          if (elementTypes[j].equals("Locale") && collectionType.equals("TreeSet")) continue;
          for (int k = 0; k < embeddedElements.length; k++) {
            if (collectionType.equals("Array")) {
              if (!embeddedElements[k].equals("")) {
                fieldNames[fieldCounter] = collectionType + "Of" + elementTypes[j] + fieldCounter;
                //                pw.println("  public " + "Object [] "+ fieldNames[fieldCounter]
                // +";");
                pw.println("  public " + elementTypes[j] + " [] " + fieldNames[fieldCounter] + ";");
                printXmlArrayFieldWithEmbeddedElement(
                    xmlPw, fieldNames[fieldCounter], embeddedElements[k]);
                printXmlArrayFieldWithEmbeddedElement(
                    xmlPw1, fieldNames[fieldCounter], embeddedElements[k]);
                printXmlArrayFieldWithEmbeddedElement(
                    xmlPw2, fieldNames[fieldCounter], embeddedElements[k]);
                buildFieldSpecs(
                    embeddedElementsForFieldSpec[k]
                        + " "
                        + "public "
                        + elementTypes[j]
                        + " [] "
                        + fieldNames[fieldCounter]); // add to the
                // field specs array*/

                fieldCounter++;
              }
            } else // Collection
            {
              fieldNames[fieldCounter] = collectionType + "Of" + elementTypes[j] + fieldCounter;
              pw.println("  public " + collectionType + " " + fieldNames[fieldCounter] + ";");
              printXmlCollectionFieldWithEmbeddedElement(
                  xmlPw, fieldNames[fieldCounter], elementsWithPackageInfo[j], embeddedElements[k]);
              printXmlCollectionFieldWithEmbeddedElement(
                  xmlPw1,
                  fieldNames[fieldCounter],
                  elementsWithPackageInfo[j],
                  embeddedElements[k]);
              printXmlCollectionFieldWithEmbeddedElement(
                  xmlPw2,
                  fieldNames[fieldCounter],
                  elementsWithPackageInfo[j],
                  embeddedElements[k]);
              buildFieldSpecs(
                  embeddedElementsForFieldSpec[k]
                      + " "
                      + "public "
                      + collectionType
                      + " "
                      + fieldNames[fieldCounter]); // add to the field specs array*/
              fieldCounter++;
            }
          }
        }
        writeFieldSpecs(pw);
        writeMethodGetLength(pw);
        writeMethodGet(
            pw,
            collectionType.equals("Array") ? "Object [] " : collectionType,
            fieldNames,
            fieldCounter);
        if (collectionType.equals("Array"))
          writeMethodSetForArray(pw, "Object [] ", fieldNames, fieldCounter);
        else writeMethodSet(pw, collectionType, fieldNames, fieldCounter);

        endClass(pw);
        pw.close();
        fout.close();
        endXmlClass(xmlPw);
        endXmlClass(xmlPw1);
        endXmlClass(xmlPw2);
        endXmlMetaDeta(xmlPw);
        endXmlMetaDeta(xmlPw1);
        endXmlMetaDeta(xmlPw2);
        xmlPw.close();
        xmlFout.close();
        xmlPw1.close();
        xmlFout1.close();
        xmlPw2.close();
        xmlFout2.close();
      }
    }
  }

  private void generateMapCollection(String mapName) throws Exception {
    final String[] keyTypes1 = {"String"};
    final String[] valueTypes1 = {
      "Object",
      "SimpleClass",
      "SimpleInterface",
      "String",
      "Date",
      "Locale",
      "BigDecimal",
      "BigInteger",
      "Byte",
      "Double",
      "Float",
      "Integer",
      "Long",
      "Short"
    };
    final String[] keyTypes2 = {
      "Object",
      "SimpleClass",
      "SimpleInterface",
      "String",
      "Date",
      "BigDecimal",
      "BigInteger",
      "Byte",
      "Double",
      "Float",
      "Integer",
      "Long",
      "Short"
    };
    final String[] valueTypes2 = {"String"};

    final String[][] keyTypes = {keyTypes1, keyTypes2};
    final String[][] valueTypes = {valueTypes1, valueTypes2};

    String[] classNameArray = {
      mapName + "StringKey" + "Collections", mapName + "StringValue" + "Collections"
    };

    for (int i = 0; i < classNameArray.length; i++) {
      String classFile = classNameArray[i];
      FileOutputStream fout = new FileOutputStream(classFile + ".java");
      PrintWriter pw = new PrintWriter(fout);
      FileOutputStream xmlFout = new FileOutputStream(classFile + ".jdo.n");
      PrintWriter xmlPw = new PrintWriter(xmlFout);
      FileOutputStream xmlFout1 = new FileOutputStream(classFile + ".jdo.a");
      PrintWriter xmlPw1 = new PrintWriter(xmlFout1);
      FileOutputStream xmlFout2 = new FileOutputStream(classFile + ".jdo.d");
      PrintWriter xmlPw2 = new PrintWriter(xmlFout2);

      startClass(pw, classFile);
      startXmlMetaData(xmlPw);
      startXmlMetaData(xmlPw1);
      startXmlMetaData(xmlPw2);

      startXmlClass(xmlPw, classFile, 0);
      startXmlClass(xmlPw1, classFile, 1);
      startXmlClass(xmlPw2, classFile, 2);

      fillMapCollection(keyTypes[i], valueTypes[i], mapName, pw, xmlPw, xmlPw1, xmlPw2);

      endClass(pw);
      pw.close();
      fout.close();
      endXmlClass(xmlPw);
      endXmlClass(xmlPw1);
      endXmlClass(xmlPw2);
      endXmlMetaDeta(xmlPw);
      endXmlMetaDeta(xmlPw1);
      endXmlMetaDeta(xmlPw2);
      xmlPw.close();
      xmlFout.close();
      xmlPw1.close();
      xmlFout1.close();
      xmlPw2.close();
      xmlFout2.close();
    }
  }

  private void fillMapCollection(
      String[] keyTypes,
      String[] valueTypes,
      String mapName,
      PrintWriter pw,
      PrintWriter xmlPw,
      PrintWriter xmlPw1,
      PrintWriter xmlPw2) {
    final String[] embeddedKeys = {"", "true", "false"};
    final String[] embeddedValues = embeddedKeys;
    final String[] embeddedKeyForFieldSpec = {"", "embedded-key=true", "embedded-key=false"};
    final String[] embeddedValueForFieldSpec = {"", "embedded-value=true", "embedded-value=false"};

    int fieldCounter = 0;
    String[] fieldNames =
        new String
            [keyTypes.length * embeddedKeys.length * valueTypes.length * embeddedValues.length];
    for (String keyType : keyTypes) {
      for (int j = 0; j < embeddedKeys.length; j++) {
        for (String valueType : valueTypes) {
          for (int l = 0; l < embeddedValues.length; l++) {
            if (keyType.equals("")
                && embeddedKeys[j].equals("")
                && valueType.equals("")
                && embeddedValues[l].equals("")) continue;
            fieldNames[fieldCounter] = mapName + "Of" + keyType + "_" + valueType + fieldCounter;
            pw.println("  public " + mapName + " " + fieldNames[fieldCounter] + ";");
            printXmlMapField(
                xmlPw,
                fieldNames[fieldCounter],
                keyType,
                embeddedKeys[j],
                valueType,
                embeddedValues[l]);
            printXmlMapField(
                xmlPw1,
                fieldNames[fieldCounter],
                keyType,
                embeddedKeys[j],
                valueType,
                embeddedValues[l]);
            printXmlMapField(
                xmlPw2,
                fieldNames[fieldCounter],
                keyType,
                embeddedKeys[j],
                valueType,
                embeddedValues[l]);
            buildFieldSpecs(
                embeddedKeyForFieldSpec[j]
                    + " "
                    + embeddedValueForFieldSpec[l]
                    + " "
                    + "public "
                    + mapName
                    + " "
                    + fieldNames[fieldCounter]); // add to the field specs array*/
            fieldCounter++;
          }
        }
      }
    }
    writeFieldSpecs(pw);
    writeMethodGetLength(pw);
    writeMethodGet(pw, mapName, fieldNames, fieldCounter);
    writeMethodSet(pw, mapName, fieldNames, fieldCounter);
  }

  public static void main(String[] args) {
    ClassGenerator classGenerator = new ClassGenerator();
    try {
      classGenerator.generate();
      classGenerator.generateCollections();
    } catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}
