|
From: jbetancourt <jbe...@co...> - 2005-01-27 01:16:43
|
I am using OGNL in conjunction with Spring. I will be publishing something
soon on this.
OGNL is really great!
----- Original Message -----
From: "Drew Davidson" <dr...@og...>
To: <spr...@li...>
Sent: Wednesday, January 26, 2005 3:06 PM
Subject: [Springframework-developer] OGNL property configurer bean factory
post-processor
> I wrote an OGNL-based property configurer (BeanFactoryPostProcessor
> implementor) that evaluates OGNL expressions in <value>, <map> and
> <list> entries, etc.
>
> It is similar in spirit to the PropertyPlaceholderConfigurer in that is
> substitutes values during the post processing phase. It looks for
> values delimitted by :[ and ] and processes them as OGNL expressions,
> which return a value.
>
> Advantages of OGNL expressions in Spring configurations:
> * Reference static members of classes directly (great for setting
> values from "static final int" constants):
>
> <property name="aConstValue"><value>:[
> @org.ognl.SomeClass@CONSTANT_VALUE ]</value>
>
> * Access Java data structures (and Collections) more easily than in
> Spring. Here are some examples, but I can't do justice to the amount of
> data structure manipulation possibilities in OGNL in this small space:
>
> - Create a Map:
> #{
> "name": "MyName",
> "description:" "This is a description of myName"
> }
>
> - Create a List of Strings:
>
> { "one", "two", "three" }
>
> - Create a List, filtered for certain elements:
>
> #someObjectInContext.items.{? name.startsWith("foo") }
>
> * Call methods on any object reachable by the bean factory
>
> * Reference and navigate other objects in the factory by name
>
>
> Example from my commerce library of configuring a factory that produces
> OrderQueryCriteria objects. These objects have setup requiring bindings
> to helper objects (OrderStatus is a custom enumerated type, SortOrdering
> is similar to Hibernate's Order class but slightly different usage
> pattern). One way to do this is to change the objects to take
> primitive-based setters and getters to construct these, or to complexify
> the Spring configuration file to provide these objects through
> factories, etc. I tried that and the config file was a bit heavy with
> "noise" due to the number of custom classes I needed just to get to
> static members, constructors, etc.
>
> public class OrderQueryCriteria extends AbstractQueryCriteria
> {
> ...
>
> public List getOrderStatus()
> {
> return orderStatus;
> }
>
> public void setOrderStatus(List value)
> {
> orderStatus = value;
> }
>
> public SortOrdering getPrimaryOrdering()
> {
> return primaryOrdering;
> }
>
> public void setPrimaryOrdering(SortOrdering value)
> {
> primaryOrdering = value;
> }
>
> public int getPageSize()
> {
> return pageSize;
> }
>
> public void setPageSize(int value)
> {
> pageSize = value;
> }
> }
>
> applicationContext-dao.xml:
>
> <bean id="orderQueryCriteria"
> class="org.ognl.dao.OrderQueryCriteria" singleton="false"
autowire="byName">
> <property name="orderStatus"><value>:[
> @EnumeratedType@getFactory(@OrderStatus@class).instances.{ #this }
> ]</value></property>
> <property name="primaryOrdering"><value>:[ new
> SortOrdering('orderDate', @SortOrdering@DESCENDING) ]</value></property>
> <property name="pageSize"><value>10</value></property>
> </bean>
>
> EnumeratedType is an abstraction for managing enumerated type objects.
> It allows you to get lists of instances and manages indexing the
> enumerations by other properties as well. Access is through static
> factory that implements the getInstances() method.
>
> orderStatus is a List of OrderStatus objects. To construct this we need
> to get the List from the EnumeratedType's factory and get a copy of the
> list that is returned (the copy is done by "projecting" the instances
> list via { #this }, which creates a new List as a result).
>
> primaryOrdering is a SortOrdering object that has an Object "target" and
> an ordering value (ASCENDING, DESCENDING or NONE). Note here that we
> are constructing this object using it's own static constant fields.
>
> The above code is accessing SortOrdering, EnumeratedType, and
> OrderStatus without any package specifications, you may note. This
> works here because the processor is looking for beans of type
> ognl.ClassResolver to use to resolve class names to actual Class
> objects. I've written an ImportClassResolver that is configured thus:
>
> <!-- id does not matter; only the fact that it exists in the
context -->
> <bean id="imports" class="org.ognl.spring.config.ImportClassResolver">
> <property name="imports">
> <list>
> <value>org.ognl.util.*</value>
> <value>org.ognl.model.shop.*</value>
> <value>org.ognl.pager.*</value>
> </list>
> </property>
> </bean>
>
> You can define as many of these as you like and they do inherit.
>
> Another feature is that the OGNL "context" object allows access to the
> rest of the Spring applicationContext through OGNL's "context variable"
> syntax.
>
> In the above code you saw reference to "#this" - this is the implicit
> value of the current object of the navigation; also available is #root
> (the original root object of the expression). This syntax also is used
> to access other elements in the context:
>
> <!-- a ListFactory produces, as the result of the factory, a List
> object -->
> <bean id="itemSortProperties"
> class="org.ognl.spring.config.ListFactory">
> <property name="list">
> <value>:[
> {
> #{ "name": "Item #",
> "property": "itemNumber",
> "advanced": false
> },
> #{ "name": "Name",
> "property": "name",
> "advanced": false
> },
> #{ "name": "Categorization",
> "property": { "product.category.name",
> "product.name" },
> "advanced": false
> },
> }
> ]</value>
> </property>
> </bean>
>
>
> <bean id="itemQueryCriteria" class="org.ognl.dao.ItemQueryCriteria"
> singleton="false" autowire="byName">
> ...
> <property name="primaryOrdering"><value>:[
> new SortOrdering(#itemSortProperties.{? name ==
> "Categorization" }[^].property, @SortOrdering@ASCENDING)
> ]</value></property>
>
> <property name="secondaryOrdering"><value>:[
> new SortOrdering(#itemSortProperties.{? name == "Item #"
> }[^].property, @SortOrdering@ASCENDING)
> ]</value></property>
>
> <property name="tertiaryOrdering"><value>:[
> new SortOrdering(#itemSortProperties.{? name == "Name"
> }[^].property, @SortOrdering@ASCENDING)
> ]</value></property>
>
> <property name="pageSize"><value>10</value></property>
>
> </bean>
>
> The above configures a List of Map objects, each of which has a "name",
> "property" and "advanced" key/value pair. The itemQueryCriteria object
> is configured from this list by referencing the other bean via
> "#itemSortProperties". Each of these uses the selection syntax to get a
> specific item out of the list, then the dynamic subscript "[^]" to
> return the first item of the list.
>
> You can also navigate through other objects in the context for other
> purposes such as mirroring another configuration value:
>
> <bean id="myObject" class="...">
> <property name="foo"><value>1254</value></property>
> ...
> </bean>
>
> <bean id="otherObject" class="...">
> <property name="bar"><value>:[ #myObject.foo ]</value></property>
> </bean>
>
> This can help cut down on error where properties are used repetitively.
>
> I'm not sure how I should distribute the source to this or if the
> project takes contributions. The code has a dependency on OGNL 2.6.3
> and above (1 jar file of ~185k). Is there a contribution mechanism that
> I can use to put instructions for use, the jar and the source up
somewhere?
>
> - Drew
>
> --
> +---------------------------------+
> < Drew Davidson | OGNL Technology >
> +---------------------------------+
> | Email: dr...@og... /
> | Web: http://www.ognl.org /
> | Vox: (520) 531-1966 <
> | Fax: (520) 531-1965 \
> | Mobile: (520) 405-2967 \
> +---------------------------------+
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
> Tool for open source databases. Create drag-&-drop reports. Save time
> by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
> Download a FREE copy at http://www.intelliview.com/go/osdn_nl
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
|