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.
014package org.apache.tapestry5.internal.hibernate;
015
016import java.io.Serializable;
017
018import org.apache.tapestry5.internal.services.SessionApplicationStatePersistenceStrategy;
019import org.apache.tapestry5.services.ApplicationStateCreator;
020import org.apache.tapestry5.services.Request;
021import 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 */
028public 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}