Dennis, 
from the error message you're getting, it seems to me that you're 
somehow trying to render a node that represents a null location.

Maybe your dao returns a list and some (or one) of the list items is null.

To check if this is the case, you can try this LocationTree.html

    <div id="treeArea">
        <div jwcid="tree" id="tree">
<span jwcid="@If" condition="ognl:location!=null">
            <span jwcid="nodeLink">
                <span jwcid="nodeLabel" />
            </span>
</span>
        </div>
    </div>

and see what happens.


> Dear Tacos developers,
> 
> First of all thanks for the very nice tapestry plug in. It solves all my 
> needs for AJAX driven websites in T4 :)
> 
> Unfortunately there is one thing (atm ;)) I cannot get to work and that 
> is the advanced tree. I've noticed some more ppl that have problems with 
> it and therefore I'm posting this email. I'd like to make a very 
> elaborate case here and maybe this (in some modified form or another) 
> can be added to the examples so that this is more trivial to implement 
> for everybody.
> 
> Therefore this is going to be a _long_ message, filled with files and 
> examples.
> 
> In anycase, first off: the story. I'm digging trough a data collection 
> filled with locations. Locations have an id, name and a parent id. These 
> locations happen to be ideally suited for tree work as they represent 
> locations on earth! The first layer are countries, the second layer are 
> states and so on (cities, streets, houses, rooms).
> 
> This will offcourse be a very large amount of data that you do not want 
> to load all at once. To keep in line with the largeness of this database 
> I've decided to use Hibernate (and ejb3, but that's not important). 
> Locations are defined in an Hibernate entity file:
> 
> ------ Location.java ------
> @Entity
> @Table(name="Locations")
> public class Location implements Serializable {
> 
>     private static final long serialVersionUID = -109168154630091533L;
> 
>     long id;
>     String name;
>     Location parentLocation;
>     Set<Location> childLocations = new HashSet<Location>();
>    
>     @Id(generate=GeneratorType.AUTO)
>     public long getId() {
>         return id;
>     }
>     public void setId(long id) {
>         this.id = id;
>     }
>    
>     @Column(nullable=false)
>     public String getName() {
>         return name;
>     }
>     public void setName(String name) {
>         this.name = name;
>     }
> 
>     @OneToOne
>     @JoinColumn(name="parentId")
>     public Location getParentLocation() {
>         return parentLocation;
>     }
>     public void setParentLocation(Location parentLocation) {
>         this.parentLocation = parentLocation;
>     }
> 
>     @OneToMany(mappedBy="parentLocation")
>     public Set<Location> getChildLocations() {
>         return childLocations;
>     }
>     public void setChildLocations(Set<Location> childLocations) {
>         this.childLocations = childLocations;
>     }
> }
> ------ EOF Location.java ------
> 
> Just very simply all the needed getters and setters for the Id, Name, 
> Parent and Children. Nothing too fancy here yet. This data will be shown 
> in a tapestry page that is surrounded by a border (not really important 
> here). The HTML code for the tapestry page is:
> 
> ------ LocationTree.html ------
> 
> <body jwcid="@Border" title="Home">
> 
>     <div id="treeArea">
>         <div jwcid="tree" id="tree">
>             <span jwcid="nodeLink">
>                 <span jwcid="nodeLabel" />
>             </span>
>         </div>
>     </div>
> 
> </body>
> ------ EOF LocationTree.html ------
> 
> Please not that I don't use an icon here, maybe loading it from the 
> database will be a version 2 of this example. With this page there also 
> must be a tapestry page file, defining all the nice components that are 
> used in the HTML.
> 
> ------ LocationTree.page ------
> <page-specification class="<fill in tacos classpath here>.LocationTreePage">
> 
>     <description>Location Tree</description>
>    
>     <property name="location" />
>     <property name="selectedLocation" persist="session"/>
>     <property name="locationState" persist="session" 
> initial-value="ognl: new java.util.HashSet()" />
>    
>     <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd" />
> 
>     <component id="nodeLink" type="tacos:AjaxDirectLink">
>         <binding name="listener" 
> value="ognl:components.tree.listeners.contentExpansion"/>
>         <binding name="parameters" 
> value="ognl:{keyProvider.getKey(components.tree.value), not 
> components.tree.isExpanded(components.tree.value),location.parentLocation}"/>
>         <binding name="updateComponents" 
> value="ognl:{location.parentLocation, 'selectedLocation' }"/>
>         <binding name="effects" value="template:%nodeLink.effects"/>
>     </component>
> 
>     <component id="nodeLabel" type="Insert">
>         <binding name="value" 
>
value="ognl:@[EMAIL PROTECTED](location.name)"/>
>         <binding name="class" value="ognl:location == selectedLocation ? 
> 'selected' : null"/>
>     </component>
>    
>     <component id="tree" type="tacos:Tree">
>         <binding name="contentProvider" value="ognl:contentProvider"/>
>         <binding name="keyProvider" value="ognl:keyProvider"/>
>         <binding name="value" value="ognl:location"/>
>         <binding name="state" value="ognl:locationState"/>
>         <binding name="sorter" 
> value="ognl:@[EMAIL PROTECTED]"/>
>         <binding name="rowStyle" value="ognl:beans.evenOdd" />
>         <binding name="partialBlockClass" value="literal:treeBlock" />
>         <binding name="linkListener" value="listener:select" />
>     </component>
>    
>    
>     <inject property="ajaxEngine" object="service:tacos.ajaxdirect" />
>    
> </page-specification>
> ------ EOF LocationTree.page ------
> 
> As shown in the page file, we use the LocationTreePage.java class for 
> the code-part of this page. As you can see in the
> select() call I'm kinda stuck here, but in anycase tapestry explodes 
> before this is ever called.
> 
> ------ LocationTreePage.java ------
> public abstract class LocationTreePage extends BasePage {
> 
>     Logger logger = Logger.getLogger( this.getClass().getName() );
>    
>     private final static ITreeContentProvider CONTENT_PROVIDER = new 
> LocationTreeContentProvider(null);
>    
>     public abstract Location getSelectedLocation();
>     public abstract void setSelectedLocation(Location location);
>    
>     public abstract Set getLocationState();
> 
>     public abstract AjaxDirectService getAjaxEngine();   
>    
>     public ITreeContentProvider getContentProvider() {
>         return CONTENT_PROVIDER;
>     }
>    
>     public IKeyProvider getKeyProvider() {
>         return LocationKeyProvider.INSTANCE;
>     }   
>    
>     public ITreeManager getTreeManager() {
>         return new TreeManager(getLocationState(), getContentProvider(), 
> getKeyProvider() );
>     }
>    
>     public void select(IRequestCycle cycle) {
>        // I'm stuck here
>     }   
>    
>     public void revealSelected(IRequestCycle cycle) {
>         getTreeManager().reveal(getSelectedLocation());
>     }
> }
> ------ EOF LocationTreePage.java ------
> 
> The comparation is done by the following class. Please note that we 
> should do something better here, but I havn't gotten around to thinking 
> about that.
> ------ LocationComparator.java ------
> public class LocationComparator implements Comparator {
>    
>     public final static Comparator INSTANCE = new LocationComparator();
>    
>     public int compare(Object o1, Object o2)
>     {
>         Location location1 = (Location)o1;
>         Location location2 = (Location)o2;
>        
>         if( location1.equals(location2) ) {
>             return 0;
>         }
>        
>         return 1;
>     }
> }
> ------ EOF LocationComparator.java ------
> 
> The keys are provided with the following class:
> ------ LocationKeyProvider.java ------
> public class LocationKeyProvider implements IKeyProvider {
> 
>     public final static LocationKeyProvider INSTANCE = new 
> LocationKeyProvider();
>    
>     public Serializable getKey(Object value) {
>         return ((Location) value).getId();
>     }
> }
> 
> ------ EOF LocationKeyProvider.java ------
> 
> Finally the last class that is used provides the actual data, there is a 
> but of custom datahandling in here. I use JNDI calls to get a EJB3bean 
> that knows about CRUD functions.
> 
> ------ LocationKeyContentProvider.java ------
> public class LocationTreeContentProvider implements ITreeContentProvider {
> 
>     Logger logger = Logger.getLogger( this.getClass().getName() );
>    
>     private final Location rootLocation;
>    
>     /**
>      * Constuctor that starts to build the tree somewhere
>      * @param rootLocation
>      */
>     public LocationTreeContentProvider(Location rootLocation) {
>         this.rootLocation = rootLocation;
>     }   
>    
>     public Collection getChildren(Object parentElement) {
>         return ((Location)parentElement).getChildLocations();
>     }
> 
>     public boolean hasChildren(Object parentElement) {
>         /**
>         if( ((Location)parentElement).getChildLocations().size() > 0 ) {
>             return true;
>         }       
>         return false;
>         */
>         return false;
>     }
> 
>     public Object getParent(Object childElement) {
>         return ((Location)childElement).getParentLocation();
>     }
> 
>     public List getElements()
>     {
>         // Get initial context
>         LocationBean locationBean=null;
>         try{
>             locationBean = (LocationBean)(new 
> InitialContext()).lookup(LocationBean.class.getName());
>         } catch (Exception e){
>             logger.error( "Unable to get location bean: " + 
> e.getMessage() );
>             return Collections.EMPTY_LIST;
>         };
> 
>         // Return the list of rootlocations
>         List<Location> list = 
> locationBean.findByParentLocation(rootLocation);
>        
>         return list;
>     }
> 
> }
> ------ EOF LocationKeyContentProvider.java ------
> 
> Just to be complete here is the listing for the EJB:
> 
> ------ LocationBeanImpl.java ------
> @Stateless
> public class LocationBeanImpl extends GenericEJBDAO<Location, Long> 
> implements LocationBean {
> 
>     /**
>      * Use constructor to tell GenericEJBDAO our class
>      */
>     public LocationBeanImpl() {
>         super(Location.class);
>     }
>    
>     /* (non-Javadoc)
>      * @see 
>
com.stocketeer.ejb.impl.LocationBean#findByParentLocation(com.stocketeer.par.Location)
>      */
>     @SuppressWarnings("unchecked")
>     public List<Location> findByParentLocation(Location parentLocation)
>     {
>         if( parentLocation == null ) {
>             return this.em.createQuery("from Location as location where 
> location.parentLocation = null").
>                     getResultList();
>         }
>         else {
>             return this.em.
>                     createQuery("from Location as location where 
> location.parentLocation = ?"
>                             ).setParameter(0, parentLocation.getId() 
> ).getResultList();
>         }
>     }
> }
> ------ EOF LocationBeanImpl.java ------
> 
> Oof, that was a lot of c/p and a bit of typing, but I'm hoping that you 
> can point me to my errors and include something that makes it easier for 
> us noob users to use all this fancy functionality. In anycase keep up 
> the good work and thanks in advance.
> 
> With this I'm getting an error:
> org.apache.tapestry.BindingException
> Unable to read OGNL expression '<parsed OGNL expression>' of 
> [EMAIL PROTECTED]: source is null for 
> getProperty(null, "name")
> 
> 
> -- 
> Kind regards,
> 
> Dennis Fleurbaaij
> E: [EMAIL PROTECTED]
> T: (0031) (0) 6 54 21 53 65
> 
> 


-- 




-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Tacos-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tacos-devel

Reply via email to