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 }