1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import no.geosoft.cc.io.FileListener;
19 import no.geosoft.cc.io.FileMonitor;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.kuali.rice.core.api.config.property.ConfigurationService;
24 import org.kuali.rice.krad.service.KRADServiceLocator;
25 import org.kuali.rice.krad.uif.util.UifBeanFactoryPostProcessor;
26 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
27 import org.springframework.core.io.FileSystemResource;
28 import org.springframework.core.io.InputStreamResource;
29 import org.springframework.core.io.Resource;
30
31 import java.io.File;
32 import java.io.InputStream;
33 import java.net.URL;
34 import java.util.ArrayList;
35 import java.util.List;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class ReloadingDataDictionary extends DataDictionary implements FileListener, URLMonitor.URLContentChangedListener {
56 private static final Log LOG = LogFactory.getLog(DataDictionary.class);
57
58 private static final String CLASS_DIR_CONFIG_PARM = "reload.data.dictionary.classes.dir";
59 private static final String SOURCE_DIR_CONFIG_PARM = "reload.data.dictionary.source.dir";
60 private static final String INTERVAL_CONFIG_PARM = "reload.data.dictionary.interval";
61
62 private URLMonitor dictionaryUrlMonitor;
63
64
65 public ReloadingDataDictionary() {
66 super();
67 }
68
69
70
71
72
73
74
75 @Override
76 public void parseDataDictionaryConfigurationFiles(boolean allowConcurrentValidation) {
77 ConfigurationService configurationService = KRADServiceLocator.getKualiConfigurationService();
78
79
80 String classesDir = configurationService.getPropertyValueAsString(CLASS_DIR_CONFIG_PARM);
81
82
83 String sourceDir = configurationService.getPropertyValueAsString(SOURCE_DIR_CONFIG_PARM);
84
85
86 int reloadInterval = Integer.parseInt(configurationService.getPropertyValueAsString(INTERVAL_CONFIG_PARM));
87
88 FileMonitor dictionaryFileMonitor = new FileMonitor(reloadInterval);
89
90 dictionaryUrlMonitor = new URLMonitor(reloadInterval);
91 dictionaryUrlMonitor.addListener(this);
92
93
94
95 List<String> configLocations = new ArrayList<String>(configFileLocations);
96
97 super.parseDataDictionaryConfigurationFiles(allowConcurrentValidation);
98 for (String configLocation : configLocations) {
99 Resource classFileResource = getFileResource(configLocation);
100 try {
101 if (classFileResource.getURI().toString().startsWith("jar:")) {
102 LOG.debug("Monitoring dictionary file at URI: " + classFileResource.getURI().toString());
103 dictionaryUrlMonitor.addURI(classFileResource.getURL());
104 } else {
105 String filePathClassesDir = classFileResource.getFile().getAbsolutePath();
106 String sourceFilePath = StringUtils.replace(filePathClassesDir, classesDir, sourceDir);
107 File dictionaryFile = new File(filePathClassesDir);
108 if (dictionaryFile.exists()) {
109 LOG.debug("Monitoring dictionary file: " + dictionaryFile.getName());
110 dictionaryFileMonitor.addFile(dictionaryFile);
111 }
112 }
113 }
114 catch (Exception e) {
115 LOG.info("Exception in picking up dictionary file for monitoring: " + e.getMessage(), e);
116 }
117 }
118
119
120 dictionaryFileMonitor.addListener(this);
121 }
122
123
124
125
126
127
128
129
130 @Override
131 public void fileChanged(File file) {
132 LOG.info("reloading dictionary configuration for " + file.getName());
133 try {
134 Resource resource = new FileSystemResource(file);
135 xmlReader.loadBeanDefinitions(resource);
136
137 UifBeanFactoryPostProcessor factoryPostProcessor = new UifBeanFactoryPostProcessor();
138 factoryPostProcessor.postProcessBeanFactory(ddBeans);
139
140
141 ddIndex.run();
142 }
143 catch (Exception e) {
144 LOG.info("Exception in dictionary hot deploy: " + e.getMessage(), e);
145 }
146 }
147
148 public void urlContentChanged(final URL url) {
149 LOG.info("reloading dictionary configuration for " + url.toString());
150 try {
151 InputStream urlStream = url.openStream();
152 InputStreamResource resource = new InputStreamResource(urlStream);
153
154 int originalValidationMode = xmlReader.getValidationMode();
155 xmlReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
156 xmlReader.loadBeanDefinitions(resource);
157 xmlReader.setValidationMode(originalValidationMode);
158
159 UifBeanFactoryPostProcessor factoryPostProcessor = new UifBeanFactoryPostProcessor();
160 factoryPostProcessor.postProcessBeanFactory(ddBeans);
161
162
163 ddIndex.run();
164 }
165 catch (Exception e) {
166 LOG.info("Exception in dictionary hot deploy: " + e.getMessage(), e);
167 }
168 }
169 }