private static List<String> getAttributeView(ClassDescriptor cld) {
   List<String> view = new ArrayList<String>();
   String basePath = cld.getUnqualifiedName() + ".";
   for (AttributeDescriptor att : cld.getAllAttributeDescriptors()) {
     if (!"id".equals(att.getName())) {
       view.add(basePath + att.getName());
     }
   }
   return view;
 }
  /**
   * Return a list of string paths that are defined as WebConfig to be shown in results. This will
   * include only attributes of the given class and not follow references. Optionally provide a
   * prefix to for creating a view for references/collections.
   *
   * @param type the class name to create a view for
   * @param model the model
   * @param webConfig we configuration
   * @param startingPath a path to prefix the class, can be null
   * @return the configured view paths for the class
   */
  public static List<String> getDefaultViewForClass(
      String type, Model model, WebConfig webConfig, String startingPath) {
    String prefix = startingPath;
    List<String> view = new ArrayList<String>();
    ClassDescriptor cld = model.getClassDescriptorByName(type);
    List<FieldConfig> fieldConfigs = getClassFieldConfigs(webConfig, cld);
    if (!StringUtils.isEmpty(prefix)) {
      try {
        // we can't add a subclass constraint, type must be same as the end of the prefix
        Path prefixPath = new Path(model, prefix);
        String prefixEndType = TypeUtil.unqualifiedName(prefixPath.getEndType().getName());
        if (!prefixEndType.equals(type)) {
          throw new IllegalArgumentException(
              "Mismatch between end type of prefix: "
                  + prefixEndType
                  + " and type parameter: "
                  + type);
        }
      } catch (PathException e) {
        LOG.error("Invalid path configured in webconfig for class: " + type);
      }
    } else {
      prefix = type;
    }

    for (FieldConfig fieldConfig : fieldConfigs) {
      String relPath = fieldConfig.getFieldExpr();
      // only add attributes, don't follow references, following references can be problematic
      // when subclasses get involved.
      if (fieldConfig.getShowInResults()) {
        try {
          Path path = new Path(model, prefix + "." + relPath);
          // use type (e.g. Protein) not prefix (e.g. Gene.proteins) to do
          // attribute check
          Path checkIsOnlyAttribute = new Path(model, type + "." + relPath);
          if (checkIsOnlyAttribute.isOnlyAttribute()) {
            view.add(path.getNoConstraintsString());
          }
        } catch (PathException e) {
          LOG.error("Invalid path configured in webconfig for class: " + type);
        }
      }
    }
    if (view.size() == 0) {
      for (AttributeDescriptor att : cld.getAllAttributeDescriptors()) {
        if (!"id".equals(att.getName())) {
          view.add(prefix + "." + att.getName());
        }
      }
    }
    return view;
  }
  /**
   * Return a List of Class objects corresponding to the fields returned by
   * getColumnFieldDescriptors().
   *
   * @return the Class objects
   */
  public List getColumnFieldClasses() {
    if (columnFieldClasses == null) {
      columnFieldClasses = new ArrayList();
      for (int i = 0; i < columnFieldDescriptors.size(); i++) {
        AttributeDescriptor ad = (AttributeDescriptor) columnFieldDescriptors.get(i);
        if (ad == null) {
          columnFieldClasses.add(null);
        } else {
          String className = ad.getType();
          columnFieldClasses.add(TypeUtil.instantiate(className));
        }
      }
    }

    return columnFieldClasses;
  }
Exemplo n.º 4
0
 /**
  * Generates code for a single attribute.
  *
  * @param attr the AttributeDescriptor
  * @param field true if the class should have the associated field, or false if the field is in
  *     the superclass
  * @return java code
  */
 protected String generate(AttributeDescriptor attr, boolean field) {
   StringBuffer sb = new StringBuffer();
   if (field) {
     sb.append(
             INDENT
                 + "// Attr: "
                 + attr.getClassDescriptor().getName()
                 + "."
                 + attr.getName()
                 + ENDL)
         .append(INDENT + "protected ")
         .append(attr.getType())
         .append(" ")
         .append(attr.getName())
         .append(";" + ENDL);
   }
   sb.append(generateGetSet(attr, field)).append(ENDL);
   return sb.toString();
 }
  /**
   * Used for making a query for a reference or collection. Only used when a user clicks on [show
   * all] under an inline table on an Object's report page. The type of that object is
   * "startingPath", eg. Department. This path will be prepended to every path in the query. The
   * "type" is the type of the reference/collection, eg. Employee.
   *
   * <p>TODO use getDefaultViewForClass() instead
   *
   * @param objType class of object we are querying for eg. Manager
   * @param model the model
   * @param webConfig the webconfig
   * @param fieldType the type of the field this object is in, eg Employee
   * @return query, eg. Department.employees.name
   */
  protected static PathQuery getQueryWithDefaultView(
      String objType, Model model, WebConfig webConfig, String fieldType) {
    String prefix = fieldType;
    PathQuery query = new PathQuery(model);
    ClassDescriptor cld = model.getClassDescriptorByName(objType);
    List<FieldConfig> fieldConfigs = getClassFieldConfigs(webConfig, cld);

    if (!StringUtils.isBlank(prefix)) {
      try {
        // if the type is different to the end of the prefix path, add a subclass constraint
        Path fieldPath = new Path(model, fieldType);
        String fieldEndType = TypeUtil.unqualifiedName(fieldPath.getEndType().getName());
        if (!fieldEndType.equals(objType)) {
          query.addConstraint(Constraints.type(fieldType, objType));
        }
      } catch (PathException e) {
        LOG.error("Invalid path configured in webconfig for class: " + objType);
      }
    }

    for (FieldConfig fieldConfig : fieldConfigs) {
      if (fieldConfig.getShowInResults()) {
        String path = prefix + "." + fieldConfig.getFieldExpr();
        int from = prefix.length() + 1;
        while (path.indexOf('.', from) != -1) {
          int dotPos = path.indexOf('.', from);
          int nextDot = path.indexOf('.', dotPos + 1);
          String outerJoin = nextDot == -1 ? path.substring(0, dotPos) : path.substring(0, nextDot);
          query.setOuterJoinStatus(outerJoin, OuterJoinStatus.OUTER);
          from = dotPos + 1;
        }
        query.addView(path);
      }
    }
    if (query.getView().size() == 0) {
      for (AttributeDescriptor att : cld.getAllAttributeDescriptors()) {
        if (!"id".equals(att.getName())) {
          query.addView(prefix + "." + att.getName());
        }
      }
    }
    return query;
  }
Exemplo n.º 6
0
  /**
   * Return a list of string paths that are defined as WebConfig to be shown in results. This will
   * include attributes of the given class and follow references.
   *
   * @param type the class name to create a view for
   * @param model the model
   * @param webConfig we configuration
   * @return the configured view paths for the class
   */
  public static List<String> getDefaultViewForClass(String type, Model model, WebConfig webConfig) {
    List<String> view = new ArrayList<String>();
    ClassDescriptor cld = model.getClassDescriptorByName(type);
    List<FieldConfig> fieldConfigs = FieldConfigHelper.getClassFieldConfigs(webConfig, cld);

    for (FieldConfig fieldConfig : fieldConfigs) {
      String relPath = fieldConfig.getFieldExpr();
      // only add attributes, don't follow references, following references can be problematic
      // when subclasses get involved.
      if (fieldConfig.getShowInResults()) {
        try {
          Path path = new Path(model, type + "." + relPath);
          // add references
          if (path.isRootPath() || path.endIsReference()) {
            for (FieldConfig fc :
                FieldConfigHelper.getClassFieldConfigs(webConfig, path.getEndClassDescriptor())) {
              Path pathToAdd =
                  new Path(model, path.toStringNoConstraints() + "." + fc.getFieldExpr());
              if (pathToAdd.endIsAttribute()
                  && (!view.contains(pathToAdd.getNoConstraintsString()))
                  && (fc.getDisplayer() == null && fc.getShowInSummary())) {
                view.add(pathToAdd.getNoConstraintsString());
              }
            }
            // add collections
          } else if (!path.endIsCollection()) {
            view.add(path.getNoConstraintsString());
          }
        } catch (PathException e) {
          LOG.error("Invalid path configured in webconfig for class: " + type);
        }
      }
    }
    if (view.size() == 0) {
      for (AttributeDescriptor att : cld.getAllAttributeDescriptors()) {
        if (!"id".equals(att.getName())) {
          view.add(type + "." + att.getName());
        }
      }
    }
    return view;
  }
Exemplo n.º 7
0
 /**
  * Generates the getFieldType method.
  *
  * @param cld the ClassDescriptor
  * @return a String with the method
  */
 public String generateGetFieldType(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT).append("public Class<?> getFieldType(final String fieldName) {\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     sb.append(INDENT + INDENT)
         .append("if (\"" + field.getName() + "\".equals(fieldName)) {\n")
         .append(INDENT + INDENT + INDENT);
     if (field instanceof AttributeDescriptor) {
       AttributeDescriptor attribute = (AttributeDescriptor) field;
       if ("boolean".equals(attribute.getType())) {
         sb.append("return Boolean.TYPE;\n");
       } else if ("short".equals(attribute.getType())) {
         sb.append("return Short.TYPE;\n");
       } else if ("int".equals(attribute.getType())) {
         sb.append("return Integer.TYPE;\n");
       } else if ("long".equals(attribute.getType())) {
         sb.append("return Long.TYPE;\n");
       } else if ("float".equals(attribute.getType())) {
         sb.append("return Float.TYPE;\n");
       } else if ("double".equals(attribute.getType())) {
         sb.append("return Double.TYPE;\n");
       } else {
         sb.append("return " + attribute.getType() + ".class;\n");
       }
     } else if (field.isReference()) {
       sb.append("return " + ((ReferenceDescriptor) field).getReferencedClassName() + ".class;\n");
     } else {
       sb.append("return java.util.Set.class;\n");
     }
     sb.append(INDENT + INDENT).append("}\n");
   }
   sb.append(INDENT + INDENT)
       .append("if (!" + cld.getName() + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT)
       .append("return TypeUtil.getFieldType(" + cld.getName() + ".class, fieldName);\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT)
       .append("throw new IllegalArgumentException(\"Unknown field \" + fieldName);\n")
       .append(INDENT)
       .append("}\n");
   return sb.toString();
 }
Exemplo n.º 8
0
 /**
  * Generates the setFieldValue method.
  *
  * @param cld the ClassDescriptor
  * @return a String with the method
  */
 public String generateSetFieldValue(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT)
       .append("public void setFieldValue(final String fieldName, final Object value) {\n")
       .append(INDENT + INDENT);
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     sb.append("if (\"" + field.getName() + "\".equals(fieldName)) {\n");
     String fieldName = field.getName();
     if ("value".equals(fieldName)) {
       fieldName = "this.value";
     } else if ("fieldName".equals(fieldName)) {
       fieldName = "this.fieldName";
     }
     if (field instanceof AttributeDescriptor) {
       AttributeDescriptor attribute = (AttributeDescriptor) field;
       if ("boolean".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Boolean) value).booleanValue();\n");
       } else if ("short".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Short) value).shortValue();\n");
       } else if ("int".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Integer) value).intValue();\n");
       } else if ("long".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Long) value).longValue();\n");
       } else if ("float".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Float) value).floatValue();\n");
       } else if ("double".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = ((Double) value).doubleValue();\n");
       } else {
         sb.append(INDENT + INDENT + INDENT)
             .append(fieldName + " = (" + attribute.getType() + ") value;\n");
       }
     } else if (field.isReference()) {
       sb.append(INDENT + INDENT + INDENT)
           .append(fieldName + " = (org.intermine.model.InterMineObject) value;\n");
     } else {
       sb.append(INDENT + INDENT + INDENT).append(fieldName + " = (java.util.Set) value;\n");
     }
     sb.append(INDENT + INDENT).append("} else ");
   }
   sb.append("{\n")
       .append(INDENT + INDENT + INDENT)
       .append("if (!" + cld.getName() + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT + INDENT)
       .append("TypeUtil.setFieldValue(this, fieldName, value);\n")
       .append(INDENT + INDENT + INDENT + INDENT)
       .append("return;\n")
       .append(INDENT + INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT + INDENT)
       .append("throw new IllegalArgumentException(\"Unknown field \" + fieldName);\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT)
       .append("}\n");
   return sb.toString();
 }
Exemplo n.º 9
0
 /**
  * Generates the getFieldValue method.
  *
  * @param cld the ClassDescriptor
  * @param proxy false to make the getFieldValue method, true to make the getFieldProxy method
  * @return a String with the method
  */
 public String generateGetFieldValue(ClassDescriptor cld, boolean proxy) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT)
       .append(
           "public Object getField"
               + (proxy ? "Proxy" : "Value")
               + "(final String fieldName) throws IllegalAccessException {\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     sb.append(INDENT + INDENT).append("if (\"" + field.getName() + "\".equals(fieldName)) {\n");
     String fieldName = field.getName();
     if ("fieldName".equals(fieldName)) {
       fieldName = "this.fieldName";
     }
     if (field instanceof AttributeDescriptor) {
       AttributeDescriptor attribute = (AttributeDescriptor) field;
       if ("boolean".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append("return Boolean.valueOf(" + fieldName + ");\n");
       } else if ("short".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT).append("return Short.valueOf(" + fieldName + ");\n");
       } else if ("int".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT)
             .append("return Integer.valueOf(" + fieldName + ");\n");
       } else if ("long".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT).append("return Long.valueOf(" + fieldName + ");\n");
       } else if ("float".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT).append("return Float.valueOf(" + fieldName + ");\n");
       } else if ("double".equals(attribute.getType())) {
         sb.append(INDENT + INDENT + INDENT).append("return Double.valueOf(" + fieldName + ");\n");
       } else {
         sb.append(INDENT + INDENT + INDENT).append("return " + fieldName + ";\n");
       }
     } else if (field.isReference()) {
       sb.append(INDENT + INDENT + INDENT);
       if (proxy) {
         sb.append("return " + fieldName + ";\n");
       } else {
         sb.append("if (" + fieldName + " instanceof ProxyReference) {\n")
             .append(INDENT + INDENT + INDENT + INDENT)
             .append("return ((ProxyReference) " + fieldName + ").getObject();\n")
             .append(INDENT + INDENT + INDENT)
             .append("} else {\n")
             .append(INDENT + INDENT + INDENT + INDENT)
             .append("return " + fieldName + ";\n")
             .append(INDENT + INDENT + INDENT)
             .append("}\n");
       }
     } else {
       sb.append(INDENT + INDENT + INDENT).append("return " + fieldName + ";\n");
     }
     sb.append(INDENT + INDENT).append("}\n");
   }
   sb.append(INDENT + INDENT)
       .append("if (!" + cld.getName() + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT)
       .append("return TypeUtil.getField" + (proxy ? "Proxy" : "Value") + "(this, fieldName);\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT)
       .append("throw new IllegalArgumentException(\"Unknown field \" + fieldName);\n")
       .append(INDENT)
       .append("}\n");
   return sb.toString();
 }
Exemplo n.º 10
0
 /**
  * Generates the setoBJECT method for deserialising objects.
  *
  * @param cld a ClassDescriptor
  * @return a String containing the method
  */
 public String generateSetObject(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT)
       .append("public void setoBJECT(String notXml, ObjectStore os) {\n")
       .append(INDENT + INDENT)
       .append("setoBJECT(NotXmlParser.SPLITTER.split(notXml), os);\n")
       .append(INDENT)
       .append("}\n")
       .append(INDENT)
       .append("public void setoBJECT(final String[] notXml, final ObjectStore os) {\n")
       .append(INDENT + INDENT)
       .append(
           "if (!"
               + cld.getName()
               + (cld.isInterface() ? "Shadow" : "")
               + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT)
       .append(
           "throw new IllegalStateException(\"Class \" + getClass().getName() + \""
               + " does not match code ("
               + cld.getName()
               + ")\");\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT)
       .append("for (int i = 2; i < notXml.length;) {\n")
       .append(INDENT + INDENT + INDENT)
       .append("int startI = i;\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     String fieldName = field.getName();
     if ("notXml".equals(fieldName)) {
       fieldName = "this.notXml";
     } else if ("os".equals(fieldName)) {
       fieldName = "this.os";
     }
     if (field instanceof AttributeDescriptor) {
       AttributeDescriptor attribute = (AttributeDescriptor) field;
       sb.append(INDENT + INDENT + INDENT)
           .append("if ((i < notXml.length) && \"a" + fieldName + "\".equals(notXml[i])) {\n")
           .append(INDENT + INDENT + INDENT + INDENT)
           .append("i++;\n")
           .append(INDENT + INDENT + INDENT + INDENT);
       if ("boolean".equals(attribute.getType())) {
         sb.append(fieldName + " = Boolean.parseBoolean(notXml[i]);\n");
       } else if ("short".equals(attribute.getType())) {
         sb.append(fieldName + " = Short.parseShort(notXml[i]);\n");
       } else if ("int".equals(attribute.getType())) {
         sb.append(fieldName + " = Integer.parseInt(notXml[i]);\n");
       } else if ("long".equals(attribute.getType())) {
         sb.append(fieldName + " = Long.parseLong(notXml[i]);\n");
       } else if ("float".equals(attribute.getType())) {
         sb.append(fieldName + " = Float.parseFloat(notXml[i]);\n");
       } else if ("double".equals(attribute.getType())) {
         sb.append(fieldName + " = Double.parseDouble(notXml[i]);\n");
       } else if ("java.lang.Boolean".equals(attribute.getType())) {
         sb.append(fieldName + " = Boolean.valueOf(notXml[i]);\n");
       } else if ("java.lang.Short".equals(attribute.getType())) {
         sb.append(fieldName + " = Short.valueOf(notXml[i]);\n");
       } else if ("java.lang.Integer".equals(attribute.getType())) {
         sb.append(fieldName + " = Integer.valueOf(notXml[i]);\n");
       } else if ("java.lang.Long".equals(attribute.getType())) {
         sb.append(fieldName + " = Long.valueOf(notXml[i]);\n");
       } else if ("java.lang.Float".equals(attribute.getType())) {
         sb.append(fieldName + " = Float.valueOf(notXml[i]);\n");
       } else if ("java.lang.Double".equals(attribute.getType())) {
         sb.append(fieldName + " = Double.valueOf(notXml[i]);\n");
       } else if ("java.util.Date".equals(attribute.getType())) {
         sb.append(fieldName + " = new java.util.Date(Long.parseLong(notXml[i]));\n");
       } else if ("java.math.BigDecimal".equals(attribute.getType())) {
         sb.append(fieldName + " = new java.math.BigDecimal(notXml[i]);\n");
       } else if ("org.intermine.objectstore.query.ClobAccess".equals(attribute.getType())) {
         sb.append(
             fieldName
                 + " = org.intermine.objectstore.query.ClobAccess"
                 + ".decodeDbDescription(os, notXml[i]);\n");
       } else if ("java.lang.String".equals(attribute.getType())) {
         sb.append("StringBuilder string = null;\n")
             .append(INDENT + INDENT + INDENT + INDENT)
             .append(
                 "while ((i + 1 < notXml.length) && (notXml[i + 1].charAt(0) == '"
                     + ENCODED_DELIM
                     + "')) {\n")
             .append(INDENT + INDENT + INDENT + INDENT + INDENT)
             .append("if (string == null) string = new StringBuilder(notXml[i]);\n")
             .append(INDENT + INDENT + INDENT + INDENT + INDENT)
             .append("i++;\n")
             .append(INDENT + INDENT + INDENT + INDENT + INDENT)
             .append("string.append(\"" + DELIM + "\").append(notXml[i].substring(1));\n")
             .append(INDENT + INDENT + INDENT + INDENT)
             .append("}\n")
             .append(INDENT + INDENT + INDENT + INDENT)
             .append(fieldName + " = string == null ? notXml[i] : string.toString();\n");
       } else {
         throw new IllegalArgumentException("Unknown type " + attribute.getType());
       }
       sb.append(INDENT + INDENT + INDENT + INDENT)
           .append("i++;\n")
           .append(INDENT + INDENT + INDENT)
           .append("}\n");
     } else if (field.isReference()) {
       ReferenceDescriptor reference = (ReferenceDescriptor) field;
       sb.append(INDENT + INDENT + INDENT)
           .append("if ((i < notXml.length) &&\"r" + fieldName + "\".equals(notXml[i])) {\n")
           .append(INDENT + INDENT + INDENT + INDENT)
           .append("i++;\n")
           .append(INDENT + INDENT + INDENT + INDENT)
           .append(
               fieldName
                   + " = new ProxyReference(os, Integer.valueOf(notXml[i])"
                   + ", "
                   + reference.getReferencedClassName()
                   + ".class);\n")
           .append(INDENT + INDENT + INDENT + INDENT)
           .append("i++;\n")
           .append(INDENT + INDENT + INDENT)
           .append("};\n");
     }
   }
   sb.append(INDENT + INDENT + INDENT)
       .append("if (startI == i) {\n")
       .append(INDENT + INDENT + INDENT + INDENT)
       .append("throw new IllegalArgumentException(\"Unknown field \" + notXml[i]);\n")
       .append(INDENT + INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT)
       .append("}\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     String fieldName = field.getName();
     if ("notXml".equals(fieldName)) {
       fieldName = "this.notXml";
     } else if ("os".equals(fieldName)) {
       fieldName = "this.os";
     }
     if (field instanceof CollectionDescriptor) {
       CollectionDescriptor coll = (CollectionDescriptor) field;
       sb.append(INDENT + INDENT)
           .append(
               fieldName
                   + " = new ProxyCollection<"
                   + coll.getReferencedClassName()
                   + ">(os, this, \""
                   + fieldName
                   + "\", "
                   + coll.getReferencedClassName()
                   + ".class);\n");
     }
   }
   sb.append(INDENT).append("}\n");
   return sb.toString();
 }
Exemplo n.º 11
0
 /**
  * Generates the getoBJECT method for producing NotXml.
  *
  * @param cld the ClassDescriptor
  * @return generated java code as a String
  */
 protected String generateGetObject(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT)
       .append("public StringConstructor getoBJECT() {\n")
       .append(INDENT + INDENT)
       .append(
           "if (!"
               + cld.getName()
               + (cld.isInterface() ? "Shadow" : "")
               + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT)
       .append("return NotXmlRenderer.render(this);\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT)
       .append("StringConstructor sb = new StringConstructor();\n")
       .append(INDENT + INDENT)
       .append("sb.append(\"" + DELIM + cld.getName() + "\");\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     if (field instanceof AttributeDescriptor) {
       AttributeDescriptor attribute = (AttributeDescriptor) field;
       if (attribute.getType().startsWith("java.")) {
         sb.append(INDENT + INDENT)
             .append("if (" + attribute.getName() + " != null) {\n")
             .append(INDENT + INDENT + INDENT)
             .append("sb.append(\"" + DELIM + "a" + field.getName() + DELIM + "\")");
         if ("java.util.Date".equals(attribute.getType())) {
           sb.append(".append(" + attribute.getName() + ".getTime());\n");
         } else if ("java.lang.String".equals(attribute.getType())) {
           sb.append(";\n")
               .append(INDENT + INDENT + INDENT)
               .append("String string = " + attribute.getName() + ";\n")
               .append(INDENT + INDENT + INDENT)
               .append("while (string != null) {\n")
               .append(INDENT + INDENT + INDENT + INDENT)
               .append("int delimPosition = string.indexOf(\"" + DELIM + "\");\n")
               .append(INDENT + INDENT + INDENT + INDENT)
               .append("if (delimPosition == -1) {\n")
               .append(INDENT + INDENT + INDENT + INDENT + INDENT)
               .append("sb.append(string);\n")
               .append(INDENT + INDENT + INDENT + INDENT + INDENT)
               .append("string = null;\n")
               .append(INDENT + INDENT + INDENT + INDENT)
               .append("} else {\n")
               .append(INDENT + INDENT + INDENT + INDENT + INDENT)
               .append("sb.append(string.substring(0, delimPosition + 3));\n")
               .append(INDENT + INDENT + INDENT + INDENT + INDENT)
               .append("sb.append(\"" + ENCODED_DELIM + "\");\n")
               .append(INDENT + INDENT + INDENT + INDENT + INDENT)
               .append("string = string.substring(delimPosition + 3);\n")
               .append(INDENT + INDENT + INDENT + INDENT)
               .append("}\n")
               .append(INDENT + INDENT + INDENT)
               .append("}\n");
         } else {
           sb.append(".append(" + attribute.getName() + ");\n");
         }
         sb.append(INDENT + INDENT).append("}\n");
       } else if ("org.intermine.objectstore.query.ClobAccess".equals(attribute.getType())) {
         sb.append(INDENT + INDENT)
             .append("if (" + attribute.getName() + " != null) {\n")
             .append(INDENT + INDENT + INDENT)
             .append("sb.append(\"" + DELIM + "a" + field.getName() + DELIM + "\" + ")
             .append(attribute.getName() + ".getDbDescription());\n")
             .append(INDENT + INDENT)
             .append("}\n");
       } else {
         sb.append(INDENT)
             .append(INDENT)
             .append("sb.append(\"" + DELIM + "a" + field.getName() + DELIM + "\")")
             .append(".append(" + field.getName() + ");\n");
       }
     } else if (field.isReference()) {
       sb.append(INDENT + INDENT)
           .append("if (" + field.getName() + " != null) {\n")
           .append(INDENT + INDENT + INDENT)
           .append("sb.append(\"" + DELIM + "r" + field.getName() + DELIM + "\")")
           .append(".append(" + field.getName() + ".getId());\n")
           .append(INDENT + INDENT)
           .append("}\n");
     }
   }
   sb.append(INDENT + INDENT).append("return sb;\n").append(INDENT).append("}\n");
   return sb.toString();
 }