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 }