private void addColumnsInternal(List<Path> columnPaths) { List<String> types = new ArrayList<String>(); int i = columns.size(); for (Path columnPath : columnPaths) { String type = TypeUtil.unqualifiedName(columnPath.getLastClassDescriptor().getName()); Class typeCls = columnPath.getLastClassDescriptor().getType(); String columnDescription = pathQuery.getGeneratedPathDescription(columnPath.toStringNoConstraints()); Column column; if (columnDescription.equals(columnPath.toStringNoConstraints())) { column = new Column(columnPath, i, typeCls); } else { column = new Column(columnPath, columnDescription, i, typeCls); } if (!types.contains(column.getColumnId())) { String fieldName = columnPath.getEndFieldDescriptor().getName(); boolean isKeyField = ClassKeyHelper.isKeyField(classKeys, type, fieldName); if (isKeyField) { column.setSelectable(true); types.add(column.getColumnId()); } } columns.add(column); i++; } }
/** * 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 the query specified in the request, shorn of all duplicate classes in the view. Note, it * is the users responsibility to ensure that there are only SequenceFeatures in the view. * * @return A query. */ protected PathQuery getQuery() { String xml = getRequiredParameter(XML_PARAM); PathQueryBuilder builder = getQueryBuilder(xml); PathQuery pq = builder.getQuery(); List<String> newView = new ArrayList<String>(); Set<ClassDescriptor> seenTypes = new HashSet<ClassDescriptor>(); for (String viewPath : pq.getView()) { Path p; try { p = new Path(pq.getModel(), viewPath); } catch (PathException e) { throw new BadRequestException("Query is invalid", e); } ClassDescriptor cd = p.getLastClassDescriptor(); if (!seenTypes.contains(cd)) { newView.add(viewPath); } seenTypes.add(cd); } if (!newView.equals(pq.getView())) { pq.clearView(); pq.addViews(newView); } return pq; }
@Override protected void checkPathQuery(PathQuery pq) throws Exception { if (pq.getView().size() > 1) { throw new BadRequestException("Queries to this service may only have one view."); } Path path = pq.makePath(pq.getView().get(0)); ClassDescriptor klazz = path.getLastClassDescriptor(); ClassDescriptor sf = im.getModel().getClassDescriptorByName("SequenceFeature"); ClassDescriptor protein = im.getModel().getClassDescriptorByName("Protein"); if (sf == klazz || protein == klazz || klazz.getAllSuperDescriptors().contains(sf) || klazz.getAllSuperDescriptors().contains(protein)) { return; // OK } else { throw new BadRequestException("Unsuitable type for export: " + klazz); } }
/** * From the columns of the PagedTable, return a List of the Paths that this exporter will use to * find sequences to export. The returned Paths are a subset of the prefixes of the column paths. * eg. if the columns are ("Gene.primaryIdentifier", "Gene.secondaryIdentifier", * "Gene.proteins.primaryIdentifier") return ("Gene", "Gene.proteins"). * * @param pt the PagedTable * @return a list of Paths that have sequence */ public static LinkedHashMap<Path, Integer> getExportClassPaths(PagedTable pt) { LinkedHashMap<Path, Integer> retPaths = new LinkedHashMap<Path, Integer>(); List<Column> columns = pt.getColumns(); for (int index = 0; index < columns.size(); index++) { Path prefix = columns.get(index).getPath().getPrefix(); ClassDescriptor prefixCD = prefix.getLastClassDescriptor(); Class<? extends FastPathObject> prefixClass = DynamicUtil.getSimpleClass(prefixCD.getType()); // Chromosome is treated as a sequence feature in the model if (SequenceFeature.class.isAssignableFrom(prefixClass) && !Chromosome.class.isAssignableFrom(prefixClass)) { if (!retPaths.keySet().contains(prefix)) { retPaths.put(prefix, index); } } } return retPaths; }
/** * Generate a list from a pathquery. * * @param pq The pathquery * @param name The name of the list * @param description The description of the list * @param tags A list of tags to add to the list * @param profile The profile the list should belong to * @throws ObjectStoreException If there is an issue running the queries that generate the list. * @throws PathException If the paths supplied are illegal. */ protected void generateListFromQuery( PathQuery pq, String name, String description, List<String> tags, Profile profile) throws ObjectStoreException, PathException { Query q = getQuery(pq, profile); String tempName = name + TEMP; String viewPathString = pq.getView().get(0); Path viewPath = pq.makePath(viewPathString); String type = viewPath.getLastClassDescriptor().getUnqualifiedName(); try { InterMineBag newList = profile.createBag(tempName, type, description, im.getClassKeys()); newList.addToBagFromQuery(q); try { im.getBagManager().addTagsToBag(tags, newList, profile); } catch (TagManager.TagNameException e) { throw new BadRequestException(e.getMessage()); } catch (TagManager.TagNamePermissionException e) { throw new ServiceForbiddenException(e.getMessage()); } profile.renameBag(tempName, name); output.addResultItem(Arrays.asList("" + newList.size())); } catch (CompletelyFalseException e) { output.addResultItem(Arrays.asList("0")); throw new BadRequestException("List not created - it would be of size 0"); } catch (UnknownBagTypeException e) { output.addResultItem(Arrays.asList("0")); throw new InternalErrorException(e.getMessage(), e); } catch (ClassKeysNotFoundException cke) { throw new BadRequestException("Bag has not class key set", cke); } finally { if (profile.getSavedBags().containsKey(tempName)) { profile.deleteBag(tempName); } } }
@Override protected void execute() throws Exception { String pathString = request.getParameter("path"); Map<String, Object> attributes = getHeaderAttributes(); output.setHeaderAttributes(attributes); if (isEmpty(pathString)) { throw new BadRequestException("No path provided"); } attributes.put("path", pathString); kvPairs.put("path", pathString); String typeConstraintStr = request.getParameter("typeConstraints"); Map<String, String> typeMap = new HashMap<String, String>(); if (!isEmpty(typeConstraintStr)) { logger.debug(typeConstraintStr); JSONObject typeJO = new JSONObject(typeConstraintStr); Iterator<String> it = (Iterator<String>) typeJO.keys(); while (it.hasNext()) { String name = it.next(); String subType = typeJO.getString(name); typeMap.put(name, subType); } } Model model = im.getModel(); Path path; try { if (typeMap.isEmpty()) { path = new Path(model, pathString); } else { path = new Path(model, pathString, typeMap); } } catch (PathException e) { throw new BadRequestException("Bad path given: " + pathString, e); } Query q = new Query(); attributes.put("class", path.getLastClassDescriptor().getUnqualifiedName()); attributes.put("field", path.getLastElement()); String type = ((AttributeDescriptor) path.getEndFieldDescriptor()).getType(); String[] parts = split(type, '.'); reverse(parts); attributes.put("type", parts[0]); QueryClass qc = new QueryClass(path.getPrefix().getEndType()); q.addFrom(qc); QueryField qf1 = new QueryField(qc, path.getLastElement()); q.addToSelect(qf1); QueryFunction qf = new QueryFunction(); q.addToSelect(qf); q.addToGroupBy(qf1); int count = im.getObjectStore().count(q, ObjectStore.SEQUENCE_IGNORE); if (formatIsCount()) { output.addResultItem(Arrays.asList(String.valueOf(count))); } else { attributes.put("count", count); Results results = im.getObjectStore().execute(q, DEFAULT_BATCH_SIZE, true, true, false); Iterator<Object> iter = results.iterator(); while (iter.hasNext()) { @SuppressWarnings("rawtypes") List row = (List) iter.next(); Map<String, Object> jsonMap = new HashMap<String, Object>(); jsonMap.put("value", row.get(0)); jsonMap.put("count", row.get(1)); JSONObject jo = new JSONObject(jsonMap); List<String> forOutput = new ArrayList<String>(); forOutput.add(jo.toString()); if (iter.hasNext()) { // Standard hack to ensure commas forOutput.add(""); } output.addResultItem(forOutput); } } }
// TODO javadoc to describe what this does private MultiRow<ResultsRow<MultiRowValue<ResultElement>>> translateRow( MultiRow<ResultsRow<MultiRowValue>> multiRow) { try { MultiRow<ResultsRow<MultiRowValue<ResultElement>>> retval = new MultiRow<ResultsRow<MultiRowValue<ResultElement>>>(); for (ResultsRow<MultiRowValue> initialList : multiRow) { ResultsRow<MultiRowValue<ResultElement>> rowCells = new ResultsRow<MultiRowValue<ResultElement>>(); for (Path columnPath : columnPaths) { String columnName = columnPath.toStringNoConstraints(); Integer columnIndexInteger = pathToIndex.get(columnName); String parentColumnName = columnPath.getPrefix().toStringNoConstraints(); if (columnIndexInteger == null) { columnIndexInteger = pathToIndex.get(parentColumnName); } if (columnIndexInteger == null) { throw new NullPointerException( "Path: \"" + columnName + "\", pathToIndex: \"" + pathToIndex + "\", prefix: \"" + parentColumnName + "\", query: \"" + PathQueryBinding.marshal( pathQuery, "", pathQuery.getModel().getName(), PathQuery.USERPROFILE_VERSION) + "\""); } int columnIndex = columnIndexInteger.intValue(); MultiRowValue origO = initialList.get(columnIndex); FastPathObject o = (FastPathObject) (origO == null ? null : origO.getValue()); int rowspan = -1; if (origO == null) { rowspan = 1; } else if (origO instanceof MultiRowFirstValue) { rowspan = ((MultiRowFirstValue) origO).getRowspan(); } String lastCd; if (columnPath.endIsAttribute()) { lastCd = columnPath.getLastClassDescriptor().getName(); } else { // special case for columns that contain objects eg. Gene.chromosomeLocation lastCd = columnPath.getLastClassDescriptor().getName(); } String type = TypeUtil.unqualifiedName(lastCd); Path path; String fieldName = null; try { if (columnPath.endIsAttribute()) { fieldName = columnName.substring(columnName.lastIndexOf(".") + 1); path = new Path(model, type + '.' + fieldName); } else { // special case for columns that contain objects path = new Path(model, type); } } catch (PathException e) { // Should never happen if the field name is valid throw new Error("There must be a bug", e); } // Three cases: // 1) attribute has a value so create a result element // 2) we have an object but attribute is null -> create a ResultElement with // value null // 3) the object is null (outer join) so add null value rowCells // Object fieldValue; // try { // fieldValue = (o == null ? null : PathUtil.resolvePath(path, o)); // } catch (PathException e) { // throw new IllegalArgumentException("Path: \"" + columnName // + "\", pathToIndex: \"" + pathToIndex + "\", prefix: \"" // + parentColumnName + "\", query: \"" // + PathQueryBinding.marshal(pathQuery, "", // pathQuery.getModel() // .getName(), PathQuery.USERPROFILE_VERSION) // + "\", columnIndex: \"" + columnIndex + "\", // initialList: \"" // + initialList + "\"", e); // } if (o != null) { String fieldCDName = path.getLastClassDescriptor().getName(); String unqualifiedFieldCD = TypeUtil.unqualifiedName(fieldCDName); boolean isKeyField; if (fieldName == null) { // special case for columns that contain objects isKeyField = false; } else { isKeyField = ClassKeyHelper.isKeyField(classKeys, unqualifiedFieldCD, fieldName); } ResultElement resultElement = new ResultElement(o, path, isKeyField); // link to report page by default, unless it says otherwise in config if (redirector != null) { try { String linkRedirect = redirector.generateLink(im, (InterMineObject) o); if (linkRedirect != null) { resultElement.setLinkRedirect(linkRedirect); } } catch (ClassCastException e) { // Simple objects cannot be consumed by redirectors. } } if (rowspan >= 0) { rowCells.add(new MultiRowFirstValue(resultElement, rowspan)); } else { rowCells.add(null); } } else { if (rowspan >= 0) { rowCells.add(new MultiRowFirstValue(null, rowspan)); } else { rowCells.add(null); } } } retval.add(rowCells); } return retval; } catch (IndexOutOfBoundsException e) { throw new RuntimeException(e); } }