001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.dao.proxy;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.config.ConfigurationException;
020import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
021import org.kuali.rice.krad.bo.BusinessObject;
022import org.kuali.rice.krad.bo.ModuleConfiguration;
023import org.kuali.rice.krad.bo.PersistableBusinessObject;
024import org.kuali.rice.krad.dao.BusinessObjectDao;
025import org.kuali.rice.krad.dao.impl.BusinessObjectDaoJpa;
026import org.kuali.rice.krad.dao.impl.BusinessObjectDaoOjb;
027import org.kuali.rice.krad.service.KRADServiceLocator;
028import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
029import org.kuali.rice.krad.service.KualiModuleService;
030import org.kuali.rice.krad.service.ModuleService;
031import org.springframework.transaction.annotation.Transactional;
032
033import javax.persistence.EntityManager;
034import java.util.ArrayList;
035import java.util.Collection;
036import java.util.HashMap;
037import java.util.List;
038import java.util.Map;
039
040@Transactional
041public class BusinessObjectDaoProxy implements BusinessObjectDao {
042
043        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BusinessObjectDaoProxy.class);
044
045        private BusinessObjectDao businessObjectDaoJpa;
046        private BusinessObjectDao businessObjectDaoOjb;
047    private static KualiModuleService kualiModuleService;
048    private static HashMap<String, BusinessObjectDao> boDaoValues = new HashMap<String, BusinessObjectDao>();
049
050    private BusinessObjectDao getDao(Class clazz) {
051        ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(clazz);
052        if (moduleService != null) {
053            ModuleConfiguration moduleConfig = moduleService.getModuleConfiguration();
054            String dataSourceName = "";
055            EntityManager entityManager = null;
056            if (moduleConfig != null) {
057                dataSourceName = moduleConfig.getDataSourceName();
058                entityManager = moduleConfig.getEntityManager();
059            }
060
061            if (StringUtils.isNotEmpty(dataSourceName)) {
062                if (boDaoValues.get(dataSourceName) != null) {
063                    return boDaoValues.get(dataSourceName);
064                } else {
065                        if (OrmUtils.isJpaAnnotated(clazz) && OrmUtils.isJpaEnabled()) {
066                        //using JPA
067                                if (entityManager != null) {
068                            BusinessObjectDaoJpa boDaoJpa =
069                                new BusinessObjectDaoJpa(entityManager, KRADServiceLocator
070                                        .getPersistenceStructureService());
071                            // add to our cache of bo daos
072                                        boDaoValues.put(dataSourceName, boDaoJpa);
073                                        return boDaoJpa;
074                                } else {
075                                        throw new ConfigurationException("EntityManager is null. EntityManager must be set in the Module Configuration bean in the appropriate spring beans xml. (see nested exception for details).");
076                                }
077                        } else {        
078                            //using OJB
079                        BusinessObjectDaoOjb boDaoOjb = new BusinessObjectDaoOjb(
080                                KRADServiceLocator.getPersistenceStructureService());
081                        boDaoOjb.setJcdAlias(dataSourceName);
082                        // add to our cache of bo daos
083                        boDaoValues.put(dataSourceName, boDaoOjb);
084                        return boDaoOjb;
085                    }    
086                }
087
088            }
089        }
090        //return businessObjectDaoJpa;
091        return (OrmUtils.isJpaAnnotated(clazz) && OrmUtils.isJpaEnabled()) ? businessObjectDaoJpa : businessObjectDaoOjb;
092    }
093
094        /**
095         * @see org.kuali.rice.krad.dao.BusinessObjectDao#countMatching(java.lang.Class, java.util.Map)
096         */
097        public int countMatching(Class clazz, Map<String, ?> fieldValues) {
098                return getDao(clazz).countMatching(clazz, fieldValues);
099        }
100
101        /**
102         * @see org.kuali.rice.krad.dao.BusinessObjectDao#countMatching(java.lang.Class, java.util.Map, java.util.Map)
103         */
104        public int countMatching(Class clazz, Map<String, ?> positiveFieldValues, Map<String, ?> negativeFieldValues) {
105                return getDao(clazz).countMatching(clazz, positiveFieldValues, negativeFieldValues);
106        }
107
108        /**
109         * @see org.kuali.rice.krad.dao.BusinessObjectDao#delete(org.kuali.rice.krad.bo.PersistableBusinessObject)
110         */
111        public void delete(PersistableBusinessObject bo) {
112                if (bo != null) {
113                        getDao(bo.getClass()).delete(bo);
114                }
115        }
116
117        /**
118         * @see org.kuali.rice.krad.dao.BusinessObjectDao#delete(java.util.List)
119         */
120        public void delete(List<? extends PersistableBusinessObject> boList) {
121                if (!boList.isEmpty()) {
122                        getDao(boList.get(0).getClass()).delete(boList);
123                }
124        }
125
126        /**
127         * @see org.kuali.rice.krad.dao.BusinessObjectDao#deleteMatching(java.lang.Class, java.util.Map)
128         */
129        public void deleteMatching(Class clazz, Map<String, ?> fieldValues) {
130                getDao(clazz).deleteMatching(clazz, fieldValues);
131        }
132
133        /**
134         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findAll(java.lang.Class)
135         */
136        public <T extends BusinessObject> Collection<T> findAll(Class<T> clazz) {
137                return getDao(clazz).findAll(clazz);
138        }
139
140        /**
141         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findAllActive(java.lang.Class)
142         */
143        public <T extends BusinessObject> Collection<T> findAllActive(Class<T> clazz) {
144                return getDao(clazz).findAllActive(clazz);
145        }
146
147        /**
148         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findAllInactive(java.lang.Class)
149         */
150        public <T extends BusinessObject> Collection<T> findAllInactive(Class<T> clazz) {
151                return getDao(clazz).findAllInactive(clazz);
152        }
153
154        /**
155         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findAllActiveOrderBy(java.lang.Class, java.lang.String, boolean)
156         */
157        public <T extends BusinessObject> Collection<T> findAllActiveOrderBy(Class<T> clazz, String sortField, boolean sortAscending) {
158                return getDao(clazz).findAllActiveOrderBy(clazz, sortField, sortAscending);
159        }
160
161        /**
162         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findAllOrderBy(java.lang.Class, java.lang.String, boolean)
163         */
164        public <T extends BusinessObject> Collection<T> findAllOrderBy(Class<T> clazz, String sortField, boolean sortAscending) {
165                return getDao(clazz).findAllOrderBy(clazz, sortField, sortAscending);
166        }
167
168        /**
169         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findBySinglePrimaryKey(java.lang.Class, java.lang.Object)
170         */
171        public <T extends BusinessObject> T findBySinglePrimaryKey(Class<T> clazz, Object primaryKey) {
172                return getDao(clazz).findBySinglePrimaryKey(clazz, primaryKey);
173        }
174        
175        /**
176         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findByPrimaryKey(java.lang.Class, java.util.Map)
177         */
178        public <T extends BusinessObject> T findByPrimaryKey(Class<T> clazz, Map<String, ?> primaryKeys) {
179                return getDao(clazz).findByPrimaryKey(clazz, primaryKeys);
180        }
181
182        /**
183         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findMatching(java.lang.Class, java.util.Map)
184         */
185        public <T extends BusinessObject> Collection<T> findMatching(Class<T> clazz, Map<String, ?> fieldValues) {
186                return getDao(clazz).findMatching(clazz, fieldValues);
187        }
188
189        /**
190         * Has the proxied DAO handle the criteria
191         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findMatching(org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria)
192         */
193        //public <T extends BusinessObject> Collection<T> findMatching(Criteria criteria) {
194        //      Class clazz = null;
195        //      try {
196        //              clazz = Class.forName(criteria.getEntityName());
197        //      } catch (ClassNotFoundException cnfe) {
198        //              throw new RuntimeException("Attempted to run JPA Criteria which uses a non-existent class to query against: "+criteria.getEntityName(), cnfe);
199        //      }
200        //      return getDao(clazz).findMatching(criteria);
201        //}
202
203        /**
204         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findMatchingActive(java.lang.Class, java.util.Map)
205         */
206        public <T extends BusinessObject> Collection<T> findMatchingActive(Class<T> clazz, Map<String, ?> fieldValues) {
207                return getDao(clazz).findMatchingActive(clazz, fieldValues);
208        }
209
210        /**
211         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findMatchingOrderBy(java.lang.Class, java.util.Map, java.lang.String, boolean)
212         */
213        public <T extends BusinessObject> Collection<T> findMatchingOrderBy(Class<T> clazz, Map<String, ?> fieldValues, String sortField, boolean sortAscending) {
214                return getDao(clazz).findMatchingOrderBy(clazz, fieldValues, sortField, sortAscending);
215        }
216
217        /**
218         * @see org.kuali.rice.krad.dao.BusinessObjectDao#retrieve(org.kuali.rice.krad.bo.PersistableBusinessObject)
219         */
220        public PersistableBusinessObject retrieve(PersistableBusinessObject object) {
221                return getDao(object.getClass()).retrieve(object);
222        }
223        
224        /**
225
226         * @see org.kuali.rice.krad.dao.BusinessObjectDao#manageReadOnly(org.kuali.rice.krad.bo.PersistableBusinessObject)
227         */
228        public PersistableBusinessObject manageReadOnly(PersistableBusinessObject bo) {
229                return getDao(bo.getClass()).manageReadOnly(bo);
230        }
231
232        /**
233         * Defers to correct DAO for this class
234         * @see org.kuali.rice.krad.dao.BusinessObjectDao#findByPrimaryKeyUsingKeyObject(java.lang.Class, java.lang.Object)
235         */
236        public <T extends BusinessObject> T findByPrimaryKeyUsingKeyObject(Class<T> clazz, Object pkObject) {
237                return getDao(clazz).findByPrimaryKeyUsingKeyObject(clazz, pkObject);
238        }
239
240        /**
241         * @see org.kuali.rice.krad.dao.BusinessObjectDao#save(org.kuali.rice.krad.bo.PersistableBusinessObject)
242         */
243        public PersistableBusinessObject save(PersistableBusinessObject bo) {
244                PersistableBusinessObject savedBo;
245                savedBo = getDao(bo.getClass()).save(bo);
246                return savedBo;
247        }
248
249        /**
250         * @see org.kuali.rice.krad.dao.BusinessObjectDao#save(java.util.List)
251         */
252        public List<? extends PersistableBusinessObject> save(List businessObjects) {
253                if (!businessObjects.isEmpty()) {
254                        return getDao(businessObjects.get(0).getClass()).save(businessObjects);
255                }
256                return new ArrayList<PersistableBusinessObject>();
257        }
258
259    private static KualiModuleService getKualiModuleService() {
260        if (kualiModuleService == null) {
261            kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
262        }
263        return kualiModuleService;
264    }
265
266        public void setBusinessObjectDaoJpa(BusinessObjectDao businessObjectDaoJpa) {
267                this.businessObjectDaoJpa = businessObjectDaoJpa;
268        }
269
270        public void setBusinessObjectDaoOjb(BusinessObjectDao businessObjectDaoOjb) {
271                this.businessObjectDaoOjb = businessObjectDaoOjb;
272        }
273}