You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by js...@apache.org on 2004/01/16 03:28:09 UTC

cvs commit: jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui FileEditor.java TestBeanGUI.java BeanInfoSupport.java WrapperEditor.java

jsalvata    2004/01/15 18:28:09

  Modified:    src/core/org/apache/jmeter/testbeans/gui FileEditor.java
                        TestBeanGUI.java BeanInfoSupport.java
                        WrapperEditor.java
  Log:
  * Using constants for attribute names.
  * Diferentiated noEdit into not accepting expressions and not accepting
  values beyond de editor's tags.
  * Fixed possible NPE in TestBeanGUI.group and .groupDisplayName.
  * Improved comments.
  
  Revision  Changes    Path
  1.4       +2 -2      jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/FileEditor.java
  
  Index: FileEditor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/FileEditor.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- FileEditor.java	15 Jan 2004 01:55:39 -0000	1.3
  +++ FileEditor.java	16 Jan 2004 02:28:08 -0000	1.4
  @@ -107,7 +107,7 @@
   		editor= new WrapperEditor(
   			new SimpleFileEditor(),
   			new ComboStringEditor(),
  -			true, true);
  +			true, true, true);
   
   		// Create a panel containing the combo and the button:
   		panel= new JPanel(new BorderLayout(5,0));
  
  
  
  1.5       +92 -50    jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/TestBeanGUI.java
  
  Index: TestBeanGUI.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/TestBeanGUI.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestBeanGUI.java	15 Jan 2004 02:00:00 -0000	1.4
  +++ TestBeanGUI.java	16 Jan 2004 02:28:08 -0000	1.5
  @@ -122,7 +122,8 @@
    * <dl>
    * <dt>group: String</dt>
    * <dd>Group under which the property should be shown in the GUI. The string is
  - * also used as a group title. The default group is "".</dd>
  + * also used as a group title (but see comment on resourceBundle below). The
  + * default group is "".</dd>
    * <dt>order: Integer</dt>
    * <dd>Order in which the property will be shown in its group. A smaller
    * integer means higher up in the GUI. The default order is 0. Properties
  @@ -130,16 +131,19 @@
    * <dt>tags: String[]</dt>
    * <dd>List of values to be offered for the property in addition to those
    * offered by its property editor.</dd>
  - * <dt>noUndefined: Boolean</dt>
  + * <dt>notUndefined: Boolean</dt>
    * <dd>If true, the property should not be left undefined. A <b>default</b>
    * attribute must be provided if this is set.</dd>
  - * <dd>noEdit: Boolean</dd>
  - * <dd>If true, the property content should not be edited manually, that is: it
  - * should always be one of the tags values.</dt>
  + * <dd>notExpression: Boolean</dd>
  + * <dd>If true, the property content should always be constant: JMeter
  + * 'expressions' (strings using ${var}, etc...) can't be used.</dt>
  + * <dd>notOther: Boolean</dd>
  + * <dd>If true, the property content must always be one of the tags values or
  + * null.</dt>
    * <dt>default: Object</dt>
    * <dd>Initial value for the property's GUI. Must be provided and be non-null
  - * if <b>noUndefined</b> is set. Must be one of the provided tags (or null) if
  - * <b>noEdit</b> is set.
  + * if <b>notUndefined</b> is set. Must be one of the provided tags (or null) if
  + * <b>notOther</b> is set.
    * </dl>
    * <p>
    * The following BeanDescriptor attributes are also understood:
  @@ -151,8 +155,8 @@
    * in the GUI. The default order is 0. Groups of equal order are sorted
    * alphabetically.</dd>
    * <dt>resourceBundle: ResourceBundle</dt>
  - * <dd>A resource bundle to be used for GUI localization. Group display names,
  - * for example, will be obtained from property "<i>group</i>.displayName" if
  + * <dd>A resource bundle to be used for GUI localization: group display names
  + * will be obtained from property "<b><i>group</i>.displayName</b>" if
    * available (where <b><i>group</i></b> is the group name).
    * </dl>
    */
  @@ -160,6 +164,20 @@
   {
       private static Logger log = LoggingManager.getLoggerForClass();
   
  +	public static final String GROUP= "group";
  +	public static final String ORDER= "order";
  +	public static final String TAGS= "tags";
  +	public static final String NOT_UNDEFINED= "notUndefined";
  +	public static final String NOT_EXPRESSION= "notExpression";
  +	public static final String NOT_OTHER= "notOther";
  +	public static final String DEFAULT= "default";
  +	public static final String RESOURCE_BUNDLE= "resourceBundle";
  +	public static final String ORDER(String group) {
  +		return "group."+group+".order";
  +	}
  +
  +	public static final String DEFAULT_GROUP= "";
  +
       /**
        * Class of the objects being edited.
        */
  @@ -315,7 +333,7 @@
   			editors[i]= propertyEditor;
   
   			// Initialize the editor with the provided default value or null:
  -            setEditorValue(i, descriptors[i].getValue("default"));
  +            setEditorValue(i, descriptors[i].getValue(DEFAULT));
           }
   
   		// Obtain message formats:
  @@ -340,7 +358,7 @@
   			PropertyEditor typeEditor, PropertyDescriptor descriptor)
   	{
   		String[] editorTags= typeEditor.getTags();
  -		String[] additionalTags= (String[])descriptor.getValue("tags");
  +		String[] additionalTags= (String[])descriptor.getValue(TAGS);
   		String[] tags= null;
   		if (editorTags == null) tags= additionalTags;
   		else if (additionalTags == null) tags= editorTags;
  @@ -350,22 +368,24 @@
   			for (int i=0; i<editorTags.length; i++) tags[j++]= editorTags[i];
   			for (int i=0; i<additionalTags.length; i++) tags[j++]= additionalTags[i];
   		}
  -		
  -		boolean noUndefined=
  -			Boolean.TRUE.equals(descriptor.getValue("noUndefined"));
  -		boolean noEdit=
  -			Boolean.TRUE.equals(descriptor.getValue("noEdit"));
  +
  +		boolean notNull=
  +			Boolean.TRUE.equals(descriptor.getValue(NOT_UNDEFINED));
  +		boolean notExpression=
  +			Boolean.TRUE.equals(descriptor.getValue(NOT_EXPRESSION));
  +		boolean notOther=
  +			Boolean.TRUE.equals(descriptor.getValue(NOT_OTHER));
   
   		PropertyEditor guiEditor;
  -		if (noUndefined && tags==null)
  +		if (notNull && tags==null)
   		{
   			guiEditor= new FieldStringEditor();
   		}
   		else
   		{
   			ComboStringEditor e= new ComboStringEditor();
  -			e.setNoUndefined(noUndefined);
  -			e.setNoEdit(noEdit);
  +			e.setNoUndefined(notNull);
  +			e.setNoEdit(notExpression && notOther);
   			e.setTags(tags);
   			
   			guiEditor= e;
  @@ -373,34 +393,55 @@
   
   		WrapperEditor wrapper= new WrapperEditor(
   			typeEditor, guiEditor,
  -			!noUndefined, // acceptsNull
  -			!noEdit // acceptsExpressions TODO: can be finer
  +			!notNull, // acceptsNull
  +			!notExpression, // acceptsExpressions
  +			!notOther // acceptsOther
   			);
   
  -		Object defaultValue= descriptor.getValue("default");
  +		Object defaultValue= descriptor.getValue(DEFAULT);
   		
  -		if (guiEditor instanceof ComboStringEditor && !noEdit)
  +		try
   		{
  -			// Provide an initial edit value:
  -			if (tags != null)
  -			{
  -				((ComboStringEditor)guiEditor).setInitialEditValue(tags[0]);
  -			}
  -			else
  -			{
  -				// 'expressions' are currently always valid on
  -				// editable fields: TODO: could be finer
  -				((ComboStringEditor)guiEditor).setInitialEditValue("${}");
  -			}
  -			// TODO: I don't like this solution. We could make a
  -			// more convenient approach if we knew whether the property
  -			// accepts expressions or not, whether it accepts any 
  -			// values beyond the provided tags or not, etc... 
  -			// ... plus we could define a "initialEditValue" property descriptor
  -			// attribute to explicitly specify which value should be used. 
  +			wrapper.setValue(defaultValue);
   		}
  +		catch (IllegalArgumentException e)
  +		{
  +			log.error("The default value for property " + descriptor.getName()
  +				+" is not valid. Or a default value was not provided and "
  +				+" property attribute notUndefined is set to true.");
  +			throw new Error(e.toString()); // programming error, so bail out.
  +		}
  +
  +		if (guiEditor instanceof ComboStringEditor)
  +		{
  +			// Provide an initial edit value if necessary:
  +		
  +			/*
  +				What follows encodes this correspondence:
   
  -		wrapper.setValue(defaultValue);
  +				 ot  ex  nl -- default or 1st tag or ${}
  +				 ot  ex !nl -- "": use "" or last valid value
  +				 ot !ex  nl -- default or 1st tag or "" or last valid value :-(
  +				 ot !ex !nl -- "": use "" or last valid value
  +				!ot  ex  nl -- ${}
  +				!ot  ex !nl -- ${}
  +				!ot !ex  nl -- not necessary (not editable)
  +				!ot !ex !nl -- not necessary (not editable)
  +
  +				[ot=other, ex=expressions, nl=null]
  +
  +			*/ 
  +
  +			String v;
  +			if (notOther) v="${}";
  +			else if (notNull) v= "";
  +			else if (defaultValue != null) v= wrapper.getAsText();
  +			else if (tags != null) v= tags[1];
  +			else if (notExpression) v= "";
  +			else v="${}";
  +
  +			((ComboStringEditor)guiEditor).setInitialEditValue(v);
  +		}
   
   		return wrapper;
   	}
  @@ -461,7 +502,7 @@
   				// so I'll bail out.
   				throw new Error("Bad property value."+e);
   				// TODO: review this and possibly change to:
  -				// setEditorValue(i, descriptors[i].getValue("default"); 
  +				// setEditorValue(i, descriptors[i].getValue(DEFAULT); 
   			}
   		}
       }
  @@ -672,7 +713,7 @@
   		cp.weightx= 1.0;
   
   		JPanel currentPanel= mainPanel;
  -		String currentGroup= "";
  +		String currentGroup= DEFAULT_GROUP;
   		int y=0;
   		
           for (int i=0; i<editors.length; i++)
  @@ -780,8 +821,8 @@
   	 */
   	private String group(PropertyDescriptor d)
   	{
  -		String group= (String)d.getValue("group");
  -		if (group == null) group= "";
  +		String group= (String)d.getValue(GROUP);
  +		if (group == null) group= DEFAULT_GROUP;
   		return group;
   	}
   
  @@ -792,8 +833,9 @@
   	{
   		try {
   			ResourceBundle b= (ResourceBundle)
  -				beanInfo.getBeanDescriptor().getValue("resourceBundle");
  -			return b.getString(group+".displayName");
  +				beanInfo.getBeanDescriptor().getValue(RESOURCE_BUNDLE);
  +			if (b == null) return group;
  +			else return b.getString(group+".displayName");
   		}
   		catch (MissingResourceException e)
   		{
  @@ -840,7 +882,7 @@
   		private Integer groupOrder(String group)
   		{
   			Integer order= (Integer)beanInfo.getBeanDescriptor()
  -					.getValue("group."+group+".order");
  +					.getValue(ORDER(group));
   			if (order == null) order= new Integer(0);
   			return order;
   		}
  @@ -853,7 +895,7 @@
   		 */
   		private Integer propertyOrder(PropertyDescriptor d)
   		{
  -			Integer order= (Integer)d.getValue("order");
  +			Integer order= (Integer)d.getValue(ORDER);
   			if (order == null) order= new Integer(0);
   			return order;
   		}
  
  
  
  1.4       +29 -11    jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/BeanInfoSupport.java
  
  Index: BeanInfoSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/BeanInfoSupport.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- BeanInfoSupport.java	15 Jan 2004 02:02:03 -0000	1.3
  +++ BeanInfoSupport.java	16 Jan 2004 02:28:08 -0000	1.4
  @@ -83,15 +83,34 @@
    * <li>Modifies the property descriptors, bean descriptor, etc. at will.
    * </ol>
    * <p>
  - * Without any such modifications, the property descriptors will already
  - * have localized display names and short descriptions, and the bean
  - * descriptor will have a "resourceBoundle" attribute to be used for further
  - * localization.
  + * Even before any such modifications, a resource bundle named xxxResources
  + * (where xxx is the fully qualified bean class name) will be obtained if
  + * available and used to localize the following:
  + * <ul>
  + * <li>Bean's display name -- from property <b>displayName</b>.
  + * <li>Properties' display names -- from properties 
  + * <b><i>propertyName</i>.displayName</b>.
  + * <li>Properties' short descriptions -- from properties
  + * <b><i>propertyName</i>.shortDescription</b>.
  + * </ul>
  + * <p>
  + * The resource bundle will be stored as the bean descriptor's "resourceBundle"
  + * attribute, so that it can be used for further localization. TestBeanGUI, for
  + * example, uses it to obtain the group's display names from properties
  + * <b><i>groupName</i>.displayName</b>.
    */
   public abstract class BeanInfoSupport implements BeanInfo {
   
   	private static transient Logger log = LoggingManager.getLoggerForClass();
   
  +	// Some known attribute names, just for convenience:
  +	public static final String TAGS= TestBeanGUI.TAGS;
  +	public static final String NOT_UNDEFINED= TestBeanGUI.NOT_UNDEFINED;
  +	public static final String NOT_EXPRESSION= TestBeanGUI.NOT_EXPRESSION;
  +	public static final String NOT_OTHER= TestBeanGUI.NOT_OTHER;
  +	public static final String DEFAULT= TestBeanGUI.DEFAULT;
  +	public static final String RESOURCE_BUNDLE= TestBeanGUI.RESOURCE_BUNDLE;
  +
   	/**
   	 * The class for which we're providing the bean info.
   	 */
  @@ -124,7 +143,7 @@
   				JMeterUtils.getLocale()); 
   
   			// Store the resource bundle as an attribute of the BeanDescriptor:
  -			getBeanDescriptor().setValue("resourceBundle", resourceBundle);
  +			getBeanDescriptor().setValue(RESOURCE_BUNDLE, resourceBundle);
   
   			// Localize the bean name
   			try
  @@ -174,8 +193,7 @@
   		}
   		catch (MissingResourceException e)
   		{
  -			log.warn("Localized strings not available for bean "+beanClass
  -							+" on locale "+JMeterUtils.getLocale());
  +			log.warn("Localized strings not available for bean "+beanClass);
   		}
   	}
   	
  @@ -215,11 +233,11 @@
   		for (int i=0; i<names.length; i++)
   		{
   			PropertyDescriptor p= property(names[i]);
  -			p.setValue("group", group);
  -			p.setValue("order", new Integer(i));
  +			p.setValue(TestBeanGUI.GROUP, group);
  +			p.setValue(TestBeanGUI.ORDER, new Integer(i));
   		}
   		numCreatedGroups++;
  -		getBeanDescriptor().setValue("group."+group+".order",
  +		getBeanDescriptor().setValue(TestBeanGUI.ORDER(group),
   			new Integer(numCreatedGroups));
   	}
   
  
  
  
  1.4       +59 -9     jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/WrapperEditor.java
  
  Index: WrapperEditor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/testbeans/gui/WrapperEditor.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WrapperEditor.java	15 Jan 2004 02:03:12 -0000	1.3
  +++ WrapperEditor.java	16 Jan 2004 02:28:08 -0000	1.4
  @@ -111,6 +111,11 @@
   	 */
   	boolean acceptsExpressions;
   
  +	/**
  +	 * Whether to allow any constant values different from the provided tags. 
  +	 */
  +	boolean acceptsOther;
  +
       /**
      	 * Keep track of the last valid value in the editor, so that we can
      	 * revert to it if the user enters an invalid value.
  @@ -148,13 +153,17 @@
       }
   */
   	public WrapperEditor(
  -			PropertyEditor typeEditor, PropertyEditor guiEditor,
  -			boolean acceptsNull, boolean acceptsExpressions) {
  +			PropertyEditor typeEditor, 
  +			PropertyEditor guiEditor,
  +			boolean acceptsNull, 
  +			boolean acceptsExpressions, 
  +			boolean acceptsOther) {
   		super();
   		this.typeEditor= typeEditor;
   		this.guiEditor= guiEditor;
   		this.acceptsNull= acceptsNull;
   		this.acceptsExpressions= acceptsExpressions;
  +		this.acceptsOther= acceptsOther;
   		
   		guiEditor.addPropertyChangeListener(this);
   	}
  @@ -169,6 +178,28 @@
   		return guiEditor.getCustomEditor();
   	}
   
  +	public String[] getTags()
  +	{
  +		return guiEditor.getTags();
  +	}
  +
  +	/**
  +	 * Determine wheter a string is one of the known tags.
  +	 * 
  +	 * @param text
  +	 * @return true iif text equals one of the getTags()
  +	 */
  +	private boolean isATag(String text)
  +	{
  +		String[] tags= getTags();
  +		if (tags == null) return false;
  +		for (int i=0; i<tags.length; i++)
  +		{
  +			if (tags[i].equals(text)) return true;
  +		}
  +		return false;
  +	}
  +	
       /**
    	 * Determine whether a string is a valid value for the property.
      	 * 
  @@ -182,6 +213,14 @@
       	if (acceptsExpressions && isExpression(text)) return true;
   
       	// Not an expression (isn't or can't be), not null.
  +    	
  +		// The known tags are assumed to be valid:
  +		if (isATag(text)) return true;
  +		
  +		// Was not a tag, so if we can't accept other values...
  +		if (! acceptsOther) return false;
  +		
  +		// Delegate the final check to the typeEditor:
       	try
       	{
       		typeEditor.setAsText(text);
  @@ -223,7 +262,8 @@
   	 * Check if a string is a valid JMeter 'expression'.
   	 * <p>
   	 * The current implementation is very basic: it just accepts any
  -	 * string containing "${" as a valid expression. TODO: improve.
  +	 * string containing "${" as a valid expression.
  +	 * TODO: improve, but keep returning true for "${}". 
   	 */
   	private final boolean isExpression(String text)
   	{
  @@ -265,6 +305,10 @@
       		else
       		{
       			// not an expression (isn't or can't be), not null.
  +				
  +				// a check, just in case:
  +				if (! acceptsOther && ! isATag(text)) shouldNeverHappen();
  +
       			try
       			{
       				typeEditor.setAsText(text);
  @@ -300,7 +344,7 @@
       				+ ":"
       				+ value);
       	}
  -    
  +
       	if (value == null)
       	{
       		if (!acceptsNull) throw new IllegalArgumentException();
  @@ -315,6 +359,8 @@
   			// Not an expression (isn't or can't be), not null.
       		typeEditor.setValue(value); // may throw IllegalArgumentExc.
       		text= typeEditor.getAsText();
  +    		
  +    		if (! acceptsOther && ! isATag(text)) throw new IllegalArgumentException();
       	}
   
       	guiEditor.setValue(text);
  @@ -342,6 +388,9 @@
   				shouldNeverHappen(e);
   			}
   			text= typeEditor.getAsText();
  +
  +			// a check, just in case:
  +			if (! acceptsOther && ! isATag(text)) shouldNeverHappen();
       	}
       
       	if (log.isDebugEnabled())
  @@ -359,10 +408,10 @@
   		}
       		
   		String value;
  -    		
  +
   		if (text == null)
   		{
  -			if (!acceptsNull) shouldNeverHappen();
  +			if (! acceptsNull) throw new IllegalArgumentException();
   			value= null;
   		}
   		else 
  @@ -373,13 +422,14 @@
   			}
   			else
   			{
  +				// Some editors do tiny transformations (e.g. "true" to "True",...):
   				typeEditor.setAsText(text); // may throw IllegalArgumentException
   				value= typeEditor.getAsText();
  +				
  +				if (! acceptsOther && ! isATag(text)) throw new IllegalArgumentException();
   			}
   		}
   
  -		// TODO: if (NOT A TAG: && noEdit) shouldNeverHappen();
  -    
   		guiEditor.setValue(value);
   
   		firePropertyChange();
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org