Hi,

> > I'm looking to access objects in a generic way - ie by 
> > casting them to a superclass and using generic methods 
> > such as getPerm/setPerm.

> What kind of access are you tallking about - i.e. what kind of
> operations are you looking to perform.

I'm trying to handle the situation around basic maintenance forms for 
inserting/updating objects, such as User.  That is on first showing a screen/form for 
a new user, the fields are blank, then on completing some invalid details, the 
screen/form is redisplayed with the details supplied by the user and the bad bits 
highlighted.  This is needed in a similar fashion for the update case too.

Code like this in my screen;


      AttributeItem[] items = mem.getAttributes();
      for (int i=0; i<items.length; i++)
      {
         if (items[i].isVisible())
         {
            TR tr = new TR()
               .addElement(new TD(items[i].getLabel()).addElement(":"))
               .addElement(new TD(items[i].getValueHtml())); //*0*
            if (items[i].getError() != null)
               tr.addElement(new TD(items[i].getError()));
            loginTable.addElement(tr);
         }
      }

Where AttributeItem defines things like the label, name, type, mandatoriness of an 
attribute.

The AttributeType then has subtypes like FreeFormString, PasswordString and 
EnumerationString (for a fixed set of values).

And *0* ultimately does a call like this


   public ConcreteElement getValueHtml(AttributeItem item)
   {
      String name = null;
      String value = null;
      if (item.getName() == null)
         name = "";
      else
         name = item.getName();
      if (item.get() == null)
         value = "";
      else
         value = item.get().toString(); // *4a*
      return new Input(Input.text,name,value);
   }

I'd like to write code like this in my action;


       Member mem = (Member)data.getUser();
       mem.restoreFromParameters(data.getParameters());  //*1*

       String validation = mem.validate();
       if (validation == null) //valid
          data.setScreen(ScreenConstants.NEW_USER_CONFIRM);
       else //invalid data - try again
       {
          data.setMessage( validation );
          data.setScreen(ScreenConstants.NEW_USER);
       }

Where the *1* call does this;


   /* get user details from the parameter parser - used during user maintenance */
   public void restoreFromParameters(ParameterParser params)
   {
      Iterator iter = _attributes.values().iterator();
      while (iter.hasNext())
      {
         AttributeItem item = (AttributeItem)iter.next();
         item.set(params); // *2*
      }
   }

Where *2* is where I just extract the relevant parameter, in the AttributeItem object, 
via this 


   public void set(ParameterParser parser)
   {
      _type.set(parser,this); // *3*
   }

   public void setValue(Object value)
   {
      _value = value; // *4b*
   }

At *3* this is delegated to the type object;


   public void set(ParameterParser parser, AttributeItem item)
   {
      item.setValue(parser.getString(item.getName()));
   }

The problem is *4a* and *4b*, this currently stores the values in the AttributeItem - 
I want it stored in the Perm/TempStorage instead.  I can pass in the actual member 
object to the attribute item, but I want to reuse the above for other classes that 
will need maintenance forms and thus want to use a common baseclass to get at them.

> You could consider using the setProperties method I added to
> ParameterParser instead. This will match parameter names to 
> setXXX
> methods for you.

I've now had a quick look at this method - it looks useful for 
the "setting" side of things (that is *4b*).  

So *1* becomes 
   data.getParameters().setProperties(mem);

[Although I would now need to write setters for all properties - and I'm lazy :-) ]

On the "getting" side of things, I'm not sure how I would handle the differences 
between simple text fields versus combo boxes and lists.  Perhaps I'd provide a 
getHtml type method for the whole object and it would (via some utility methods) just 
pull out all the details, such as;

The screen becomes
   ecsPageFormPart.addElement(mem.getHtml());

The getHtml() is 

   public ConcreteElement getHtml()
   {
       ElementContainer html = new ElementContainer();
       addFreeFormString(html,getName());
       addEnumeratedString(html,getCountry(), SomeConstants.countryList);
       return html;
   }

and the add routines would build the appropriate Input html object with an existing 
value if needed.

So - maybe my suggestion is not needed then.  

I like this from the point of view, it keeps the attributes as full attributes.

I don't like it from the point that we already using hashtables for some generic data 
- so why not do it for all and use methods that work on the hashtable, rather than 
methods per attribute.  I guess I still need at least a line per attribute - even just 
to create it as an attribute item.

I hope my rambling makes sense.

So, what I am saying is that I agree with you and will go down that route.

Regards,
Chris
"There is no spoon"
______________________________________________
FREE Personalized Email at Mail.com
Sign up at http://www.mail.com/?sr=signup



------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Problems?:           [EMAIL PROTECTED]

Reply via email to