use of com.opensymphony.xwork2.ModelDriven in project struts by apache.
the class BeanValidationInterceptor method addBeanValidationErrors.
@SuppressWarnings("nls")
protected void addBeanValidationErrors(Set<ConstraintViolation<Object>> constraintViolations, Object action) {
if (constraintViolations != null) {
ValidatorContext validatorContext = new DelegatingValidatorContext(action, textProviderFactory);
for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
String key = constraintViolation.getMessage();
String message = key;
try {
message = validatorContext.getText(key);
if (convertToUtf8 && StringUtils.isNotBlank(message)) {
message = new String(message.getBytes(convertFromEncoding), "UTF-8");
}
} catch (Exception e) {
LOG.error("Error while trying to fetch message: {}", key, e);
}
if (isActionError(constraintViolation)) {
LOG.debug("Adding action error [{}]", message);
validatorContext.addActionError(message);
} else {
ValidationError validationError = buildBeanValidationError(constraintViolation, message);
String fieldName = validationError.getFieldName();
if (action instanceof ModelDriven && fieldName.startsWith(ValidatorConstants.MODELDRIVEN_PREFIX)) {
fieldName = fieldName.replace("model.", ValidatorConstants.EMPTY_SPACE);
}
LOG.debug("Adding field error [{}] with message [{}]", fieldName, validationError.getMessage());
validatorContext.addFieldError(fieldName, validationError.getMessage());
}
}
}
}
use of com.opensymphony.xwork2.ModelDriven in project struts by apache.
the class ScopedModelDrivenInterceptor method intercept.
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (action instanceof ScopedModelDriven) {
ScopedModelDriven modelDriven = (ScopedModelDriven) action;
if (modelDriven.getModel() == null) {
ActionContext ctx = ActionContext.getContext();
ActionConfig config = invocation.getProxy().getConfig();
String cName = className;
if (cName == null) {
try {
Method method = action.getClass().getMethod(GET_MODEL, EMPTY_CLASS_ARRAY);
Class cls = method.getReturnType();
cName = cls.getName();
} catch (NoSuchMethodException e) {
throw new StrutsException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config);
}
}
String modelName = name;
if (modelName == null) {
modelName = cName;
}
Object model = resolveModel(objectFactory, ctx, cName, scope, modelName);
modelDriven.setModel(model);
modelDriven.setScopeKey(modelName);
}
}
return invocation.invoke();
}
use of com.opensymphony.xwork2.ModelDriven in project struts by apache.
the class StrutsLocalizedTextProvider method findText.
/**
* <p>
* Finds a localized text message for the given key, aTextName. Both the key and the message
* itself is evaluated as required. The following algorithm is used to find the requested
* message:
* </p>
*
* <ol>
* <li>If {@link #searchDefaultBundlesFirst} is <code>true</code>, look for the message in the default resource bundles first.</li>
* <li>Look for message in aClass' class hierarchy.
* <ol>
* <li>Look for the message in a resource bundle for aClass</li>
* <li>If not found, look for the message in a resource bundle for any implemented interface</li>
* <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
* </ol></li>
* <li>If not found and aClass is a {@link ModelDriven} Action, then look for message in
* the model's class hierarchy (repeat sub-steps listed above).</li>
* <li>If not found, look for message in child property. This is determined by evaluating
* the message key as an OGNL expression. For example, if the key is
* <i>user.address.state</i>, then it will attempt to see if "user" can be resolved into an
* object. If so, repeat the entire process from the beginning with the object's class as
* aClass and "address.state" as the message key.</li>
* <li>If not found, look for the message in aClass' package hierarchy.</li>
* <li>If still not found, look for the message in the default resource bundles
* (Note: the lookup is not repeated again if {@link #searchDefaultBundlesFirst} was <code>true</code>).</li>
* <li>Return defaultMessage</li>
* </ol>
*
* <p>
* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a
* message for that specific key cannot be found, the general form will also be looked up
* (i.e. user.phone[*]).
* </p>
*
* <p>
* If a message is found, it will also be interpolated. Anything within <code>${...}</code>
* will be treated as an OGNL expression and evaluated as such.
* </p>
*
* <p>
* If a message is <b>not</b> found a DEBUG level log warning will be logged.
* </p>
*
* @param aClass the class whose name to use as the start point for the search
* @param aTextName the key to find the text message for
* @param locale the locale the message should be for
* @param defaultMessage the message to be returned if no text message can be found in any
* resource bundle
* @param args arguments
* @param valueStack the value stack to use to evaluate expressions instead of the
* one in the ActionContext ThreadLocal
* @return the localized text, or null if none can be found and no defaultMessage is provided
*/
@Override
public String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack) {
String indexedTextName = null;
if (aTextName == null) {
LOG.warn("Trying to find text with null key!");
aTextName = "";
}
// calculate indexedTextName (collection[*]) if applicable
if (aTextName.contains("[")) {
int i = -1;
indexedTextName = aTextName;
while ((i = indexedTextName.indexOf('[', i + 1)) != -1) {
int j = indexedTextName.indexOf(']', i);
String a = indexedTextName.substring(0, i);
String b = indexedTextName.substring(j);
indexedTextName = a + "[*" + b;
}
}
// Allow for and track an early lookup for the message in the default resource bundles first, before searching the class hierarchy.
// The early lookup is only performed when the text provider has been configured to do so, otherwise follow the standard processing order.
boolean performedInitialDefaultBundlesMessageLookup = false;
GetDefaultMessageReturnArg result = null;
// If search default bundles first is set true, call alternative logic first.
if (searchDefaultBundlesFirst) {
result = getDefaultMessageWithAlternateKey(aTextName, indexedTextName, locale, valueStack, args, defaultMessage);
performedInitialDefaultBundlesMessageLookup = true;
if (!unableToFindTextForKey(result)) {
// Found a message in the default resource bundles for aTextName or indexedTextName.
return result.message;
}
}
// search up class hierarchy
String msg = findMessage(aClass, aTextName, indexedTextName, locale, args, null, valueStack);
if (msg != null) {
return msg;
}
if (ModelDriven.class.isAssignableFrom(aClass)) {
ActionContext context = ActionContext.getContext();
// search up model's class hierarchy
ActionInvocation actionInvocation = context.getActionInvocation();
// ActionInvocation may be null if we're being run from a Sitemesh filter, so we won't get model texts if this is null
if (actionInvocation != null) {
Object action = actionInvocation.getAction();
if (action instanceof ModelDriven) {
Object model = ((ModelDriven) action).getModel();
if (model != null) {
msg = findMessage(model.getClass(), aTextName, indexedTextName, locale, args, null, valueStack);
if (msg != null) {
return msg;
}
}
}
}
}
// nothing still? alright, search the package hierarchy now
for (Class clazz = aClass; (clazz != null) && !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
String basePackageName = clazz.getName();
while (basePackageName.lastIndexOf('.') != -1) {
basePackageName = basePackageName.substring(0, basePackageName.lastIndexOf('.'));
String packageName = basePackageName + ".package";
msg = getMessage(packageName, locale, aTextName, valueStack, args);
if (msg != null) {
return msg;
}
if (indexedTextName != null) {
msg = getMessage(packageName, locale, indexedTextName, valueStack, args);
if (msg != null) {
return msg;
}
}
}
}
// see if it's a child property
int idx = aTextName.indexOf('.');
if (idx != -1) {
String newKey = null;
String prop = null;
if (aTextName.startsWith(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX)) {
idx = aTextName.indexOf('.', XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length());
if (idx != -1) {
prop = aTextName.substring(XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX.length(), idx);
newKey = XWorkConverter.CONVERSION_ERROR_PROPERTY_PREFIX + aTextName.substring(idx + 1);
}
} else {
prop = aTextName.substring(0, idx);
newKey = aTextName.substring(idx + 1);
}
if (prop != null) {
Object obj = valueStack.findValue(prop);
try {
Object actionObj = ReflectionProviderFactory.getInstance().getRealTarget(prop, valueStack.getContext(), valueStack.getRoot());
if (actionObj != null) {
PropertyDescriptor propertyDescriptor = ReflectionProviderFactory.getInstance().getPropertyDescriptor(actionObj.getClass(), prop);
if (propertyDescriptor != null) {
Class clazz = propertyDescriptor.getPropertyType();
if (clazz != null) {
if (obj != null) {
valueStack.push(obj);
}
msg = findText(clazz, newKey, locale, null, args);
if (obj != null) {
valueStack.pop();
}
if (msg != null) {
return msg;
}
}
}
}
} catch (Exception e) {
LOG.debug("unable to find property {}", prop, e);
}
}
}
// so we check first to avoid repeating the same operation twice.
if (!performedInitialDefaultBundlesMessageLookup) {
result = getDefaultMessageWithAlternateKey(aTextName, indexedTextName, locale, valueStack, args, defaultMessage);
}
// could we find the text, if not log a warn
if (unableToFindTextForKey(result) && LOG.isDebugEnabled()) {
String warn = "Unable to find text for key '" + aTextName + "' ";
if (indexedTextName != null) {
warn += " or indexed key '" + indexedTextName + "' ";
}
warn += "in class '" + aClass.getName() + "' and locale '" + locale + "'";
LOG.debug(warn);
}
return result != null ? result.message : null;
}
use of com.opensymphony.xwork2.ModelDriven in project struts by apache.
the class StrutsLocalizedTextProviderTest method testFindTextInPackage.
public void testFindTextInPackage() throws Exception {
ModelDriven action = new ModelDrivenAction2();
Mock mockActionInvocation = new Mock(ActionInvocation.class);
mockActionInvocation.expectAndReturn("getAction", action);
ActionContext.getContext().withActionInvocation((ActionInvocation) mockActionInvocation.proxy());
String message = localizedTextProvider.findText(ModelDrivenAction2.class, "package.properties", Locale.getDefault());
assertEquals("It works!", message);
}
use of com.opensymphony.xwork2.ModelDriven in project struts by apache.
the class RestActionInvocation method selectTarget.
@SuppressWarnings("unchecked")
protected void selectTarget() {
// Select target (content to return)
Throwable e = (Throwable) stack.findValue("exception");
if (e != null) {
// Exception
target = e;
hasErrors = true;
} else if (action instanceof ValidationAware && ((ValidationAware) action).hasErrors()) {
// Error messages
ValidationAware validationAwareAction = ((ValidationAware) action);
Map errors = new HashMap();
if (validationAwareAction.getActionErrors().size() > 0) {
errors.put("actionErrors", validationAwareAction.getActionErrors());
}
if (validationAwareAction.getFieldErrors().size() > 0) {
errors.put("fieldErrors", validationAwareAction.getFieldErrors());
}
target = errors;
hasErrors = true;
} else if (action instanceof ModelDriven) {
// Model
target = ((ModelDriven) action).getModel();
} else {
target = action;
}
if (shouldRestrictToGET()) {
target = null;
}
}
Aggregations