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.config;
17  
18  import org.kuali.rice.core.api.config.ConfigurationException;
19  import org.kuali.rice.core.api.config.property.ConfigContext;
20  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
21  import org.kuali.rice.core.framework.config.module.ModuleConfigurer;
22  import org.kuali.rice.krad.service.DataDictionaryService;
23  import org.kuali.rice.krad.service.KRADServiceLocatorInternal;
24  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
25  import org.kuali.rice.krad.util.KRADConstants;
26  
27  import javax.sql.DataSource;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.concurrent.Executors;
31  import java.util.concurrent.ScheduledExecutorService;
32  import java.util.concurrent.TimeUnit;
33  
34  public class KRADConfigurer extends ModuleConfigurer {
35  
36      private DataSource applicationDataSource;
37      private DataSource serverDataSource;
38  
39      private boolean includeKnsSpringBeans;
40  
41      private static final String KRAD_SPRING_BEANS_PATH = "classpath:org/kuali/rice/krad/config/KRADSpringBeans.xml";
42      private static final String KNS_SPRING_BEANS_PATH = "classpath:org/kuali/rice/kns/config/KNSSpringBeans.xml";
43  
44      @Override
45      public void addAdditonalToConfig() {
46          configureDataSource();
47      }
48  
49      @Override
50      public List<String> getPrimarySpringFiles() {
51          final List<String> springFileLocations = new ArrayList<String>();
52          springFileLocations.add(KRAD_SPRING_BEANS_PATH);
53  
54          if (isExposeServicesOnBus()) {
55              //TODO FIXME hack!  KRAD should not be loading core!  (needed for now to publish core services)
56              springFileLocations.add("classpath:org/kuali/rice/core/config/COREServiceBusSpringBeans.xml");
57          }
58  
59          if (isIncludeKnsSpringBeans()) {
60              springFileLocations.add(KNS_SPRING_BEANS_PATH);
61          }
62  
63          return springFileLocations;
64      }
65  
66      @Override
67      public void doAdditionalContextStartedLogic() {
68          loadDataDictionary();
69          publishDataDictionaryComponents();
70      }
71  
72      /**
73       * Used to "poke" the Data Dictionary again after the Spring Context is initialized.  This is to
74       * allow for modules loaded with KualiModule after the KNS has already been initialized to work.
75       *
76       * Also initializes the DateTimeService
77       */
78      protected void loadDataDictionary() {
79          if (isLoadDataDictionary()) {
80              LOG.info("KRAD Configurer - Loading DD");
81              DataDictionaryService dds = KRADServiceLocatorWeb.getDataDictionaryService();
82              if (dds == null) {
83                  dds = (DataDictionaryService) GlobalResourceLoader
84                          .getService(KRADServiceLocatorWeb.DATA_DICTIONARY_SERVICE);
85              }
86              dds.getDataDictionary().parseDataDictionaryConfigurationFiles(false);
87  
88              if (isValidateDataDictionary()) {
89                  LOG.info("KRAD Configurer - Validating DD");
90                  dds.getDataDictionary().validateDD(isValidateDataDictionaryEboReferences());
91              }
92  
93              // KULRICE-4513 After the Data Dictionary is loaded and validated, perform Data Dictionary bean overrides.
94              dds.getDataDictionary().performBeanOverrides();
95          }
96      }
97  
98      protected void publishDataDictionaryComponents() {
99          if (isComponentPublishingEnabled()) {
100             long delay = getComponentPublishingDelay();
101             LOG.info("Publishing of Data Dictionary components is enabled, scheduling publish after " + delay + " millisecond delay");
102             ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
103             try {
104                 scheduler.schedule(new Runnable() {
105                     @Override
106                     public void run() {
107                         long s = System.currentTimeMillis();
108                         LOG.info("Executing scheduled Data Dictionary component publishing...");
109                         try {
110                             KRADServiceLocatorInternal.getDataDictionaryComponentPublisherService().publishAllComponents();
111                         } catch (RuntimeException e) {
112                             LOG.error("Failed to publish data dictionary components.", e);
113                             throw e;
114                         } finally {
115                             long e = System.currentTimeMillis();
116                             LOG.info("... finished scheduled execution of Data Dictionary component publishing.  Took " + (e-s) + " milliseconds");
117                         }
118                     }
119                 }, delay, TimeUnit.MILLISECONDS);
120             } finally {
121                 scheduler.shutdown();
122             }
123         }
124     }
125 
126     /**
127      * Returns true - KNS UI should always be included.
128      *
129      * @see org.kuali.rice.core.framework.config.module.ModuleConfigurer#shouldRenderWebInterface()
130      */
131     @Override
132     public boolean shouldRenderWebInterface() {
133         return true;
134     }
135 
136     public boolean isLoadDataDictionary() {
137         return ConfigContext.getCurrentContextConfig().getBooleanProperty("load.data.dictionary", true);
138     }
139 
140     public boolean isValidateDataDictionary() {
141         return ConfigContext.getCurrentContextConfig().getBooleanProperty("validate.data.dictionary", false);
142     }
143 
144     public boolean isValidateDataDictionaryEboReferences() {
145         return ConfigContext.getCurrentContextConfig().getBooleanProperty("validate.data.dictionary.ebo.references",
146                 false);
147     }
148 
149     public boolean isComponentPublishingEnabled() {
150         return ConfigContext.getCurrentContextConfig().getBooleanProperty(KRADConstants.Config.COMPONENT_PUBLISHING_ENABLED, false);
151     }
152 
153     public long getComponentPublishingDelay() {
154         return ConfigContext.getCurrentContextConfig().getNumericProperty(KRADConstants.Config.COMPONENT_PUBLISHING_DELAY, 0);
155     }
156 
157     /**
158      * Used to "poke" the Data Dictionary again after the Spring Context is initialized.  This is to
159      * allow for modules loaded with KualiModule after the KNS has already been initialized to work.
160      *
161      * Also initializes the DateTimeService
162      */
163     protected void configureDataSource() {
164         if (getApplicationDataSource() != null && getServerDataSource() == null) {
165             throw new ConfigurationException(
166                     "An application data source was defined but a server data source was not defined.  Both must be specified.");
167         }
168         if (getApplicationDataSource() == null && getServerDataSource() != null) {
169             throw new ConfigurationException(
170                     "A server data source was defined but an application data source was not defined.  Both must be specified.");
171         }
172 
173         if (getApplicationDataSource() != null) {
174             ConfigContext.getCurrentContextConfig()
175                     .putObject(KRADConstants.KRAD_APPLICATION_DATASOURCE, getApplicationDataSource());
176         }
177         if (getServerDataSource() != null) {
178             ConfigContext.getCurrentContextConfig()
179                     .putObject(KRADConstants.KRAD_SERVER_DATASOURCE, getServerDataSource());
180         }
181     }
182 
183     public DataSource getApplicationDataSource() {
184         return this.applicationDataSource;
185     }
186 
187     public DataSource getServerDataSource() {
188         return this.serverDataSource;
189     }
190 
191     public void setApplicationDataSource(DataSource applicationDataSource) {
192         this.applicationDataSource = applicationDataSource;
193     }
194 
195     public void setServerDataSource(DataSource serverDataSource) {
196         this.serverDataSource = serverDataSource;
197     }
198 
199     /**
200      * Indicates whether the legacy KNS module should be included which will include
201      * the KNS spring beans file
202      *
203      * @return boolean true if kns should be supported, false if not
204      */
205     public boolean isIncludeKnsSpringBeans() {
206         return includeKnsSpringBeans;
207     }
208 
209     /**
210      * Setter for the include kns support indicator
211      *
212      * @param includeKnsSpringBeans
213      */
214     public void setIncludeKnsSpringBeans(boolean includeKnsSpringBeans) {
215         this.includeKnsSpringBeans = includeKnsSpringBeans;
216     }
217 }