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.service.impl;
017    
018    import org.apache.log4j.Logger;
019    import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
020    import org.kuali.rice.krad.bo.PersistableBusinessObject;
021    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
022    import org.kuali.rice.krad.service.KualiModuleService;
023    import org.kuali.rice.krad.service.ModuleService;
024    import org.kuali.rice.krad.service.PersistenceService;
025    import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
026    import org.springframework.beans.BeanUtils;
027    import org.springframework.transaction.annotation.Transactional;
028    import org.springframework.util.CollectionUtils;
029    
030    import java.util.Iterator;
031    import java.util.List;
032    import java.util.Map;
033    
034    /**
035     * This class is the service implementation for the Persistence structure.
036     * OjbRepositoryExplorer provides functions for extracting information from the
037     * OJB repository at runtime. This is the default implementation, that is
038     * delivered with Kuali.
039     */
040    @Transactional
041    public class PersistenceServiceImpl extends PersistenceServiceImplBase implements PersistenceService {
042    
043            private static Logger LOG = Logger.getLogger(PersistenceServiceImpl.class);
044    
045        private KualiModuleService kualiModuleService;
046    
047            private PersistenceService persistenceServiceJpa;
048    
049            private PersistenceService persistenceServiceOjb;
050    
051            public void setPersistenceServiceJpa(PersistenceService persistenceServiceJpa) {
052                    this.persistenceServiceJpa = persistenceServiceJpa;
053            }
054    
055            public void setPersistenceServiceOjb(PersistenceService persistenceServiceOjb) {
056                    this.persistenceServiceOjb = persistenceServiceOjb;
057            }
058    
059            private PersistenceService getService(Class clazz) {
060            return (isJpaEnabledForKradClass(clazz)) ?
061                                                    persistenceServiceJpa : persistenceServiceOjb;
062            }
063    
064            // This method is for OJB specfic features. It is now being called directly where needed.
065            public void clearCache() {
066                    throw new UnsupportedOperationException("This should be called directly from the OJB Impl if needed.");
067            }
068    
069            // This method is for OJB specfic features. It is now being called directly where needed.
070            public void loadRepositoryDescriptor(String ojbRepositoryFilePath) {
071                    throw new UnsupportedOperationException("This should be called directly from the OJB Impl if needed.");
072            }
073    
074            public Object resolveProxy(Object o) {
075                    return getService(o.getClass()).resolveProxy(o);
076            }
077    
078            /**
079             * @see org.kuali.rice.krad.service.PersistenceService#retrieveNonKeyFields(java.lang.Object)
080             */
081            public void retrieveNonKeyFields(Object persistableObject) {
082            if (persistableObject != null &&
083                    ExternalizableBusinessObjectUtils.isExternalizableBusinessObject(persistableObject.getClass())) {
084                //
085                // special handling for EBOs
086                //
087                Map<String, ?> criteria = KRADServiceLocatorWeb.getDataObjectMetaDataService().getPrimaryKeyFieldValues(persistableObject);
088                if (!CollectionUtils.isEmpty(criteria)) {
089                    ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(persistableObject.getClass());
090                    if (moduleService != null) {
091                        Class<? extends ExternalizableBusinessObject> clazz =
092                                ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(persistableObject.getClass());
093                        ExternalizableBusinessObject freshEbo = moduleService.getExternalizableBusinessObject(clazz, (Map<String, Object>)criteria);
094                        if (freshEbo != null) {
095                            BeanUtils.copyProperties(freshEbo, persistableObject);
096                        }
097                    }
098                }
099            } else {
100                getService(persistableObject.getClass()).retrieveNonKeyFields(persistableObject);
101            }
102            }
103    
104            /**
105             * @see org.kuali.rice.krad.service.PersistenceService#retrieveReferenceObject(java.lang.Object,
106             *      String referenceObjectName)
107             */
108            public void retrieveReferenceObject(Object persistableObject, String referenceObjectName) {
109                    getService(persistableObject.getClass()).retrieveReferenceObject(persistableObject, referenceObjectName);
110            }
111    
112            /**
113             * @see org.kuali.rice.krad.service.PersistenceService#retrieveReferenceObject(java.lang.Object,
114             *      String referenceObjectName)
115             */
116            public void retrieveReferenceObjects(Object persistableObject, List referenceObjectNames) {
117                    getService(persistableObject.getClass()).retrieveReferenceObjects(persistableObject, referenceObjectNames);
118            }
119    
120            /**
121             * @see org.kuali.rice.krad.service.PersistenceService#retrieveReferenceObject(java.lang.Object,
122             *      String referenceObjectName)
123             */
124            public void retrieveReferenceObjects(List persistableObjects, List referenceObjectNames) {
125                    if (persistableObjects == null) {
126                            throw new IllegalArgumentException("invalid (null) persistableObjects");
127                    }
128                    if (persistableObjects.isEmpty()) {
129                            throw new IllegalArgumentException("invalid (empty) persistableObjects");
130                    }
131                    if (referenceObjectNames == null) {
132                            throw new IllegalArgumentException("invalid (null) referenceObjectNames");
133                    }
134                    if (referenceObjectNames.isEmpty()) {
135                            throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
136                    }
137    
138                    for (Iterator i = persistableObjects.iterator(); i.hasNext();) {
139                            Object persistableObject = i.next();
140                            retrieveReferenceObjects(persistableObject, referenceObjectNames);
141                    }
142            }
143    
144            /**
145             * @see org.kuali.rice.krad.service.PersistenceService#getFlattenedPrimaryKeyFieldValues(java.lang.Object)
146             */
147            public String getFlattenedPrimaryKeyFieldValues(Object persistableObject) {
148                    return getService(persistableObject.getClass()).getFlattenedPrimaryKeyFieldValues(persistableObject);
149            }
150    
151            /**
152             * For each reference object to the parent persistableObject, sets the key
153             * values for that object. First, if the reference object already has a
154             * value for the key, the value is left unchanged. Otherwise, for
155             * non-anonymous keys, the value is taken from the parent object. For
156             * anonymous keys, all other persistableObjects are checked until a value
157             * for the key is found.
158             * 
159             * @see org.kuali.rice.krad.service.PersistenceService#getReferencedObject(java.lang.Object,
160             *      org.apache.ojb.broker.metadata.ObjectReferenceDescriptor)
161             */
162            public void linkObjects(Object persistableObject) {
163                    getService(persistableObject.getClass()).linkObjects(persistableObject);
164            }
165    
166            /**
167             * 
168             * @see org.kuali.rice.krad.service.PersistenceService#allForeignKeyValuesPopulatedForReference(org.kuali.rice.krad.bo.BusinessObject,
169             *      java.lang.String)
170             */
171            public boolean allForeignKeyValuesPopulatedForReference(PersistableBusinessObject bo, String referenceName) {
172                    return getService(bo.getClass()).allForeignKeyValuesPopulatedForReference(bo, referenceName);
173            }
174    
175            /**
176             * 
177             * @see org.kuali.rice.krad.service.PersistenceService#refreshAllNonUpdatingReferences(org.kuali.rice.krad.bo.BusinessObject)
178             */
179            public void refreshAllNonUpdatingReferences(PersistableBusinessObject bo) {
180                    getService(bo.getClass()).refreshAllNonUpdatingReferences(bo);
181            }
182    
183            /**
184             * Defers to the service for the given class
185             * 
186             * @see org.kuali.rice.krad.service.PersistenceService#isProxied(java.lang.Object)
187             */
188            public boolean isProxied(Object bo) {
189                    return getService(bo.getClass()).isProxied(bo);
190            }
191    
192        public KualiModuleService getKualiModuleService() {
193            return kualiModuleService;
194        }
195    
196        public void setKualiModuleService(KualiModuleService kualiModuleService) {
197            this.kualiModuleService = kualiModuleService;
198        }
199    }