![JAR search and dependency download from the Maven repository](/logo.png)
org.metawidget.inspector.impl.propertystyle.BasePropertyStyle Maven / Gradle / Ivy
// Metawidget
//
// This file is dual licensed under both the LGPL
// (http://www.gnu.org/licenses/lgpl-2.1.html) and the EPL
// (http://www.eclipse.org/org/documents/epl-v10.php). As a
// recipient of Metawidget, you may choose to receive it under either
// the LGPL or the EPL.
//
// Commercial licenses are also available. See http://metawidget.org
// for details.
package org.metawidget.inspector.impl.propertystyle;
import java.util.Map;
import java.util.Set;
import org.metawidget.inspector.impl.BaseTraitStyle;
import org.metawidget.inspector.impl.BaseTraitStyleConfig;
import org.metawidget.util.ArrayUtils;
import org.metawidget.util.ClassUtils;
import org.metawidget.util.CollectionUtils;
import org.metawidget.util.simple.StringUtils;
/**
* Convenience implementation for PropertyStyles.
*
* @author Richard Kennard
*/
public abstract class BasePropertyStyle
extends BaseTraitStyle
implements PropertyStyle {
//
// Constructor
//
protected BasePropertyStyle( BaseTraitStyleConfig config ) {
super( config );
}
//
// Public methods
//
public Map getProperties( String type ) {
return getTraits( type );
}
/**
* Traverses the given Object heirarchy using properties of the given names.
*
* Note: traversal involves calling Property.read, which invokes getter methods and can
* therefore have side effects. For example, a JSF controller 'ResourceController' may have a
* method 'getLoggedIn' which has to check the HttpSession, maybe even hit some EJBs or access
* the database.
*/
public ValueAndDeclaredType traverse( Object toTraverse, String type, boolean onlyToParent, String... names ) {
// Special support for direct class lookup
if ( toTraverse == null ) {
// If there are names, return null
if ( names != null && names.length > 0 ) {
return new ValueAndDeclaredType( null, null );
}
return new ValueAndDeclaredType( null, type );
}
// Sanity check that the given toTraverse is, in fact, of the given type.
//
// This is harder than it seems. We cannot do a simple 'equals', but to do a
// 'isAssignableFrom' we must instantiate the class. But instantiating the class may
// not be possible because of proxies, virtual classes, what tier we're on, etc. Basically,
// we can't be too strict about it.
//
// Use the toTraverse's ClassLoader, to support ClassLoader isolation (eg. classes from a
// WAR being inspected by an EJB lib) and dynamic classes (eg. Groovy)
Class> sanityCheck = ClassUtils.niceForName( type, toTraverse.getClass().getClassLoader() );
if ( sanityCheck != null && !sanityCheck.isAssignableFrom( toTraverse.getClass() ) ) {
return new ValueAndDeclaredType( null, null );
}
// Traverse through names (if any)
Object traverse = toTraverse;
String traverseDeclaredType = type;
if ( names == null || names.length == 0 ) {
// If no names, no parent
if ( onlyToParent ) {
return new ValueAndDeclaredType( null, null );
}
} else {
Set