View Javadoc

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