View Javadoc

1   /**
2    * Copyright 2005-2012 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  package org.kuali.rice.krad.service.impl;
17  
18  import org.apache.ojb.broker.metadata.ClassDescriptor;
19  import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
20  import org.apache.ojb.broker.metadata.DescriptorRepository;
21  import org.apache.ojb.broker.metadata.FieldDescriptor;
22  import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
23  import org.kuali.rice.core.api.config.property.ConfigContext;
24  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
25  import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor;
26  import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager;
27  import org.kuali.rice.core.framework.persistence.jpa.metadata.ObjectDescriptor;
28  import org.kuali.rice.core.framework.persistence.ojb.BaseOjbConfigurer;
29  import org.kuali.rice.krad.bo.PersistableBusinessObject;
30  import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension;
31  import org.kuali.rice.krad.exception.ClassNotPersistableException;
32  
33  import java.util.ArrayList;
34  import java.util.List;
35  
36  public class PersistenceServiceStructureImplBase {
37  
38  	private DescriptorRepository descriptorRepository;
39  
40  	/**
41  	 * Constructs a PersistenceServiceImpl instance.
42  	 */
43  	public PersistenceServiceStructureImplBase() {
44  		String ojbPropertyFileLocation = ConfigContext.getCurrentContextConfig().getProperty(BaseOjbConfigurer.RICE_OJB_PROPERTIES_PARAM);
45          String currentValue = System.getProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
46  		try {
47  			System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, ojbPropertyFileLocation);
48  			org.apache.ojb.broker.metadata.MetadataManager metadataManager = org.apache.ojb.broker.metadata.MetadataManager.getInstance();
49  			descriptorRepository = metadataManager.getGlobalRepository();
50  	    } finally {
51  	        if (currentValue == null) {
52  	            System.getProperties().remove(BaseOjbConfigurer.OJB_PROPERTIES_PROP);
53  	        } else {
54  	            System.setProperty(BaseOjbConfigurer.OJB_PROPERTIES_PROP, currentValue);
55  	        }
56  	    }
57  	}
58  
59  	/**
60  	 * @return DescriptorRepository containing everything OJB knows about persistable classes
61  	 */
62  	protected DescriptorRepository getDescriptorRepository() {
63  		return descriptorRepository;
64  	}
65  
66  	/**
67  	 *
68  	 * This method returns a list of primary key field names.  This method uses the CacheNoCopy caching method.
69  	 * "NoCopy" is the faster of the caching annotations, but because it does not make a copy the list that is
70  	 * returned must not be modified.  To enforce this the returned list is wrapped in a Collections.unmodifiableList
71  	 * method.  This will cause an exception to be thrown if the list is altered.
72  	 *
73  	 * @param clazz
74  	 * @return unmodifiableList of field names.  Any attempt to alter list will result in an UnsupportedOperationException
75  	 */
76  	public List listPrimaryKeyFieldNames(Class clazz) {
77      	// Rice JPA MetadataManager
78  		if (isJpaEnabledForKradClass(clazz)) {
79  			List fieldNames = new ArrayList();
80  	    	EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(clazz);
81  	    	for (org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor field : descriptor.getPrimaryKeys()) {
82  	    		fieldNames.add(field.getName());
83  	    	}
84  	    	return fieldNames;
85  		} else {
86  	    	// Legacy OJB
87  			List fieldNamesLegacy = new ArrayList();
88  			ClassDescriptor classDescriptor = getClassDescriptor(clazz);
89  			FieldDescriptor keyDescriptors[] = classDescriptor.getPkFields();
90  
91  			for (int i = 0; i < keyDescriptors.length; ++i) {
92  				FieldDescriptor keyDescriptor = keyDescriptors[i];
93  				fieldNamesLegacy.add(keyDescriptor.getAttributeName());
94  			}
95  			return fieldNamesLegacy;
96  		}
97  	}
98  
99  	/* 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 }