View Javadoc

1   /*
2    * Copyright 2006-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.kuali.rice.krad.service.impl;
18  
19  import org.apache.ojb.broker.metadata.ClassDescriptor;
20  import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
21  import org.apache.ojb.broker.metadata.DescriptorRepository;
22  import org.apache.ojb.broker.metadata.FieldDescriptor;
23  import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
24  import org.kuali.rice.core.api.config.property.ConfigContext;
25  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
26  import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor;
27  import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager;
28  import org.kuali.rice.core.framework.persistence.jpa.metadata.ObjectDescriptor;
29  import org.kuali.rice.core.framework.persistence.ojb.BaseOjbConfigurer;
30  import org.kuali.rice.krad.bo.PersistableBusinessObject;
31  import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
32  import org.kuali.rice.krad.exception.ClassNotPersistableException;
33  import org.kuali.rice.krad.util.spring.CacheNoCopy;
34  
35  import java.util.ArrayList;
36  import java.util.List;
37  
38  public class PersistenceServiceStructureImplBase {
39  
40  	private DescriptorRepository descriptorRepository;
41  
42  	/**
43  	 * Constructs a PersistenceServiceImpl instance.
44  	 */
45  	public PersistenceServiceStructureImplBase() {
46  		String ojbPropertyFileLocation = ConfigContext.getCurrentContextConfig().getProperty(BaseOjbConfigurer.RICE_OJB_PROPERTIES_PARAM);
47          String currentValue = System.getProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
48  		try {
49  			System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, ojbPropertyFileLocation);
50  			org.apache.ojb.broker.metadata.MetadataManager metadataManager = org.apache.ojb.broker.metadata.MetadataManager.getInstance();
51  			descriptorRepository = metadataManager.getGlobalRepository();
52  	    } finally {
53  	        if (currentValue == null) {
54  	            System.getProperties().remove(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
55  	        } else {
56  	            System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, currentValue);
57  	        }
58  	    }
59  	}
60  
61  	/**
62  	 * @return DescriptorRepository containing everything OJB knows about persistable classes
63  	 */
64  	protected DescriptorRepository getDescriptorRepository() {
65  		return descriptorRepository;
66  	}
67  
68  	/**
69  	 *
70  	 * This method returns a list of primary key field names.  This method uses the CacheNoCopy caching method.
71  	 * "NoCopy" is the faster of the caching annotations, but because it does not make a copy the list that is
72  	 * returned must not be modified.  To enforce this the returned list is wrapped in a Collections.unmodifiableList
73  	 * method.  This will cause an exception to be thrown if the list is altered.
74  	 *
75  	 * @param clazz
76  	 * @return unmodifiableList of field names.  Any attempt to alter list will result in an UnsupportedOperationException
77  	 */
78  	@CacheNoCopy
79  	public List listPrimaryKeyFieldNames(Class clazz) {
80      	// Rice JPA MetadataManager
81  		if (isJpaEnabledForKradClass(clazz)) {
82  			List fieldNames = new ArrayList();
83  	    	EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(clazz);
84  	    	for (org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor field : descriptor.getPrimaryKeys()) {
85  	    		fieldNames.add(field.getName());
86  	    	}
87  	    	return fieldNames;
88  		} else {
89  	    	// Legacy OJB
90  			List fieldNamesLegacy = new ArrayList();
91  			ClassDescriptor classDescriptor = getClassDescriptor(clazz);
92  			FieldDescriptor keyDescriptors[] = classDescriptor.getPkFields();
93  
94  			for (int i = 0; i < keyDescriptors.length; ++i) {
95  				FieldDescriptor keyDescriptor = keyDescriptors[i];
96  				fieldNamesLegacy.add(keyDescriptor.getAttributeName());
97  			}
98  			return fieldNamesLegacy;
99  		}
100 	}
101 
102 	/* Not used anywhere... need to check KFS and batch stuff */
103 	/**
104 	 * @param classDescriptor
105 	 * @return name of the database table associated with given classDescriptor,
106 	 *         stripped of its leading schemaName
107 	 */
108 	/*
109 	@CacheNoCopy
110 	protected String getTableName(ClassDescriptor classDescriptor) {
111 		String schemaName = classDescriptor.getSchema();
112 		String fullTableName = classDescriptor.getFullTableName();
113 
114 		String tableName = null;
115 		if (StringUtils.isNotBlank(schemaName)) {
116 			tableName = StringUtils.substringAfter(fullTableName, schemaName + ".");
117 		}
118 		if (StringUtils.isBlank(tableName)) {
119 			tableName = fullTableName;
120 		}
121 
122 		return tableName;
123 	}
124 	*/
125 
126 	/**
127 	 * @param persistableClass
128 	 * @return ClassDescriptor for the given Class
129 	 * @throws IllegalArgumentException
130 	 *             if the given Class is null
131 	 * @throws ClassNotPersistableException
132 	 *             if the given Class is unknown to OJB
133 	 */
134 	// Legacy OJB - no need for JPA equivalent
135 	protected ClassDescriptor getClassDescriptor(Class persistableClass) {
136 		if (persistableClass == null) {
137 			throw new IllegalArgumentException("invalid (null) object");
138 		}
139 
140 		ClassDescriptor classDescriptor = null;
141 		DescriptorRepository globalRepository = getDescriptorRepository();
142 		try {
143 			classDescriptor = globalRepository.getDescriptorFor(persistableClass);
144 		} catch (ClassNotPersistenceCapableException e) {
145 			throw new ClassNotPersistableException("class '" + persistableClass.getName() + "' is not persistable", e);
146 		}
147 
148 		return classDescriptor;
149 	}
150 	
151 	/**
152 	 * Determines if JPA is enabled for the KNS and for the given class
153 	 * 
154 	 * @param clazz the class to check for JPA enabling of
155 	 * @return true if JPA is enabled for the class, false otherwise
156 	 */
157 	public boolean isJpaEnabledForKradClass(Class clazz) {
158 		final boolean jpaAnnotated = OrmUtils.isJpaAnnotated(clazz);
159 		final boolean jpaEnabled = OrmUtils.isJpaEnabled();
160 		final boolean prefixJpaEnabled = OrmUtils.isJpaEnabled("rice.krad");
161 		return jpaAnnotated && (jpaEnabled || prefixJpaEnabled);
162 	}
163 
164 	/**
165 	 * @see org.kuali.rice.krad.service.PersistenceStructureService#getBusinessObjectAttributeClass(java.lang.Class,
166 	 *      java.lang.String)
167 	 */
168 	@CacheNoCopy
169 	public Class<? extends PersistableBusinessObjectExtension> getBusinessObjectAttributeClass(Class<? extends PersistableBusinessObject> clazz, String attributeName) {
170 		String baseAttributeName = attributeName;
171 		String subAttributeString = null;
172 		if (attributeName.contains(".")) {
173 			baseAttributeName = attributeName.substring(0, attributeName.indexOf('.'));
174 			subAttributeString = attributeName.substring(attributeName.indexOf('.') + 1);
175 		}
176 
177     	// Rice JPA MetadataManager
178 		if (isJpaEnabledForKradClass(clazz)) {
179 			Class attributeClass = null;
180 	    	EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(clazz);
181 	    	ObjectDescriptor objectDescriptor = descriptor.getObjectDescriptorByName(baseAttributeName);
182 			if (objectDescriptor != null) {
183 				attributeClass = objectDescriptor.getTargetEntity();
184 			}
185 
186 			// recurse if necessary
187 			if (subAttributeString != null) {
188 				attributeClass = getBusinessObjectAttributeClass(attributeClass, subAttributeString);
189 			}
190 
191 			return attributeClass;
192 		} else {
193 	    	// Legacy OJB
194 			Class attributeClassLegacy = null;
195 			ClassDescriptor classDescriptor = this.getClassDescriptor(clazz);
196 			ObjectReferenceDescriptor refDescriptor = classDescriptor.getObjectReferenceDescriptorByName(baseAttributeName);
197 
198 			if (refDescriptor != null) {
199 				attributeClassLegacy = refDescriptor.getItemClass();
200 			}
201 
202 			// recurse if necessary
203 			if (subAttributeString != null) {
204 				attributeClassLegacy = getBusinessObjectAttributeClass(attributeClassLegacy, subAttributeString);
205 			}
206 
207 			return attributeClassLegacy;
208 		}
209 	}
210 
211 }