Java tutorial
/** * 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.api.handler; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.Date; import java.util.UUID; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.OpenmrsObject; import org.openmrs.User; import org.openmrs.Voidable; import org.openmrs.annotation.AllowEmptyStrings; import org.openmrs.annotation.AllowLeadingOrTrailingWhitespace; import org.openmrs.annotation.Handler; import org.openmrs.aop.RequiredDataAdvice; import org.openmrs.api.APIException; /** * This class deals with any object that implements {@link OpenmrsObject}. When an * {@link OpenmrsObject} is saved (via a save* method in a service), this handler is automatically * called by the {@link RequiredDataAdvice} AOP class. <br> * <br> * This class sets the uuid property on the given OpenmrsObject to a randomly generated <a * href="http://wikipedia.org/wiki/UUID">UUID</a> if it is non-null. * * @see RequiredDataHandler * @see SaveHandler * @since 1.5 */ @Handler(supports = OpenmrsObject.class) public class OpenmrsObjectSaveHandler implements SaveHandler<OpenmrsObject> { private static final Log log = LogFactory.getLog(OpenmrsObjectSaveHandler.class); /** * This sets the uuid property on the given OpenmrsObject if it is non-null. * * @see org.openmrs.api.handler.RequiredDataHandler#handle(org.openmrs.OpenmrsObject, * org.openmrs.User, java.util.Date, java.lang.String) * @should set empty string properties to null * @should not set empty string properties to null for AllowEmptyStrings annotation * @should not trim empty strings for AllowLeadingOrTrailingWhitespace annotation * @should trim strings without AllowLeadingOrTrailingWhitespace annotation * @should trim empty strings for AllowEmptyStrings annotation */ public void handle(OpenmrsObject openmrsObject, User creator, Date dateCreated, String reason) { if (openmrsObject.getUuid() == null) { openmrsObject.setUuid(UUID.randomUUID().toString()); } //Set all empty string properties, that do not have the AllowEmptyStrings annotation, to null. //And also trim leading and trailing white space for properties that do not have the //AllowLeadingOrTrailingWhitespace annotation. PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(openmrsObject); for (PropertyDescriptor property : properties) { if (property.getPropertyType() == null) { continue; } // Ignore properties that don't have a getter (e.g. GlobalProperty.valueReferenceInternal) or // don't have a setter (e.g. Patient.familyName) if (property.getWriteMethod() == null || property.getReadMethod() == null) { continue; } // Ignore properties that have a deprecated getter or setter if (property.getWriteMethod().getAnnotation(Deprecated.class) != null || property.getReadMethod().getAnnotation(Deprecated.class) != null) { continue; } //We are dealing with only strings if (!property.getPropertyType().equals(String.class)) { continue; } try { Object value = PropertyUtils.getProperty(openmrsObject, property.getName()); if (value == null) { continue; } Object valueBeforeTrim = value; if (property.getWriteMethod().getAnnotation(AllowLeadingOrTrailingWhitespace.class) == null) { value = ((String) value).trim(); //If we have actually trimmed any space, set the trimmed value. if (!valueBeforeTrim.equals(value)) { PropertyUtils.setProperty(openmrsObject, property.getName(), value); } } //Check if user is interested in setting empty strings to null if (property.getWriteMethod().getAnnotation(AllowEmptyStrings.class) != null) { continue; } if ("".equals(value) && !(openmrsObject instanceof Voidable && ((Voidable) openmrsObject).isVoided())) { //Set to null only if object is not already voided PropertyUtils.setProperty(openmrsObject, property.getName(), null); } } catch (UnsupportedOperationException ex) { // there is no need to log this. These should be (mostly) silently skipped over if (log.isInfoEnabled()) { log.info( "The property " + property.getName() + " is no longer supported and should be ignored.", ex); } } catch (InvocationTargetException ex) { if (log.isWarnEnabled()) { log.warn("Failed to access property " + property.getName() + "; accessor threw exception.", ex); } } catch (Exception ex) { throw new APIException("failed.change.property.value", new Object[] { property.getName() }, ex); } } } }