001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
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, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.orm.hibernate.tuplizer;
020
021import java.io.Serializable;
022import java.util.HashMap;
023
024import lucee.commons.lang.ExceptionUtil;
025import lucee.commons.lang.StringUtil;
026import lucee.runtime.Component;
027import lucee.runtime.ComponentScope;
028import lucee.runtime.engine.ThreadLocalPageContext;
029import lucee.runtime.exp.PageException;
030import lucee.runtime.op.Caster;
031import lucee.runtime.op.Decision;
032import lucee.runtime.orm.hibernate.CommonUtil;
033import lucee.runtime.orm.hibernate.HBMCreator;
034import lucee.runtime.orm.hibernate.HibernateCaster;
035import lucee.runtime.orm.hibernate.HibernateUtil;
036import lucee.runtime.orm.hibernate.tuplizer.accessors.CFCAccessor;
037import lucee.runtime.orm.hibernate.tuplizer.proxy.CFCHibernateProxyFactory;
038import lucee.runtime.type.Struct;
039import lucee.runtime.type.util.KeyConstants;
040
041import org.hibernate.EntityMode;
042import org.hibernate.EntityNameResolver;
043import org.hibernate.HibernateException;
044import org.hibernate.engine.SessionFactoryImplementor;
045import org.hibernate.engine.SessionImplementor;
046import org.hibernate.mapping.PersistentClass;
047import org.hibernate.mapping.Property;
048import org.hibernate.property.Getter;
049import org.hibernate.property.PropertyAccessor;
050import org.hibernate.property.Setter;
051import org.hibernate.proxy.ProxyFactory;
052import org.hibernate.tuple.Instantiator;
053import org.hibernate.tuple.entity.AbstractEntityTuplizer;
054import org.hibernate.tuple.entity.EntityMetamodel;
055
056
057public class AbstractEntityTuplizerImpl extends AbstractEntityTuplizer {
058
059        private static CFCAccessor accessor=new CFCAccessor();
060        
061        public AbstractEntityTuplizerImpl(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
062                super(entityMetamodel, persistentClass);
063        }
064
065        @Override
066        public Serializable getIdentifier(Object entity, SessionImplementor arg1) {
067                return toIdentifier(super.getIdentifier(entity, arg1));
068        }
069        
070        @Override
071        public Serializable getIdentifier(Object entity) throws HibernateException {
072                return toIdentifier(super.getIdentifier(entity));
073        }
074
075        private Serializable toIdentifier(Serializable id) {
076                if(id instanceof Component) {
077                        HashMap<String, Object> map = new HashMap<String, Object>();
078                        Component cfc=(Component) id;
079                        ComponentScope scope = cfc.getComponentScope();
080                        lucee.runtime.component.Property[] props = HibernateUtil.getIDProperties(cfc, true,true);
081                        lucee.runtime.component.Property p;
082                        String name;
083                        Object value;
084                        for(int i=0;i<props.length;i++){
085                                p=props[i];
086                                name=p.getName();
087                                value=scope.get(CommonUtil.createKey(name),null);
088                                String type=p.getType();
089                                if(Decision.isAnyType(type)) {
090                                        type="string";
091                                        try {
092                                                Object o=p.getMetaData();
093                                                if(o instanceof Struct) {
094                                                        Struct meta=(Struct) o;
095                                                        String gen = Caster.toString(meta.get(KeyConstants._generator, null),null);
096                                                        if(!StringUtil.isEmpty(gen)){
097                                                                type=HBMCreator.getDefaultTypeForGenerator(gen, "string");
098                                                        }
099                                                }
100                                        }
101                                        catch (Throwable t) {
102                                                ExceptionUtil.rethrowIfNecessary(t);
103                                        }
104                                }
105
106                                try {
107                                        value=HibernateCaster.toHibernateValue(ThreadLocalPageContext.get(), value, type);
108                                }
109                                catch (PageException pe) {}
110
111                                map.put(name, value);
112                        }
113                        return map;
114                }
115                return id;
116        }
117
118
119        @Override
120        protected Instantiator buildInstantiator(PersistentClass persistentClass) {
121                return new CFCInstantiator(persistentClass);
122        }
123        
124        /**
125         * return accessors 
126         * @param mappedProperty
127         * @return
128         */
129        private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
130                if ( mappedProperty.isBackRef() ) {
131                        PropertyAccessor ac = mappedProperty.getPropertyAccessor(null);
132                        if(ac!=null) return ac;
133                }
134                return accessor;
135        }
136
137        
138        @Override
139        protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
140                return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
141        }
142
143        
144        @Override
145        protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
146                return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
147        }
148        
149        @Override
150        protected ProxyFactory buildProxyFactory(PersistentClass pc, Getter arg1,Setter arg2) {
151                CFCHibernateProxyFactory pf = new CFCHibernateProxyFactory();
152                pf.postInstantiate(pc);
153                
154                return pf;
155        }
156
157        @Override
158        public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
159                return CFCEntityNameResolver.INSTANCE.resolveEntityName(entityInstance);
160        }
161
162        @Override
163        public EntityNameResolver[] getEntityNameResolvers() {
164                return new EntityNameResolver[] { CFCEntityNameResolver.INSTANCE };
165        }
166
167        @Override
168        public Class getConcreteProxyClass() {
169                return Component.class;// ????
170        }
171
172        @Override
173        public Class getMappedClass() {
174                return Component.class; // ????
175        }
176
177        public EntityMode getEntityMode() {
178                return EntityMode.MAP;
179        }
180
181        @Override
182        public boolean isInstrumented() {
183                return false;
184        }
185
186}