/* Copyright 2005-2006 Tim Fennell * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sourceforge.stripes.tag; import net.sourceforge.stripes.controller.StripesConstants; import net.sourceforge.stripes.exception.StripesJspException; import net.sourceforge.stripes.action.ActionBean; import net.sourceforge.stripes.util.bean.BeanUtil; import net.sourceforge.stripes.util.bean.ExpressionException; import net.sourceforge.stripes.util.Log; /** * <p>An alternative tag population strategy that will normally prefer the value from the ActionBean * over values from the request - even when the ActionBean returns null! Only if the ActionBean * is not present, or does not define an attribute with the name supplied to the tag will other * population sources be examined. When that happens, the strategy will check the value * specified on the page next, and finally the value(s) in the request.</p> * * <p>If the field represented by the tag is determined to be in error (i.e. the ActionBean is * present and has validation errors for the matching field) then the repopulation behaviour * will revert to the default behaviour of preferring the request parameters.</p> * * @author Tim Fennell * @since Stripes 1.4 */ public class BeanFirstPopulationStrategy extends DefaultPopulationStrategy { private static final Log log = Log.getInstance(BeanFirstPopulationStrategy.class); /** * Implementation of the interface method that will follow the search described in the class * level JavaDoc and attempt to find a value for this tag. * * @param tag the form input tag whose value to populate * @return Object will be one of null, a single Object or an Array of Objects depending upon * what was submitted in the prior request, and what is declared on the ActionBean */ @Override public Object getValue(InputTagSupport tag) throws StripesJspException { // If the specific tag is in error, grab the values from the request if (tag.hasErrors()) { return super.getValue(tag); } else { // Try getting from the ActionBean. If the bean is present and the property // is defined, then the value from the bean takes precedence even if it's null ActionBean bean = tag.getActionBean(); Object value = null; boolean kaboom = false; if (bean != null) { try { value = BeanUtil.getPropertyValue(tag.getName(), bean); } catch (ExpressionException ee) { if (!StripesConstants.SPECIAL_URL_KEYS.contains(tag.getName())) { log.info("Could not find property [", tag.getName(), "] on ActionBean.", ee); } kaboom = true; } } // If there's no matching bean property, then look elsewhere if (bean == null || kaboom) { value = getValueFromTag(tag); if (value == null) { value = getValuesFromRequest(tag); } } return value; } } }