001    /*
002     * Databinder: a simple bridge from Wicket to Hibernate
003     * Copyright (C) 2006  Nathan Hamblen nathan@technically.us
004    
005     * This library is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU Lesser General Public
007     * License as published by the Free Software Foundation; either
008     * version 2.1 of the License, or (at your option) any later version.
009     * 
010     * This library is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * Lesser General Public License for more details.
014     * 
015     * You should have received a copy of the GNU Lesser General Public
016     * License along with this library; if not, write to the Free Software
017     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
018     */
019    package net.databinder.models.cay;
020    
021    import net.databinder.cay.Databinder;
022    import net.databinder.models.BindingModel;
023    import net.databinder.models.LoadableWritableModel;
024    
025    import org.apache.cayenne.DataObject;
026    import org.apache.cayenne.DataObjectUtils;
027    import org.apache.cayenne.ObjectId;
028    import org.apache.cayenne.PersistenceState;
029    
030    /**
031     * Basic model mapping to a single Cayenne data object. Detaches at the end
032     * of a request *unless* the object has uncommitted changes.
033     **/
034    public class DataObjectModel extends LoadableWritableModel implements BindingModel {
035            
036            private ObjectId id;
037            private DataObject retainedObject;
038    
039            public DataObjectModel(Class<? extends DataObject> objectClass) {
040                    setObject(Databinder.getContext().newObject(objectClass));
041            }
042            
043            public DataObjectModel(ObjectId id) {
044                    this.id = id;
045            }
046    
047            public DataObjectModel(DataObject object) {
048                    id = object.getObjectId();
049            }
050    
051            /** Loads from storage unless the object has been retained. */
052            @Override
053            protected Object load() {
054                    if (retainedObject != null) {
055                            Databinder.getContext().registerNewObject(retainedObject);
056                            return retainedObject;
057                    }
058                    return DataObjectUtils.objectForPK(Databinder.getContext(), id);
059            }
060    
061            /**
062             * @param object must be a Cayenne DataObject
063             */
064            public void setObject(Object object) {
065                    DataObject dataObject = (DataObject) object;
066                    id = dataObject.getObjectId();
067                    setTempModelObject(dataObject);
068                    if (!isBound())
069                            retainedObject = dataObject;
070                    else
071                            retainedObject = null;
072            }
073            
074            @Override
075            public DataObject getObject() {
076                    return (DataObject) super.getObject();
077            }
078            
079            /**
080             * Detaches any retained object that is fully commited to storage.
081             */
082            @Override
083            protected void onDetach() {
084                    if (retainedObject != null) {
085                            id = retainedObject.getObjectId();
086                            if (retainedObject.getPersistenceState() == PersistenceState.COMMITTED)
087                                    retainedObject = null;
088                    }
089            }
090            
091            public boolean isBound() {
092                    return !id.isTemporary();
093            }
094            
095            public void unbind() {
096                    setObject(Databinder.getContext().createAndRegisterNewObject(id.getEntityName()));
097            }
098    
099    }