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

org.metawidget.inspector.impl.BaseTraitStyle Maven / Gradle / Ivy

There is a newer version: 4.2
Show newest version
// Metawidget (licensed under LGPL)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package org.metawidget.inspector.impl;

import java.util.Collections;
import java.util.Map;
import java.util.regex.Pattern;

import org.metawidget.util.ArrayUtils;
import org.metawidget.util.CollectionUtils;
import org.metawidget.util.LogUtils;
import org.metawidget.util.LogUtils.Log;

/**
 * Convenience implementation for ActionStyles and PropertyStyles.
 * 

* Handles caching and excluding names and types. * * @author Richard Kennard */ public abstract class BaseTraitStyle { // // Private members // /** * Cache of trait lookups. *

* Lookups are potentially expensive, so we cache them. The cache itself is a member variable, * not a static, because we rely on BaseObjectInspector and * ConfigReader to only create one instance of ActionStyle and * PropertyStyle for all Inspectors. *

* This also stops problems with subclasses of BaseTraitStyle sharing the same * static cache. *

* Note: the cache is unbounded, because the number of Classes in the system is fixed. This even * applies to hot deployment products such as FakeReplace, because new Classes are replaced such * that they .equal() their originals. */ /* package private */final Map> mCache; private Pattern mExcludeBaseType; private Class[] mExcludeReturnType; private String[] mExcludeName; // // Protected members // protected final Log mLog = LogUtils.getLog( getClass() ); // // Constructor // protected BaseTraitStyle( BaseTraitStyleConfig config ) { if ( config.isCacheLookups() ) { mCache = CollectionUtils.newHashMap(); } else { mCache = null; } mExcludeBaseType = config.getExcludeBaseType(); mExcludeReturnType = config.getExcludeReturnType(); mExcludeName = config.getExcludeName(); } // // Public methods // /** * SPI for tools such as FakeReplace that * need to clear the cache. *

* This does not affect immutability, as our external behaviour is unchanged (we will just be a * little slower the next time we are called, while we re-cache). */ public void clearCache() { if ( mCache == null ) { return; } synchronized ( mCache ) { mCache.clear(); } } // // Protected methods // protected final Map getTraits( String type ) { if ( mCache == null ) { return getUncachedTraits( type ); } synchronized ( mCache ) { Map traits = getCachedTraits( type ); if ( traits == null ) { traits = getUncachedTraits( type ); cacheTraits( type, traits ); } return traits; } } protected final Map getCachedTraits( String type ) { return mCache.get( type ); } protected final void cacheTraits( String type, Map traits ) { mCache.put( type, Collections.unmodifiableMap( traits ) ); } protected abstract Map getUncachedTraits( String type ); /** * Whether to exclude the given trait, of the given type, in the given class, when searching * for traits. *

* This can be useful when the convention or base class define traits that are * framework-specific, and should be filtered out from 'real' business model traits. *

* By default, calls isExcludedReturnType and isExcludedName and * returns true if either of them return true. Returns false otherwise. * * @return true if the trait should be excluded, false otherwise */ protected final boolean isExcluded( Class classToExclude, String name, Class returnType ) { if ( isExcludedBaseType( classToExclude ) ) { return true; } if ( isExcludedReturnType( returnType ) ) { return true; } if ( isExcludedName( name ) ) { return true; } return false; } /** * Whether to exclude the given base type when searching up the model inheritance chain. *

* This can be useful when the base types define traits that are framework-specific, and should * be filtered out from 'real' business model traits. *

* By default, excludes any base types from BaseTraitStyleConfig.setExcludeBaseType. * * @return true if the trait should be excluded, false otherwise */ protected boolean isExcludedBaseType( Class classToExclude ) { String className = classToExclude.getName(); if ( mExcludeBaseType != null && mExcludeBaseType.matcher( className ).matches() ) { return true; } return false; } /** * Whether to exclude the given return type when searching for traits. *

* This can be useful when the convention or base class define traits that are * framework-specific, and should be filtered out from 'real' business model traits. *

* By default, excludes any return types from * BaseTraitStyleConfig.setExcludeReturnType. * * @param clazz * return type to consider for exclusion * @return true if the trait should be excluded, false otherwise */ protected boolean isExcludedReturnType( Class clazz ) { if ( mExcludeReturnType != null ) { for ( Class excludedClass : mExcludeReturnType ) { if ( excludedClass.isAssignableFrom( clazz ) ) { return true; } } } return false; } /** * Whether to exclude the given name when searching for traits. *

* This can be useful when the convention defines traits that are framework-specific (eg. * getClass()), and should be filtered out from 'real' business model traits. *

* By default, excludes any names from BaseTraitStyleConfig.setExcludeName. * * @param name * to consider for exclusion * @return true if the trait should be excluded, false otherwise */ protected boolean isExcludedName( String name ) { if ( ArrayUtils.contains( mExcludeName, name ) ) { return true; } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy