/**
  * Called by makePathQueryForCollection
  *
  * @param webConfig the webConfig
  * @param model the object model
  * @param object the InterMineObject
  * @param field the name of the field for the collection in the InterMineObject
  * @param sr the list of classes and subclasses
  * @return a PathQuery
  */
 private static PathQuery makePathQueryForCollectionForClass(
     WebConfig webConfig, Model model, InterMineObject object, String field, List<Class<?>> sr) {
   Class<?> commonClass = CollectionUtil.findCommonSuperclass(sr);
   String typeOfCollection = TypeUtil.unqualifiedName(DynamicUtil.getSimpleClassName(commonClass));
   String startClass = TypeUtil.unqualifiedName(DynamicUtil.getSimpleClassName(object.getClass()));
   String collectionPath = startClass + "." + field;
   PathQuery pathQuery =
       getQueryWithDefaultView(typeOfCollection, model, webConfig, collectionPath);
   pathQuery.addConstraint(Constraints.eq(startClass + ".id", object.getId().toString()));
   return pathQuery;
 }
  /**
   * 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);
  }
  /**
   * 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;
  }
Пример #5
0
 /**
  * Add a contains constraint to Query (q) built with the query class and attribute given in input
  *
  * @param query The query to add a reference to.
  * @param qc The class the reference belongs to.
  * @param attribute the name of the field of the class.
  * @param attributePath Another similarly named field - I wish it had been documented!
  * @return The query class of the attributePath.
  */
 protected QueryClass addReference(
     final Query query, final QueryClass qc, String attribute, String attributePath) {
   ConstraintSet cs = (ConstraintSet) query.getConstraint();
   QueryReference qr = null;
   String type = "";
   boolean useSubClass = false;
   if (WidgetConfigUtil.isPathContainingSubClass(os.getModel(), attribute)) {
     useSubClass = true;
     type = attribute.substring(attribute.indexOf("[") + 1, attribute.indexOf("]"));
     attribute = attribute.substring(0, attribute.indexOf("["));
   }
   QueryClass qcTmp = null;
   try {
     qr = new QueryObjectReference(qc, attribute);
     if (useSubClass) {
       try {
         qcTmp = new QueryClass(Class.forName(os.getModel().getPackageName() + "." + type));
       } catch (ClassNotFoundException cnfe) {
         LOG.error("The type " + type + " doesn't exist in the model.");
       }
     } else {
       qcTmp = new QueryClass(qr.getType());
     }
   } catch (IllegalArgumentException e) {
     // Not a reference - try collection instead
     qr = new QueryCollectionReference(qc, attribute);
     if (useSubClass) {
       try {
         qcTmp = new QueryClass(Class.forName(os.getModel().getPackageName() + "." + type));
       } catch (ClassNotFoundException cnfe) {
         LOG.error("The type " + type + " doesn't exist in the model.");
       }
     } else {
       qcTmp = new QueryClass(TypeUtil.getElementType(qc.getType(), attribute));
     }
   }
   QueryClass ret;
   if (!queryClassInQuery.containsKey(attributePath)) {
     ret = qcTmp;
     query.addFrom(ret);
     cs.addConstraint(new ContainsConstraint(qr, ConstraintOp.CONTAINS, ret));
     queryClassInQuery.put(attributePath, ret);
   } else {
     ret = queryClassInQuery.get(attributePath);
   }
   return ret;
 }
  /**
   * 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;
  }
Пример #7
0
  private void populateParentChildMap(Map<String, SOTerm> soTerms, String parentSOTermName) {
    String parentClsName = TypeUtil.javaiseClassName(parentSOTermName);
    ClassDescriptor cd = model.getClassDescriptorByName(parentClsName);
    if (cd == null) {
      LOG.error("couldn't find class in model:" + parentClsName);
      return;
    }
    Class<?> parentClass = cd.getType();

    // all collections for gene
    Map<String, Class<?>> childCollections = model.getCollectionsForClass(parentClass);

    Set<CollectionHolder> children = new HashSet<CollectionHolder>();

    // for each collection, see if this is a child class
    for (Map.Entry<String, Class<?>> entry : childCollections.entrySet()) {

      String childCollectionName = entry.getKey();
      String childClassName = entry.getValue().getSimpleName();

      // TODO use same method as in the oboparser
      // is this a child collection? e.g. transcript
      SOTerm soterm = soTerms.get(childClassName.toLowerCase());

      if (soterm == null) {
        // for testing
        continue;
      }

      // is gene in transcript parents collection
      for (OntologyTerm parent : soterm.getParents()) {
        if (parent.getName().equals(parentSOTermName)) {
          CollectionHolder h = new CollectionHolder(childClassName, childCollectionName);
          children.add(h);
        }
      }
    }
    if (children.size() > 0) {
      parentToChildren.put(parentSOTermName, children);
    }
  }
Пример #8
0
  /**
   * Fetches the equivalent object information for a whole batch of objects.
   *
   * @param batch the objects
   * @throws ObjectStoreException if something goes wrong
   */
  protected void getEquivalentsFor(List<ResultsRow<Object>> batch) throws ObjectStoreException {
    long time = System.currentTimeMillis();
    long time1 = time;
    boolean databaseEmpty = hints.databaseEmpty();
    if (savedDatabaseEmptyFetch == -1) {
      savedDatabaseEmptyFetch = System.currentTimeMillis() - time;
    }
    if (databaseEmpty) {
      savedDatabaseEmpty++;
      return;
    }
    // TODO: add all the objects that are referenced by these objects, and follow primary keys
    // We can make use of the ObjectStoreFastCollectionsForTranslatorImpl's ability to work this
    // all out for us.
    Set<InterMineObject> objects = new HashSet<InterMineObject>();
    for (ResultsRow<Object> row : batch) {
      for (Object object : row) {
        if (object instanceof InterMineObject) {
          InterMineObject imo = (InterMineObject) object;
          if (idMap.get(imo.getId()) == null) {
            objects.add(imo);
            for (String fieldName : TypeUtil.getFieldInfos(imo.getClass()).keySet()) {
              Object fieldValue;
              try {
                fieldValue = imo.getFieldProxy(fieldName);
              } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
              }
              if ((fieldValue instanceof InterMineObject)
                  && (!(fieldValue instanceof ProxyReference))) {
                objects.add((InterMineObject) fieldValue);
              } else if (fieldValue instanceof Collection<?>) {
                for (Object collectionElement : ((Collection<?>) fieldValue)) {
                  if ((collectionElement instanceof InterMineObject)
                      && (!(collectionElement instanceof ProxyReference))) {
                    objects.add((InterMineObject) collectionElement);
                  }
                }
              }
            }
          }
        }
      }
    }
    objects.removeAll(equivalents.keySet());
    // Now objects contains all the objects we need to fetch data for.
    Map<InterMineObject, Set<InterMineObject>> results =
        new HashMap<InterMineObject, Set<InterMineObject>>();
    for (InterMineObject object : objects) {
      results.put(object, Collections.synchronizedSet(new HashSet<InterMineObject>()));
    }

    Map<PrimaryKey, ClassDescriptor> pksToDo = new IdentityHashMap<PrimaryKey, ClassDescriptor>();
    Map<ClassDescriptor, List<InterMineObject>> cldToObjectsForCld =
        new IdentityHashMap<ClassDescriptor, List<InterMineObject>>();
    Map<Class<?>, List<InterMineObject>> categorised = CollectionUtil.groupByClass(objects, false);
    Map<ClassDescriptor, Boolean> cldsDone = new IdentityHashMap<ClassDescriptor, Boolean>();
    for (Class<?> c : categorised.keySet()) {
      Set<ClassDescriptor> classDescriptors = model.getClassDescriptorsForClass(c);
      for (ClassDescriptor cld : classDescriptors) {
        if (!cldsDone.containsKey(cld)) {
          cldsDone.put(cld, Boolean.TRUE);
          Set<PrimaryKey> keysForClass;
          if (source == null) {
            keysForClass = new HashSet<PrimaryKey>(PrimaryKeyUtil.getPrimaryKeys(cld).values());
          } else {
            keysForClass = DataLoaderHelper.getPrimaryKeys(cld, source, lookupOs);
          }
          if (!keysForClass.isEmpty()) {
            time = System.currentTimeMillis();
            boolean classNotExists = hints.classNotExists(cld.getType());
            String className = Util.getFriendlyName(cld.getType());
            if (!savedTimes.containsKey(className)) {
              savedTimes.put(className, new Long(System.currentTimeMillis() - time));
            }
            if (!classNotExists) {
              // LOG.error("Inspecting class " + className);
              List<InterMineObject> objectsForCld = new ArrayList<InterMineObject>();
              for (Map.Entry<Class<?>, List<InterMineObject>> category : categorised.entrySet()) {
                if (cld.getType().isAssignableFrom(category.getKey())) {
                  objectsForCld.addAll(category.getValue());
                }
              }
              cldToObjectsForCld.put(cld, objectsForCld);
              // So now we have a list of objects for this CLD.
              for (PrimaryKey pk : keysForClass) {
                // LOG.error("Adding pk " + cld.getName() + "." + pk.getName());
                pksToDo.put(pk, cld);
              }
            } else {
              // LOG.error("Empty class " + className);
            }
          }
        }
      }
    }
    doPks(pksToDo, results, cldToObjectsForCld, time1);
    batchQueried += results.size();
    equivalents.putAll(results);
  }