View Javadoc

1   /**
2    * Copyright 2005-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  package org.kuali.rice.krad.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.component.Component;
21  import org.kuali.rice.core.api.component.ComponentService;
22  import org.kuali.rice.core.api.config.ConfigurationException;
23  import org.kuali.rice.core.framework.parameter.ParameterConstants;
24  import org.kuali.rice.krad.bo.BusinessObject;
25  import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
26  import org.kuali.rice.krad.datadictionary.DocumentEntry;
27  import org.kuali.rice.krad.datadictionary.TransactionalDocumentEntry;
28  import org.kuali.rice.krad.document.TransactionalDocument;
29  import org.kuali.rice.krad.service.DataDictionaryComponentPublisherService;
30  import org.kuali.rice.krad.service.DataDictionaryService;
31  import org.kuali.rice.krad.service.KualiModuleService;
32  import org.kuali.rice.krad.util.KRADUtils;
33  
34  import java.util.ArrayList;
35  import java.util.HashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  /**
40   * Reference implementation of the {@code DataDictionaryComponentPublisherService}.
41   *
42   * This implementation derives components from the DataDictionary for all BusinessObjects and Documents.
43   *
44   * @author Kuali Rice Team (rice.collab@kuali.org)
45   */
46  public class DataDictionaryComponentPublisherServiceImpl implements DataDictionaryComponentPublisherService {
47  
48      private static final Logger LOG = Logger.getLogger(DataDictionaryComponentPublisherServiceImpl.class);
49  
50      private static final String DEFAULT_COMPONENT_SET_ID_PREFIX = "DD:";
51  
52      private DataDictionaryService dataDictionaryService;
53      private KualiModuleService kualiModuleService;
54      private ComponentService componentService;
55      private String applicationId;
56  
57      @Override
58      public void publishAllComponents() {
59          List<Component> componentsToPublish = getComponentsToPublish();
60          getComponentService().publishDerivedComponents(generateComponentSetId(), componentsToPublish);
61      }
62  
63      protected String generateComponentSetId() {
64          if (StringUtils.isBlank(getApplicationId())) {
65              throw new ConfigurationException("A valid non-null, non-blank application id was not injected into " + getClass().getName());
66          }
67          return DEFAULT_COMPONENT_SET_ID_PREFIX + getApplicationId();
68      }
69  
70      protected List<Component> getComponentsToPublish() {
71          List<Component> components = new ArrayList<Component>();
72  
73          Map<String, Component> uniqueComponentMap = new HashMap<String, Component>();
74          for (BusinessObjectEntry businessObjectEntry : getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().values()) {
75              try {
76                  Component component = deriveComponentFromBusinessObjectEntry(businessObjectEntry);
77                  uniqueComponentMap.put(component.getCode(), component);
78              }
79              catch (Exception e) {
80                  LOG.error("An exception was encountered when attempting to publish all components for business object class: " + businessObjectEntry.getBusinessObjectClass(), e);
81              }
82          }
83          for (DocumentEntry documentEntry : getDataDictionaryService().getDataDictionary().getDocumentEntries().values()) {
84              if (documentEntry instanceof TransactionalDocumentEntry) {
85                  try {
86                      Component component = deriveComponentFromDocumentEntry(documentEntry);
87                      uniqueComponentMap.put(component.getCode(), component);
88                  }
89                  catch (Exception e) {
90                      LOG.error("An exception was encountered when attempting to publish all components for transactional document class: " + documentEntry.getDocumentClass(), e);
91                  }
92              }
93          }
94          components.addAll(uniqueComponentMap.values());
95          return components;
96      }
97  
98  	protected Component deriveComponentFromClass(Class<?> componentSourceClass) {
99          String componentCode = getKualiModuleService().getComponentCode(componentSourceClass);
100         String componentName = deriveComponentName(componentSourceClass);
101         String namespace = getKualiModuleService().getNamespaceCode(componentSourceClass);
102         if (StringUtils.isBlank(componentName)) {
103             componentName = componentCode;
104         }
105         Component.Builder detailType = Component.Builder.create(namespace, componentCode, componentName);
106         return detailType.build();
107     }
108 
109     protected Component deriveComponentFromBusinessObjectEntry(BusinessObjectEntry businessObjectEntry) {
110         Class<?> businessObjectClass = businessObjectEntry.getBaseBusinessObjectClass();
111         if (businessObjectClass == null) {
112             businessObjectClass = businessObjectEntry.getBusinessObjectClass();
113         }
114         return deriveComponentFromClass(businessObjectClass);
115     }
116 
117     protected Component deriveComponentFromDocumentEntry(DocumentEntry documentEntry) {
118         Class<?> documentClass = documentEntry.getBaseDocumentClass();
119         if (documentClass == null) {
120             documentClass = documentEntry.getDocumentClass();
121         }
122         return deriveComponentFromClass(documentClass);
123     }
124 
125 	protected String deriveComponentName(Class<?> componentSourceClass) {
126         if (componentSourceClass == null) {
127             throw new IllegalArgumentException("The deriveComponentName method requires non-null componentSourceClass");
128         }
129         
130         /*
131          * Some business objects have a Component annotation that sets the value
132          * of the classes annotaion.  This if block will test to see if it is there, try to get the
133          * component value from the Data Dictionary if the BusinessObjectEntry exists, if it doesn't
134          * exist, it will fall back to the annotation's value.
135          */
136         if (componentSourceClass.isAnnotationPresent(ParameterConstants.COMPONENT.class)) {
137             BusinessObjectEntry boe = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(componentSourceClass.getName());
138             if (boe != null) {
139                 return boe.getObjectLabel();
140             }
141             else {
142                 return ((ParameterConstants.COMPONENT) componentSourceClass.getAnnotation(ParameterConstants.COMPONENT.class)).component();
143             }
144         }
145 
146         /*
147          * If block that determines if the class is either a BusinessObject or a TransactionalDocument
148          * return calls try to either get the BusinessObjectEntry's ObjectLable, or grabbing the
149          * data dictionary's BusinessTitleForClass if it is a BusinessObject, or the DocumentLabel if it is a
150          * TransactionalDocument
151          */
152         if (TransactionalDocument.class.isAssignableFrom(componentSourceClass)) {
153             return getDataDictionaryService().getDocumentLabelByClass(componentSourceClass);
154         }
155         else if (BusinessObject.class.isAssignableFrom(componentSourceClass) ) {
156             BusinessObjectEntry boe = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(componentSourceClass.getName());
157             if (boe != null) {
158                 return boe.getObjectLabel();
159             }
160             else {
161                 return KRADUtils.getBusinessTitleForClass(componentSourceClass);
162             }
163         }
164         throw new IllegalArgumentException("The deriveComponentName method of requires TransactionalDocument or BusinessObject class. Was: " + componentSourceClass.getName() );
165     }
166 
167     public DataDictionaryService getDataDictionaryService() {
168         return dataDictionaryService;
169     }
170 
171     public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
172         this.dataDictionaryService = dataDictionaryService;
173     }
174 
175     public KualiModuleService getKualiModuleService() {
176         return kualiModuleService;
177     }
178 
179     public void setKualiModuleService(KualiModuleService kualiModuleService) {
180         this.kualiModuleService = kualiModuleService;
181     }
182 
183     public ComponentService getComponentService() {
184         return componentService;
185     }
186 
187     public void setComponentService(ComponentService componentService) {
188         this.componentService = componentService;
189     }
190 
191     public String getApplicationId() {
192         return applicationId;
193     }
194 
195     public void setApplicationId(String applicationId) {
196         this.applicationId = applicationId;
197     }
198     
199 }