/* File: AccessLevelBeanInfo.java * Copyright (C) 2002-2003 The University of Iowa * Created by: Jeremy Faden <jbf@space.physics.uiowa.edu> * Jessica Swanner <jessica@space.physics.uiowa.edu> * Edward E. West <eew@space.physics.uiowa.edu> * * This file is part of the das2 library. * * das2 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.das2.beans; import org.das2.DasApplication; import java.beans.*; import java.util.ArrayList; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; import org.das2.util.LoggerManager; /** * This class is designed to implement access levels for bean properties. * The system property "edu.uiowa.physics.das.beans.AccessLevelBeanInfo.AccessLevel" will * determine the access level of the bean. The access levels that are currently supported * are "ALL" and "END_USER". The access level must be set prior to this class being loaded. * * @author Edward West */ public abstract class AccessLevelBeanInfo extends SimpleBeanInfo { private static final Logger logger= LoggerManager.getLogger("das2.system"); /** * Type-safe enumeration class used to specify access levels * for bean properties. * * **NOTE TO DEVELOPERS** * The order parameter for the constructor should not be specified as a negative number */ public static class AccessLevel implements Comparable { public static final AccessLevel ALL = new AccessLevel("ALL", 0); public static final AccessLevel DASML = new AccessLevel("DASML", 1000); public static final AccessLevel END_USER = new AccessLevel("END_USER", 0x7FFF0000); private String str; private int order; private AccessLevel(String str, int order) { this.str = str; this.order = order; } public int compareTo(Object o) { return order - ((AccessLevel)o).order; } @Override public boolean equals(Object o) { if ( !( o instanceof AccessLevel ) ) return false; return order==((AccessLevel)o).order; } @Override public int hashCode() { return this.order; } @Override public String toString() { return str; } } /** * this level indicates what persistence is allowed. */ public static class PersistenceLevel implements Comparable { public static final PersistenceLevel NONE = new PersistenceLevel( "NONE", 0); public static final PersistenceLevel TRANSIENT = new PersistenceLevel( "TRANSIENT", 1000 ); public static final PersistenceLevel PERSISTENT = new PersistenceLevel( "PERSISTENT", 2000); private String str; private int order; private PersistenceLevel(String str, int order) { this.str = str; this.order = order; } public int compareTo(Object o) { return order - ((PersistenceLevel)o).order; } @Override public boolean equals(Object o) { if ( !( o instanceof PersistenceLevel ) ) return false; return order==((PersistenceLevel)o).order; } @Override public int hashCode() { return this.order; } @Override public String toString() { return str; } } private Property[] properties; private Class beanClass; private static AccessLevel accessLevel; private static final Object lockObject = new Object(); static { String level = DasApplication.getProperty("edu.uiowa.physics.das.beans.AccessLevelBeanInfo.AccessLevel",null); if (level==null) { accessLevel = AccessLevel.ALL; } else if (level.equals("ALL")) { accessLevel = AccessLevel.ALL; } else if (level.equals("DASML")) { accessLevel = AccessLevel.DASML; } else if (level.equals("END_USER")) { accessLevel = AccessLevel.END_USER; } else { accessLevel = AccessLevel.ALL; } } /** * Returns the access level for AccessLevelBeanInfo objects. */ public static AccessLevel getAccessLevel() { return accessLevel; } /** * Sets the access level for AccessLevelBeanInfo objects. */ public static void setAccessLevel(AccessLevel level) { synchronized (lockObject) { accessLevel = level; } } public static Object getLock() { return lockObject; } /** * Creates and instance of AccessLevelBeanInfo. * Each element of the <code>properties</code> array must be of the type * <code>Object[]</code> with the following format: * <code>{ propertyName, accessorMethod, mutatorMethod, accessLevel}</code> * where the elements have the following meaning. * <ul> * <li><code>propertyName</code> - A <code>String</code> naming the property being specified.</li> * <li><code>accessorMethod</code> - A <code>String</code> specifying the name of the read method * for this property.</li> * <li><code>mutatorMethod</code> - A <code>String</code> specifying the name of the write method * for this property</li> * <li><code>accessLevel</code> - A <code>org.das2.beans.AccessLevelBeanInfo.AccessLevel</code> instance specifying * the access level for this property.</li> * </ul> */ protected AccessLevelBeanInfo(Property[] properties, Class beanClass) { this.properties = properties; this.beanClass = beanClass; } /** * convenient method that only returns the descriptors for the specified persistence level. * Also implements the property inheritance. */ public PropertyDescriptor[] getPropertyDescriptors( PersistenceLevel persistenceLevel ) { synchronized (lockObject) { try { ArrayList result= new ArrayList(); for (int index = 0; index < properties.length; index++) { if (persistenceLevel.compareTo(properties[index].getPersistenceLevel()) <= 0) { result.add( properties[index].getPropertyDescriptor(beanClass) ); } } BeanInfo[] moreBeanInfos= getAdditionalBeanInfo() ; if ( moreBeanInfos!=null ) { for ( int i=0; i<moreBeanInfos.length; i++ ) { result.addAll( Arrays.asList( moreBeanInfos[i].getPropertyDescriptors() ) ); } } return (PropertyDescriptor[]) result.toArray( new PropertyDescriptor[ result.size() ] ); } catch (IntrospectionException ie) { throw new IllegalStateException(ie.getMessage()); } } } /** * get the property descriptors for the object. * @return */ @Override public PropertyDescriptor[] getPropertyDescriptors() { synchronized (lockObject) { try { int count = 0; for (int index = 0; index < properties.length; index++) { if (accessLevel.compareTo(properties[index].getLevel()) <= 0) { count++; } } PropertyDescriptor[] descriptors = new PropertyDescriptor[count]; int propertyIndex = 0; for (int index = 0; index < properties.length; index++) { if (accessLevel.compareTo(properties[index].getLevel()) <= 0) { logger.log(Level.FINE, "property: {0}", properties[index].getPropertyDescriptor(beanClass).getDisplayName()); descriptors[propertyIndex] = properties[index].getPropertyDescriptor(beanClass); propertyIndex++; } } return descriptors; } catch (IntrospectionException ie) { throw new IllegalStateException(ie.getMessage()); } } } /** * get the Property for the PropertyDescriptor. * @param pd * @return */ public Property getProperty( PropertyDescriptor pd ) { String name= pd.getName(); for ( int i=0; i<properties.length; i++ ) { if ( properties[i].name.equals(name) ) { return properties[i]; } } BeanInfo[] additional= getAdditionalBeanInfo(); if ( additional!=null && additional.length>0) { for ( int i=0; i<additional.length; i++ ) { BeanInfo b= additional[i]; if ( b instanceof AccessLevelBeanInfo ) { Property p= ((AccessLevelBeanInfo)b).getProperty(pd); if ( p!=null ) return p; } } } return null; } /** * get the descriptor for the class. * @return */ @Override public BeanDescriptor getBeanDescriptor() { return new BeanDescriptor(beanClass); } /** AccessLevelBeanInfo.Property is a helper class for subclasses of * AccessLevelBeanInfo to specify a list of properties in a way that * is independant of the underlying Bean/PropertyDescriptor implementation. * * @author Edward West */ protected static class Property { /** The name the user will see for this property */ private final String name; /** The AccessLevel associated with this property */ private final AccessLevel level; /** The PersistenceLevel associated with this property */ private final PersistenceLevel persistenceLevel; /** The name of the accessor method for this property */ private final String getter; /** The name of the mutator method for this property */ private final String setter; /** The name of the indexed accessor method for this property */ private final String igetter; /** The name of the indexed mutator method for this property */ private final String isetter; /** The class of the graphical editor for this property */ private final Class editor; /** flag indicated whether of not this property is indexed */ private final boolean indexed; /** Creates a new Property object. * @param name the name the user will see for this property * @param level the AccessLevel associated with this property * @param getter the name of the accessor method for this property * @param setter the name of the mutator method for this property * @param editor the class name of the graphical editor for this property */ public Property(String name, AccessLevel level, PersistenceLevel persistenceLevel, String getter, String setter, Class editor) { this.name = name; this.level = level; this.persistenceLevel= persistenceLevel; this.getter = getter; this.setter = setter; this.igetter = null; this.isetter = null; this.editor = editor; this.indexed = false; } /** Creates a new Property object. * @param name the name the user will see for this property * @param level the AccessLevel associated with this property * @param getter the name of the accessor method for this property * @param setter the name of the mutator method for this property * @param editor the class name of the graphical editor for this property */ public Property(String name, AccessLevel level, String getter, String setter, Class editor) { this( name, level, PersistenceLevel.TRANSIENT, getter, setter, editor ); } /** Creates a new Property object that is indexed. * @param name the name the user will see for this property * @param level the AccessLevel associated with this property * @param getter the name of the accessor method for this property * @param setter the name of the mutator method for this property * @param igetter the name of the indexed accessor method for this property * @param isetter the name of the indexed mutator method for this property * @param editor the class name of the graphical editor for this property */ public Property(String name, AccessLevel level, PersistenceLevel persistenceLevel, String getter, String setter, String igetter, String isetter, Class editor) { this.name = name; this.level = level; this.persistenceLevel= persistenceLevel; this.getter = getter; this.setter = setter; this.igetter = igetter; this.isetter = isetter; this.editor = editor; this.indexed = true; } /** Creates a new Property object that is indexed. * @param name the name the user will see for this property * @param level the AccessLevel associated with this property * @param getter the name of the accessor method for this property * @param setter the name of the mutator method for this property * @param igetter the name of the indexed accessor method for this property * @param isetter the name of the indexed mutator method for this property * @param editor the class name of the graphical editor for this property */ public Property(String name, AccessLevel level, String getter, String setter, String igetter, String isetter, Class editor) { this( name, level, PersistenceLevel.TRANSIENT, getter, setter, igetter, isetter, editor ); } /** Returns the access level for this property */ public AccessLevel getLevel() { return level; } /** Returns a PropertyDescriptor for this property that is associated * with the specified bean class. */ public PropertyDescriptor getPropertyDescriptor(Class beanClass) throws IntrospectionException { PropertyDescriptor pd; if (indexed) { pd = new IndexedPropertyDescriptor(name, beanClass, getter, setter, igetter, isetter); } else { pd = new PropertyDescriptor(name, beanClass, getter, setter); } if (editor != null) { pd.setPropertyEditorClass(editor); } return pd; } public AccessLevelBeanInfo.PersistenceLevel getPersistenceLevel() { return persistenceLevel; } } }