1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.service.impl;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.regex.Pattern;
25 import java.util.regex.PatternSyntaxException;
26
27 import org.apache.commons.beanutils.PropertyUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.log4j.Logger;
30 import org.apache.ojb.broker.metadata.ClassDescriptor;
31 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
32 import org.kuali.ole.sys.OLEPropertyConstants;
33 import org.kuali.ole.sys.businessobject.BusinessObjectComponent;
34 import org.kuali.ole.sys.businessobject.BusinessObjectProperty;
35 import org.kuali.ole.sys.businessobject.DataMappingFieldDefinition;
36 import org.kuali.ole.sys.businessobject.FunctionalFieldDescription;
37 import org.kuali.ole.sys.dataaccess.BusinessObjectMetaDataDao;
38 import org.kuali.ole.sys.service.NonTransactional;
39 import org.kuali.ole.sys.service.OleBusinessObjectMetaDataService;
40 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
41 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
42 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
43 import org.kuali.rice.kns.service.DataDictionaryService;
44 import org.kuali.rice.krad.bo.BusinessObject;
45 import org.kuali.rice.krad.bo.DataObjectRelationship;
46 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
47 import org.kuali.rice.krad.service.BusinessObjectService;
48 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
49 import org.kuali.rice.krad.service.LookupService;
50
51 @NonTransactional
52 public class OleBusinessObjectMetaDataServiceImpl implements OleBusinessObjectMetaDataService {
53 private Logger LOG = Logger.getLogger(OleBusinessObjectMetaDataServiceImpl.class);
54 private DataDictionaryService dataDictionaryService;
55 private ParameterService parameterService;
56 private BusinessObjectService businessObjectService;
57 private BusinessObjectMetaDataService businessObjectMetaDataService;
58 private BusinessObjectMetaDataDao businessObjectMetaDataDao;
59 private LookupService lookupService;
60
61 public void setParameterService(ParameterService parameterService) {
62 this.parameterService = parameterService;
63 }
64
65 protected BusinessObjectComponent getBusinessObjectComponent(Class<?> componentClass) {
66 return new BusinessObjectComponent(KRADServiceLocatorWeb.getKualiModuleService().getNamespaceCode(componentClass), (org.kuali.rice.kns.datadictionary.BusinessObjectEntry) dataDictionaryService.getDataDictionary().getBusinessObjectEntry(componentClass.getName()));
67 }
68
69 @Override
70 public BusinessObjectProperty getBusinessObjectProperty(String componentClass, String propertyName) {
71 try {
72 return new BusinessObjectProperty(getBusinessObjectComponent(Class.forName(componentClass)), dataDictionaryService.getDataDictionary().getBusinessObjectEntry(componentClass).getAttributeDefinition(propertyName));
73 }
74 catch (ClassNotFoundException ex) {
75 LOG.error( "Unable to resolve component class name: " + componentClass );
76 }
77 return null;
78 }
79
80 @Override
81 public DataMappingFieldDefinition getDataMappingFieldDefinition(String componentClass, String propertyName) {
82 Map<String, String> primaryKeys = new HashMap<String, String>();
83 primaryKeys.put(OLEPropertyConstants.COMPONENT_CLASS, componentClass);
84 primaryKeys.put(OLEPropertyConstants.PROPERTY_NAME, propertyName);
85 FunctionalFieldDescription functionalFieldDescription = businessObjectService.findByPrimaryKey(FunctionalFieldDescription.class, primaryKeys);
86 if (functionalFieldDescription == null) {
87 functionalFieldDescription = new FunctionalFieldDescription(componentClass, propertyName);
88 }
89 functionalFieldDescription.refreshNonUpdateableReferences();
90 return getDataMappingFieldDefinition(functionalFieldDescription);
91 }
92
93 @Override
94 public DataMappingFieldDefinition getDataMappingFieldDefinition(FunctionalFieldDescription functionalFieldDescription) {
95 BusinessObjectEntry businessObjectEntry = (BusinessObjectEntry) dataDictionaryService.getDataDictionary().getBusinessObjectEntry(functionalFieldDescription.getComponentClass());
96 String propertyType = "";
97 try {
98 propertyType = PropertyUtils.getPropertyType(businessObjectEntry.getBusinessObjectClass().newInstance(), functionalFieldDescription.getPropertyName()).getSimpleName();
99 }
100 catch (Exception e) {
101 if (LOG.isDebugEnabled()) {
102 LOG.debug("OleBusinessObjectMetaDataServiceImpl unable to get type of property: " + functionalFieldDescription.getPropertyName(), e);
103 }
104 }
105 return new DataMappingFieldDefinition(functionalFieldDescription, businessObjectEntry,
106 businessObjectEntry.getAttributeDefinition(functionalFieldDescription.getPropertyName()),
107 businessObjectMetaDataDao.getFieldMetaData(businessObjectEntry.getBusinessObjectClass(), functionalFieldDescription.getPropertyName()),
108 propertyType,
109 getReferenceComponentLabel(businessObjectEntry.getBusinessObjectClass(), functionalFieldDescription.getPropertyName()));
110 }
111
112 @Override
113 public List<BusinessObjectComponent> findBusinessObjectComponents(String namespaceCode, String componentLabel) {
114 Map<Class, BusinessObjectComponent> matchingBusinessObjectComponents = new HashMap<Class, BusinessObjectComponent>();
115 Pattern componentLabelRegex = null;
116 if (StringUtils.isNotBlank(componentLabel)) {
117 String patternStr = componentLabel.replace("*", ".*").toUpperCase();
118 try {
119 componentLabelRegex = Pattern.compile(patternStr);
120 }
121 catch (PatternSyntaxException ex) {
122 LOG.error("OleBusinessObjectMetaDataServiceImpl unable to parse componentLabel pattern, ignoring.", ex);
123 }
124 }
125 for (org.kuali.rice.krad.datadictionary.BusinessObjectEntry businessObjectEntry : dataDictionaryService.getDataDictionary().getBusinessObjectEntries().values()) {
126 if ((StringUtils.isBlank(namespaceCode) || namespaceCode.equals(KRADServiceLocatorWeb.getKualiModuleService().getNamespaceCode(businessObjectEntry.getBusinessObjectClass())))
127 && ((componentLabelRegex == null) || (StringUtils.isNotBlank(businessObjectEntry.getObjectLabel()) && componentLabelRegex.matcher(businessObjectEntry.getObjectLabel().toUpperCase()).matches()))) {
128 matchingBusinessObjectComponents.put(businessObjectEntry.getBusinessObjectClass(), new BusinessObjectComponent(KRADServiceLocatorWeb.getKualiModuleService().getNamespaceCode(businessObjectEntry.getBusinessObjectClass()), (BusinessObjectEntry) businessObjectEntry));
129 }
130 }
131 return new ArrayList<BusinessObjectComponent>(matchingBusinessObjectComponents.values());
132 }
133
134 @Override
135 public List<BusinessObjectProperty> findBusinessObjectProperties(String namespaceCode, String componentLabel, String propertyLabel) {
136 List<BusinessObjectComponent> businessObjectComponents = findBusinessObjectComponents(namespaceCode, componentLabel);
137
138 Pattern propertyLabelRegex = null;
139 if (StringUtils.isNotBlank(propertyLabel)) {
140 String patternStr = propertyLabel.replace("*", ".*").toUpperCase();
141 try {
142 propertyLabelRegex = Pattern.compile(patternStr);
143 }
144 catch (PatternSyntaxException ex) {
145 LOG.error("OleBusinessObjectMetaDataServiceImpl unable to parse propertyLabel pattern, ignoring.", ex);
146 }
147 }
148
149 List<BusinessObjectProperty> matchingBusinessObjectProperties = new ArrayList<BusinessObjectProperty>();
150 for (BusinessObjectComponent businessObjectComponent : businessObjectComponents) {
151 for (AttributeDefinition attributeDefinition : dataDictionaryService.getDataDictionary().getBusinessObjectEntry(businessObjectComponent.getComponentClass().toString()).getAttributes()) {
152 if (!attributeDefinition.getName().endsWith(OLEPropertyConstants.VERSION_NUMBER) && !attributeDefinition.getName().endsWith(OLEPropertyConstants.OBJECT_ID) && ((propertyLabelRegex == null) || propertyLabelRegex.matcher(attributeDefinition.getLabel().toUpperCase()).matches())) {
153 matchingBusinessObjectProperties.add(new BusinessObjectProperty(businessObjectComponent, attributeDefinition));
154 }
155 }
156 }
157
158 return matchingBusinessObjectProperties;
159 }
160
161 @Override
162 public List<FunctionalFieldDescription> findFunctionalFieldDescriptions(String namespaceCode, String componentLabel, String propertyLabel, String description, String active) {
163 Set<String> componentClasses = new HashSet<String>();
164 Set<String> propertyNames = new HashSet<String>();
165 for (BusinessObjectProperty businessObjectProperty : findBusinessObjectProperties(namespaceCode, componentLabel, propertyLabel)) {
166 componentClasses.add(businessObjectProperty.getComponentClass());
167 propertyNames.add(businessObjectProperty.getPropertyName());
168 }
169 Map<String, String> fieldValues = new HashMap<String, String>();
170 fieldValues.put(OLEPropertyConstants.NAMESPACE_CODE, namespaceCode);
171 fieldValues.put(OLEPropertyConstants.COMPONENT_CLASS, buildOrCriteria(componentClasses));
172 fieldValues.put(OLEPropertyConstants.PROPERTY_NAME, buildOrCriteria(propertyNames));
173 fieldValues.put(OLEPropertyConstants.DESCRIPTION, description);
174 fieldValues.put(OLEPropertyConstants.ACTIVE, active);
175 List<FunctionalFieldDescription> searchResults = (List<FunctionalFieldDescription>) lookupService.findCollectionBySearchHelper(FunctionalFieldDescription.class, fieldValues, false);
176 for (FunctionalFieldDescription functionalFieldDescription : searchResults) {
177 functionalFieldDescription.refreshNonUpdateableReferences();
178 }
179 return searchResults;
180 }
181
182 protected String buildOrCriteria(Set<String> values) {
183 StringBuffer orCriteria = new StringBuffer();
184 List<String> valueList = new ArrayList<String>(values);
185 for (int i = 0; i < valueList.size(); i++) {
186 orCriteria.append(valueList.get(i));
187 if (i < (valueList.size() - 1)) {
188 orCriteria.append("|");
189 }
190 }
191 return orCriteria.toString();
192 }
193
194 @Override
195 public boolean isMatch(String componentClass, String propertyName, String tableNameSearchCriterion, String fieldNameSearchCriterion) {
196 ClassDescriptor classDescriptor = null;
197 try {
198 classDescriptor = org.apache.ojb.broker.metadata.MetadataManager.getInstance().getGlobalRepository().getDescriptorFor(componentClass);
199 Pattern tableNameRegex = null;
200 if (StringUtils.isNotBlank(tableNameSearchCriterion)) {
201 String patternStr = tableNameSearchCriterion.replace("*", ".*").toUpperCase();
202 try {
203 tableNameRegex = Pattern.compile(patternStr);
204 }
205 catch (PatternSyntaxException ex) {
206 LOG.error("DataMappingFieldDefinitionLookupableHelperServiceImpl unable to parse tableName pattern, ignoring.", ex);
207 }
208 }
209 Pattern fieldNameRegex = null;
210 if (StringUtils.isNotBlank(fieldNameSearchCriterion)) {
211 String patternStr = fieldNameSearchCriterion.replace("*", ".*").toUpperCase();
212 try {
213 fieldNameRegex = Pattern.compile(patternStr);
214 }
215 catch (PatternSyntaxException ex) {
216 LOG.error("DataMappingFieldDefinitionLookupableHelperServiceImpl unable to parse fieldName pattern, ignoring.", ex);
217 }
218 }
219 return ((tableNameRegex == null) || tableNameRegex.matcher(classDescriptor.getFullTableName().toUpperCase()).matches()) && ((fieldNameRegex == null) || ((classDescriptor.getFieldDescriptorByName(propertyName) != null) && fieldNameRegex.matcher(classDescriptor.getFieldDescriptorByName(propertyName).getColumnName().toUpperCase()).matches()));
220 }
221 catch (ClassNotPersistenceCapableException e) {
222 return StringUtils.isBlank(tableNameSearchCriterion) && StringUtils.isBlank(fieldNameSearchCriterion);
223 }
224 }
225
226 @Override
227 public String getReferenceComponentLabel(Class componentClass, String propertyName) {
228 DataObjectRelationship relationship = null;
229 try {
230 relationship = businessObjectMetaDataService.getBusinessObjectRelationship((BusinessObject) componentClass.newInstance(), propertyName);
231 }
232 catch (Exception e) {
233 if ( LOG.isDebugEnabled() ) {
234 LOG.debug("KfsBusinessObjectMetadataServiceImpl unable to instantiate componentClass: " + componentClass, e);
235 }
236 }
237 if (relationship != null) {
238 return dataDictionaryService.getDataDictionary().getBusinessObjectEntry(relationship.getRelatedClass().getName()).getObjectLabel();
239 }
240 return "";
241 }
242
243 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
244 this.dataDictionaryService = dataDictionaryService;
245 }
246
247 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
248 this.businessObjectService = businessObjectService;
249 }
250
251 public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
252 this.businessObjectMetaDataService = businessObjectMetaDataService;
253 }
254
255 public void setBusinessObjectMetaDataDao(BusinessObjectMetaDataDao businessObjectMetaDataDao) {
256 this.businessObjectMetaDataDao = businessObjectMetaDataDao;
257 }
258
259 public void setLookupService(LookupService lookupService) {
260 this.lookupService = lookupService;
261 }
262 }