diff options
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.common.runtime/src/org/eclipse/jst/jsf/common/runtime/internal/model/component/ComponentInfo.java')
-rw-r--r-- | jsf/plugins/org.eclipse.jst.jsf.common.runtime/src/org/eclipse/jst/jsf/common/runtime/internal/model/component/ComponentInfo.java | 930 |
1 files changed, 0 insertions, 930 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common.runtime/src/org/eclipse/jst/jsf/common/runtime/internal/model/component/ComponentInfo.java b/jsf/plugins/org.eclipse.jst.jsf.common.runtime/src/org/eclipse/jst/jsf/common/runtime/internal/model/component/ComponentInfo.java deleted file mode 100644 index 6bb462940..000000000 --- a/jsf/plugins/org.eclipse.jst.jsf.common.runtime/src/org/eclipse/jst/jsf/common/runtime/internal/model/component/ComponentInfo.java +++ /dev/null @@ -1,930 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2008 Oracle Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Oracle Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.jst.jsf.common.runtime.internal.model.component; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import org.eclipse.jst.jsf.common.runtime.internal.model.ViewObject; -import org.eclipse.jst.jsf.common.runtime.internal.model.component.AbstractVisitor.VisitationPolicy; -import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.FacetDecorator; - -/** - * Models a basic UI component instance - * - * TODO: should implement a visitor pattern to traverse component trees - * - * @author cbateman - * - */ -public class ComponentInfo extends ViewObject implements Serializable, - IVisitable -{ - /** - * serializable id - */ - private static final long serialVersionUID = 2517204356825585699L; - - private final static int DEFAULT_ARRAY_SIZE = 4; - - private transient BeanPropertyManager _beanPropertyManager; - /** - * Encapsulates all of the data for the view object - */ - protected final ComponentInfoData _data; - - // initialized - // by - // getBeanProperties - - /** - * @param id - * @param parent - * @param componentTypeInfo - * @param isRendered - */ - protected ComponentInfo(final String id, final ComponentInfo parent, - final ComponentTypeInfo componentTypeInfo, final boolean isRendered) - { - super(new ComponentInfoData(id, parent, componentTypeInfo, isRendered)); - _data = (ComponentInfoData) super.getData(); - - final Set propExclude = new HashSet(); - propExclude.add("attributeNames"); //$NON-NLS-1$ - propExclude.add("componentTypeInfo"); //$NON-NLS-1$ - propExclude.add("valueChangeListeners"); //$NON-NLS-1$ - propExclude.add("visitableChildren"); //$NON-NLS-1$ - - _beanPropertyManager = new BeanPropertyManager(this, propExclude); - } - - /** - * @param data - */ - protected ComponentInfo(final ComponentInfoData data) - { - super(data); - _data = data; - } - - /** - * Construct a new component info using the attributes keyed by name in - * attributes to set values. The names must match the corresponding bean - * property names. Primitives should be wrapped in their corresponding - * object types. Exceptions will be thrown if there is a type mismatch on an - * expected type. Number will be used for all numeric primitive wrappers an - * the corresponding "to" will be called. - * - * @param parent - * @param componentTypeInfo - * @param attributes - * @throws ClassCastException - * if an attribute's value doesn't match the expected type - * @throws NullPointerException - * if an attribute value is null for a value whose type is - * expected to be primitive - * @throws IllegalArgumentException - * if attributes does not contain a required key. - */ - protected ComponentInfo(final ComponentInfo parent, - final ComponentTypeInfo componentTypeInfo, final Map attributes) - { - this(getStringProperty("id", attributes, false), parent, //$NON-NLS-1$ - componentTypeInfo, getBooleanProperty("rendered", attributes, false)); //$NON-NLS-1$ - } - - /** - * @param key - * @param attributes - * @param mandatory - * @return the value in attributes at location key, forcing a - * ClassCastException if it turns out not to be a String. - * @throws ClassCastException - * if the attribute for key is not a String - * @throws IllegalArgumentException - * if the attribute for key is null but mandatory is true. - */ - protected static String getStringProperty(final String key, - final Map attributes, final boolean mandatory) - { - final Object value = attributes.get(key); - - if (mandatory && value == null) - { - throw new IllegalArgumentException(key - + " is a mandatory attribute"); //$NON-NLS-1$ - } - return (String) value; - } - - /** - * @param key - * @param attributes - * @param mandatory - * - * @return the value in attributes at location, forcing a ClassCastExceptio - * if it is not a Boolean and mandatory. returns false if no value - * and not mandatory - * @throws IllegalArgumentException - * if key is not found and value is mandatory - */ - protected static boolean getBooleanProperty(final String key, - final Map attributes, final boolean mandatory) - { - final Boolean value = (Boolean) attributes.get(key); - - if (value == null) - { - if (mandatory) - { - throw new IllegalArgumentException(key + "is mandatory"); //$NON-NLS-1$ - } - return false; - } - - return value.booleanValue(); - } - - /** - * @param key - * @param attributes - * @return the integer property for key. Casts the value to Number and calls - * Number.intValue(). 0 if no value. - */ - protected static int getIntegerProperty(final String key, - final Map attributes) - { - final Number value = (Number) attributes.get(key); - - if (value == null) - { - return 0; - } - - return value.intValue(); - } - - /** - * @param key - * @param attributes - * @return the component info value from attributes - */ - protected static ComponentInfo getComponentProperty(final String key, - final Map attributes) - { - return (ComponentInfo) attributes.get(key); - } - - /** - * @return the id - */ - public final String getId() - { - return _data.getId(); - } - - /** - * @return the component type info - */ - public final ComponentTypeInfo getComponentTypeInfo() - { - return _data.getComponentTypeInfo(); - } - - /** - * Pre-condition: isModifiable() == true Post-condition: getChildren() will - * return an empty list. - */ - protected final void clearChildren() - { - _data.getChildren().clear(); - } - - /** - * @return the children. List is unmodifiable. List contains all children - * including facets. - */ - public final List/* <ComponentInfo> */getChildren() - { - if (_data.isProtected()) - { - return _data.getChildren(); - } - return Collections.unmodifiableList(_data.getChildren()); - } - - /** - * Get the sub-set of {@link #getChildren()} that are facets. This is a - * convenience method for {@link #getDecorators(Class)} - * - * @return all component children that are facets - */ - public final List getFacets() - { - return getDecorators(ComponentFactory.FACET); - } - - /** - * @param childComponent - */ - public final void addChild(final ComponentInfo childComponent) - { - if (childComponent == this) - { - throw new IllegalArgumentException( - "A component cannot be its own child"); //$NON-NLS-1$ - } - _data.addChild(childComponent); - // we need to reset the child's parent to me - childComponent.setParent(this); - } - - /** - * @param parent - */ - public final void setParent(ComponentInfo parent) - { - _data.setParent(parent); - } - - /** - * @param name - * @param facetComponent - */ - public final void addFacet(final String name, - final ComponentInfo facetComponent) - { - addChild(facetComponent); - addDecorator(new FacetDecorator(name, facetComponent)); - } - - /** - * @param component - * @return if component corresponds to a facet of this component, returns - * the name of that facet. Returns null if not found. - */ - public final String getFacetName(final ComponentInfo component) - { - if (component == null) - { - return null; - } - - final List facets = getDecorators(ComponentFactory.FACET); - - for (final Iterator it = facets.iterator(); it.hasNext();) - { - final FacetDecorator facet = (FacetDecorator) it.next(); - if (component == facet.getDecorates()) - { - return facet.getName(); - } - } - - // component is not a facet - return null; - } - - /** - * @param name - * @return if this has a facet called name, then returns it's single root - * component. - */ - public final ComponentInfo getFacet(final String name) - { - if (name == null) - { - return null; - } - - final List facets = getDecorators(ComponentFactory.FACET); - - for (final Iterator it = facets.iterator(); it.hasNext();) - { - final FacetDecorator facet = (FacetDecorator) it.next(); - if (name.equals(facet.getName())) - { - return facet.getDecorates(); - } - } - - // not found - return null; - } - - public String toString() - { - final String parentId = getParent() != null ? getParent().getId() - : "null"; //$NON-NLS-1$ - String toString = getMostSpecificComponentName() + ": id=" //$NON-NLS-1$ - + _data.getId() + ", parentId: " + parentId + ", family=" //$NON-NLS-1$ //$NON-NLS-2$ - + getComponentTypeInfo().getComponentFamily() + ", render=" //$NON-NLS-1$ - + getComponentTypeInfo().getRenderFamily() + ", rendered=" //$NON-NLS-1$ - + isRendered(); - - // use bean introspection to dump child properties - if (this.getClass() != ComponentInfo.class) - { - toString += dumpProperties(); - } - - return toString; - } - - private String dumpProperties() - { - String properties = ""; //$NON-NLS-1$ - try - { - final BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass(), - ComponentInfo.class); - - final PropertyDescriptor[] descriptors = beanInfo - .getPropertyDescriptors(); - for (int i = 0; i < descriptors.length; i++) - { - final PropertyDescriptor desc = descriptors[i]; - final String name = desc.getName(); - final Object valueObj = desc.getValue(name); - final String value = valueObj != null ? valueObj.toString() - : "null"; //$NON-NLS-1$ - properties += ", " + name + "=" + value; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - catch (final IntrospectionException e) - { - return "Error introspecting bean: " + e.getLocalizedMessage(); //$NON-NLS-1$ - } - - return properties; - } - - /** - * @return used for toString. Clients should not use. - */ - protected String getMostSpecificComponentName() - { - return "UIComponent"; //$NON-NLS-1$ - } - - /** - * @return the parent of this component or null. - */ - public final ComponentInfo getParent() - { - return _data.getParent(); - } - - /** - * @return the rendered flag - */ - public final boolean isRendered() - { - return _data.isRendered(); - } - - public synchronized void addAdapter(final Class adapterType, - final Object adapter) - { - super.addAdapter(adapterType, adapter); - - // force an update on the next call to getBeanProperties - _beanPropertyManager.reset(); - } - - public synchronized Object removeAdapter(final Class adapterType) - { - final Object removed = super.removeAdapter(adapterType); - - _beanPropertyManager.reset(); - - return removed; - } - - /** - * @return the set of all bean property names for this component. The set is - * unmodifiable and will throw exceptions if modification is - * attempted. - */ - protected final Map/* <String, ComponentBeanProperty> */getBeanProperties() - { - return Collections.unmodifiableMap(_beanPropertyManager - .getBeanProperties()); - } - - /** - * @author cbateman - * - */ - public static class ComponentInfoData extends ViewObjectData - { - /** - * - */ - private static final long serialVersionUID = 5052732412917986062L; - /** - * the component id - */ - private final String _id; - /** - * the component's parent or null if none - */ - private ComponentInfo _parent; - - /** - * the type info for this component - */ - protected final ComponentTypeInfo _componentTypeInfo; - /** - * the rendered flage - */ - protected final boolean _isRendered; - - private List /* <ComponentInfo> */_children = new ArrayList( - DEFAULT_ARRAY_SIZE); - - /** - * @param id - * @param parent - * @param componentTypeInfo - * @param isRendered - */ - public ComponentInfoData(final String id, ComponentInfo parent, - ComponentTypeInfo componentTypeInfo, boolean isRendered) - { - super(false); - _id = id; - _parent = parent; - _componentTypeInfo = componentTypeInfo; - _isRendered = isRendered; - } - - /** - * @param childComponent - */ - protected void addChild(ComponentInfo childComponent) - { - enforceProtection(); - - getChildren().add(childComponent); - } - - /** - * @return the modifiable list of children - */ - protected final List/* <ComponentInfo> */getChildren() - { - return _children; - } - - protected void doBeforeProtecting() - { - super.doBeforeProtecting(); - // compact the children array list - if (_children.size() > 0) - { - _children = Collections.unmodifiableList(_children); - } - else - { - _children = Collections.EMPTY_LIST; - } - } - - /** - * @return the isRendered flag - */ - protected final boolean isRendered() - { - return _isRendered; - } - - /** - * @return the component type info flag - */ - protected final ComponentTypeInfo getComponentTypeInfo() - { - return _componentTypeInfo; - } - - /** - * @return the parent or null if no parent - */ - protected final ComponentInfo getParent() - { - return _parent; - } - - /** - * @param parent - */ - protected final void setParent(ComponentInfo parent) - { - enforceProtection(); - _parent = parent; - } - - /** - * @return the component id - */ - protected final String getId() - { - return _id; - } - } - - /** - * This is similar to the runtime getAttributes().get(name) call. The reason - * we don't implement a Map of all attribute values is that the implicit - * property structure can change at any time due to add/removeAdapter. To - * get all attributes known for a component, instead use: - * - * The synchronized block is advised to protect against concurrent - * modification exceptions on the keySet iterator. - * - * @param name - * - * @return the value of the attribute or null if none. - * - */ - public synchronized ComponentBeanProperty getAttribute(final String name) - { - return (ComponentBeanProperty) getBeanProperties().get(name); - } - - /** - * @return the set of valid attribute names. The Set is not modifiable. - */ - public synchronized Set/* <String> */getAttributeNames() - { - return getBeanProperties().keySet(); - } - - /** - * Stores a bean property descriptor along information about which - * implementation class declares it and what key to pass to getAdapter() in - * order to get it. - * - */ - public final static class ComponentBeanProperty - { - private final PropertyDescriptor _propertyDescriptor; - private final Object _declaringImplementation; - private final Class _adapterKeyClass; - - // only instantiable locally - private ComponentBeanProperty(Class adapterKeyClass, - Object declaringImplementationClass, - PropertyDescriptor propertyDescriptor) - { - super(); - _adapterKeyClass = adapterKeyClass; - _declaringImplementation = declaringImplementationClass; - _propertyDescriptor = propertyDescriptor; - } - - /** - * @return the value of property - */ - public final Object getValue() - { - final Method method = _propertyDescriptor.getReadMethod(); - if (method != null) - { - try - { - method.setAccessible(true); - return method.invoke(_declaringImplementation, - new Object[0]); - } - catch (IllegalArgumentException e) - { - e.printStackTrace(); - } - catch (IllegalAccessException e) - { - e.printStackTrace(); - } - catch (InvocationTargetException e) - { - e.printStackTrace(); - } - } - // if any step fails, return null - return null; - } - - /** - * @return the property descriptor - */ - public final PropertyDescriptor getPropertyDescriptor() - { - return _propertyDescriptor; - } - - /** - * @return the implemenation - */ - public final Object getDeclaringImplementationClass() - { - return _declaringImplementation; - } - - /** - * @return the adapter class for the interface that the declaring - * implementation is providing the impl for - */ - public final Class getAdapterKeyClass() - { - return _adapterKeyClass; - } - } - - /** - * Manages bean property information for a component - * - * @author cbateman - * - */ - protected final static class BeanPropertyManager - { - /** - * a map of the bean property names exposed by this component including - * all those added by addAdapter(). - * - * this is synthetic based the class definition and installed adapters - * so as long that info is available, no need to serialize. - */ - protected transient Map /* - * <String, - * ComponentBeanProperty> - */_beanProperties; // lazily - private final transient ComponentInfo _component; - private final transient Set _excludeNames; - - /** - * @param component - * @param excludeNames - */ - protected BeanPropertyManager(final ComponentInfo component, - final Set excludeNames) - { - _component = component; - _excludeNames = excludeNames; - } - - /** - * Will throw exception of the calling thread already holds the "this" - * monitor lock. This is to ensure that caller always acquires locks in - * appropriate order to prevent deadlock. - * - * @return the internal set of bean properties. This Set may be modified - * internally. - */ - public Map getBeanProperties() - { - if (Thread.holdsLock(this)) - { - throw new IllegalStateException( - "Must not already own this lock"); //$NON-NLS-1$ - } - - // must always acquire component lock first to prevent deadlock - synchronized (_component) - { - synchronized (this) - { - if (_beanProperties == null) - { - _beanProperties = calculateAllBeanPropNames(ViewObject.class); - } - - return _beanProperties; - } - } - } - - /** - * Will throw exception if the calling thread already holds the "this" - * monitor lock. This is to ensure that caller always acquires locks in - * appropriate order to prevent deadlock. - * - * Clears the internal map and sets to null. This will force it to be - * completely new built on the next call to getBeanProperties - */ - public void reset() - { - if (Thread.holdsLock(this)) - { - throw new IllegalStateException( - "Must not already own this lock"); //$NON-NLS-1$ - } - - // must always acquire component lock first to prevent deadlock - synchronized (_component) - { - synchronized (this) - { - if (_beanProperties != null) - { - _beanProperties.clear(); - _beanProperties = null; - } - } - } - } - - /** - * @param stopClass - * @return a synchronized map of all bean property names on this class - * up to stopClass, as well as all adapter property names (as - * though this really implemented them). - */ - private Map calculateAllBeanPropNames(final Class stopClass) - { - // use a set to prevents the duplicates - final Map allProperties = new HashMap(); - - { - final Class myClass = _component.getClass(); - final List myProperties = getOrCreateBeanProperties(myClass, - stopClass); - - addToMap(myProperties, _component, myClass, allProperties, _excludeNames); - } - - { - for (final Iterator it = _component.getAdapterMap().entrySet() - .iterator(); it.hasNext();) - { - Map.Entry entry = (Entry) it.next(); - - final Class adapterClass = (Class) entry.getKey(); - final Object declaringClass = entry.getValue(); - // get all props, excluding the ones on Object. - final List props = getOrCreateBeanProperties(adapterClass, - null); - addToMap(props, declaringClass, adapterClass, allProperties, - _excludeNames); - } - } - - return Collections.synchronizedMap(allProperties); - } - - private static void addToMap( - final List/* <ComponentBeanProperty> */addThese, - final Object declaringObject, final Class declaringAdapter, - final Map toMe, - Set excludeNames) - { - for (final Iterator it = addThese.iterator(); it.hasNext();) - { - final PropertyDescriptor desc = (PropertyDescriptor) it.next(); - - if (!toMe.containsKey(desc.getName()) - && !excludeNames.contains(desc.getName())) - { - toMe.put(desc.getName(), new ComponentBeanProperty( - declaringAdapter, declaringObject, desc)); - } - } - } - - /** - * lazily loaded with the local properties (those not defined using - * adapters) - * - * MUST INITIALIZE early so can synchronize on it - */ - private transient static Map /* <Class, List<PropertyDescriptor> */PROPERTY_MAP = new HashMap(); - - /** - * @param startClass - * @param stopClass - * @return a unmodifiable list of properties starting from startClass. - * stopClass is only used if an entry doesn't already exist in - * PROPERTY_MAP for startClass. The method is synchronized on - * the PROPERTY_MAP it updates. - */ - protected static List/* <PropertyDescriptor */getOrCreateBeanProperties( - final Class startClass, final Class stopClass) - { - synchronized (PROPERTY_MAP) - { - List localBeanProps = (List) PROPERTY_MAP.get(startClass); - - if (localBeanProps == null) - { - localBeanProps = calculateBeanProperties(startClass, - stopClass); - PROPERTY_MAP.put(startClass, Collections - .unmodifiableList(localBeanProps)); - } - - return localBeanProps; - } - } - - /** - * @param startClass - * @param stopClass - * @return a List<String> containing all of the bean names between - * startClass and stopClass. Start class must be a descendant - * (sub-class, sub-sub-class etc.) of stopClass. The properties - * on stopClass are excluded from analysis. - */ - private static List/* <PropertyDescriptor> */calculateBeanProperties( - final Class startClass, final Class stopClass) - { - BeanInfo beanInfo; - List names = new ArrayList(); - - try - { - beanInfo = Introspector.getBeanInfo(startClass, stopClass); - final PropertyDescriptor[] descriptors = beanInfo - .getPropertyDescriptors(); - - if (descriptors != null) - { - names = Arrays.asList(descriptors); - } - } - catch (final IntrospectionException e) - { - e.printStackTrace(); - } - return names; - } - - } - - /** - * Visits this node and it's entire tree and makes all nodes protected. - */ - public final void setSubtreeProtected() - { - // lock children first - final ComponentTreeVisitor protectionVisitor = new ComponentTreeVisitor(VisitationPolicy.ChildrenFirstPolicy) - { - public void visit(ComponentInfo component) - { - component.setProtected(); - } - }; - - accept(protectionVisitor); - } - - public void accept(AbstractVisitor visitor) - { - // check policy ordering - if (visitor.getPolicy().getOrdering() == VisitationPolicy.VISIT_PARENT_FIRST) - { - visitor.visit(this); - visitChildren(visitor); - } - else - { - visitChildren(visitor); - visitor.visit(this); - } - } - - private void visitChildren(AbstractVisitor visitor) - { - for (final Iterator it = getVisitableChildren(); it.hasNext();) - { - visitor.visit(it.next()); - } - } - - public Iterator getVisitableChildren() - { - return getChildren().iterator(); - } -}
\ No newline at end of file |