Prevent a crash in testpage overlay when deleting a resource

This commit is contained in:
James Agnew 2018-02-23 15:24:20 -05:00
parent e241b31905
commit 3b2930f8e9
6 changed files with 109 additions and 89 deletions

View File

@ -82,10 +82,11 @@ import java.util.Map.Entry;
import static org.apache.commons.lang3.StringUtils.*;
@SuppressWarnings("WeakerAccess")
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
public static final long INDEX_STATUS_INDEXED = Long.valueOf(1L);
public static final long INDEX_STATUS_INDEXING_FAILED = Long.valueOf(2L);
public static final long INDEX_STATUS_INDEXED = 1L;
public static final long INDEX_STATUS_INDEXING_FAILED = 2L;
public static final String NS_JPA_PROFILE = "https://github.com/jamesagnew/hapi-fhir/ns/jpa/profile";
public static final String OO_SEVERITY_ERROR = "error";
public static final String OO_SEVERITY_INFO = "information";
@ -379,7 +380,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} else {
ResourceLink resourceLink = new ResourceLink(nextPathAndRef.getPath(), theEntity, nextId, theUpdateTime);
if (theLinks.add(resourceLink)) {
ourLog.info("Indexing remote resource reference URL: {}", nextId);
ourLog.debug("Indexing remote resource reference URL: {}", nextId);
}
continue;
}
@ -417,7 +418,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
IBaseResource newResource = missingResourceDef.newInstance();
newResource.setId(resName + "/" + id);
IFhirResourceDao<IBaseResource> placeholderResourceDao = (IFhirResourceDao<IBaseResource>) getDao(newResource.getClass());
ourLog.info("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
ourLog.debug("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
valueOf = placeholderResourceDao.update(newResource).getEntity().getId();
} else {
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
@ -673,7 +674,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
@SuppressWarnings("unchecked")
public <R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType) {
if (myResourceTypeToDao == null) {
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<Class<? extends IBaseResource>, IFhirResourceDao<?>>();
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>();
for (IFhirResourceDao<?> next : myResourceDaos) {
theResourceTypeToDao.put(next.getResourceType(), next);
}
@ -1549,7 +1550,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
}
Long next = matches.iterator().next();
String newId = translatePidIdToForcedId(resourceTypeString, next);
ourLog.info("Replacing inline match URL[{}] with ID[{}}", nextId.getValue(), newId);
ourLog.debug("Replacing inline match URL[{}] with ID[{}}", nextId.getValue(), newId);
nextRef.setReference(newId);
}
}
@ -1615,7 +1616,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
}
if (!changed.isChanged() && !theForceUpdate && myConfig.isSuppressUpdatesWithNoChange()) {
ourLog.info("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
ourLog.debug("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
if (theResource != null) {
populateResourceIdFromEntity(theEntity, theResource);
}
@ -1657,7 +1658,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
historyEntry.setEncoding(changed.getEncoding());
historyEntry.setResource(changed.getResource());
ourLog.info("Saving history entry {}", historyEntry.getIdDt());
ourLog.debug("Saving history entry {}", historyEntry.getIdDt());
myResourceHistoryTableDao.save(historyEntry);
}
@ -1765,7 +1766,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
// Store composite string uniques
if (getConfig().isUniqueIndexesEnabled()) {
for (ResourceIndexedCompositeStringUnique next : removeCommon(existingCompositeStringUniques, compositeStringUniques)) {
ourLog.info("Removing unique index: {}", next);
ourLog.debug("Removing unique index: {}", next);
myEntityManager.remove(next);
theEntity.getParamsCompositeStringUnique().remove(next);
}
@ -1776,7 +1777,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
throw new PreconditionFailedException("Can not create resource of type " + theEntity.getResourceType() + " as it would create a duplicate index matching query: " + next.getIndexString() + " (existing index belongs to " + existing.getResource().getIdDt().toUnqualifiedVersionless().getValue() + ")");
}
}
ourLog.info("Persisting unique index: {}", next);
ourLog.debug("Persisting unique index: {}", next);
myEntityManager.persist(next);
}
}
@ -1821,7 +1822,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
if (nextChildDef instanceof RuntimeChildResourceDefinition) {
RuntimeChildResourceDefinition nextChildDefRes = (RuntimeChildResourceDefinition) nextChildDef;
Set<String> validTypes = new HashSet<String>();
Set<String> validTypes = new HashSet<>();
boolean allowAny = false;
for (Class<? extends IBaseResource> nextValidType : nextChildDefRes.getResourceTypes()) {
if (nextValidType.isInterface()) {
@ -2147,7 +2148,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
}
if (forcedId.isEmpty() == false) {
List<Long> retVal = new ArrayList<Long>(forcedId.size());
List<Long> retVal = new ArrayList<>(forcedId.size());
for (ForcedId next : forcedId) {
retVal.add(next.getResourcePid());
}

View File

@ -127,7 +127,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
}
ourLog.info("Processed addTag {}/{} on {} in {}ms", theScheme, theTerm, theId, w.getMillisAndRestart());
ourLog.debug("Processed addTag {}/{} on {} in {}ms", theScheme, theTerm, theId, w.getMillisAndRestart());
}
@Override
@ -273,7 +273,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
ourLog.info("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
ourLog.debug("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
return retVal;
}
@ -350,7 +350,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
}
ourLog.info("Processed delete on {} (matched {} resource(s)) in {}ms", theUrl, deletedResources.size(), w.getMillis());
ourLog.debug("Processed delete on {} (matched {} resource(s)) in {}ms", theUrl, deletedResources.size(), w.getMillis());
DeleteMethodOutcome retVal = new DeleteMethodOutcome();
retVal.setDeletedEntities(deletedResources);
@ -462,7 +462,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulCreate", outcome.getId(), w.getMillisAndRestart());
outcome.setOperationOutcome(createInfoOperationOutcome(msg));
ourLog.info(msg);
ourLog.debug(msg);
return outcome;
}
@ -530,7 +530,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
StopWatch w = new StopWatch();
TagList tags = super.getTags(myResourceType, null);
ourLog.info("Processed getTags on {} in {}ms", myResourceName, w.getMillisAndRestart());
ourLog.debug("Processed getTags on {} in {}ms", myResourceName, w.getMillisAndRestart());
return tags;
}
@ -557,7 +557,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
StopWatch w = new StopWatch();
TagList retVal = super.getTags(myResourceType, theResourceId);
ourLog.info("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
ourLog.debug("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
return retVal;
}
@ -569,7 +569,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
StopWatch w = new StopWatch();
IBundleProvider retVal = super.history(myResourceName, null, theSince, theUntil);
ourLog.info("Processed history on {} in {}ms", myResourceName, w.getMillisAndRestart());
ourLog.debug("Processed history on {} in {}ms", myResourceName, w.getMillisAndRestart());
return retVal;
}
@ -586,7 +586,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
IBundleProvider retVal = super.history(myResourceName, entity.getId(), theSince, theUntil);
ourLog.info("Processed history on {} in {}ms", id, w.getMillisAndRestart());
ourLog.debug("Processed history on {} in {}ms", id, w.getMillisAndRestart());
return retVal;
}
@ -622,7 +622,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (myDaoConfig.isMarkResourcesForReindexingUponSearchParameterChange()) {
if (isNotBlank(theExpression)) {
final String resourceType = theExpression.substring(0, theExpression.indexOf('.'));
ourLog.info("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", resourceType, theExpression);
ourLog.debug("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", resourceType, theExpression);
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -633,7 +633,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
});
ourLog.info("Marked {} resources for reindexing", updatedCount);
ourLog.debug("Marked {} resources for reindexing", updatedCount);
}
}
@ -665,7 +665,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
doMetaAdd(theMetaAdd, history);
}
ourLog.info("Processed metaAddOperation on {} in {}ms", new Object[]{theResourceId, w.getMillisAndRestart()});
ourLog.debug("Processed metaAddOperation on {} in {}ms", new Object[]{theResourceId, w.getMillisAndRestart()});
@SuppressWarnings("unchecked")
MT retVal = (MT) metaGetOperation(theMetaAdd.getClass(), theResourceId, theRequestDetails);
@ -699,7 +699,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
myEntityManager.flush();
ourLog.info("Processed metaDeleteOperation on {} in {}ms", new Object[]{theResourceId.getValue(), w.getMillisAndRestart()});
ourLog.debug("Processed metaDeleteOperation on {} in {}ms", new Object[]{theResourceId.getValue(), w.getMillisAndRestart()});
@SuppressWarnings("unchecked")
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequestDetails);
@ -864,7 +864,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
throw new ResourceGoneException("Resource was deleted at " + deleted.getValueAsString());
}
ourLog.info("Processed read on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
ourLog.debug("Processed read on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
return retVal;
}
@ -968,7 +968,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
myEntityManager.merge(entity);
ourLog.info("Processed remove tag {}/{} on {} in {}ms", theScheme, theTerm, theId.getValue(), w.getMillisAndRestart());
ourLog.debug("Processed remove tag {}/{} on {} in {}ms", theScheme, theTerm, theId.getValue(), w.getMillisAndRestart());
}
@Transactional(propagation = Propagation.SUPPORTS)
@ -1282,7 +1282,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulCreate", outcome.getId(), w.getMillisAndRestart());
outcome.setOperationOutcome(createInfoOperationOutcome(msg));
ourLog.info(msg);
ourLog.debug(msg);
return outcome;
}
@ -1339,7 +1339,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete() == false && !theForValidate) {
ourLog.info("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
ourLog.debug("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
myResourceLinkDao.delete(resultList);
return;
}

View File

@ -36,6 +36,7 @@ public abstract class BaseHasResource {
@Temporal(TemporalType.TIMESTAMP)
private Date myDeleted;
// TODO: move to resource history table
@Column(name = "RES_VERSION", nullable = true, length = 7)
@Enumerated(EnumType.STRING)
@OptimisticLock(excluded = true)

View File

@ -95,7 +95,6 @@ public class JavaMailEmailSender implements IEmailSender {
@Override
public void send(EmailDetails theDetails) {
String subscriptionId = theDetails.getSubscription().toUnqualifiedVersionless().getValue();
ourLog.info("Sending email for subscription {} to recipients: {}", subscriptionId, theDetails.getTo());
StopWatch sw = new StopWatch();
StringTemplateResolver templateResolver = new StringTemplateResolver();
@ -116,15 +115,18 @@ public class JavaMailEmailSender implements IEmailSender {
MimeMessage email = mySender.createMimeMessage();
String from = trim(theDetails.getFrom());
ourLog.info("Sending email for subscription {} from [{}] to recipients: [{}]", subscriptionId, from, theDetails.getTo());
try {
email.setFrom(trim(theDetails.getFrom()));
email.setFrom(from);
email.setRecipients(Message.RecipientType.TO, toTrimmedCommaSeparatedString(theDetails.getTo()));
email.setSubject(subject);
email.setText(body);
email.setSentDate(new Date());
email.addHeader("X-FHIR-Subscription", subscriptionId);
} catch (MessagingException e) {
throw new InternalErrorException("Failed to create email messaage", e);
throw new InternalErrorException("Failed to create email message", e);
}
mySender.send(email);

View File

@ -96,27 +96,29 @@ public class Controller extends BaseController {
}
@RequestMapping(value = { "/delete" })
public String actionDelete(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
addCommonParams(theReq, theRequest, theModel);
public String actionDelete(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
addCommonParams(theServletRequest, theRequest, theModel);
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
RuntimeResourceDefinition def;
try {
def = getResourceType(theRequest, theReq);
def = getResourceType(theRequest, theServletRequest);
} catch (ServletException e) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
String id = StringUtils.defaultString(theReq.getParameter("resource-delete-id"));
String id = StringUtils.defaultString(theServletRequest.getParameter("resource-delete-id"));
if (StringUtils.isBlank(id)) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError("No ID specified", null));
return "resource";
}
ResultType returnsResource = ResultType.BUNDLE;
ResultType returnsResource = ResultType.RESOURCE;
String outcomeDescription = "Delete Resource";
long start = System.currentTimeMillis();
@ -192,27 +194,29 @@ public class Controller extends BaseController {
}
@RequestMapping(value = { "/read" })
public String actionRead(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
addCommonParams(theReq, theRequest, theModel);
public String actionRead(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
addCommonParams(theServletRequest, theRequest, theModel);
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
RuntimeResourceDefinition def;
try {
def = getResourceType(theRequest, theReq);
def = getResourceType(theRequest, theServletRequest);
} catch (ServletException e) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
String id = StringUtils.defaultString(theReq.getParameter("id"));
String id = StringUtils.defaultString(theServletRequest.getParameter("id"));
if (StringUtils.isBlank(id)) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError("No ID specified", null));
return "resource";
}
ResultType returnsResource = ResultType.RESOURCE;
String versionId = StringUtils.defaultString(theReq.getParameter("vid"));
String versionId = StringUtils.defaultString(theServletRequest.getParameter("vid"));
String outcomeDescription;
if (StringUtils.isBlank(versionId)) {
versionId = null;
@ -242,45 +246,18 @@ public class Controller extends BaseController {
@RequestMapping({ "/resource" })
public String actionResource(HttpServletRequest theServletRequest, final ResourceRequest theRequest, final BindingResult theBindingResult, final ModelMap theModel) {
IBaseResource conformance = addCommonParams(theServletRequest, theRequest, theModel);
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
String resourceName = theRequest.getResource();
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
TreeSet<String> includes = new TreeSet<String>();
TreeSet<String> revIncludes = new TreeSet<String>();
TreeSet<String> sortParams = new TreeSet<String>();
boolean haveSearchParams = false;
List<List<String>> queryIncludes = new ArrayList<List<String>>();
switch (theRequest.getFhirVersion(myConfig)) {
case DSTU2:
haveSearchParams = extractSearchParamsDstu2(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
case DSTU3:
haveSearchParams = extractSearchParamsDstu3CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
case R4:
haveSearchParams = extractSearchParamsR4CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
default:
throw new IllegalStateException("Unknown FHIR version: " + theRequest.getFhirVersion(myConfig));
}
theModel.put("includes", includes);
theModel.put("revincludes", revIncludes);
theModel.put("queries", Collections.emptyList()); // TODO: remove this, it does nothing
theModel.put("haveSearchParams", haveSearchParams);
theModel.put("queryIncludes", queryIncludes);
theModel.put("sortParams", sortParams);
populateModelForResource(theServletRequest, theRequest, theModel);
if (isNotBlank(theRequest.getUpdateId())) {
String updateId = theRequest.getUpdateId();
String updateVid = defaultIfEmpty(theRequest.getUpdateVid(), null);
IBaseResource updateResource = (IBaseResource) client.read(def.getImplementingClass(), new IdDt(resourceName, updateId, updateVid));
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
IBaseResource updateResource = client.read(def.getImplementingClass(), new IdDt(resourceName, updateId, updateVid));
String updateResourceString = theRequest.newParser(getContext(theRequest)).setPrettyPrint(true).encodeResourceToString(updateResource);
theModel.put("updateResource", updateResourceString);
theModel.put("updateResourceId", updateId);
@ -291,10 +268,43 @@ public class Controller extends BaseController {
return "resource";
}
private void populateModelForResource(HttpServletRequest theServletRequest, HomeRequest theRequest, ModelMap theModel) {
IBaseResource conformance = addCommonParams(theServletRequest, theRequest, theModel);
String resourceName = theRequest.getResource();
TreeSet<String> includes = new TreeSet<>();
TreeSet<String> revIncludes = new TreeSet<>();
TreeSet<String> sortParams = new TreeSet<>();
boolean haveSearchParams = false;
List<List<String>> queryIncludes = new ArrayList<>();
switch (theRequest.getFhirVersion(myConfig)) {
case DSTU2:
haveSearchParams = extractSearchParamsDstu2(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
case DSTU3:
haveSearchParams = extractSearchParamsDstu3CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
case R4:
haveSearchParams = extractSearchParamsR4CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes);
break;
default:
throw new IllegalStateException("Unknown FHIR version: " + theRequest.getFhirVersion(myConfig));
}
theModel.put("includes", includes);
theModel.put("revincludes", revIncludes);
theModel.put("queries", Collections.emptyList()); // TODO: remove this, it does nothing
theModel.put("haveSearchParams", haveSearchParams);
theModel.put("queryIncludes", queryIncludes);
theModel.put("sortParams", sortParams);
}
@SuppressWarnings("unchecked")
@RequestMapping(value = { "/search" })
public String actionSearch(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) throws IOException {
addCommonParams(theReq, theRequest, theModel);
public String actionSearch(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) throws IOException {
addCommonParams(theServletRequest, theRequest, theModel);
StringWriter clientCodeJsonStringWriter = new StringWriter();
JsonWriter clientCodeJsonWriter = new JsonWriter(clientCodeJsonStringWriter);
@ -305,19 +315,20 @@ public class Controller extends BaseController {
clientCodeJsonWriter.value((String) theModel.get("base"));
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
IUntypedQuery search = client.search();
IQuery query;
if (isNotBlank(theReq.getParameter("resource"))) {
if (isNotBlank(theServletRequest.getParameter("resource"))) {
try {
query = search.forResource((Class<? extends IBaseResource>) getResourceType(theRequest, theReq).getImplementingClass());
query = search.forResource(getResourceType(theRequest, theServletRequest).getImplementingClass());
} catch (ServletException e) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError(e.toString(), e));
return "resource";
}
clientCodeJsonWriter.name("resource");
clientCodeJsonWriter.value(theReq.getParameter("resource"));
clientCodeJsonWriter.value(theServletRequest.getParameter("resource"));
} else {
query = search.forAllResources();
clientCodeJsonWriter.name("resource");
@ -349,7 +360,7 @@ public class Controller extends BaseController {
paramIdx++;
String paramIdxString = Integer.toString(paramIdx);
boolean shouldContinue = handleSearchParam(paramIdxString, theReq, query, clientCodeJsonWriter);
boolean shouldContinue = handleSearchParam(paramIdxString, theServletRequest, query, clientCodeJsonWriter);
if (!shouldContinue) {
break;
}
@ -358,7 +369,7 @@ public class Controller extends BaseController {
clientCodeJsonWriter.name("includes");
clientCodeJsonWriter.beginArray();
String[] incValues = theReq.getParameterValues(Constants.PARAM_INCLUDE);
String[] incValues = theServletRequest.getParameterValues(Constants.PARAM_INCLUDE);
if (incValues != null) {
for (String next : incValues) {
if (isNotBlank(next)) {
@ -371,7 +382,7 @@ public class Controller extends BaseController {
clientCodeJsonWriter.name("revincludes");
clientCodeJsonWriter.beginArray();
String[] revIncValues = theReq.getParameterValues(Constants.PARAM_REVINCLUDE);
String[] revIncValues = theServletRequest.getParameterValues(Constants.PARAM_REVINCLUDE);
if (revIncValues != null) {
for (String next : revIncValues) {
if (isNotBlank(next)) {
@ -382,9 +393,10 @@ public class Controller extends BaseController {
}
clientCodeJsonWriter.endArray();
String limit = theReq.getParameter("resource-search-limit");
String limit = theServletRequest.getParameter("resource-search-limit");
if (isNotBlank(limit)) {
if (!limit.matches("[0-9]+")) {
populateModelForResource(theServletRequest, theRequest, theModel);
theModel.put("errorMsg", toDisplayError("Search limit must be a numeric value.", null));
return "resource";
}
@ -397,13 +409,13 @@ public class Controller extends BaseController {
clientCodeJsonWriter.nullValue();
}
String[] sort = theReq.getParameterValues("sort_by");
String[] sort = theServletRequest.getParameterValues("sort_by");
if (sort != null) {
for (String next : sort) {
if (isBlank(next)) {
continue;
}
String direction = theReq.getParameter("sort_direction");
String direction = theServletRequest.getParameter("sort_direction");
if ("asc".equals(direction)) {
query.sort().ascending(new StringClientParam(next));
} else if ("desc".equals(direction)) {
@ -505,7 +517,7 @@ public class Controller extends BaseController {
Class<? extends IBaseResource> type = null; // def.getImplementingClass();
if ("history-type".equals(theMethod)) {
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
type = (Class<? extends IBaseResource>) def.getImplementingClass();
type = def.getImplementingClass();
}
String body = validate ? theReq.getParameter("resource-validate-body") : theReq.getParameter("resource-create-body");
@ -588,7 +600,7 @@ public class Controller extends BaseController {
Class<? extends IBaseResource> type = null; // def.getImplementingClass();
if ("history-type".equals(theMethod)) {
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
type = (Class<? extends IBaseResource>) def.getImplementingClass();
type = def.getImplementingClass();
id = StringUtils.defaultString(theReq.getParameter("resource-history-id"));
}

View File

@ -150,6 +150,10 @@
elements of type "Reference". Thanks to GitHub user @t4deon for supplying
a testcase!
</action>
<action type="fix">
Deleting a resource from the testpage overlay resulted in an error page after
clicking "delete", even though the delete succeeded.
</action>
</release>
<release version="3.2.0" date="2018-01-13">
<action type="add">