/**
   * Create a PathQuery to get results for a collection of items from an InterMineObject
   *
   * @param webConfig the WebConfig
   * @param os the production ObjectStore
   * @param object the InterMineObject
   * @param referencedClassName the collection type
   * @param field the name of the field for the collection in the InterMineObject
   * @return a PathQuery
   */
  public static PathQuery makePathQueryForCollection(
      WebConfig webConfig,
      ObjectStore os,
      InterMineObject object,
      String referencedClassName,
      String field) {

    String className = TypeUtil.unqualifiedName(DynamicUtil.getSimpleClassName(object.getClass()));
    Path path;
    try {
      path = new Path(os.getModel(), className + "." + field);
    } catch (PathException e) {
      throw new IllegalArgumentException(
          "Could not build path for \"" + className + "." + field + "\".");
    }
    List<Class<?>> types = new ArrayList<Class<?>>();
    if (path.endIsCollection()) {
      CollectionDescriptor end = (CollectionDescriptor) path.getEndFieldDescriptor();
      // Only look for types if the refClass exactly matches the path type.
      if (end.getReferencedClassName().equals(referencedClassName)) {
        types = queryForTypesInCollection(object, field, os);
      }
      if (types.isEmpty()) {
        // the collection was empty, but still generate a query with the collection type
        types.add(os.getModel().getClassDescriptorByName(referencedClassName).getType());
      }
    } else if (path.endIsReference()) {
      types.add(path.getLastClassDescriptor().getType());
    }
    return makePathQueryForCollectionForClass(webConfig, os.getModel(), object, field, types);
  }
Example #2
0
 /**
  * Generates the getElementType method.
  *
  * @param cld the ClassDescriptor
  * @return a String with the method
  */
 public String generateGetElementType(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT).append("public Class<?> getElementType(final String fieldName) {\n");
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     if (field.isCollection()) {
       sb.append(INDENT + INDENT)
           .append("if (\"" + field.getName() + "\".equals(fieldName)) {\n")
           .append(INDENT + INDENT + INDENT)
           .append(
               "return " + ((CollectionDescriptor) field).getReferencedClassName() + ".class;\n")
           .append(INDENT + INDENT)
           .append("}\n");
     }
   }
   sb.append(INDENT + INDENT)
       .append("if (!" + cld.getName() + ".class.equals(getClass())) {\n")
       .append(INDENT + INDENT + INDENT)
       .append("return TypeUtil.getElementType(" + 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();
 }
Example #3
0
  /**
   * Generates code for a single collection.
   *
   * @param col the CollectionDescriptor
   * @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(CollectionDescriptor col, boolean field) {
    String type = "java.util.Set<" + col.getReferencedClassName() + ">";
    String impl = "java.util.HashSet<" + col.getReferencedClassName() + ">";

    StringBuffer sb = new StringBuffer();
    if (field) {
      sb.append(
              INDENT + "// Col: " + col.getClassDescriptor().getName() + "." + col.getName() + ENDL)
          .append(INDENT)
          .append("protected ")
          .append(type)
          .append(" ")
          .append(col.getName())
          .append(" = new ")
          .append(impl)
          .append("();" + ENDL);
    }
    sb.append(generateGetSet(col, field)).append(ENDL);
    return sb.toString();
  }
  /**
   * Search for the classes in a collection for a given InterMineObject, for example find all of the
   * sub-classes of Employee in the Department.employees collection of a given Department. If there
   * are no subclasses or the collection is empty a list with the type of the collection is
   * returned.
   *
   * @param object an InterMineObject to inspect
   * @param field the name if the collection to check
   * @param os the ObjectStore in which to execute the query
   * @return a list of classes in the collection
   */
  public static List<Class<?>> queryForTypesInCollection(
      InterMineObject object, String field, ObjectStore os) {
    List<Class<?>> typesInCollection = new ArrayList<Class<?>>();

    // if there are no subclasses there can only be one type in the collection
    Model model = os.getModel();
    ClassDescriptor startCld =
        model.getClassDescriptorByName(DynamicUtil.getSimpleClassName(object));
    CollectionDescriptor col = startCld.getCollectionDescriptorByName(field, true);
    ClassDescriptor colCld = col.getReferencedClassDescriptor();

    if (model.getAllSubs(colCld).isEmpty()) {
      // there aren't any subclasses, so no need to do a query
      typesInCollection.add(colCld.getType());
    } else {
      // there may be multiple subclasses in the collection, need to run a query
      Query query = new Query();
      QueryClass qc = new QueryClass(colCld.getType());
      query.addFrom(qc);
      query.addToSelect(new QueryField(qc, "class"));
      query.setDistinct(true);
      query.setConstraint(
          new ContainsConstraint(
              new QueryCollectionReference(object, field), ConstraintOp.CONTAINS, qc));
      for (Object o : os.executeSingleton(query)) {
        typesInCollection.add((Class<?>) o);
      }

      // Collection was empty but add collection type to be consistent with collection types
      // without subclasses.
      if (typesInCollection.isEmpty()) {
        typesInCollection.add(colCld.getType());
      }
    }
    return typesInCollection;
  }
Example #5
0
 /**
  * Generates the addCollectionElement method.
  *
  * @param cld the ClassDescriptor
  * @return a String with the method
  */
 public String generateAddCollectionElement(ClassDescriptor cld) {
   StringBuffer sb = new StringBuffer();
   sb.append(INDENT)
       .append("public void addCollectionElement(final String fieldName,")
       .append(" final org.intermine.model.InterMineObject element) {\n")
       .append(INDENT + INDENT);
   for (FieldDescriptor field : cld.getAllFieldDescriptors()) {
     if (field.isCollection()) {
       String fieldName = field.getName();
       if ("fieldName".equals(fieldName)) {
         fieldName = "this.fieldName";
       } else if ("element".equals(fieldName)) {
         fieldName = "this.element";
       }
       sb.append("if (\"" + field.getName() + "\".equals(fieldName)) {\n")
           .append(INDENT + INDENT + INDENT)
           .append(
               fieldName
                   + ".add(("
                   + ((CollectionDescriptor) field).getReferencedClassName()
                   + ") element);\n")
           .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.addCollectionElement(this, fieldName, element);\n")
       .append(INDENT + INDENT + INDENT + INDENT)
       .append("return;\n")
       .append(INDENT + INDENT + INDENT)
       .append("}\n")
       .append(INDENT + INDENT + INDENT)
       .append("throw new IllegalArgumentException(\"Unknown collection \" + fieldName);\n")
       .append(INDENT + INDENT)
       .append("}\n")
       .append(INDENT)
       .append("}\n");
   return sb.toString();
 }
Example #6
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();
 }
Example #7
0
  /**
   * Write code for getters and setters for given field.
   *
   * @param field descriptor for field
   * @param fieldPresent true if this class has the associated field
   * @return string with generated java code
   */
  protected String generateGetSet(FieldDescriptor field, boolean fieldPresent) {
    String name = field.getName();
    String type = getType(field);

    StringBuffer sb = new StringBuffer();

    // Get method
    sb.append(INDENT)
        .append("public ")
        .append(type)
        .append(" get")
        .append(StringUtil.reverseCapitalisation(name))
        .append("()");
    if (!fieldPresent) {
      sb.append(";" + ENDL);
    } else {
      sb.append(" { ");
      if ((field instanceof ReferenceDescriptor) && (!(field instanceof CollectionDescriptor))) {
        // This is an object reference.
        sb.append("if (")
            .append(name)
            .append(" instanceof org.intermine.objectstore.proxy.ProxyReference) { return ")
            .append("((")
            .append(type)
            .append(") ((org.intermine.objectstore.proxy.ProxyReference) ")
            .append(name)
            .append(").getObject()); }; return (")
            .append(type)
            .append(") ")
            .append(name)
            .append("; }" + ENDL);
      } else {
        sb.append("return ").append(name).append("; }" + ENDL);
      }
    }

    // Set method
    sb.append(INDENT)
        .append("public void ")
        .append("set")
        .append(StringUtil.reverseCapitalisation(name))
        .append("(final ")
        .append(type)
        .append(" ")
        .append(name)
        .append(")");
    if (!fieldPresent) {
      sb.append(";" + ENDL);
    } else {
      sb.append(" { ").append("this.").append(name).append(" = ").append(name).append("; }" + ENDL);
    }

    if (field instanceof ReferenceDescriptor) {
      if (field instanceof CollectionDescriptor) {
        sb.append(INDENT)
            .append("public void add")
            .append(StringUtil.reverseCapitalisation(name))
            .append("(final ")
            .append(((CollectionDescriptor) field).getReferencedClassDescriptor().getName())
            .append(" arg)");
        if (fieldPresent) {
          sb.append(" { ").append(name).append(".add(arg); }" + ENDL);
        } else {
          sb.append(";" + ENDL);
        }
      } else {
        // This is an object reference.
        sb.append(INDENT)
            .append("public void proxy")
            .append(StringUtil.reverseCapitalisation(name))
            .append("(final org.intermine.objectstore.proxy.ProxyReference ")
            .append(name)
            .append(")");
        if (fieldPresent) {
          sb.append(" { this.").append(name).append(" = ").append(name).append("; }" + ENDL);
        } else {
          sb.append(";" + ENDL);
        }
        sb.append(INDENT)
            .append("public org.intermine.model.InterMineObject proxGet")
            .append(StringUtil.reverseCapitalisation(name))
            .append("()");
        if (fieldPresent) {
          sb.append(" { return ").append(name).append("; }" + ENDL);
        } else {
          sb.append(";" + ENDL);
        }
      }
    }

    return sb.toString();
  }
Example #8
0
  /**
   * Add a collection of objects of type X to objects of type Y by using a connecting class. Eg. Add
   * a collection of Protein objects to Gene by examining the Transcript objects in the transcripts
   * collection of the Gene, which would use a query like: SELECT DISTINCT gene FROM Gene AS gene,
   * Transcript AS transcript, Protein AS protein WHERE (gene.transcripts CONTAINS transcript AND
   * transcript.protein CONTAINS protein) ORDER BY gene and then set protected gene.protein (if
   * created BioEntity1 -&gt; BioEntity2 -&gt; BioEntity3 ==&gt; BioEntity1 -&gt; BioEntity3
   *
   * @param firstClsName the first class in the query
   * @param firstClassFieldName the field in the firstClass which should contain the connectingClass
   * @param connectingClsName the class referred to by firstClass.sourceFieldName
   * @param connectingClassFieldName the field in connectingClass which should contain secondClass
   * @param secondClsName the class referred to by connectingClass.connectingClassFieldName
   * @param createFieldName the collection field in the secondClass - the collection to create/set
   * @param createInFirstClass if true create the new collection field in firstClass, otherwise
   *     create in secondClass
   * @throws Exception if anything goes wrong
   */
  protected void insertCollectionField(
      String firstClsName,
      String firstClassFieldName,
      String connectingClsName,
      String connectingClassFieldName,
      String secondClsName,
      String createFieldName,
      boolean createInFirstClass)
      throws Exception {
    InterMineObject lastDestObject = null;
    Set<InterMineObject> newCollection = new HashSet<InterMineObject>();

    String insertMessage =
        "insertCollectionField("
            + firstClsName
            + ", "
            + firstClassFieldName
            + ", "
            + connectingClsName
            + ", "
            + connectingClassFieldName
            + ","
            + secondClsName
            + ", "
            + createFieldName
            + ", "
            + createInFirstClass
            + ")";

    // Check that classes and fields specified exist in model
    try {
      String errorMessage = "Not performing " + insertMessage;
      PostProcessUtil.checkFieldExists(model, firstClsName, firstClassFieldName, errorMessage);
      PostProcessUtil.checkFieldExists(
          model, connectingClsName, connectingClassFieldName, errorMessage);
      PostProcessUtil.checkFieldExists(model, secondClsName, createFieldName, errorMessage);
    } catch (MetaDataException e) {
      return;
    }

    LOG.info("Beginning " + insertMessage);
    long startTime = System.currentTimeMillis();

    // if this is a many to many collection we can use ObjectStore.addToCollection which will
    // write directly to the database.
    boolean manyToMany = false;
    ClassDescriptor destCld;
    if (createInFirstClass) {
      destCld = model.getClassDescriptorByName(firstClsName);
    } else {
      destCld = model.getClassDescriptorByName(secondClsName);
    }
    CollectionDescriptor col = destCld.getCollectionDescriptorByName(createFieldName);
    if (col == null) {
      String msg =
          "Error running post-process `create-references` for `"
              + createFieldName
              + "` since this collection doesn't exist in the model.";
      LOG.error(msg);
      return;
    }

    if (col.relationType() == CollectionDescriptor.M_N_RELATION) {
      manyToMany = true;
    }

    Iterator<ResultsRow<InterMineObject>> resIter =
        PostProcessUtil.findConnectingClasses(
            osw.getObjectStore(),
            model.getClassDescriptorByName(firstClsName).getType(),
            firstClassFieldName,
            model.getClassDescriptorByName(connectingClsName).getType(),
            connectingClassFieldName,
            model.getClassDescriptorByName(secondClsName).getType(),
            createInFirstClass);

    // results will be firstClass ; destClass (ordered by firstClass)
    osw.beginTransaction();
    int count = 0;

    while (resIter.hasNext()) {
      ResultsRow<InterMineObject> rr = resIter.next();

      InterMineObject thisSourceObject;
      InterMineObject thisDestObject;

      if (createInFirstClass) {
        thisDestObject = rr.get(0);
        thisSourceObject = rr.get(1);
      } else {
        thisDestObject = rr.get(1);
        thisSourceObject = rr.get(0);
      }

      if (!manyToMany
          && (lastDestObject == null || !thisDestObject.getId().equals(lastDestObject.getId()))) {

        if (lastDestObject != null) {
          try {
            InterMineObject tempObject = PostProcessUtil.cloneInterMineObject(lastDestObject);
            Set<InterMineObject> oldCollection =
                (Set<InterMineObject>) tempObject.getFieldValue(createFieldName);
            newCollection.addAll(oldCollection);
            tempObject.setFieldValue(createFieldName, newCollection);
            count += newCollection.size();
            osw.store(tempObject);
          } catch (IllegalAccessException e) {
            LOG.error(
                "Object with ID "
                    + thisDestObject.getId()
                    + " has no "
                    + createFieldName
                    + " field",
                e);
          }
        }

        newCollection = new HashSet<InterMineObject>();
      }

      if (manyToMany) {
        osw.addToCollection(
            thisDestObject.getId(), destCld.getType(), createFieldName, thisSourceObject.getId());
      } else {
        newCollection.add(thisSourceObject);
      }

      lastDestObject = thisDestObject;
    }

    if (!manyToMany && lastDestObject != null) {
      // clone so we don't change the ObjectStore cache
      InterMineObject tempObject = PostProcessUtil.cloneInterMineObject(lastDestObject);
      tempObject.setFieldValue(createFieldName, newCollection);
      count += newCollection.size();
      osw.store(tempObject);
    }
    LOG.info(
        "Finished: created "
            + count
            + " references in "
            + secondClsName
            + " to "
            + firstClsName
            + " via "
            + connectingClsName
            + " - took "
            + (System.currentTimeMillis() - startTime)
            + " ms.");
    osw.commitTransaction();

    // now ANALYSE tables relation to class that has been altered - may be rows added
    // to indirection tables
    if (osw instanceof ObjectStoreWriterInterMineImpl) {
      ClassDescriptor cld = model.getClassDescriptorByName(secondClsName);
      DatabaseUtil.analyse(((ObjectStoreWriterInterMineImpl) osw).getDatabase(), cld, false);
    }
  }