You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by paha <ch...@yahoo.com> on 2010/04/21 17:30:57 UTC

T5.1 Setters returning value

Is there any reason to ignore setters, returning an object itself in
beaneditor & co? I used to write classes, which can be created with chain of
setter calls e.g.
someObject.setSomeValue(value).setAnotherValue(value)

the problem is, tapestry considers such "properties" read-only. Is it
possible to accept such setters as valid ones in future releases?


-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28288048.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by Inge Solvoll <in...@gmail.com>.
Try decorating instead of overriding. Could require less copying?

On Thu, Apr 22, 2010 at 3:53 PM, paha <ch...@yahoo.com> wrote:

>
> well, the solution is almost perfect now. "almost" - because i have to
> completely duplicate the code of PropertyAccessImpl replacing 2 calls to
> Introspector.getBeanInfo buried inside private methods :)
>
> here is a service override and final class
>
> public static void contributeServiceOverride(MappedConfiguration<Class,
> Object> configuration) {
>        //Allow setters returning object itself to be detected
>        configuration.add(PropertyAccess.class, new
> SpringPropertyAccessImpl());
>    }
>
>
>
> > package de.cgp.kunden.services;
> >
> > import
> > org.apache.tapestry5.ioc.internal.services.ClassPropertyAdapterImpl;
> > import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
> > import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
> > import org.apache.tapestry5.ioc.services.PropertyAccess;
> > import org.springframework.beans.BeanUtils;
> >
> > import java.beans.IntrospectionException;
> > import java.beans.PropertyDescriptor;
> > import java.util.Arrays;
> > import java.util.LinkedList;
> > import java.util.List;
> > import java.util.Map;
> >
> > /**
> >  * User: Pasha
> >  * Date: 22.04.2010
> >  * Time: 11:49:43
> >  */
> > public class SpringPropertyAccessImpl implements PropertyAccess {
> >
> >     private final Map<Class, ClassPropertyAdapter> adapters =
> > CollectionFactory.newConcurrentMap();
> >
> >     @Override
> >     public Object get(Object instance, String propertyName) {
> >         return getAdapter(instance).get(instance, propertyName);
> >     }
> >
> >     @Override
> >     public void set(Object instance, String propertyName, Object value) {
> >         getAdapter(instance).set(instance, propertyName, value);
> >     }
> >
> >     /**
> >      * Clears the cache of adapters and asks the Introspector to clear
> its
> > cache.
> >      */
> >     @Override
> >     public synchronized void clearCache() {
> >         adapters.clear();
> >     }
> >
> >     @Override
> >     public ClassPropertyAdapter getAdapter(Object instance) {
> >         return getAdapter(instance.getClass());
> >     }
> >
> >     @Override
> >     public ClassPropertyAdapter getAdapter(Class forClass) {
> >         ClassPropertyAdapter result = adapters.get(forClass);
> >
> >         if (result == null) {
> >             result = buildAdapter(forClass);
> >             adapters.put(forClass, result);
> >         }
> >
> >         return result;
> >     }
> >
> >     /**
> >      * Builds a new adapter and updates the _adapters cache. This not
> only
> > guards access to the adapter cache, but also
> >      * serializes access to the Java Beans Introspector, which is not
> > thread safe. In addition, handles the case where
> >      * the class in question is an interface, accumulating properties
> > inherited from super-classes.
> >      */
> >     private synchronized ClassPropertyAdapter buildAdapter(Class
> forClass)
> > {
> >         // In some race conditions, we may hit this method for the same
> > class multiple times.
> >         // We just let it happen, replacing the old ClassPropertyAdapter
> > with a new one.
> >
> >         try {
> >
> >
> >             List<PropertyDescriptor> descriptors =
> > CollectionFactory.newList();
> >
> >             addAll(descriptors, getPropertyDescriptors(forClass));
> >
> >             if (forClass.isInterface())
> > addPropertiesFromExtendedInterfaces(forClass, descriptors);
> >
> >             return new ClassPropertyAdapterImpl(forClass, descriptors);
> >         }
> >         catch (Throwable ex) {
> >             throw new RuntimeException(ex);
> >         }
> >     }
> >
> >     private PropertyDescriptor[] getPropertyDescriptors(Class forClass) {
> >         return BeanUtils.getPropertyDescriptors(forClass);
> >     }
> >
> >     private <T> void addAll(List<T> list, T[] array) {
> >         list.addAll(Arrays.asList(array));
> >     }
> >
> >     private void addPropertiesFromExtendedInterfaces(Class forClass,
> > List<PropertyDescriptor> descriptors) {
> >         LinkedList<Class> queue = CollectionFactory.newLinkedList();
> >
> >         // Seed the queue
> >         addAll(queue, forClass.getInterfaces());
> >
> >         while (!queue.isEmpty()) {
> >             Class c = queue.removeFirst();
> >
> >
> >             addAll(descriptors, getPropertyDescriptors(c));
> >             addAll(queue, c.getInterfaces());
> >         }
> >     }
> >
> >
> > }
> >
> >
> --
> View this message in context:
> http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28329198.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: T5.1 Setters returning value

Posted by paha <ch...@yahoo.com>.
well, the solution is almost perfect now. "almost" - because i have to
completely duplicate the code of PropertyAccessImpl replacing 2 calls to
Introspector.getBeanInfo buried inside private methods :)

here is a service override and final class

public static void contributeServiceOverride(MappedConfiguration<Class,
Object> configuration) {
        //Allow setters returning object itself to be detected 
        configuration.add(PropertyAccess.class, new
SpringPropertyAccessImpl());
    }



> package de.cgp.kunden.services;
> 
> import
> org.apache.tapestry5.ioc.internal.services.ClassPropertyAdapterImpl;
> import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
> import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
> import org.apache.tapestry5.ioc.services.PropertyAccess;
> import org.springframework.beans.BeanUtils;
> 
> import java.beans.IntrospectionException;
> import java.beans.PropertyDescriptor;
> import java.util.Arrays;
> import java.util.LinkedList;
> import java.util.List;
> import java.util.Map;
> 
> /**
>  * User: Pasha
>  * Date: 22.04.2010
>  * Time: 11:49:43
>  */
> public class SpringPropertyAccessImpl implements PropertyAccess {
> 
>     private final Map<Class, ClassPropertyAdapter> adapters =
> CollectionFactory.newConcurrentMap();
> 
>     @Override
>     public Object get(Object instance, String propertyName) {
>         return getAdapter(instance).get(instance, propertyName);
>     }
> 
>     @Override
>     public void set(Object instance, String propertyName, Object value) {
>         getAdapter(instance).set(instance, propertyName, value);
>     }
> 
>     /**
>      * Clears the cache of adapters and asks the Introspector to clear its
> cache.
>      */
>     @Override
>     public synchronized void clearCache() {
>         adapters.clear();
>     }
> 
>     @Override
>     public ClassPropertyAdapter getAdapter(Object instance) {
>         return getAdapter(instance.getClass());
>     }
> 
>     @Override
>     public ClassPropertyAdapter getAdapter(Class forClass) {
>         ClassPropertyAdapter result = adapters.get(forClass);
> 
>         if (result == null) {
>             result = buildAdapter(forClass);
>             adapters.put(forClass, result);
>         }
> 
>         return result;
>     }
> 
>     /**
>      * Builds a new adapter and updates the _adapters cache. This not only
> guards access to the adapter cache, but also
>      * serializes access to the Java Beans Introspector, which is not
> thread safe. In addition, handles the case where
>      * the class in question is an interface, accumulating properties
> inherited from super-classes.
>      */
>     private synchronized ClassPropertyAdapter buildAdapter(Class forClass)
> {
>         // In some race conditions, we may hit this method for the same
> class multiple times.
>         // We just let it happen, replacing the old ClassPropertyAdapter
> with a new one.
> 
>         try {
> 
> 
>             List<PropertyDescriptor> descriptors =
> CollectionFactory.newList();
> 
>             addAll(descriptors, getPropertyDescriptors(forClass));
> 
>             if (forClass.isInterface())
> addPropertiesFromExtendedInterfaces(forClass, descriptors);
> 
>             return new ClassPropertyAdapterImpl(forClass, descriptors);
>         }
>         catch (Throwable ex) {
>             throw new RuntimeException(ex);
>         }
>     }
> 
>     private PropertyDescriptor[] getPropertyDescriptors(Class forClass) {
>         return BeanUtils.getPropertyDescriptors(forClass);
>     }
> 
>     private <T> void addAll(List<T> list, T[] array) {
>         list.addAll(Arrays.asList(array));
>     }
> 
>     private void addPropertiesFromExtendedInterfaces(Class forClass,
> List<PropertyDescriptor> descriptors) {
>         LinkedList<Class> queue = CollectionFactory.newLinkedList();
> 
>         // Seed the queue
>         addAll(queue, forClass.getInterfaces());
> 
>         while (!queue.isEmpty()) {
>             Class c = queue.removeFirst();
> 
> 
>             addAll(descriptors, getPropertyDescriptors(c));
>             addAll(queue, c.getInterfaces());
>         }
>     }
> 
> 
> }
> 
> 
-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28329198.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by paha <ch...@yahoo.com>.

Inge Solvoll-2 wrote:
> 
> Sounds like you did a ServiceOverride without actually realizing it
> yourself
> :)
> well i was pretty sure i'm reinventing some wheels :) . of course i wanted
> to do a service override as soon as i realized that PropertyAccess is
> introduced via ioc 



Inge Solvoll-2 wrote:
> 
> And you have an excellent solution to your problem. Here is a link that
> explains how to not do it using a very very ugly hack :)
> thanks, try it as soon as possible.

-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28328938.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by Inge Solvoll <in...@gmail.com>.
Sounds like you did a ServiceOverride without actually realizing it yourself
:)

And you have an excellent solution to your problem. Here is a link that
explains how to not do it using a very very ugly hack :)

http://tapestry.apache.org/tapestry5.1/tapestry-ioc/cookbook/override.html

On Thu, Apr 22, 2010 at 2:13 PM, paha <ch...@yahoo.com> wrote:

>
> Solved the problem with one very very nasty hack, but if somebody
> interested:
>
> i commented the ioc binding for PropertyAccess implementation  in
> org.apache.tapestry5.ioc.services.TapestryIOCModule
> // binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
>
> then i introduced an own implementation in my app via
> binder.bind(PropertyAccess.class, SpringPropertyAccessImpl.class);
> as i said, BeanUtils from spring3 detect unvoid setters flawlessly.
>
>
> Well, my solution is ugly. I have to keep own version of tapsetry-ioc in my
> maven repo. But it is much much better than changing the code in many
> projects that use setter chaining or introducing wrapper classes around the
> domain objects.
>
> I'm quite newbie in tapestry ioc. Is there any clean way to introduce my
> own
> PropertyAccess implementation without hacking into source code? Is there
> any
> possibility of reconsidering setter detection
> in future releases?
> --
> View this message in context:
> http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28328043.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: T5.1 Setters returning value

Posted by paha <ch...@yahoo.com>.
Solved the problem with one very very nasty hack, but if somebody interested:

i commented the ioc binding for PropertyAccess implementation  in
org.apache.tapestry5.ioc.services.TapestryIOCModule
// binder.bind(PropertyAccess.class, PropertyAccessImpl.class);

then i introduced an own implementation in my app via 
binder.bind(PropertyAccess.class, SpringPropertyAccessImpl.class);
as i said, BeanUtils from spring3 detect unvoid setters flawlessly.


Well, my solution is ugly. I have to keep own version of tapsetry-ioc in my
maven repo. But it is much much better than changing the code in many
projects that use setter chaining or introducing wrapper classes around the
domain objects.
 
I'm quite newbie in tapestry ioc. Is there any clean way to introduce my own
PropertyAccess implementation without hacking into source code? Is there any
possibility of reconsidering setter detection
in future releases?
-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28328043.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by Geoff Callender <ge...@gmail.com>.
?? What do you mean?

On 22/04/2010, at 5:59 AM, Yury Luneff wrote:

>> Tapestry follows the definition of JavaBeans properties, set by Sun,
> 
> isn't "isSmth" and "setSmth" a standard for boolean properties? well, 
> tapestry seeks "setSmth" disregarding the type.
> 
> Maybe, it is an old holywar topic, but it still bothers me sometime as 
> getter/setter generation in IDEA regars some other standards than 
> tapestry does follow :-)
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by Yury Luneff <bi...@ya.ru>.
> Tapestry follows the definition of JavaBeans properties, set by Sun,

isn't "isSmth" and "setSmth" a standard for boolean properties? well, 
tapestry seeks "setSmth" disregarding the type.

Maybe, it is an old holywar topic, but it still bothers me sometime as 
getter/setter generation in IDEA regars some other standards than 
tapestry does follow :-)


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by paha <ch...@yahoo.com>.


Howard Lewis Ship wrote:
> 
> Tapestry uses the standard Introspector object to identify
> properties.  
> 

Can you give me a hint, how i can change this? It is a PropertyAccessImpl
class, that is doing the magic, isn't? Is it possible to replace this class
via config? Or is it the only way - to tweak it in source code?

-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28326506.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by paha <ch...@yahoo.com>.

Howard Lewis Ship wrote:
> 
> Tapestry follows the definition of JavaBeans properties, set by Sun
> 
Well, Spring3 BeanUtils.getPropertyDescriptors(User.class) returns all
property descriptions with setters even if they are not void. 
Now i have to either give up using setter chaining which is very useful or
write a useless wrapper class overriding unvoid setters for every domain
object i want to edit. 
-- 
View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28324962.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5.1 Setters returning value

Posted by Howard Lewis Ship <hl...@gmail.com>.
Tapestry follows the definition of JavaBeans properties, set by Sun,
and in fact, uses the standard Introspector object to identify
properties.  A setter method must return void.

On Wed, Apr 21, 2010 at 8:30 AM, paha <ch...@yahoo.com> wrote:
>
> Is there any reason to ignore setters, returning an object itself in
> beaneditor & co? I used to write classes, which can be created with chain of
> setter calls e.g.
> someObject.setSomeValue(value).setAnotherValue(value)
>
> the problem is, tapestry considers such "properties" read-only. Is it
> possible to accept such setters as valid ones in future releases?
>
>
> --
> View this message in context: http://old.nabble.com/T5.1-Setters-returning-value-tp28288048p28288048.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org