/** {@inheritDoc} */ @Override public ActionForward execute( @SuppressWarnings("unused") ActionMapping mapping, @SuppressWarnings("unused") ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession session = request.getSession(); final InterMineAPI im = SessionMethods.getInterMineAPI(session); ObjectStore os = im.getObjectStore(); WebConfig webConfig = SessionMethods.getWebConfig(request); Integer objectId = new Integer(request.getParameter("object")); String fieldName = request.getParameter("field"); String fileType = request.getParameter("type"); InterMineObject object = os.getObjectById(objectId); FieldExporter fieldExporter = null; Set classes = DynamicUtil.decomposeClass(object.getClass()); Iterator classIter = classes.iterator(); while (classIter.hasNext()) { Class c = (Class) classIter.next(); Type thisTypeConfig = webConfig.getTypes().get(c.getName()); FieldConfig fc = thisTypeConfig.getFieldConfigMap().get(fieldName); if (fc != null) { String fieldExporterClassName = fc.getFieldExporter(); if (fieldExporterClassName != null) { fieldExporter = (FieldExporter) Class.forName(fieldExporterClassName).newInstance(); break; } } } if (fieldExporter == null) { Object fieldValue = object.getFieldValue(fieldName); if (fileType == null || fileType.length() == 0) { response.setContentType("text/plain; charset=UTF-8"); response.setHeader("Content-Disposition ", "inline; filename=" + fieldName + ".txt"); } else { response.setContentType("text/" + fileType); response.setHeader( "Content-Disposition ", "inline; filename=" + fieldName + "." + fileType); } PrintStream out = new PrintStream(response.getOutputStream()); if (fieldValue instanceof ClobAccess) { ((ClobAccess) fieldValue).drainToPrintStream(out); } else { out.print(fieldValue); } out.flush(); } else { fieldExporter.exportField(object, fieldName, os, response); } return null; }
// In a future Java8 world, this should produce a Stream<FieldConfig>, to avoid the double loop. private static Collection<FieldConfig> resultConfigs(WebConfig webConfig, ClassDescriptor cld) { final List<FieldConfig> fieldConfigs = getClassFieldConfigs(webConfig, cld); Iterator<FieldConfig> it = fieldConfigs.iterator(); while (it.hasNext()) { FieldConfig f = it.next(); if (!f.getShowInResults()) { it.remove(); } } return fieldConfigs; }
/** * 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; }
private static List<String> getSubview(WebConfig webConfig, Model m, Path path) throws PathException { List<String> subview = new ArrayList<String>(); String basePath = path.toStringNoConstraints() + "."; List<FieldConfig> subconfs = getClassFieldConfigs(webConfig, path.getEndClassDescriptor()); for (FieldConfig fc : subconfs) { String pathString = basePath + fc.getFieldExpr(); Path pathToAdd = new Path(m, pathString); if (pathToAdd.endIsAttribute() && (fc.getDisplayer() == null && fc.getShowInSummary())) { subview.add(pathToAdd.getNoConstraintsString()); } } return subview; }
private Map<String, Object> getObjectDetails(InterMineObject imo) { WebConfig webConfig = InterMineContext.getWebConfig(); Model m = im.getModel(); Map<String, Object> objectDetails = new HashMap<String, Object>(); String className = DynamicUtil.getSimpleClassName(imo.getClass()); ClassDescriptor cd = m.getClassDescriptorByName(className); for (FieldConfig fc : FieldConfigHelper.getClassFieldConfigs(webConfig, cd)) { try { Path p = new Path(m, cd.getUnqualifiedName() + "." + fc.getFieldExpr()); if (p.endIsAttribute() && fc.getShowInSummary()) { objectDetails.put( p.getNoConstraintsString().replaceAll("^[^.]*\\.", ""), PathUtil.resolvePath(p, imo)); } } catch (PathException e) { LOG.error(e); } } return objectDetails; }
/** * 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; }
/** {@inheritDoc} */ @Override public ActionForward execute( ComponentContext context, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession session = request.getSession(); final InterMineAPI im = SessionMethods.getInterMineAPI(session); InterMineBag imBag = (InterMineBag) request.getAttribute("bag"); WebConfig webConfig = SessionMethods.getWebConfig(request); Model model = im.getModel(); TemplateManager templateManager = im.getTemplateManager(); Map<Class, ApiTemplate> conversionTypesMap = TypeConverter.getConversionTemplates( templateManager.getConversionTemplates(), TypeUtil.instantiate(model.getPackageName() + "." + imBag.getType())); ArrayList<String> conversionTypes = new ArrayList<String>(); Map<Type, Boolean> fastaMap = new HashMap<Type, Boolean>(); for (Class<?> clazz : conversionTypesMap.keySet()) { conversionTypes.add(TypeUtil.unqualifiedName(clazz.getName())); Type type = webConfig.getTypes().get(clazz.getName()); FieldConfig fieldConfig = type.getFieldConfigMap().get("length"); if (fieldConfig != null && fieldConfig.getDisplayer() != null) { fastaMap.put(type, Boolean.TRUE); } else { fastaMap.put(type, Boolean.FALSE); } } // Use custom converters BagQueryConfig bagQueryConfig = im.getBagQueryConfig(); String bagType = imBag.getType(); Set<AdditionalConverter> additionalConverters = bagQueryConfig.getAdditionalConverters(bagType); request.setAttribute("customConverters", additionalConverters); request.setAttribute("conversionTypes", conversionTypes); request.setAttribute("fastaMap", fastaMap); return null; }
/** * Get the view as configured in the webconfig. Guarantees to return a non-empty non-null list. * * @param type The type we are trying to get a view for. * @param model The data model * @param webConfig The web-configuration. * @param fieldConfigs * @return The list of paths that we can use to construct a query. * @throws UnconfiguredException if the class has not configured view. */ private static List<String> getConfiguredView(ClassDescriptor cld, WebConfig webConfig) throws UnconfiguredException { Collection<String> view = new LinkedHashSet<String>(); // Preserve order and uniqueness. Model m = cld.getModel(); for (FieldConfig fieldConfig : resultConfigs(webConfig, cld)) { try { Path p = new Path(m, cld.getUnqualifiedName() + "." + fieldConfig.getFieldExpr()); // add subpaths of references and roots, attrs themselves, ignore collections. if (p.isRootPath() || p.endIsReference()) { view.addAll(getSubview(webConfig, m, p)); } else if (p.endIsAttribute()) { view.add(p.getNoConstraintsString()); } } catch (PathException e) { LOG.error("Invalid path configured in webconfig for class: " + cld); } } if (view.isEmpty()) { throw new UnconfiguredException(); } return new ArrayList<String>(view); }
/** * 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; }