001    // Copyright 2009 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    package org.apache.tapestry5.internal.hibernate;
015    
016    import java.io.Serializable;
017    
018    import org.apache.tapestry5.internal.services.SessionApplicationStatePersistenceStrategy;
019    import org.apache.tapestry5.services.ApplicationStateCreator;
020    import org.apache.tapestry5.services.Request;
021    import org.hibernate.HibernateException;
022    
023    /**
024     * Persists Hibernate entities as SSOs by storing their primary key in the {@link org.apache.tapestry5.services.Session}.
025     * 
026     * @see org.apache.tapestry5.internal.hibernate.PersistedEntity
027     */
028    public class EntityApplicationStatePersistenceStrategy extends SessionApplicationStatePersistenceStrategy 
029    {
030    
031            private final org.hibernate.Session hibernateSession;
032    
033            public EntityApplicationStatePersistenceStrategy(Request request, org.hibernate.Session hibernateSession) 
034            {
035                    super(request);
036                    this.hibernateSession = hibernateSession;
037            }
038    
039            @SuppressWarnings("unchecked")
040            public <T> T get(Class<T> ssoClass, ApplicationStateCreator<T> creator) 
041            {
042                    final Object persistedValue =  getOrCreate(ssoClass, creator);
043                    
044                    if(persistedValue instanceof PersistedEntity)
045                    {
046                            final PersistedEntity persisted = (PersistedEntity) persistedValue;
047                            
048                            Object restored = persisted.restore(this.hibernateSession);
049                            
050                            //shall we maybe throw an exception instead?
051                            if(restored == null)
052                            {
053                                    set(ssoClass, null);
054                                    return (T) getOrCreate(ssoClass, creator);
055                            }
056    
057                            return (T) restored;
058                    }
059                    
060                    return (T) persistedValue;
061            }
062    
063            public <T> void set(Class<T> ssoClass, T sso) 
064            {       
065                    final String key = buildKey(ssoClass);
066                    Object entity;
067                    
068                    if(sso != null)
069                    {
070                            try 
071                            {
072                                    final String entityName = this.hibernateSession.getEntityName(sso);
073                                    final Serializable id = this.hibernateSession.getIdentifier(sso);
074            
075                                    entity = new PersistedEntity(entityName, id);
076                            } 
077                            catch (final HibernateException ex) 
078                            {
079                                    // if entity not attached to a Hibernate Session yet, store it as usual sso
080                                    entity = sso;
081                            }
082                    }
083                    else
084                    {
085                            entity = sso;
086                    }
087                    
088                    getSession().setAttribute(key, entity);
089            }
090    
091    }