All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.struts.faces.application.DynaActionFormELResolver Maven / Gradle / Ivy

There is a newer version: 1.5.0-RC2
Show newest version
/*
 * $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.struts.faces.application;

import java.beans.FeatureDescriptor;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.DynaActionForm;

/**
 * Defines property resolution behavior on instances of {@link DynaActionForm}.
 *
 * 

This resolver handles base objects of type {@code DynaActionForm} * with requested property name {code map}.

* *

This resolver is in read-only mode, which means that {@link #isReadOnly} * will always return {@code true} and {@link #setValue} will always throw * {@code PropertyNotWritableException}.

* *

{@code ELResolver}s are combined together using * {@link CompositeELResolver}s, to define rich semantics for evaluating * an expression. See the JavaDocs for {@link ELResolver} for details.

* * @see CompositeELResolver * @see ELResolver * @see DynaActionForm#getMap() * @since Struts 1.4.1 */ public class DynaActionFormELResolver extends ELResolver { /** * The {@code Log} instance for this class. */ private static final Log LOG = LogFactory.getLog(DynaActionFormELResolver.class); /** * Creates a new read {@code DynaActionFormELResolver}. */ public DynaActionFormELResolver() { if (LOG.isDebugEnabled()) { LOG.debug("Creating new Dyna-Action-From-ELResolver instance"); } } /** * If the base object is a {@code DynaActionForm} and the requested * property name is {code map} then the type {@code Map.class} will be * returned. * *

If the base is a {@code DynaActionForm} and the requested property * name is {code map}, the {@code propertyResolved} property of the * {@code ELContext} object must be set to {@code true} by this resolver, * before returning. If this property is not {@code true} after this * method is called, the caller should ignore the return value.

* *

Assuming the base is a {@code DynaActionForm} and the requested * property name is {code map}, this method will always return * {@code Map.class}. This is because a {@code DynaActionForm} with the * property 'map' accepts only the object {@code Map} as the value for * this given key.

* * @param context The context of this evaluation. * @param base The base to analyze. Only bases of type * {@code DynaActionForm} are handled by this resolver. * @param property The key to return the acceptable type for. Only keys * with value {@code map} are handled by this resolver. * * @return If the {@code propertyResolved} property of {@code ELContext} * was set to {@code true}, then the most general acceptable type; * otherwise undefined. * * @throws NullPointerException if context is {@code null} * @throws ELException if an exception was thrown while performing * the property or variable resolution. The thrown exception * must be included as the cause property of this exception, if * available. */ @Override public Class getType(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (test(base, property)) { if (LOG.isTraceEnabled() ) { LOG.trace("Returning property-type '" + property + "' for DynaActionForm '" + base + "'"); } context.setPropertyResolved(true); return Map.class; } return null; } /** * If the base object is a {@code DynaActionForm} and the requested * property name is {@code map}, returns the {@code map} of the * {@code DynaActionForm}. Otherwise {@code null} is returned. * *

If the base is a {@code DynaActionForm} and the requested property * name is {@code map}, the {@code propertyResolved} property of the * {@code ELContext} object must be set to {@code true} by this resolver, * before returning. If this property is not {@code true} after this method * is called, the caller should ignore the return value.

* *

Just as in {@link DynaActionForm#getMap()}, just because {@code null} * is returned doesn't mean there is no mapping for the key; it's also * possible that the method explicitly returns {@code null}.

* * @param context The context of this evaluation. * @param base The base to be analyzed. Only bases of type * {@code DynaActionForm} are handled by this resolver. * @param property The key whose associated value is to be returned. Only keys * with value {@code map} are handled by this resolver. * * @return If the {@code propertyResolved} property of {@code ELContext} * was set to {@code true}, then the value associated with the given key. * * @throws NullPointerException if context is {@code null}. * @throws ELException if an exception was thrown while performing * the property or variable resolution. The thrown exception * must be included as the cause property of this exception, if * available. */ @Override public Object getValue(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (test(base, property)) { if (LOG.isTraceEnabled()) { LOG.trace("Returning property-value '" + property + "' for DynaActionForm '" + base + "'"); } context.setPropertyResolved(true); return (((DynaActionForm) base).getMap()); } return null; } /** * If the base is a {@code DynaActionForm} and the requested property * name is {@code map}, this method always throw * {@code PropertyNotWritableException}, because the {@code map} * property is a ready-only property of the {@code DynaActionForm} * class. * * @param context The context of this evaluation. * @param base The base to be modified. Only bases of type * {@code DynaActionForm} are handled by this resolver. * @param property The key with which the specified value is to be * associated. Only keys with value {@code map} are handled by * this resolver. * @param value The value to be associated with the specified key. * @throws NullPointerException if context is {@code null}. * @throws PropertyNotWritableException is always throw, because * the {@code map} property is a ready-only property of the * {@code DynaActionForm} class. * @throws ELException if an exception was thrown while performing * the property or variable resolution. The thrown exception * must be included as the cause property of this exception, if * available. */ @Override public void setValue(ELContext context, Object base, Object property, Object value) { if (context == null) { throw new NullPointerException(); } if (test(base, property)) { if (LOG.isTraceEnabled()) { LOG.trace("Set property-value '" + property + "' for DynaActionForm '" + base + "'"); } throw new PropertyNotWritableException(property.toString()); } } /** * If the base is a {@code DynaActionForm} and the requested property * name is {@code map}, returns whether a call to {@link #setValue} * will always fail. This method always returns {@code true}, because * the {@code map} property is a ready-only property of the * {@code DynaActionForm} class. * *

If the base is a {@code DynaActionForm} and the requested property * name is {@code map}, the {@code propertyResolved} property of the * {@code ELContext} object must be set to {@code true} by this resolver, * before returning. If this property is not {@code true} after this * method is called, the caller should ignore the return value.

* * @param context The context of this evaluation. * @param base The base to analyze. Only bases of type * {@code DynaActionForm} are handled by this resolver. * @param property The key to return the read-only status for. Only keys * with value {@code map} are handled by this resolver. * * @return If the {@code propertyResolved} property of {@code ELContext} * was set to {@code true}, then {@code true} if calling the * {@code setValue} method will always fail or {@code false} if it * is possible that such a call may succeed; otherwise undefined. * * @throws NullPointerException if context is {@code null} * @throws ELException if an exception was thrown while performing * the property or variable resolution. The thrown exception * must be included as the cause property of this exception, if * available. */ @Override public boolean isReadOnly(ELContext context, Object base, Object property) { if (context == null) { throw new NullPointerException(); } if (test(base, property)) { if (LOG.isTraceEnabled()) { LOG.trace("Return ready-only status for property '" + property + "' for DynaActionForm " + base + "'"); } context.setPropertyResolved(true); return true; } return false; } /** * If the base object is a {@code DynaActionForm}, returns an * {@code Iterator} containing the set of keys available in the * {@code DynaActionForm}. Otherwise, returns {@code null}. * *

The {@code Iterator} returned must contain zero or more * instances of {@link FeatureDescriptor}. Each info object * contains information about a key in the Map, and is initialized * as follows:

*
    *
  • displayName - The return value of calling the * {@code toString} method on this key, or {@code null} if * the key is {@code null}.
  • *
  • name - Same as displayName property.
  • *
  • shortDescription - JavaDoc-Code of * {@link DynaActionForm#getMap()}
  • *
  • expert - {@code false}
  • *
  • hidden - {@code false}
  • *
  • preferred - {@code true}
  • *
* In addition, the following named attributes must be set in the * returned {@code FeatureDescriptor}s: *
    *
  • {@link ELResolver#TYPE} - The return value of calling * the {@code getClass()} method on this key, or * {@code null} if the key is {@code null}.
  • *
  • {@link ELResolver#RESOLVABLE_AT_DESIGN_TIME} - * {@code true}
  • *
* * @param context The context of this evaluation. * @param base The object whose keys are to be iterated over. Only * bases of type {@code DynaActionForm} are handled by this * resolver. * * @return An {@code Iterator} containing zero or more (possibly * infinitely more) {@code FeatureDescriptor} objects, each * representing a key in this {@code DynaActionForm}, or * {@code null} if the base object is not a * {@code DynaActionForm}. */ @Override public Iterator getFeatureDescriptors( ELContext context, Object base) { if (base instanceof DynaActionForm) { if (LOG.isTraceEnabled()) { LOG.trace("Get Feature-Descriptors for DynaActionForm '" + base + "'"); } final FeatureDescriptor descriptor = new FeatureDescriptor(); descriptor.setName("map"); descriptor.setDisplayName("map"); descriptor.setExpert(false); descriptor.setHidden(false); descriptor.setPreferred(true); descriptor.setShortDescription("Returns the Map containing the property " + "values. This is done mostly to facilitate accessing the " + "DynaActionForm through JavaBeans accessors, in order to use " + "the JavaServer Pages Standard Tag Library (JSTL)."); descriptor.setValue(TYPE, Map.class); descriptor.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE); return Collections.singleton(descriptor).iterator(); } return null; } /** * If the base object is a {@code DynaActionForm}, returns the most * general type that this resolver accepts for the {@code property} * argument. Otherwise, returns {@code null}. * *

Assuming the base is a {@code DynaActionForm}, this method will * always return {@code Object.class}. This is because any object is * accepted as a key and is coerced into a string.

* * @param context The context of this evaluation. * @param base The base to analyze. Only bases of type * {@code DynaActionForm} are handled by this resolver. * * @return {@code null} if base is not a {@code DynaActionForm}; otherwise * {@code Object.class}. */ @Override public Class getCommonPropertyType(ELContext context, Object base) { if (base instanceof DynaActionForm) { if (LOG.isTraceEnabled()) { LOG.trace("Get Common-Property-Type for DynaActionForm '" + base + "'"); } return Object.class; } return null; } /** * If the base object is a {@code DynaActionForm} and the requested * property name is {@code map}. * * @param base The requested base object. Only bases of type * {@code DynaActionForm} are handled by this resolver. * @param property The requested key. Only keys * with value {@code map} are handled by this resolver. * * @return {@code true} if request could handle with this resolver. */ private static boolean test(final Object base, final Object property) { return base instanceof DynaActionForm && "map".equals(property); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy