class RequiredDataAdvice implements MethodBeforeAdvice {

	@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() });
		}
	}

}