/*
* Copyright: (c) 2004-2011 Mayo Foundation for Medical Education and
* Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
* triple-shield Mayo logo are trademarks and service marks of MFMER.
*
* Except as contained in the copyright notice above, or as used to identify
* MFMER as the author of this software, the trade names, trademarks, service
* marks, or product names of the copyright holder shall not be used in
* advertising, promotion or otherwise in connection with this software without
* prior written authorization of the copyright holder.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.mayo.cts2.framework.webapp.rest.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import edu.mayo.cts2.framework.model.codesystemversion.CodeSystemVersionCatalogEntry;
import edu.mayo.cts2.framework.model.codesystemversion.CodeSystemVersionCatalogEntryDirectory;
import edu.mayo.cts2.framework.model.codesystemversion.CodeSystemVersionCatalogEntryList;
import edu.mayo.cts2.framework.model.codesystemversion.CodeSystemVersionCatalogEntryMsg;
import edu.mayo.cts2.framework.model.command.Page;
import edu.mayo.cts2.framework.model.command.ResolvedReadContext;
import edu.mayo.cts2.framework.model.core.Message;
import edu.mayo.cts2.framework.model.core.VersionTagReference;
import edu.mayo.cts2.framework.model.directory.DirectoryResult;
import edu.mayo.cts2.framework.model.exception.ExceptionFactory;
import edu.mayo.cts2.framework.model.service.core.NameOrURI;
import edu.mayo.cts2.framework.model.service.core.Query;
import edu.mayo.cts2.framework.model.service.exception.UnknownCodeSystemVersion;
import edu.mayo.cts2.framework.model.util.ModelUtils;
import edu.mayo.cts2.framework.service.command.restriction.CodeSystemVersionQueryServiceRestrictions;
import edu.mayo.cts2.framework.service.command.restriction.CodeSystemVersionQueryServiceRestrictions.EntityRestriction;
import edu.mayo.cts2.framework.service.profile.codesystemversion.CodeSystemVersionHistoryService;
import edu.mayo.cts2.framework.service.profile.codesystemversion.CodeSystemVersionMaintenanceService;
import edu.mayo.cts2.framework.service.profile.codesystemversion.CodeSystemVersionQuery;
import edu.mayo.cts2.framework.service.profile.codesystemversion.CodeSystemVersionQueryService;
import edu.mayo.cts2.framework.service.profile.codesystemversion.CodeSystemVersionReadService;
import edu.mayo.cts2.framework.webapp.naming.CodeSystemVersionNameResolver;
import edu.mayo.cts2.framework.webapp.rest.command.QueryControl;
import edu.mayo.cts2.framework.webapp.rest.command.RestFilter;
import edu.mayo.cts2.framework.webapp.rest.command.RestReadContext;
import edu.mayo.cts2.framework.webapp.rest.query.CodeSystemVersionQueryBuilder;
import edu.mayo.cts2.framework.webapp.rest.util.ControllerUtils;
/**
* The Class CodeSystemVersionController.
*
* @author <a href="mailto:kevin.peterson@mayo.edu">Kevin Peterson</a>
*/
@Controller
public class CodeSystemVersionController extends AbstractMessageWrappingController {
@Cts2Service
private CodeSystemVersionReadService codeSystemVersionReadService;
@Cts2Service
private CodeSystemVersionQueryService codeSystemVersionQueryService;
@Cts2Service
private CodeSystemVersionMaintenanceService codeSystemVersionMaintenanceService;
@Cts2Service
private CodeSystemVersionHistoryService codeSystemVersionHistoryService;
@Resource
private CodeSystemVersionNameResolver codeSystemVersionNameResolver;
private UrlTemplateBinder<CodeSystemVersionCatalogEntry> URL_BINDER = new
UrlTemplateBinder<CodeSystemVersionCatalogEntry>(){
@Override
public Map<String,String> getPathValues(CodeSystemVersionCatalogEntry resource) {
Assert.notNull(resource.getVersionOf(),"'versionOf' is required.");
Map<String,String> returnMap = new HashMap<String,String>();
String codeSystemName = resource.getVersionOf().getContent();
String codeSystemVersionName = resource.getCodeSystemVersionName();
returnMap.put(VAR_CODESYSTEMID, codeSystemName);
String versionId = resource.getOfficialResourceVersionId();
String id = versionId != null ? versionId : codeSystemVersionName;
returnMap.put(VAR_CODESYSTEMVERSIONID, id);
return returnMap;
}
};
private final static MessageFactory<CodeSystemVersionCatalogEntry> MESSAGE_FACTORY =
new MessageFactory<CodeSystemVersionCatalogEntry>() {
@Override
public Message createMessage(CodeSystemVersionCatalogEntry resource) {
CodeSystemVersionCatalogEntryMsg msg = new CodeSystemVersionCatalogEntryMsg();
msg.setCodeSystemVersionCatalogEntry(resource);
return msg;
}
};
@RequestMapping(value=PATH_CODESYSTEMVERSION_CHANGEHISTORY, method=RequestMethod.GET)
public CodeSystemVersionCatalogEntryList getChangeHistory(
HttpServletRequest httpServletRequest,
@PathVariable(VAR_CODESYSTEMVERSIONID) String codeSystemVersionName,
@RequestParam(required=false) Date PARAM_FROMDATE,
@RequestParam(required=false) Date PARAM_TODATE,
Page page) {
DirectoryResult<CodeSystemVersionCatalogEntry> result =
this.codeSystemVersionHistoryService.getChangeHistory(
ModelUtils.nameOrUriFromName(codeSystemVersionName),
PARAM_FROMDATE,
PARAM_TODATE);
return this.populateDirectory(
result,
page,
httpServletRequest,
CodeSystemVersionCatalogEntryList.class);
}
@RequestMapping(value=PATH_CODESYSTEMVERSION_EARLIESTCHANGE, method=RequestMethod.GET)
public CodeSystemVersionCatalogEntryMsg getEarliesChange(
HttpServletRequest httpServletRequest,
@PathVariable(VAR_CODESYSTEMVERSIONID) String codeSystemVersionName) {
CodeSystemVersionCatalogEntry result =
this.codeSystemVersionHistoryService.getEarliestChangeFor(ModelUtils.nameOrUriFromName(codeSystemVersionName));
CodeSystemVersionCatalogEntryMsg msg = new CodeSystemVersionCatalogEntryMsg();
msg.setCodeSystemVersionCatalogEntry(result);
return this.wrapMessage(msg, httpServletRequest);
}
@RequestMapping(value=PATH_CODESYSTEMVERSION_LATESTCHANGE, method=RequestMethod.GET)
public CodeSystemVersionCatalogEntryMsg getLastChange(
HttpServletRequest httpServletRequest,
@PathVariable(VAR_CODESYSTEMVERSIONID) String codeSystemName) {
CodeSystemVersionCatalogEntry result =
this.codeSystemVersionHistoryService.getLastChangeFor(ModelUtils.nameOrUriFromName(codeSystemName));
CodeSystemVersionCatalogEntryMsg msg = new CodeSystemVersionCatalogEntryMsg();
msg.setCodeSystemVersionCatalogEntry(result);
return this.wrapMessage(msg, httpServletRequest);
}
/**
* Creates the code system version.
*
* @param changeseturi the changeseturi
* @param codeSystemVersion the code system version
* @param codeSystemName the code system name
* @param codeSystemVersionName the code system version name
*/
@RequestMapping(value=PATH_CODESYSTEMVERSION, method=RequestMethod.POST)
public Object createCodeSystemVersion(
HttpServletResponse httpServletResponse,
@RequestParam(value=PARAM_CHANGESETCONTEXT, required=false) String changeseturi,
@RequestBody CodeSystemVersionCatalogEntry codeSystemVersion) {
return this.doCreate(
httpServletResponse,
codeSystemVersion,
changeseturi,
PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID,
URL_BINDER,
this.codeSystemVersionMaintenanceService);
}
@RequestMapping(value=PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID, method=RequestMethod.PUT)
public Object updateCodeSystemVersion(
HttpServletResponse httpServletResponse,
@RequestParam(value=PARAM_CHANGESETCONTEXT, required=false) String changeseturi,
@RequestBody CodeSystemVersionCatalogEntry codeSystemVersion,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@PathVariable(VAR_CODESYSTEMVERSIONID) String codeSystemVersionName) {
return this.doUpdate(
httpServletResponse,
codeSystemVersion,
changeseturi,
ModelUtils.nameOrUriFromName(codeSystemVersionName),
this.codeSystemVersionMaintenanceService);
}
@RequestMapping(value=PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID, method=RequestMethod.DELETE)
public Object deleteCodeSystemVersion(
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@PathVariable(VAR_CODESYSTEMVERSIONID) String versionId,
@RequestParam(PARAM_CHANGESETCONTEXT) String changeseturi) {
ResolvedReadContext readContext = new ResolvedReadContext();
readContext.setChangeSetContextUri(changeseturi);
String codeSystemVersionName =
codeSystemVersionNameResolver.getCodeSystemVersionNameFromVersionId(
this.codeSystemVersionReadService,
codeSystemName,
versionId,
readContext);
NameOrURI identifier =
ModelUtils.nameOrUriFromName(
codeSystemVersionName);
return this.doDelete(
httpServletResponse,
identifier,
changeseturi,
this.codeSystemVersionMaintenanceService);
}
/**
* Gets the code system versions of code system.
*
* @param httpServletRequest the http servlet request
* @param restrictions the restrictions
* @param resolvedFilter the filter
* @param page the page
* @param codeSystemId the code system id
* @return the code system versions of code system
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSIONS_OF_CODESYSTEM}, method=RequestMethod.GET)
public Object getCodeSystemVersionsOfCodeSystem(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
CodeSystemVersionQueryServiceRestrictions restrictions,
RestFilter resolvedFilter,
Page page,
boolean list,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName) {
restrictions.setCodeSystem(ModelUtils.nameOrUriFromName(codeSystemName));
return this.getCodeSystemVersions(
httpServletRequest,
restReadContext,
queryControl,
restrictions,
resolvedFilter,
page,
list);
}
/**
* Does code system version exist.
*
* @param httpServletResponse the http servlet response
* @param codeSystemName the code system name
* @param codeSystemVersionName the code system version name
*/
@RequestMapping(value=PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID, method=RequestMethod.HEAD)
public void doesCodeSystemVersionExist(
HttpServletResponse httpServletResponse,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@PathVariable(VAR_CODESYSTEMVERSIONID) String codeSystemVersionName) {
this.doExists(
httpServletResponse,
this.codeSystemVersionReadService,
UnknownCodeSystemVersion.class,
ModelUtils.nameOrUriFromName(codeSystemVersionName));
}
/**
* Gets the code system versions of code system count.
*
* @param httpServletResponse the http servlet response
* @param restrictions the restrictions
* @param resolvedFilter the filter
* @param codeSystemId the code system id
* @return the code system versions of code system count
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSIONS_OF_CODESYSTEM}, method=RequestMethod.HEAD)
public void getCodeSystemVersionsOfCodeSystemCount(
HttpServletResponse httpServletResponse,
RestReadContext restReadContext,
CodeSystemVersionQueryServiceRestrictions restrictions,
RestFilter resolvedFilter,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName) {
restrictions.setCodeSystem(ModelUtils.nameOrUriFromName(codeSystemName));
this.getCodeSystemVersionsCount(
httpServletResponse,
restReadContext,
restrictions,
resolvedFilter);
}
@RequestMapping(value={
PATH_CODESYSTEMVERSIONS}, method=RequestMethod.POST)
public Object getCodeSystemVersions(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@RequestBody Query query,
CodeSystemVersionQueryServiceRestrictions restrictions,
RestFilter restFilter,
Page page,
boolean list) {
CodeSystemVersionQueryBuilder builder = this.getNewResourceQueryBuilder();
CodeSystemVersionQuery resourceQuery = builder.
addQuery(query).
addRestFilter(restFilter).
addRestrictions(restrictions).
addRestReadContext(restReadContext).
build();
return this.doQuery(
httpServletRequest,
list,
this.codeSystemVersionQueryService,
resourceQuery,
page,
queryControl,
CodeSystemVersionCatalogEntryDirectory.class,
CodeSystemVersionCatalogEntryList.class);
}
/**
* Gets the code system versions.
*
* @param httpServletRequest the http servlet request
* @param restrictions the restrictions
* @param resolvedFilter the filter
* @param page the page
* @return the code system versions
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSIONS}, method=RequestMethod.GET)
public Object getCodeSystemVersions(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
CodeSystemVersionQueryServiceRestrictions restrictions,
RestFilter resolvedFilter,
Page page,
boolean list) {
return this.getCodeSystemVersions(
httpServletRequest,
restReadContext,
queryControl,
null,
restrictions,
resolvedFilter,
page,
list);
}
/**
* Gets the code system versions count.
*
* @param httpServletResponse the http servlet response
* @param restrictions the restrictions
* @param resolvedFilter the filter
* @return the code system versions count
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSIONS}, method=RequestMethod.HEAD)
public void getCodeSystemVersionsCount(
HttpServletResponse httpServletResponse,
RestReadContext restReadContext,
CodeSystemVersionQueryServiceRestrictions restrictions,
RestFilter restFilter) {
CodeSystemVersionQuery resourceQuery = this.getNewResourceQueryBuilder().
addRestFilter(restFilter).
addRestrictions(restrictions).
addRestReadContext(restReadContext).
build();
int count =
this.codeSystemVersionQueryService.
count(resourceQuery);
this.setCount(count, httpServletResponse);
}
@RequestMapping(value={
PATH_CODESYSTEMBYID + "/" + ENTITY + "/" + ALL_WILDCARD,
PATH_CODESYSTEMBYID + "/" + ENTITIES
},
method=RequestMethod.GET)
public ModelAndView getCodeSystemVersionOfCodeSystemByTagRedirect(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@RequestParam(value=PARAM_TAG, defaultValue=DEFAULT_TAG) String tag,
@RequestParam(value="redirect", defaultValue=DEFAULT_REDIRECT) boolean redirect) {
//TODO: Accept tag URIs here
VersionTagReference tagReference = new VersionTagReference(tag);
String codeSystemVersionName =
this.codeSystemVersionNameResolver.
getVersionNameFromTag(
codeSystemVersionReadService,
ModelUtils.nameOrUriFromName(codeSystemName),
tagReference,
this.resolveRestReadContext(restReadContext));
String contextPath = this.getUrlPathHelper().getContextPath(httpServletRequest);
String requestUri = StringUtils.removeStart(this.getUrlPathHelper().getRequestUri(httpServletRequest),contextPath);
requestUri = StringUtils.removeStart(requestUri, "/");
requestUri = StringUtils.replaceOnce(
requestUri,
CODESYSTEM + "/" + codeSystemName + "/",
CODESYSTEM + "/" + codeSystemName + "/" +
VERSION + "/" + codeSystemVersionName + "/");
if(redirect){
@SuppressWarnings("unchecked")
Map<String,Object> parameters =
new HashMap<String,Object>(httpServletRequest.getParameterMap());
parameters.remove(PARAM_REDIRECT);
return new ModelAndView(
"redirect:"+ "/" + requestUri + this.mapToQueryString(parameters));
} else {
return new ModelAndView(
"forward:"+ "/" + requestUri );
}
}
@RequestMapping(value=PATH_CODESYSTEMVERSIONBYTAG,
method=RequestMethod.GET)
public Object getCodeSystemVersionOfCodeSystemByTag(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@RequestParam(value=PARAM_TAG, defaultValue=DEFAULT_TAG) String tag) {
//TODO: Accept tag URIs here
VersionTagReference tagReference = new VersionTagReference(tag);
CodeSystemVersionCatalogEntry codeSystemVersion = this.codeSystemVersionReadService.readByTag(
ModelUtils.nameOrUriFromName(codeSystemName),
tagReference,
this.resolveRestReadContext(restReadContext));
if(codeSystemVersion == null){
throw ExceptionFactory.createUnknownResourceException(codeSystemName, UnknownCodeSystemVersion.class);
}
return this.buildResponse(httpServletRequest,
MESSAGE_FACTORY.createMessage(codeSystemVersion));
}
/**
* Gets the code system version by name.
*
* @param httpServletRequest the http servlet request
* @param codeSystemName the code system name
* @param codeSystemVersionName the code system version name
* @return the code system version by name
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID
},
method=RequestMethod.GET)
public Object getCodeSystemVersionByNameOrOfficialResourceVersionId(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@PathVariable(VAR_CODESYSTEMID) String codeSystemName,
@PathVariable(VAR_CODESYSTEMVERSIONID) String versionId) {
ResolvedReadContext readContext = this.resolveRestReadContext(restReadContext);
String codeSystemVersionName =
codeSystemVersionNameResolver.getCodeSystemVersionNameFromVersionId(
this.codeSystemVersionReadService,
codeSystemName,
versionId,
readContext);
Object msg = this.doRead(
httpServletRequest,
MESSAGE_FACTORY,
this.codeSystemVersionReadService,
restReadContext,
UnknownCodeSystemVersion.class,
ModelUtils.nameOrUriFromName(codeSystemVersionName));
return msg;
}
/**
* Gets the code system version by name.
*
* @param httpServletRequest the http servlet request
* @param codeSystemVersionName the code system version name
* @return the code system version by name
*/
@RequestMapping(value={
PATH_CODESYSTEMVERSIONBYID
},
method=RequestMethod.GET)
public Object getCodeSystemVersionByNameOrOfficialResourceVersionId(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@PathVariable(VAR_CODESYSTEMVERSIONID) String versionId) {
Object msg = this.doRead(
httpServletRequest,
MESSAGE_FACTORY,
this.codeSystemVersionReadService,
restReadContext,
UnknownCodeSystemVersion.class,
ModelUtils.nameOrUriFromName(versionId));
return msg;
}
@RequestMapping(value=PATH_CODESYSTEMVERSIONBYURI, method=RequestMethod.GET)
public ModelAndView getCodeSystemVersionByUri(
HttpServletRequest httpServletRequest,
RestReadContext restReadContext,
QueryControl queryControl,
@RequestParam(PARAM_URI) String uri,
@RequestParam(value="redirect", defaultValue=DEFAULT_REDIRECT) boolean redirect) {
return this.doReadByUri(
httpServletRequest,
MESSAGE_FACTORY,
PATH_CODESYSTEMVERSIONBYURI,
PATH_CODESYSTEMVERSION_OF_CODESYSTEM_BYID,
URL_BINDER,
this.codeSystemVersionReadService,
restReadContext,
UnknownCodeSystemVersion.class,
ModelUtils.nameOrUriFromUri(uri),
redirect);
}
@InitBinder
public void initCodeSystemRestrictionBinder(
WebDataBinder binder,
@RequestParam(value=PARAM_ENTITY, required=false) List<String> entity,
@RequestParam(value=PARAM_CODESYSTEM, required=false) String codesystem) {
if(binder.getTarget() instanceof CodeSystemVersionQueryServiceRestrictions){
CodeSystemVersionQueryServiceRestrictions restrictions =
(CodeSystemVersionQueryServiceRestrictions) binder.getTarget();
if(StringUtils.isNotEmpty(codesystem)){
restrictions.setCodeSystem(ModelUtils.nameOrUriFromEither(codesystem));
}
if(CollectionUtils.isNotEmpty(entity)){
restrictions.setEntityRestriction(new EntityRestriction());
restrictions.getEntityRestriction().setEntities(
ControllerUtils.idsToEntityNameOrUriSet(entity));
}
}
}
private CodeSystemVersionQueryBuilder getNewResourceQueryBuilder(){
return new CodeSystemVersionQueryBuilder(
this.codeSystemVersionQueryService,
this.getFilterResolver(),
this.getReadContextResolver());
}
public CodeSystemVersionReadService getCodeSystemVersionReadService() {
return codeSystemVersionReadService;
}
public void setCodeSystemVersionReadService(
CodeSystemVersionReadService codeSystemVersionReadService) {
this.codeSystemVersionReadService = codeSystemVersionReadService;
}
public CodeSystemVersionQueryService getCodeSystemVersionQueryService() {
return codeSystemVersionQueryService;
}
public void setCodeSystemVersionQueryService(
CodeSystemVersionQueryService codeSystemVersionQueryService) {
this.codeSystemVersionQueryService = codeSystemVersionQueryService;
}
public CodeSystemVersionMaintenanceService getCodeSystemVersionMaintenanceService() {
return codeSystemVersionMaintenanceService;
}
public void setCodeSystemVersionMaintenanceService(
CodeSystemVersionMaintenanceService codeSystemVersionMaintenanceService) {
this.codeSystemVersionMaintenanceService = codeSystemVersionMaintenanceService;
}
public CodeSystemVersionHistoryService getCodeSystemVersionHistoryService() {
return codeSystemVersionHistoryService;
}
public void setCodeSystemVersionHistoryService(
CodeSystemVersionHistoryService codeSystemVersionHistoryService) {
this.codeSystemVersionHistoryService = codeSystemVersionHistoryService;
}
public CodeSystemVersionNameResolver getCodeSystemVersionNameResolver() {
return codeSystemVersionNameResolver;
}
public void setCodeSystemVersionNameResolver(
CodeSystemVersionNameResolver codeSystemVersionNameResolver) {
this.codeSystemVersionNameResolver = codeSystemVersionNameResolver;
}
}