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 private static final Logger logger = LoggerFactory.getLogger(DefaultPropertyLoadContext.class); 041 042 List<String> locations; 043 String encoding; 044 String missingLocationsMode = Mode.INFORM.name(); 045 Properties locationHelperProperties; 046 String locationHelperInclude; 047 String locationHelperExclude; 048 List<String> locationHelperIncludes; 049 List<String> locationHelperExcludes; 050 String organizationGroupId; 051 String groupIdProperty = Constants.DEFAULT_GROUP_ID_PROPERTY; 052 String versionProperty = Constants.DEFAULT_VERSION_PROPERTY; 053 054 @Override 055 public Properties init() { 056 Assert.notNull(helper, "helper is null"); 057 Properties global = getGlobalProperties(locationHelperProperties); 058 this.globalPropertiesMode = resolve(globalPropertiesMode, global); 059 this.missingLocationsMode = resolve(missingLocationsMode, global); 060 logger.info("Global properties mode - " + globalPropertiesMode); 061 logger.info("Missing locations mode - " + missingLocationsMode); 062 this.encoding = resolve(encoding, global); 063 this.organizationGroupId = resolve(organizationGroupId, global); 064 validateGlobalPropertiesMode(globalPropertiesMode); 065 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode); 066 this.locationHelperProperties = getLocationHelperProperties(locationHelperProperties, gpm); 067 logger.info("Property file encoding - " + encoding); 068 logger.info("Using " + locationHelperProperties.size() + " properties to assist with property loading."); 069 validate(); 070 if (logger.isDebugEnabled()) { 071 PropertyUtils.debug(locationHelperProperties); 072 } 073 Properties p = new Properties(); 074 p.putAll(PropertyUtils.toEmpty(properties)); 075 p.putAll(PropertyUtils.toEmpty(locationHelperProperties)); 076 return p; 077 } 078 079 protected void validateGlobalPropertiesMode(String globalPropertiesMode) { 080 validateResolved(globalPropertiesMode); 081 GlobalPropertiesMode.valueOf(globalPropertiesMode); 082 } 083 084 @Override 085 protected void validate() { 086 validateGlobalPropertiesMode(globalPropertiesMode); 087 validateResolved(encoding); 088 validateResolved(missingLocationsMode); 089 Mode.valueOf(missingLocationsMode); 090 } 091 092 @Override 093 public String getLocation(String location, Properties properties) { 094 String resolvedLocation = getResolvedLocation(location, properties); 095 return getValidatedLocation(resolvedLocation, Mode.valueOf(missingLocationsMode)); 096 } 097 098 protected String getValidatedLocation(String location, Mode missingLocationsMode) { 099 validateResolved(location); 100 if (LocationUtils.exists(location)) { 101 return location; 102 } else { 103 ModeUtils.validate(missingLocationsMode, "Skipping non-existent location - [{}]", location, "Could not locate [" + location + "]"); 104 return null; 105 } 106 } 107 108 protected void validateResolved(String string) { 109 if (PropertyUtils.containsUnresolvedPlaceholder(string)) { 110 throw new IllegalArgumentException("Unable to resolve [" + string + "]"); 111 } 112 } 113 114 protected String getResolvedLocation(String location, Properties properties) { 115 boolean resolve = PropertyUtils.containsUnresolvedPlaceholder(location); 116 if (resolve) { 117 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode); 118 Properties duplicate = PropertyUtils.getProperties(properties, gpm); 119 List<PropertyProcessor> processors = getLocationProcessors(); 120 for (PropertyProcessor processor : processors) { 121 processor.process(duplicate); 122 } 123 return helper.replacePlaceholders(location, duplicate); 124 } else { 125 return location; 126 } 127 } 128 129 protected Properties getGlobalProperties(Properties properties) { 130 return PropertyUtils.getGlobalProperties(PropertyUtils.toEmpty(properties)); 131 } 132 133 protected Properties getLocationHelperProperties(Properties properties, GlobalPropertiesMode mode) { 134 Properties locationHelperProperties = PropertyUtils.duplicate(PropertyUtils.toEmpty(properties)); 135 List<PropertyProcessor> processors = getLocationHelperProcessors(); 136 for (PropertyProcessor processor : processors) { 137 processor.process(locationHelperProperties); 138 } 139 return locationHelperProperties; 140 } 141 142 protected List<PropertyProcessor> getLocationProcessors() { 143 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode); 144 List<PropertyProcessor> processors = new ArrayList<PropertyProcessor>(); 145 processors.add(new GlobalOverrideProcessor(gpm)); 146 processors.add(new ResolvePlaceholdersProcessor(helper, gpm)); 147 return processors; 148 } 149 150 protected String getGroupId() { 151 if (groupIdProperty == null) { 152 return null; 153 } else if (locationHelperProperties == null) { 154 return null; 155 } else { 156 return locationHelperProperties.getProperty(groupIdProperty); 157 } 158 } 159 160 protected List<PropertyProcessor> getLocationHelperProcessors() { 161 List<PropertyProcessor> processors = new ArrayList<PropertyProcessor>(); 162 163 this.locationHelperIncludes = CollectionUtils.sortedMerge(locationHelperIncludes, locationHelperInclude); 164 this.locationHelperExcludes = CollectionUtils.sortedMerge(locationHelperExcludes, locationHelperExclude); 165 processors.add(new TrimProcessor(locationHelperIncludes, locationHelperExcludes)); 166 167 String groupId = getGroupId(); 168 if (organizationGroupId != null && groupId != null) { 169 processors.add(new OrgProcessor(organizationGroupId, groupId)); 170 processors.add(new HomeProcessor(organizationGroupId, groupId)); 171 } 172 173 if (groupIdProperty != null) { 174 processors.add(new PathProcessor(groupIdProperty)); 175 } 176 177 if (versionProperty != null) { 178 processors.add(new VersionProcessor(versionProperty)); 179 } 180 181 GlobalPropertiesMode gpm = GlobalPropertiesMode.valueOf(globalPropertiesMode); 182 processors.add(new GlobalOverrideProcessor(gpm)); 183 processors.add(new ResolvePlaceholdersProcessor(helper, gpm)); 184 185 return processors; 186 } 187 188 public String getMissingLocationsMode() { 189 return missingLocationsMode; 190 } 191 192 public void setMissingLocationsMode(String missingLocationsMode) { 193 this.missingLocationsMode = missingLocationsMode; 194 } 195 196 @Override 197 public List<String> getLocations() { 198 return locations; 199 } 200 201 public void setLocations(List<String> locations) { 202 this.locations = locations; 203 } 204 205 public Properties getLocationHelperProperties() { 206 return locationHelperProperties; 207 } 208 209 public void setLocationHelperProperties(Properties locationHelperProperties) { 210 this.locationHelperProperties = locationHelperProperties; 211 } 212 213 @Override 214 public String getEncoding() { 215 return encoding; 216 } 217 218 public void setEncoding(String encoding) { 219 this.encoding = encoding; 220 } 221 222 public String getOrganizationGroupId() { 223 return organizationGroupId; 224 } 225 226 public void setOrganizationGroupId(String organizationGroupId) { 227 this.organizationGroupId = organizationGroupId; 228 } 229 230 public String getGroupIdProperty() { 231 return groupIdProperty; 232 } 233 234 public void setGroupIdProperty(String groupIdProperty) { 235 this.groupIdProperty = groupIdProperty; 236 } 237 238 public String getVersionProperty() { 239 return versionProperty; 240 } 241 242 public void setVersionProperty(String versionProperty) { 243 this.versionProperty = versionProperty; 244 } 245 246 public List<String> getLocationHelperIncludes() { 247 return locationHelperIncludes; 248 } 249 250 public void setLocationHelperIncludes(List<String> locationHelperIncludes) { 251 this.locationHelperIncludes = locationHelperIncludes; 252 } 253 254 public List<String> getLocationHelperExcludes() { 255 return locationHelperExcludes; 256 } 257 258 public void setLocationHelperExcludes(List<String> locationHelperExcludes) { 259 this.locationHelperExcludes = locationHelperExcludes; 260 } 261 262 public String getLocationHelperInclude() { 263 return locationHelperInclude; 264 } 265 266 public void setLocationHelperInclude(String locationHelperInclude) { 267 this.locationHelperInclude = locationHelperInclude; 268 } 269 270 public String getLocationHelperExclude() { 271 return locationHelperExclude; 272 } 273 274 public void setLocationHelperExclude(String locationHelperExclude) { 275 this.locationHelperExclude = locationHelperExclude; 276 } 277 278 }