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.ojb.broker.metadata.ClassDescriptor;
019 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
020 import org.apache.ojb.broker.metadata.DescriptorRepository;
021 import org.apache.ojb.broker.metadata.FieldDescriptor;
022 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
023 import org.kuali.rice.core.api.config.property.ConfigContext;
024 import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
025 import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor;
026 import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager;
027 import org.kuali.rice.core.framework.persistence.jpa.metadata.ObjectDescriptor;
028 import org.kuali.rice.core.framework.persistence.ojb.BaseOjbConfigurer;
029 import org.kuali.rice.krad.bo.PersistableBusinessObject;
030 import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
031 import org.kuali.rice.krad.exception.ClassNotPersistableException;
032
033 import java.util.ArrayList;
034 import java.util.List;
035
036 public class PersistenceServiceStructureImplBase {
037
038 private DescriptorRepository descriptorRepository;
039
040 /**
041 * Constructs a PersistenceServiceImpl instance.
042 */
043 public PersistenceServiceStructureImplBase() {
044 String ojbPropertyFileLocation = ConfigContext.getCurrentContextConfig().getProperty(BaseOjbConfigurer.RICE_OJB_PROPERTIES_PARAM);
045 String currentValue = System.getProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
046 try {
047 System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, ojbPropertyFileLocation);
048 org.apache.ojb.broker.metadata.MetadataManager metadataManager = org.apache.ojb.broker.metadata.MetadataManager.getInstance();
049 descriptorRepository = metadataManager.getGlobalRepository();
050 } finally {
051 if (currentValue == null) {
052 System.getProperties().remove(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
053 } else {
054 System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, currentValue);
055 }
056 }
057 }
058
059 /**
060 * @return DescriptorRepository containing everything OJB knows about persistable classes
061 */
062 protected DescriptorRepository getDescriptorRepository() {
063 return descriptorRepository;
064 }
065
066 /**
067 *
068 * This method returns a list of primary key field names. This method uses the CacheNoCopy caching method.
069 * "NoCopy" is the faster of the caching annotations, but because it does not make a copy the list that is
070 * returned must not be modified. To enforce this the returned list is wrapped in a Collections.unmodifiableList
071 * method. This will cause an exception to be thrown if the list is altered.
072 *
073 * @param clazz
074 * @return unmodifiableList of field names. Any attempt to alter list will result in an UnsupportedOperationException
075 */
076 public List listPrimaryKeyFieldNames(Class clazz) {
077 // Rice JPA MetadataManager
078 if (isJpaEnabledForKradClass(clazz)) {
079 List fieldNames = new ArrayList();
080 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(clazz);
081 for (org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor field : descriptor.getPrimaryKeys()) {
082 fieldNames.add(field.getName());
083 }
084 return fieldNames;
085 } else {
086 // Legacy OJB
087 List fieldNamesLegacy = new ArrayList();
088 ClassDescriptor classDescriptor = getClassDescriptor(clazz);
089 FieldDescriptor keyDescriptors[] = classDescriptor.getPkFields();
090
091 for (int i = 0; i < keyDescriptors.length; ++i) {
092 FieldDescriptor keyDescriptor = keyDescriptors[i];
093 fieldNamesLegacy.add(keyDescriptor.getAttributeName());
094 }
095 return fieldNamesLegacy;
096 }
097 }
098
099 /* Not used anywhere... need to check KFS and batch stuff */
100 /**
101 * @param classDescriptor
102 * @return name of the database table associated with given classDescriptor,
103 * stripped of its leading schemaName
104 */
105 /*
106 @CacheNoCopy
107 protected String getTableName(ClassDescriptor classDescriptor) {
108 String schemaName = classDescriptor.getSchema();
109 String fullTableName = classDescriptor.getFullTableName();
110
111 String tableName = null;
112 if (StringUtils.isNotBlank(schemaName)) {
113 tableName = StringUtils.substringAfter(fullTableName, schemaName + ".");
114 }
115 if (StringUtils.isBlank(tableName)) {
116 tableName = fullTableName;
117 }
118
119 return tableName;
120 }
121 */
122
123 /**
124 * @param persistableClass
125 * @return ClassDescriptor for the given Class
126 * @throws IllegalArgumentException
127 * if the given Class is null
128 * @throws ClassNotPersistableException
129 * if the given Class is unknown to OJB
130 */
131 // Legacy OJB - no need for JPA equivalent
132 protected ClassDescriptor getClassDescriptor(Class persistableClass) {
133 if (persistableClass == null) {
134 throw new IllegalArgumentException("invalid (null) object");
135 }
136
137 ClassDescriptor classDescriptor = null;
138 DescriptorRepository globalRepository = getDescriptorRepository();
139 try {
140 classDescriptor = globalRepository.getDescriptorFor(persistableClass);
141 } catch (ClassNotPersistenceCapableException e) {
142 throw new ClassNotPersistableException("class '" + persistableClass.getName() + "' is not persistable", e);
143 }
144
145 return classDescriptor;
146 }
147
148 /**
149 * Determines if JPA is enabled for the KNS and for the given class
150 *
151 * @param clazz the class to check for JPA enabling of
152 * @return true if JPA is enabled for the class, false otherwise
153 */
154 public boolean isJpaEnabledForKradClass(Class clazz) {
155 final boolean jpaAnnotated = OrmUtils.isJpaAnnotated(clazz);
156 final boolean jpaEnabled = OrmUtils.isJpaEnabled();
157 final boolean prefixJpaEnabled = OrmUtils.isJpaEnabled("rice.krad");
158 return jpaAnnotated && (jpaEnabled || prefixJpaEnabled);
159 }
160
161 /**
162 * @see org.kuali.rice.krad.service.PersistenceStructureService#getBusinessObjectAttributeClass(java.lang.Class,
163 * java.lang.String)
164 */
165 public Class<? extends PersistableBusinessObjectExtension> getBusinessObjectAttributeClass(Class<? extends PersistableBusinessObject> clazz, String attributeName) {
166 String baseAttributeName = attributeName;
167 String subAttributeString = null;
168 if (attributeName.contains(".")) {
169 baseAttributeName = attributeName.substring(0, attributeName.indexOf('.'));
170 subAttributeString = attributeName.substring(attributeName.indexOf('.') + 1);
171 }
172
173 // Rice JPA MetadataManager
174 if (isJpaEnabledForKradClass(clazz)) {
175 Class attributeClass = null;
176 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(clazz);
177 ObjectDescriptor objectDescriptor = descriptor.getObjectDescriptorByName(baseAttributeName);
178 if (objectDescriptor != null) {
179 attributeClass = objectDescriptor.getTargetEntity();
180 }
181
182 // recurse if necessary
183 if (subAttributeString != null) {
184 attributeClass = getBusinessObjectAttributeClass(attributeClass, subAttributeString);
185 }
186
187 return attributeClass;
188 } else {
189 // Legacy OJB
190 Class attributeClassLegacy = null;
191 ClassDescriptor classDescriptor = this.getClassDescriptor(clazz);
192 ObjectReferenceDescriptor refDescriptor = classDescriptor.getObjectReferenceDescriptorByName(baseAttributeName);
193
194 if (refDescriptor != null) {
195 attributeClassLegacy = refDescriptor.getItemClass();
196 }
197
198 // recurse if necessary
199 if (subAttributeString != null) {
200 attributeClassLegacy = getBusinessObjectAttributeClass(attributeClassLegacy, subAttributeString);
201 }
202
203 return attributeClassLegacy;
204 }
205 }
206
207 }