001 /**
002 * Copyright 2010-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.common.util.property;
017
018 import java.util.ArrayList;
019 import java.util.List;
020 import java.util.Properties;
021
022 import org.kuali.common.util.CollectionUtils;
023 import org.kuali.common.util.LocationUtils;
024 import org.kuali.common.util.Mode;
025 import org.kuali.common.util.ModeUtils;
026 import org.kuali.common.util.PropertyUtils;
027 import org.kuali.common.util.property.processor.GlobalOverrideProcessor;
028 import org.kuali.common.util.property.processor.HomeProcessor;
029 import org.kuali.common.util.property.processor.OrgProcessor;
030 import org.kuali.common.util.property.processor.PathProcessor;
031 import org.kuali.common.util.property.processor.PropertyProcessor;
032 import org.kuali.common.util.property.processor.ResolvePlaceholdersProcessor;
033 import org.kuali.common.util.property.processor.TrimProcessor;
034 import org.kuali.common.util.property.processor.VersionProcessor;
035 import org.slf4j.Logger;
036 import org.slf4j.LoggerFactory;
037 import org.springframework.util.Assert;
038
039 public class DefaultPropertyLoadContext extends DefaultPropertyContext implements PropertyLoadContext {
040
041 private static final Logger logger = LoggerFactory.getLogger(DefaultPropertyLoadContext.class);
042
043 List<String> locations;
044 String encoding = "UTF-8";
045 String missingLocationsMode = Mode.INFORM.name();
046 Properties locationHelperProperties;
047 String locationHelperInclude;
048 String locationHelperExclude;
049 List<String> locationHelperIncludes;
050 List<String> locationHelperExcludes;
051 String organizationGroupId;
052 String groupIdProperty = Constants.DEFAULT_GROUP_ID_PROPERTY;
053 String versionProperty = Constants.DEFAULT_VERSION_PROPERTY;
054
055 @Override
056 public Properties init() {
057 Assert.notNull(helper, "helper is null");
058 Properties global = getGlobalProperties(locationHelperProperties);
059 this.globalPropertiesMode = resolve(globalPropertiesMode, global);
060 this.missingLocationsMode = resolve(missingLocationsMode, global);
061 logger.info("Global properties mode - " + globalPropertiesMode);
062 logger.info("Missing locations mode - " + missingLocationsMode);
063 this.encoding = resolve(encoding, global);
064 this.organizationGroupId = resolve(organizationGroupId, global);
065 validateGlobalPropertiesMode(globalPropertiesMode);
066 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode);
067 this.locationHelperProperties = getLocationHelperProperties(locationHelperProperties, gpm);
068 logger.info("Property file encoding - " + encoding);
069 logger.info("Using " + locationHelperProperties.size() + " properties to assist with property loading.");
070 validate();
071 if (logger.isDebugEnabled()) {
072 PropertyUtils.debug(locationHelperProperties);
073 }
074 Properties p = new Properties();
075 p.putAll(PropertyUtils.toEmpty(properties));
076 p.putAll(PropertyUtils.toEmpty(locationHelperProperties));
077 return p;
078 }
079
080 protected void validateGlobalPropertiesMode(String globalPropertiesMode) {
081 validateResolved(globalPropertiesMode);
082 GlobalPropertiesMode.valueOf(globalPropertiesMode);
083 }
084
085 @Override
086 protected void validate() {
087 validateGlobalPropertiesMode(globalPropertiesMode);
088 validateResolved(encoding);
089 validateResolved(missingLocationsMode);
090 Mode.valueOf(missingLocationsMode);
091 }
092
093 @Override
094 public String getLocation(String location, Properties properties) {
095 String resolvedLocation = getResolvedLocation(location, properties);
096 return getValidatedLocation(resolvedLocation, Mode.valueOf(missingLocationsMode));
097 }
098
099 protected String getValidatedLocation(String location, Mode missingLocationsMode) {
100 validateResolved(location);
101 if (LocationUtils.exists(location)) {
102 return location;
103 } else {
104 ModeUtils.validate(missingLocationsMode, "Skipping non-existent location - [{}]", location, "Could not locate [" + location + "]");
105 return null;
106 }
107 }
108
109 protected void validateResolved(String string) {
110 if (PropertyUtils.containsUnresolvedPlaceholder(string)) {
111 throw new IllegalArgumentException("Unable to resolve [" + string + "]");
112 }
113 }
114
115 protected String getResolvedLocation(String location, Properties properties) {
116 boolean resolve = PropertyUtils.containsUnresolvedPlaceholder(location);
117 if (resolve) {
118 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode);
119 Properties duplicate = PropertyUtils.getProperties(properties, gpm);
120 List<PropertyProcessor> processors = getLocationProcessors();
121 for (PropertyProcessor processor : processors) {
122 processor.process(duplicate);
123 }
124 return helper.replacePlaceholders(location, duplicate);
125 } else {
126 return location;
127 }
128 }
129
130 protected Properties getGlobalProperties(Properties properties) {
131 return PropertyUtils.getGlobalProperties(PropertyUtils.toEmpty(properties));
132 }
133
134 protected Properties getLocationHelperProperties(Properties properties, GlobalPropertiesMode mode) {
135 Properties locationHelperProperties = PropertyUtils.duplicate(PropertyUtils.toEmpty(properties));
136 List<PropertyProcessor> processors = getLocationHelperProcessors();
137 for (PropertyProcessor processor : processors) {
138 processor.process(locationHelperProperties);
139 }
140 return locationHelperProperties;
141 }
142
143 protected List<PropertyProcessor> getLocationProcessors() {
144 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode);
145 List<PropertyProcessor> processors = new ArrayList<PropertyProcessor>();
146 processors.add(new GlobalOverrideProcessor(gpm));
147 processors.add(new ResolvePlaceholdersProcessor(helper, gpm));
148 return processors;
149 }
150
151 protected String getGroupId() {
152 if (groupIdProperty == null) {
153 return null;
154 } else if (locationHelperProperties == null) {
155 return null;
156 } else {
157 return locationHelperProperties.getProperty(groupIdProperty);
158 }
159 }
160
161 protected List<PropertyProcessor> getLocationHelperProcessors() {
162 List<PropertyProcessor> processors = new ArrayList<PropertyProcessor>();
163
164 this.locationHelperIncludes = CollectionUtils.sortedMerge(locationHelperIncludes, locationHelperInclude);
165 this.locationHelperExcludes = CollectionUtils.sortedMerge(locationHelperExcludes, locationHelperExclude);
166 processors.add(new TrimProcessor(locationHelperIncludes, locationHelperExcludes));
167
168 String groupId = getGroupId();
169 if (organizationGroupId != null && groupId != null) {
170 processors.add(new OrgProcessor(organizationGroupId, groupId));
171 processors.add(new HomeProcessor(organizationGroupId, groupId));
172 }
173
174 if (groupIdProperty != null) {
175 processors.add(new PathProcessor(groupIdProperty));
176 }
177
178 if (versionProperty != null) {
179 processors.add(new VersionProcessor(versionProperty));
180 }
181
182 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode);
183 processors.add(new GlobalOverrideProcessor(gpm));
184 processors.add(new ResolvePlaceholdersProcessor(helper, gpm));
185
186 return processors;
187 }
188
189 public String getMissingLocationsMode() {
190 return missingLocationsMode;
191 }
192
193 public void setMissingLocationsMode(String missingLocationsMode) {
194 this.missingLocationsMode = missingLocationsMode;
195 }
196
197 @Override
198 public List<String> getLocations() {
199 return locations;
200 }
201
202 public void setLocations(List<String> locations) {
203 this.locations = locations;
204 }
205
206 public Properties getLocationHelperProperties() {
207 return locationHelperProperties;
208 }
209
210 public void setLocationHelperProperties(Properties locationHelperProperties) {
211 this.locationHelperProperties = locationHelperProperties;
212 }
213
214 @Override
215 public String getEncoding() {
216 return encoding;
217 }
218
219 public void setEncoding(String encoding) {
220 this.encoding = encoding;
221 }
222
223 public String getOrganizationGroupId() {
224 return organizationGroupId;
225 }
226
227 public void setOrganizationGroupId(String organizationGroupId) {
228 this.organizationGroupId = organizationGroupId;
229 }
230
231 public String getGroupIdProperty() {
232 return groupIdProperty;
233 }
234
235 public void setGroupIdProperty(String groupIdProperty) {
236 this.groupIdProperty = groupIdProperty;
237 }
238
239 public String getVersionProperty() {
240 return versionProperty;
241 }
242
243 public void setVersionProperty(String versionProperty) {
244 this.versionProperty = versionProperty;
245 }
246
247 public List<String> getLocationHelperIncludes() {
248 return locationHelperIncludes;
249 }
250
251 public void setLocationHelperIncludes(List<String> locationHelperIncludes) {
252 this.locationHelperIncludes = locationHelperIncludes;
253 }
254
255 public List<String> getLocationHelperExcludes() {
256 return locationHelperExcludes;
257 }
258
259 public void setLocationHelperExcludes(List<String> locationHelperExcludes) {
260 this.locationHelperExcludes = locationHelperExcludes;
261 }
262
263 public String getLocationHelperInclude() {
264 return locationHelperInclude;
265 }
266
267 public void setLocationHelperInclude(String locationHelperInclude) {
268 this.locationHelperInclude = locationHelperInclude;
269 }
270
271 public String getLocationHelperExclude() {
272 return locationHelperExclude;
273 }
274
275 public void setLocationHelperExclude(String locationHelperExclude) {
276 this.locationHelperExclude = locationHelperExclude;
277 }
278
279 }