From: Matt S. <mat...@sp...> - 2007-05-21 23:17:04
|
There is a use case that Morph does not cover that has been an "itch" of mine since pretty much the beginning. Morph.get(request, "something") will only return request attributes, never request parameters. There are a lot of ways this could be worked around, but there are a couple reasons that conspired to cause this. One reason the code works the way it does now is because of how I wrote reflectors. My intent for reflectors was that they would be very low-level objects with relatively simple behavior. So, I have a separate ServletRequestAttributeReflector and ServletRequestParameterReflector, just like I have separate CollectionReflector and IteratorReflectors (rather than trying to squeeze them into a single ContainerReflector). This keeps their implementation very clean and makes them easily testable. The other reason for this behavior is the SimpleDelegatingReflector's strategy for choosing a reflector for an object. Currently, the first reflector that can reflect an object is chosen and that's it, which makes the implementation of most Reflector methods trivial, for example, protected Object getImpl(Object bean, String propertyName) throws Exception { return getBeanReflector(bean).get(bean, propertyName); } So there are a number of ways to work around this and I could never decide the best one: 1) Write a ServletRequestReflector that delegates to the ServletRequestParameterReflector and ServletRequestAttributeReflector. An upside is this approach is fairly simple to understand conceptually. A downside of this approach is the delegation code here could become a bit repetitive if this situation is encountered multiple times. One need not look far to find another example where this would have to be implemented again or called again (if some sort of delegate or superclass was written): again for the Servlet API we have separate a ServletContextInitParameterReflector and ServletContextAttributeReflector. 2) Change the default implementation of SimpleDelegatingReflector so that it tries multiple reflectors if the first one fails. The big downside here is this could be fairly confusing since all objects are reflectable by the ObjectReflector which could be unexpected and/or confusing. For example, this would cause all objects to automatically receive a "class" property. In addition to being confusing, this could cause problems when using objects over which the user has little or no control, such a ServletRequest objects. If the implementation class for the request object has public mutators, those would be exposed which could be a particular annoyance for adherents to interface-based design that just declare lots of stuff public to make utilizing dependency injections frameworks (like me). 3) Introduce a configuration parameter or some type of Strategy delegate object that decides how a delegate is chosen in the SimpleDelegatingReflector. 4) Introduce a new type of DelegatingReflector (the current delegate implementation is called 'simple' after all!) I don't think #3 or #4 is really workable, because the behavior I'm really trying to affect here is for the Morph static method, so option 3 and 4 are really just dodging the original issues presented by option 2. I suppose options 3 and 4 would really be the implementation approach for option #1. I guess after writing this massive amount of text I'm leaning towards option #1, but I would love to hear some more ideas. Thanks, Matt S -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |