001    /**
002     * Copyright 2005-2012 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     */
016    package org.kuali.rice.krad.dao.proxy;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.config.ConfigurationException;
020    import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
021    import org.kuali.rice.krad.bo.BusinessObject;
022    import org.kuali.rice.krad.bo.ModuleConfiguration;
023    import org.kuali.rice.krad.bo.PersistableBusinessObject;
024    import org.kuali.rice.krad.dao.BusinessObjectDao;
025    import org.kuali.rice.krad.dao.impl.BusinessObjectDaoJpa;
026    import org.kuali.rice.krad.dao.impl.BusinessObjectDaoOjb;
027    import org.kuali.rice.krad.service.KRADServiceLocator;
028    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
029    import org.kuali.rice.krad.service.KualiModuleService;
030    import org.kuali.rice.krad.service.ModuleService;
031    import org.springframework.transaction.annotation.Transactional;
032    
033    import javax.persistence.EntityManager;
034    import java.util.ArrayList;
035    import java.util.Collection;
036    import java.util.HashMap;
037    import java.util.List;
038    import java.util.Map;
039    
040    @Transactional
041    public 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    }