package org.nextprot.api.web.controller; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jsondoc.core.pojo.*; import org.jsondoc.core.util.JSONDocType; import org.jsondoc.springmvc.controller.JSONDocController; import org.jsondoc.springmvc.scanner.SpringJSONDocScanner; import org.nextprot.api.commons.constants.AnnotationCategory; import org.nextprot.api.commons.utils.StringUtils; import org.nextprot.api.core.service.ReleaseInfoService; import org.nextprot.api.core.service.export.format.EntryBlock; import org.nextprot.api.security.service.impl.NPSecurityContext; import org.nextprot.api.web.service.impl.ExportServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.PostConstruct; import java.util.*; import java.util.Map.Entry; @Controller public class JSONDocRoleController extends JSONDocController { private final static Log LOGGER = LogFactory.getLog(ExportServiceImpl.class); private JSONDoc jsonDoc; public JSONDocRoleController() { super(null, "", null); } @Autowired private Environment env; @Autowired private ReleaseInfoService releaseInfoService; private static ApiMethodDoc cloneMethodDoc(ApiMethodDoc met, String path, String description, boolean xmlSupported, boolean copyPathParam) { ApiMethodDoc m = new ApiMethodDoc(); m.setQueryparameters(met.getQueryparameters()); Set<String> produces = new HashSet<String>(); if(xmlSupported) produces.add(MediaType.APPLICATION_XML_VALUE); produces.add(MediaType.APPLICATION_JSON_VALUE); m.setProduces(produces); m.setConsumes(met.getConsumes()); Set<ApiParamDoc> set = new HashSet<ApiParamDoc>(); if(copyPathParam){ ApiParamDoc apd = met.getPathparameters().iterator().next(); // public ApiParamDoc(String name, String description, JSONDocType jsondocType, String required, String[] allowedvalues, String format, String defaultvalue) { set.add(new ApiParamDoc(apd.getName(), description, apd.getJsondocType(), apd.getRequired(), apd.getAllowedvalues(), apd.getFormat(), apd.getDefaultvalue())); m.setPathparameters(set); } m.setQueryparameters(met.getQueryparameters()); m.setPath(path); m.setVerb(ApiVerb.GET); return m; } @PostConstruct public void init() { List<String> packages = new ArrayList<String>(); packages.addAll(Arrays.asList(new String[] { "org.nextprot.api.commons", "org.nextprot.api.core", "org.nextprot.api.isoform", "org.nextprot.api.rdf", "org.nextprot.api.solr", "org.nextprot.api.user", "org.nextprot.api.web", "org.nextprot.api.blast" })); String version = releaseInfoService.findReleaseInfo().getApiRelease(); for (String profile : env.getActiveProfiles()) { if (profile.equalsIgnoreCase("build")) { packages.add("org.nextprot.api.build"); packages.add("org.nextprot.api.tasks"); packages.add("org.nextprot.api.etl"); break; } } jsonDoc = new SpringJSONDocScanner().getJSONDoc(version, "", packages); for (Set<ApiDoc> apiDocs : jsonDoc.getApis().values()) { { //////////////////////////// Appends documentation to Entry Controller //////////////////////////// ApiMethodDoc met = getMethodOfType(apiDocs, "Entry"); for (ApiDoc apiDoc : filterApiDocsFor(apiDocs, "Entry")) { // adding blocks for (EntryBlock block : EntryBlock.values()) { if (!block.equals(EntryBlock.FULL_ENTRY)) { String name = block.name().toLowerCase().replaceAll("_", "-"); String path = "/entry/{entry}/" + StringUtils.camelToKebabCase(name); apiDoc.getMethods().add(cloneMethodDoc(met, path, "", true, true)); } } // adding subparts for (AnnotationCategory model : AnnotationCategory.values()) { if(!model.equals(AnnotationCategory.VIRTUAL_ANNOTATION) && !model.isChildOf(AnnotationCategory.VIRTUAL_ANNOTATION)){ String name = model.getApiTypeName(); String path = "/entry/{entry}/" + StringUtils.camelToKebabCase(name); String description = "Exports only the " + name + " from an entry, located on the hierarchy: " + model.getHierarchy(); ApiMethodDoc methodDoc = cloneMethodDoc(met, path, description, true, true); methodDoc.getQueryparameters().add(buildOptionalQueryParameter("term-child-of", "An optional cv term filter: export annotations " + "which cv term matches the cv term parameter or one of its descendants")); methodDoc.getQueryparameters().add(buildOptionalQueryParameter("property-name", "An optional property name filter: export annotations " + "which contains this property name (see also property-value filter)")); methodDoc.getQueryparameters().add(buildOptionalQueryParameter("property-value", "An optional property value filter: export annotations " + "which contains the property name with this property value or accession (see also property-name filter)")); apiDoc.getMethods().add(methodDoc); } } } } } } private ApiParamDoc buildOptionalQueryParameter(String name, String desc) { return new ApiParamDoc(name, desc, new JSONDocType("string"), "false", new String[]{""}, "", ""); } private static ApiMethodDoc getMethodOfType(Collection<ApiDoc> apiDocs, String type) { // Adds terminology for (ApiDoc apiDoc : apiDocs) { if (apiDoc.getName().equals(type) && apiDoc.getMethods() != null && !apiDoc.getMethods().isEmpty()) { return apiDoc.getMethods().iterator().next(); } } return null; } private static Collection<ApiDoc> filterApiDocsFor(Collection<ApiDoc> apiDocs, String type) { List<ApiDoc> docs = new ArrayList<ApiDoc>(); for (ApiDoc apiDoc : apiDocs) { if (apiDoc.getName().equals(type)) { docs.add(apiDoc); } } return docs; } @RequestMapping(value = JSONDocController.JSONDOC_DEFAULT_PATH, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Override public @ResponseBody JSONDoc getApi() { Set<String> contextRoles = NPSecurityContext.getCurrentUserRoles(); LOGGER.info("Context roles"); for (String role : contextRoles) { LOGGER.info(role); } Map<String, Set<ApiDoc>> contextApis = new TreeMap<String, Set<ApiDoc>>(); for (Entry<String, Set<ApiDoc>> apis : jsonDoc.getApis().entrySet()) { // For each class annotation (ApiDoc) Set<ApiDoc> contextApiDocs = new TreeSet<ApiDoc>(); for (ApiDoc apiDoc : apis.getValue()) { // Check authorization at class level if (apiDoc.getAuth() == null || apiDoc.getAuth().equals("ROLE_ANONYMOUS") || (contextRoles != null && !Collections.disjoint(contextRoles, apiDoc.getAuth().getRoles()))) { // For each method annotation (ApiMethodDoc) Set<ApiMethodDoc> contextApiMethodDocs = new TreeSet<ApiMethodDoc>(); for (ApiMethodDoc apiMethodDoc : apiDoc.getMethods()) { //Add Iso Mapper Documentation if the user it is an ADMIN (the service doesn't need authentication to work though, it is just for documentation) if(apiDoc.getName().equalsIgnoreCase("Isoform Mapping")){ if((contextRoles != null) && (contextRoles.contains("ROLE_ADMIN"))){ contextApiMethodDocs.add(apiMethodDoc); } }// Check authorization at method level else if (apiMethodDoc.getAuth() == null || apiMethodDoc.getAuth().equals("ROLE_ANONYMOUS") || contextRoles != null && !Collections.disjoint(contextRoles, apiMethodDoc.getAuth().getRoles())) { contextApiMethodDocs.add(apiMethodDoc); } } if (!contextApiMethodDocs.isEmpty()) { // Create a copy of apiDoc but with methods according to // contextRoles ApiDoc tmpApiDoc = new ApiDoc(); tmpApiDoc.setDescription(apiDoc.getDescription()); tmpApiDoc.setName(apiDoc.getName()); tmpApiDoc.setGroup(apiDoc.getGroup()); tmpApiDoc.setMethods(contextApiMethodDocs); tmpApiDoc.setSupportedversions(apiDoc.getSupportedversions()); tmpApiDoc.setAuth(apiDoc.getAuth()); contextApiDocs.add(tmpApiDoc); } } } if (!contextApiDocs.isEmpty()) { contextApis.put(apis.getKey(), contextApiDocs); LOGGER.info("Add \"" + apis.getKey() + "\" Api to the current user"); } } JSONDoc contextJSONDoc = new JSONDoc(releaseInfoService.findReleaseInfo().getApiRelease(), ""); contextJSONDoc.setApis(contextApis); contextJSONDoc.setObjects(jsonDoc.getObjects()); contextJSONDoc.setFlows(jsonDoc.getFlows()); return contextJSONDoc; } }