/** * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.module.webservices.rest.web.resource.impl; import org.openmrs.OpenmrsData; import org.openmrs.OpenmrsMetadata; import org.openmrs.api.context.Context; import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.module.webservices.rest.util.ReflectionUtil; import org.openmrs.module.webservices.rest.web.ConversionUtil; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; import org.openmrs.module.webservices.rest.web.annotation.RepHandler; import org.openmrs.module.webservices.rest.web.api.RestService; import org.openmrs.module.webservices.rest.web.representation.RefRepresentation; import org.openmrs.module.webservices.rest.web.resource.api.Resource; import org.openmrs.module.webservices.rest.web.response.ConversionException; import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; import org.openmrs.module.webservices.rest.web.response.ResponseException; import java.util.HashSet; import java.util.Set; /** * Helpful base implementation of {@link DelegatingSubclassHandler} */ public abstract class BaseDelegatingSubclassHandler<Superclass, Subclass extends Superclass> implements DelegatingSubclassHandler<Superclass, Subclass> { /** * Properties that should silently be ignored if you try to get them. Implementations should * generally configure this property with a list of properties that were added to their * underlying domain object after the minimum OpenMRS version required by this module. For * example PatientIdentifierTypeResource will allow "locationBehavior" to be missing, since it * wasn't added to PatientIdentifierType until OpenMRS 1.9. delegate class */ protected Set<String> allowedMissingProperties = new HashSet<String>(); /** * Uses introspection into the generic interface to determine the superclass plugged into by * this handler * * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingSubclassHandler#getSuperclass() */ @SuppressWarnings("unchecked") @Override public Class<Superclass> getSuperclass() { return ReflectionUtil.getParameterizedTypeFromInterface(getClass(), DelegatingSubclassHandler.class, 0); } /** * Uses introspection into the generic interface to determine the subclass handled by this * handler * * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingSubclassHandler#getSubclassHandled() */ @SuppressWarnings("unchecked") @Override public Class<Subclass> getSubclassHandled() { return ReflectionUtil.getParameterizedTypeFromInterface(getClass(), DelegatingSubclassHandler.class, 1); } /** * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceHandler#getUpdatableProperties() */ @Override public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { return getCreatableProperties(); } /** * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceHandler#save(java.lang.Object) */ @SuppressWarnings("unchecked") @Override public Subclass save(Subclass delegate) { return (Subclass) getResource().save(delegate); } /** * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceHandler#purge(java.lang.Object, * org.openmrs.module.webservices.rest.web.RequestContext) */ @Override public void purge(Subclass delegate, RequestContext context) throws ResponseException { getResource().purge(delegate, context); } /** * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceHandler#getResourceVersion() */ @Override public String getResourceVersion() { return RestConstants.PROPERTY_FOR_RESOURCE_VERSION_DEFAULT_VALUE; } /** * @return the resource this handler works with */ @SuppressWarnings("unchecked") public DelegatingCrudResource<Superclass> getResource() { // get the service-managed singleton version of the resource Resource resource = Context.getService(RestService.class).getResourceBySupportedClass(getSuperclass()); return (DelegatingCrudResource<Superclass>) resource; }; /** * Assumes we can get a "display" property * * @param delegate * @return standard REF representation of delegate * @throws ConversionException */ @RepHandler(RefRepresentation.class) public SimpleObject convertToRef(Subclass delegate) throws ConversionException { DelegatingResourceDescription rep = new DelegatingResourceDescription(); rep.addProperty("uuid"); rep.addProperty("display"); if (delegate instanceof OpenmrsData) { if (((OpenmrsData) delegate).isVoided()) rep.addProperty("voided"); } else if (delegate instanceof OpenmrsMetadata) { if (((OpenmrsMetadata) delegate).isRetired()) rep.addProperty("retired"); } rep.addSelfLink(); return getResource().convertDelegateToRepresentation(delegate, rep); } /** * Gets the audit information of a resource. * * @param resource the resource. * @return a {@link SimpleObject} with the audit information. */ @PropertyGetter("auditInfo") public SimpleObject getAuditInfo(Object resource) { return ConversionUtil.getAuditInfo(resource); } @Override public Subclass newDelegate(SimpleObject object) { return newDelegate(); } }