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.service.impl;
017
018import org.apache.log4j.Logger;
019import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
020import org.kuali.rice.krad.bo.PersistableBusinessObject;
021import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
022import org.kuali.rice.krad.service.KualiModuleService;
023import org.kuali.rice.krad.service.ModuleService;
024import org.kuali.rice.krad.service.PersistenceService;
025import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
026import org.springframework.beans.BeanUtils;
027import org.springframework.transaction.annotation.Transactional;
028import org.springframework.util.CollectionUtils;
029
030import java.util.Iterator;
031import java.util.List;
032import 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
041public 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}