use of org.openmrs.OpenmrsObject in project openmrs-core by openmrs.
the class ValidateUtil method validateFieldLengths.
/**
* Test the field lengths are valid
*
* @param errors
* @param aClass the class of the object being tested
* @param fields a var args that contains all of the fields from the model
* @should pass validation if regEx field length is not too long
* @should fail validation if regEx field length is too long
* @should fail validation if name field length is too long
* @should return immediately if validation is disabled and have no errors
*/
public static void validateFieldLengths(Errors errors, Class<?> aClass, String... fields) {
if (disableValidation) {
return;
}
Assert.notNull(errors, "Errors object must not be null");
for (String field : fields) {
Object value = errors.getFieldValue(field);
if (value == null || !(value instanceof String)) {
continue;
}
int length = Context.getAdministrationService().getMaximumPropertyLength((Class<? extends OpenmrsObject>) aClass, field);
if (length == -1) {
return;
}
if (((String) value).length() > length) {
errors.rejectValue(field, "error.exceededMaxLengthOfField", new Object[] { length }, null);
}
}
}
use of org.openmrs.OpenmrsObject in project openmrs-core by openmrs.
the class RequiredDataAdvice method before.
/**
* @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method,
* java.lang.Object[], java.lang.Object)
* @should not fail on update method with no arguments
*/
@Override
@SuppressWarnings("unchecked")
public void before(Method method, Object[] args, Object target) throws Throwable {
String methodName = method.getName();
// skip out early if there are no arguments
if (args == null || args.length == 0) {
return;
}
Object mainArgument = args[0];
// fail early on a null parameter
if (mainArgument == null) {
return;
}
// not updating the primary argument. eg: ConceptService.updateConceptWord(Concept)
if (methodName.startsWith("save") || methodName.startsWith("create")) {
// if the first argument is an OpenmrsObject, handle it now
Reflect reflect = new Reflect(OpenmrsObject.class);
if (reflect.isSuperClass(mainArgument)) {
// fail early if the method name is not like saveXyz(Xyz)
if (!methodNameEndsWithClassName(method, mainArgument.getClass())) {
return;
}
// if a second argument exists, pass that to the save handler as well
// (with current code, it means we're either in an obs save or a user save)
String other = null;
if (args.length > 1 && args[1] instanceof String) {
other = (String) args[1];
}
ValidateUtil.validate(mainArgument);
recursivelyHandle(SaveHandler.class, (OpenmrsObject) mainArgument, other);
} else // if the first argument is a list of openmrs objects, handle them all now
if (Reflect.isCollection(mainArgument) && isOpenmrsObjectCollection(mainArgument)) {
// ideally we would fail early if the method name is not like savePluralOfXyz(Collection<Xyz>)
// but this only occurs once in the API (AdministrationService.saveGlobalProperties
// so it is not worth handling this case
// if a second argument exists, pass that to the save handler as well
// (with current code, it means we're either in an obs save or a user save)
String other = null;
if (args.length > 1) {
other = (String) args[1];
}
Collection<OpenmrsObject> openmrsObjects = (Collection<OpenmrsObject>) mainArgument;
for (OpenmrsObject object : openmrsObjects) {
ValidateUtil.validate(mainArgument);
recursivelyHandle(SaveHandler.class, object, other);
}
}
} else {
// with Patients or Concepts as the first argument
if (!methodNameEndsWithClassName(method, mainArgument.getClass())) {
return;
}
if (methodName.startsWith("void")) {
Voidable voidable = (Voidable) args[0];
Date dateVoided = voidable.getDateVoided() == null ? new Date() : voidable.getDateVoided();
String voidReason = (String) args[1];
recursivelyHandle(VoidHandler.class, voidable, Context.getAuthenticatedUser(), dateVoided, voidReason, null);
} else if (methodName.startsWith("unvoid")) {
Voidable voidable = (Voidable) args[0];
Date originalDateVoided = voidable.getDateVoided();
User originalVoidingUser = voidable.getVoidedBy();
recursivelyHandle(UnvoidHandler.class, voidable, originalVoidingUser, originalDateVoided, null, null);
} else if (methodName.startsWith("retire")) {
Retireable retirable = (Retireable) args[0];
String retireReason = (String) args[1];
recursivelyHandle(RetireHandler.class, retirable, retireReason);
} else if (methodName.startsWith("unretire")) {
Retireable retirable = (Retireable) args[0];
Date originalDateRetired = retirable.getDateRetired();
recursivelyHandle(UnretireHandler.class, retirable, Context.getAuthenticatedUser(), originalDateRetired, null, null);
}
}
}
use of org.openmrs.OpenmrsObject in project openmrs-core by openmrs.
the class BaseOpenmrsDatatypeTest method serialize_shouldReturnTheUuidOfTheObject.
/**
* @see BaseOpenmrsDatatype#serialize(org.openmrs.OpenmrsObject)
*/
@Test
public void serialize_shouldReturnTheUuidOfTheObject() {
OpenmrsObject location = new Location();
String expectedUuid = "some uuid";
location.setUuid(expectedUuid);
BaseOpenmrsDatatype datatype = new MockLocationDatatype();
Assert.assertEquals(expectedUuid, datatype.serialize(location));
}
use of org.openmrs.OpenmrsObject in project openmrs-core by openmrs.
the class RequiredDataAdvice method recursivelyHandle.
/**
* This loops over all declared collections on the given object and all declared collections on
* parent objects to use the given <code>handlerType</code>.
*
* @param <H> the type of Handler to get (should extend {@link RequiredDataHandler})
* @param handlerType the type of Handler to get (should extend {@link RequiredDataHandler})
* @param openmrsObject the object that is being acted upon
* @param currentUser the current user to set recursively on the object
* @param currentDate the date to set recursively on the object
* @param other an optional second argument that was passed to the service method (usually a
* void/retire reason)
* @param alreadyHandled an optional list of objects that have already been handled and should
* not be processed again. this is intended to prevent infinite recursion when
* handling collection properties.
* @see HandlerUtil#getHandlersForType(Class, Class)
*/
@SuppressWarnings("unchecked")
public static <H extends RequiredDataHandler> void recursivelyHandle(Class<H> handlerType, OpenmrsObject openmrsObject, User currentUser, Date currentDate, String other, List<OpenmrsObject> alreadyHandled) {
if (openmrsObject == null) {
return;
}
Class<? extends OpenmrsObject> openmrsObjectClass = openmrsObject.getClass();
if (alreadyHandled == null) {
alreadyHandled = new ArrayList<>();
}
// fetch all handlers for the object being saved
List<H> handlers = HandlerUtil.getHandlersForType(handlerType, openmrsObjectClass);
// loop over all handlers, calling onSave on each
for (H handler : handlers) {
handler.handle(openmrsObject, currentUser, currentDate, other);
}
alreadyHandled.add(openmrsObject);
Reflect reflect = new Reflect(OpenmrsObject.class);
List<Field> allInheritedFields = reflect.getInheritedFields(openmrsObjectClass);
// loop over all child collections of OpenmrsObjects and recursively save on those
for (Field field : allInheritedFields) {
// skip field if it's declared independent
if (Reflect.isAnnotationPresent(openmrsObjectClass, field.getName(), Independent.class)) {
continue;
}
if (reflect.isCollectionField(field) && !isHandlerMarkedAsDisabled(handlerType, field)) {
// the collection we'll be looping over
Collection<OpenmrsObject> childCollection = getChildCollection(openmrsObject, field);
if (childCollection != null) {
for (Object collectionElement : childCollection) {
if (!alreadyHandled.contains(collectionElement)) {
recursivelyHandle(handlerType, (OpenmrsObject) collectionElement, currentUser, currentDate, other, alreadyHandled);
}
}
}
}
}
}
use of org.openmrs.OpenmrsObject in project openmrs-core by openmrs.
the class RequiredDataAdvice method getChildCollection.
/**
* This method gets a child attribute off of an OpenmrsObject. It usually uses the getter for
* the attribute, but can use the direct field (even if its private) if told to by the
* {@link AllowDirectAccess} annotation.
*
* @param openmrsObject the object to get the collection off of
* @param field the name of the field that is the collection
* @return the actual collection of objects that is on the given <code>openmrsObject</code>
* @should get value of given child collection on given field
* @should should be able to get annotated private fields
* @should throw APIException if getter method not found
*/
@SuppressWarnings("unchecked")
protected static Collection<OpenmrsObject> getChildCollection(OpenmrsObject openmrsObject, Field field) {
String fieldName = field.getName();
String getterName = "get" + StringUtils.capitalize(fieldName);
try {
// checks if direct access is allowed
if (field.isAnnotationPresent(AllowDirectAccess.class)) {
boolean previousFieldAccessibility = field.isAccessible();
field.setAccessible(true);
Collection<OpenmrsObject> childCollection = (Collection<OpenmrsObject>) field.get(openmrsObject);
field.setAccessible(previousFieldAccessibility);
return childCollection;
} else {
// access the field via its getter method
Class<? extends OpenmrsObject> openmrsObjectClass = openmrsObject.getClass();
Method getterMethod = openmrsObjectClass.getMethod(getterName, (Class[]) null);
return (Collection<OpenmrsObject>) getterMethod.invoke(openmrsObject, new Object[] {});
}
} catch (IllegalAccessException e) {
if (field.isAnnotationPresent(AllowDirectAccess.class)) {
throw new APIException("unable.get.field", new Object[] { fieldName, openmrsObject.getClass() });
} else {
throw new APIException("unable.getter.method", new Object[] { "use", getterName, fieldName, openmrsObject.getClass() });
}
} catch (InvocationTargetException e) {
throw new APIException("unable.getter.method", new Object[] { "run", getterName, fieldName, openmrsObject.getClass() });
} catch (NoSuchMethodException e) {
throw new APIException("unable.getter.method", new Object[] { "find", getterName, fieldName, openmrsObject.getClass() });
}
}
Aggregations