View Javadoc

1   /**
2    * Copyright 2010-2013 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.common.util.config.service;
17  
18  import java.io.File;
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.Properties;
22  
23  import org.apache.commons.lang3.StringUtils;
24  import org.kuali.common.util.Assert;
25  import org.kuali.common.util.CollectionUtils;
26  import org.kuali.common.util.LocationUtils;
27  import org.kuali.common.util.Mode;
28  import org.kuali.common.util.ModeUtils;
29  import org.kuali.common.util.PropertyUtils;
30  import org.kuali.common.util.nullify.Nullifier;
31  import org.kuali.common.util.project.ProjectService;
32  import org.kuali.common.util.project.ProjectUtils;
33  import org.kuali.common.util.project.model.Project;
34  import org.kuali.common.util.property.Constants;
35  import org.kuali.common.util.property.processor.OverrideProcessor;
36  import org.kuali.common.util.xml.service.XmlService;
37  import org.springframework.util.PropertyPlaceholderHelper;
38  
39  /**
40   * @deprecated
41   */
42  @Deprecated
43  public abstract class AbstractCachingConfigService implements ConfigService {
44  
45  	public AbstractCachingConfigService(ProjectService projectService, XmlService xmlService) {
46  		Assert.noNulls(projectService, xmlService);
47  		this.projectService = projectService;
48  		this.xmlService = xmlService;
49  	}
50  
51  	private static final String METAINF = "META-INF";
52  	private static final String CLASSPATH = "classpath:";
53  	private static final String CLASSPATH_PREFIX_KEY = "classpath.prefix";
54  	private static final String CONFIG = "config";
55  	private static final String PROPS = "metadata.properties";
56  	private static final String DELIMITER = ":";
57  	private static final PropertyPlaceholderHelper HELPER = Constants.DEFAULT_PROPERTY_PLACEHOLDER_HELPER;
58  
59  	private final ProjectService projectService;
60  	private final XmlService xmlService;
61  
62  	@Override
63  	public Properties getProperties(String configId) {
64  		return getProperties(configId, (Properties) null);
65  	}
66  
67  	@Override
68  	public Properties getProperties(List<String> configIds) {
69  		return getProperties(configIds, null);
70  	}
71  
72  	@Override
73  	public Properties getProperties(String configId, Properties overrides) {
74  		return getProperties(CollectionUtils.toEmptyList(configId), overrides);
75  	}
76  
77  	@Override
78  	public Properties getProperties(List<String> configIds, Properties overrides) {
79  		List<org.kuali.common.util.config.ProjectConfig> requests = org.kuali.common.util.config.ConfigUtils.getProjectConfigs(CollectionUtils.toEmptyList(configIds));
80  		return loadProperties(requests, PropertyUtils.toEmpty(overrides));
81  	}
82  
83  	protected abstract org.kuali.common.util.config.ProjectConfigContainer getCachedConfig(String groupId, String artifactId);
84  
85  	protected abstract void clearCache();
86  
87  	protected abstract org.kuali.common.util.config.ProjectConfigContainer getProjectConfig(String content, String encoding);
88  
89  	protected abstract String getFilename();
90  
91  	protected Properties loadProperties(List<org.kuali.common.util.config.ProjectConfig> requests, Properties overrides) {
92  		// Convert the ConfigRequest objects into Location objects
93  		List<org.kuali.common.util.config.Location> locations = getLocations(requests);
94  		// Allocate some storage
95  		Properties properties = new Properties();
96  		// Get system/environment properties
97  		Properties global = PropertyUtils.getGlobalProperties();
98  		// Cycle through our list of locations
99  		for (org.kuali.common.util.config.Location location : locations) {
100 			// Combine properties we've already loaded with overrides and global properties
101 			Properties resolver = PropertyUtils.combine(properties, overrides, global);
102 			// Use the combined properties to resolve any placeholders in the location
103 			String resolvedLocation = HELPER.replacePlaceholders(location.getValue(), resolver);
104 			// If the location exists, load it
105 			if (LocationUtils.exists(resolvedLocation)) {
106 				Properties loaded = PropertyUtils.load(resolvedLocation, location.getEncoding());
107 				new OverrideProcessor(Mode.INFORM, loaded, 2).process(properties);
108 			} else {
109 				// Take appropriate action for missing locations (ignore, inform, warn, or error out)
110 				ModeUtils.validate(location.getMissingMode(), "Non-existent location [" + resolvedLocation + "]");
111 			}
112 		}
113 		// Override the loaded properties with overrides properties
114 		new OverrideProcessor(Mode.INFORM, overrides, 2).process(properties);
115 		// Override everything with system/environment properties
116 		new OverrideProcessor(Mode.INFORM, global, 2).process(properties);
117 		// Decrypt them
118 		PropertyUtils.decrypt(properties);
119 		// Resolve them, throwing an exception if any value cannot be fully resolved
120 		PropertyUtils.resolve(properties);
121 		// Return what we've found
122 		return properties;
123 	}
124 
125 	protected Properties getBaseFilterProperties() {
126 		return new Properties();
127 	}
128 
129 	protected org.kuali.common.util.config.ProjectConfigContainer loadMetadata(String groupId, String artifactId) {
130 
131 		Assert.notNull(projectService, "projectService is null");
132 
133 		Project project = projectService.getProject(groupId, artifactId);
134 		String location = getMetadataConfigFilePath(project, getFilename());
135 
136 		// Throw an exception if they are asking for config metadata that doesn't exist
137 		Assert.exists(location, "[" + location + "] does not exist");
138 		Properties properties = getBaseFilterProperties();
139 		Properties projectProperties = getFilterProperties(project);
140 		properties.putAll(projectProperties);
141 		String encoding = ProjectUtils.getEncoding(project);
142 		String content = getFilteredContent(location, properties, encoding);
143 		return getProjectConfig(content, encoding);
144 	}
145 
146 	protected List<org.kuali.common.util.config.Location> getLocations(List<org.kuali.common.util.config.ProjectConfig> configs) {
147 		List<org.kuali.common.util.config.Location> locations = new ArrayList<org.kuali.common.util.config.Location>();
148 		for (org.kuali.common.util.config.ProjectConfig config : configs) {
149 			List<org.kuali.common.util.config.Location> requestLocations = findLocations(config);
150 			locations.addAll(requestLocations);
151 		}
152 		return locations;
153 	}
154 
155 	protected List<org.kuali.common.util.config.Location> findLocations(org.kuali.common.util.config.ProjectConfig request) {
156 		org.kuali.common.util.config.ProjectConfigContainer config = getCachedConfig(request.getGroupId(), request.getArtifactId());
157 		if (StringUtils.isBlank(request.getContextId())) {
158 			return new ArrayList<org.kuali.common.util.config.Location>(CollectionUtils.toEmptyList(config.getLocations()));
159 		} else {
160 			String[] tokens = StringUtils.split(request.getContextId(), DELIMITER);
161 			List<org.kuali.common.util.config.ContextConfig> contexts = config.getContexts();
162 			org.kuali.common.util.config.ContextConfig context = null;
163 			for (String token : tokens) {
164 				context = findContextConfig(contexts, token);
165 				contexts = context.getContexts();
166 			}
167 			return context.getLocations();
168 		}
169 	}
170 
171 	protected org.kuali.common.util.config.ContextConfig findContextConfig(List<org.kuali.common.util.config.ContextConfig> contexts, String contextId) {
172 		for (org.kuali.common.util.config.ContextConfig context : contexts) {
173 			if (StringUtils.equals(contextId, context.getId())) {
174 				return context;
175 			}
176 		}
177 		throw new IllegalArgumentException("Unknown contextId [" + contextId + "]");
178 	}
179 
180 	protected String getMetadataConfigFilePath(Project project, String filename) {
181 		String resourcePath = ProjectUtils.getResourcePath(project.getGroupId(), project.getArtifactId());
182 		return CLASSPATH + METAINF + "/" + resourcePath + "/" + CONFIG + "/" + filename;
183 	}
184 
185 	protected String getFilteredContent(String location, Properties properties, String encoding) {
186 		PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", ":", true);
187 		String originalContent = LocationUtils.toString(location, encoding);
188 		String filteredContent = helper.replacePlaceholders(originalContent, properties);
189 		return filteredContent;
190 	}
191 
192 	protected Properties getFilterProperties(Project project) {
193 		String classpathPrefix = ProjectUtils.getClasspathPrefix(project.getGroupId(), project.getArtifactId());
194 		Properties duplicate = PropertyUtils.duplicate(project.getProperties());
195 		duplicate.setProperty(CLASSPATH_PREFIX_KEY, classpathPrefix);
196 		String location = getMetadataConfigFilePath(project, PROPS);
197 		Properties metadata = new Properties();
198 		if (LocationUtils.exists(location)) {
199 			String encoding = ProjectUtils.getEncoding(project);
200 			metadata = PropertyUtils.load(location, encoding);
201 		}
202 		duplicate.putAll(metadata);
203 		return duplicate;
204 	}
205 
206 	protected void store(File file, org.kuali.common.util.config.ProjectConfigContainer config) {
207 
208 		Assert.notNull(file, "file is null");
209 		Assert.notNull(config, "config is null");
210 
211 		org.kuali.common.util.config.ProjectConfigContainer clone = new org.kuali.common.util.config.ProjectConfigContainer(config);
212 
213 		Nullifier nullifier = new org.kuali.common.util.config.ProjectConfigContainerNullifier();
214 		nullifier.nullify();
215 
216 		xmlService.write(file, clone);
217 	}
218 
219 	public ProjectService getProjectService() {
220 		return projectService;
221 	}
222 
223 	public XmlService getXmlService() {
224 		return xmlService;
225 	}
226 
227 }