package hep.aida.ref.plotter; import hep.aida.IBaseStyle; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; public abstract class BaseStyle extends WeakStyleListener implements IBaseStyle { private Hashtable internalParameterHash = new Hashtable(); private Hashtable parameterHash = new Hashtable(); private Hashtable baseStyles = new Hashtable(); private List parentList = new ArrayList(); private String name = "plotter"; /** * Create a BaseStyle without a parent. * The parent, if ever available, can be set via the setParent method. * */ protected BaseStyle () { super(); initializeBaseStyle(); addParameter( new BooleanStyleParameter(Style.IS_VISIBLE, true) ); } /** * Create a clone of a BaseStyle. * @param style The BaseStyle to be cloned. * */ protected BaseStyle ( BaseStyle style ) { this(); copyStyle( this, style ); List pl = style.parentList(); this.setParentList(pl); } private void copyStyle( BaseStyle newStyle, BaseStyle oldStyle ) { Collection pars = oldStyle.parameters(); Iterator iter = pars.iterator(); while( iter.hasNext() ) { AbstractStyleParameter oldPar = (AbstractStyleParameter) iter.next(); String[] av = oldPar.allowedValues(); if ( ! oldPar.isParameterValueSet() ) newStyle.setParameter(oldPar.name()); else newStyle.setParameter( oldPar.name(), oldPar.parameterValue(), av); } String[] names = newStyle.baseStyleNames(); for ( int i = 0; i < names.length; i++ ) copyStyle( newStyle.baseStyle( names[i] ), oldStyle.baseStyle( names[i] ) ); } /** * Initialize the BaseStyle. * This method has to be overwritten by all Style that has to add parameters or * internal BaseStyles. * */ protected abstract void initializeBaseStyle(); /** * Set the name of this BaseStyle. * @param name The name. * */ protected void setName( String name ) { this.name = name; } /** * Get the name of this BaseStyle. * @return The name of the BaseStyle. * */ public String name() { return name; } /** * @return The type of the style. */ public Class type() { return this.getClass().getInterfaces()[0]; } /** * @return A sub style, knowing its name. */ public IBaseStyle child(String name) { return (IBaseStyle) baseStyles.get( name ); } /** * @return The array of sub styles. */ public IBaseStyle[] children() { IBaseStyle[] children = new IBaseStyle[baseStyles.size()]; Set keys = baseStyles.keySet(); Iterator i = keys.iterator(); int count = 0; while( i.hasNext() ) children[count++] = (IBaseStyle) baseStyles.get(i.next()); return children; } /** * Set isVisible of the data. */ public boolean setVisible(boolean visible) { return setParameter(Style.IS_VISIBLE, String.valueOf(visible) ); } /** * Get isVisible of the data. * return The isVisible of the data. */ public boolean isVisible() { String isVisible = parameterValue(Style.IS_VISIBLE); return Boolean.valueOf(isVisible).booleanValue(); } /** * Set the parent for this BaseStyle. * @param style The parent for this BaseStyle. * */ public void setParent( IBaseStyle style ) { if (style == null) return; ArrayList list = new ArrayList(1); list.add(style); setParentList(list); } /** * First remove current parents (if present), then add new parents * from the list. If <code>list == null || list.size() == 0</code>, * just remove current parents. */ public void setParentList( List list ) { if (parentList != null && parentList.size() > 0) { int size = parentList.size(); Object[] tmpArray = parentList.toArray(); for (int i=0; i<size; i++) { Object obj = tmpArray[i]; if (obj instanceof IBaseStyle) removeParent((IBaseStyle) obj, false); } parentList.clear(); } if (list == null || list.size() == 0) return; for (int i=0; i<list.size(); i++) { Object obj = list.get(i); if (obj instanceof IBaseStyle) addParent((IBaseStyle) obj, false); } notifyStyleChanged(); } /** * Remove all parents and all the parents' parents */ public void removeAllParents() { /* if (parentList != null && parentList.size() > 0) { for (int i=0; i<parentList.size(); i++) { Object obj = parentList.get(i); if (obj instanceof BaseStyle) ((BaseStyle) obj).removeAllParents(); } } */ // remove all immediate parents setParentList(null); } /** * This method removes one parent and all its children (recursively). * To remove all parents use <code>setParentList(null)</code> */ public void removeParent( IBaseStyle style ) { removeParent(style, true); } void removeParent( IBaseStyle style, boolean sendNotification ) { if (style instanceof BaseStyle) ((BaseStyle) style).removeStyleListener(this); if (!isMyParent(style)) return; parentList.remove(style); // remove parent children recursively IBaseStyle[] parentChildren = style.children(); for (int i=0; i<parentChildren.length; i++) { String name = parentChildren[i].name(); BaseStyle localChild = baseStyle(name); if (localChild != null) localChild.removeParent(parentChildren[i]); } if ( sendNotification ) notifyStyleChanged(); } public void addParent( IBaseStyle style ) { addParent(style, true); } void addParent( IBaseStyle style, boolean sendNotification ) { if (isMyParent(style)) return; if (style == this) { System.out.println("***** SELF-Parent :: skip :: "+style.name()); return; } if (parentList == null) parentList = new ArrayList(); parentList.add(style); if (style instanceof BaseStyle) ((BaseStyle) style).addStyleListener(this); // add parent children recursively IBaseStyle[] parentChildren = style.children(); for (int i=0; i<parentChildren.length; i++) { String name = parentChildren[i].name(); BaseStyle localChild = baseStyle(name); if (localChild != null) localChild.addParent(parentChildren[i]); } if ( sendNotification ) notifyStyleChanged(); } public void addParentList( List pl ) { if (pl == null || pl.size() == 0) return; if (parentList == null) parentList = new ArrayList(); for (int i=0; i<pl.size(); i++) { Object obj = pl.get(i); if (obj instanceof IBaseStyle) addParent((IBaseStyle) obj, false); } notifyStyleChanged(); } // Check if "style" is in the parent list public boolean isMyParent(IBaseStyle style) { if ( style == null || parentList == null || parentList.size() == 0 ) return false; return parentList.contains(style); } /** * Get the parent for this BaseStyle. * @return The parent. * */ public List parentList() { return parentList; } /** * Add a BaseStyle to this BaseStyle. * This method is to be invoked when a BaseStyle contains other BaseStyles in order * for the reset and the setParent methods to work properly. * */ protected boolean addBaseStyle( IBaseStyle baseStyle, String name ) { BaseStyle bs = (BaseStyle) baseStyle; bs.setName(name); if ( baseStyles.get( bs.name() ) != null ) ( (BaseStyle) baseStyles.get(bs.name()) ).removeStyleListener(this); baseStyles.put( bs.name(), baseStyle ); bs.addStyleListener(this); notifyStyleChanged(); return true; } /** * Get a BaseStyle contained in this BaseStyle. * The indexing is the internal one. * */ private BaseStyle baseStyle( String name ) { return (BaseStyle) child(name); } /** * Get the available BaseStyle names attached to this BaseStyle. * */ private String[] baseStyleNames() { String[] names = new String[ baseStyles.size() ]; Enumeration e = baseStyles.keys(); int count = 0; while( e.hasMoreElements() ) names[ count++ ] = (String) e.nextElement(); return names; } /** * Add a new parameter to this BaseStyle. * @param styleParameter The style parameter. * */ protected void addParameter( AbstractStyleParameter styleParameter ) { addParameter(styleParameter, true); } private void addParameter( AbstractStyleParameter styleParameter, boolean isInternal) { String name = styleParameter.name(); if ( isRegisteredParameter(name) ) throw new IllegalArgumentException("Parameter "+styleParameter.name()+" already belongs to this style."); if ( isInternal ) internalParameterHash.put(name, styleParameter); parameterHash.put(name, styleParameter); } private boolean isInternalParameter( String parameterName ) { return internalParameterHash.containsKey(parameterName); } private boolean isExternalParameter( String parameterName ) { return ( ! internalParameterHash.containsKey(parameterName) ) && parameterHash.containsKey(parameterName); } private boolean isRegisteredParameter( String parameterName ) { return parameterHash.containsKey(parameterName); } public AbstractStyleParameter parameter(String parName) { if ( ! isRegisteredParameter(parName) ) throw new IllegalArgumentException("Parameter with name "+parName+" does not belong to this style."); return (AbstractStyleParameter) parameterHash.get(parName); } public AbstractStyleParameter deepestSetParameter(String parameterName) { //protected AbstractStyleParameter deepestSetParameter(String parameterName) { if ( parameter(parameterName).isParameterValueSet() || parentList == null || parentList.size() == 0) return parameter(parameterName); else { Iterator it = parentList().iterator(); BaseStyle pbs = null; while (it.hasNext()) { pbs = (BaseStyle) it.next(); if (pbs == null) continue; if (pbs.isParameterSet(parameterName)) { return pbs.deepestSetParameter(parameterName); } } return (pbs == null) ? parameter(parameterName) : pbs.parameter(parameterName); } } protected int numberOfParameters() { return parameterHash.size(); } protected Collection parameters() { return parameterHash.values(); } public boolean isParameterSet(String parameterName) { return isParameterSet(parameterName, true); } public boolean isParameterSet(String parameterName, boolean recursive) { if ( parameter(parameterName).isParameterValueSet() || !recursive || parentList == null || parentList.size() == 0) return parameter(parameterName).isParameterValueSet(); else { boolean isSet = false; Iterator it = parentList().iterator(); while (it.hasNext()) { BaseStyle pbs = (BaseStyle) it.next(); if (pbs == null) continue; if (pbs.isParameterSet(parameterName, recursive)) { isSet = true; break; } } return isSet; } } /** * Below are the AIDA methods. * */ public String[] availableParameterOptions(String parameterName) { AbstractStyleParameter par = parameter(parameterName); return par.allowedValues(); } public String[] availableParameters() { int size = numberOfParameters(); String[] pars = new String[ size ]; Collection parameters = parameters(); Iterator iter = parameters.iterator(); int count = 0; while( iter.hasNext() ) pars[count++] = ( (AbstractStyleParameter) iter.next() ).name(); return pars; } public String parameterValue(String parameterName) { AbstractStyleParameter par = deepestSetParameter(parameterName); return par.parameterValue(); } public void reset() { reset(true); } private void reset( boolean sendNotification ) { removeAllParents(); Enumeration parKeys = parameterHash.keys(); while( parKeys.hasMoreElements() ) parameter( (String) parKeys.nextElement() ).reset(); Enumeration keys = baseStyles.keys(); while( keys.hasMoreElements() ) baseStyle( (String) keys.nextElement() ).reset(false); if ( sendNotification ) notifyStyleChanged(); } public boolean setParameter(String parameterName) { boolean result = false; if ( isRegisteredParameter(parameterName) ) { result = parameter(parameterName).setParameter(); if ( ! isInternalParameter(parameterName) ) result = false; } else { StringStyleParameter styleParameter = new StringStyleParameter(parameterName, null); addParameter(styleParameter, false); } notifyStyleChanged(); return result; } public boolean setParameter(String parameterName, String parValue) { String[] av = null; if (isRegisteredParameter(parameterName) && parameter(parameterName) instanceof RevolvingStyleParameter) { String[] oldAv = parameter(parameterName).allowedValues(); if (oldAv == null || oldAv.length == 0) av = new String[] { parValue }; } return setParameter(parameterName, parValue, av); } public boolean setParameter(String parameterName, String parValue, String[] parAllowedValues) { boolean result = false; if ( isRegisteredParameter(parameterName) ) { if (parAllowedValues != null) parameter(parameterName).setAllowedValues(parAllowedValues); result = parameter(parameterName).setParameter(parValue); if ( ! isInternalParameter(parameterName) ) result = false; } else { StringStyleParameter styleParameter = new StringStyleParameter(parameterName, null); addParameter(styleParameter, false); if (parAllowedValues != null) styleParameter.setAllowedValues(parAllowedValues); styleParameter.setValue(parValue); } notifyStyleChanged(); return result; } // Use this method to give styles a different default than the "standard one" public void setParameterDefault(String parameterName, String parDefaultValue) { if ( ! isRegisteredParameter(parameterName) ) throw new IllegalArgumentException("Parameter "+parameterName+" does not exist "); parameter(parameterName).setDefaultValue(parDefaultValue); notifyStyleChanged(); } /** * Notify the listeners that the style has changed. * */ public void styleChanged(BaseStyle style) { notifyStyleChanged(); } void notifyStyleChanged() { StyleListener[] tmp = getValidStyleListeners(); for ( int i = 0; i < tmp.length; i++ ) { tmp[i].styleChanged(this); } } }