001    package org.trails.component;
002    
003    import org.apache.commons.logging.Log;
004    import org.apache.commons.logging.LogFactory;
005    import org.apache.tapestry.IAsset;
006    import org.apache.tapestry.annotations.Asset;
007    import org.apache.tapestry.annotations.ComponentClass;
008    import org.apache.tapestry.annotations.InjectObject;
009    import org.apache.tapestry.annotations.Parameter;
010    import org.apache.tapestry.form.IPropertySelectionModel;
011    import org.hibernate.criterion.DetachedCriteria;
012    import org.hibernate.criterion.Restrictions;
013    import org.trails.descriptor.IClassDescriptor;
014    import org.trails.persistence.HibernatePersistenceService;
015    
016    
017    /**
018     * This component produces a editor for a ManyToOne or ManyToMany collection
019     */
020    @ComponentClass(allowBody = true, allowInformalParameters = true)
021    public abstract class HibernateEditCollection extends EditCollection
022    {
023    
024            @Asset(value = "/org/trails/component/EditCollection.html")
025            public abstract IAsset get$template();
026    
027            protected static final Log LOG = LogFactory.getLog(HibernateEditCollection.class);
028    
029            /**
030             * @todo: remove when the components reuse issue goes away
031             */
032            @InjectObject("service:trails.hibernate.PersistenceService")
033            public abstract HibernatePersistenceService getHibernatePersistenceService();
034    
035            /**
036             * @todo: remove when the components reuse issue goes away
037             */
038            @Override
039            public HibernatePersistenceService getPersistenceService()
040            {
041                    return getHibernatePersistenceService();
042            }
043    
044            @Parameter(required = false)
045            public abstract DetachedCriteria getCriteria();
046    
047            /**
048             * @return
049             */
050            public IPropertySelectionModel getSelectionModel()
051            {
052                    IClassDescriptor elementDescriptor = getDescriptorService().getClassDescriptor(getCollectionDescriptor().getElementType());
053    
054                    if (getCriteria() == null)
055                    {
056                            // don't allow use to select from all here
057                            if (getCollectionDescriptor().isChildRelationship())
058                            {
059                                    return new IdentifierSelectionModel(getSelectedList(), elementDescriptor.getIdentifierDescriptor().getName());
060                            }
061                            // but do here
062                            else if (getCollectionDescriptor().getInverseProperty() != null && getCollectionDescriptor().isOneToMany())
063                            {
064                                    DetachedCriteria criteria = DetachedCriteria.forClass(getCollectionDescriptor().getElementType());
065                                    String identifier = elementDescriptor.getIdentifierDescriptor().getName();
066                                    if (getModel() != null)
067                                    {
068                                            criteria.add(
069                                                            Restrictions.disjunction()
070                                                                            .add(Restrictions.isNull(getCollectionDescriptor().getInverseProperty()))
071                                                                            .add(Restrictions.eq(
072                                                                            getCollectionDescriptor().getInverseProperty() + "." + identifier,
073                                                                            getPersistenceService().getIdentifier(getModel(), elementDescriptor))));
074                                    } else
075                                    {
076                                            criteria.add(Restrictions.isNull(getCollectionDescriptor().getInverseProperty()));
077                                    }
078    
079                                    return new IdentifierSelectionModel(getPersistenceService().getInstances(getCollectionDescriptor().getElementType(), criteria), elementDescriptor.getIdentifierDescriptor().getName());
080                            } else
081                            {
082                                    return new IdentifierSelectionModel(getPersistenceService().getAllInstances(getCollectionDescriptor().getElementType()),
083                                            elementDescriptor.getIdentifierDescriptor().getName());
084                            }
085                    } else
086                    {
087                            return new IdentifierSelectionModel(
088                                            getPersistenceService().getInstances(getCollectionDescriptor().getElementType(), getCriteria()),
089                                            elementDescriptor.getIdentifierDescriptor().getName());
090                    }
091            }
092    }