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 }