griffon/util/Environment.java

`Environment.java`
`001 /* 002 * Copyright 2004-2012 the original author or authors. 003 * 004 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 017 package griffon.util; 018 019 import groovy.lang.Closure; 020 import groovy.lang.GroovyObjectSupport; 021 import groovy.lang.MissingMethodException; 022 023 import java.util.HashMap; 024 import java.util.Locale; 025 import java.util.Map; 026 027 /** 028 * An enum that represents the current environment 029 * 030 * @author Graeme Rocher (Grails 1.1) 031 */ 032 public enum Environment { 033 /** The development environment */ 034 DEVELOPMENT, 035 036 /** The production environment */ 037 PRODUCTION, 038 039 /** The test environment */ 040 TEST, 041 042 /** A custom environment */ 043 CUSTOM; 044 045 /** 046 * Constant used to resolve the environment via System.getProperty(Environment.KEY) 047 */ 048 public static final String KEY = "griffon.env"; 049 050 /** 051 * Constants that indicates whether this GriffonApplication is running in the default environment 052 */ 053 public static final String DEFAULT = "griffon.env.default"; 054 private static final String PRODUCTION_ENV_SHORT_NAME = "prod"; 055 private static final String DEVELOPMENT_ENVIRONMENT_SHORT_NAME = "dev"; 056 057 private static final String TEST_ENVIRONMENT_SHORT_NAME = "test"; 058 private static Map<String, String> envNameMappings = new HashMap<String, String>() {{ 059 put(DEVELOPMENT_ENVIRONMENT_SHORT_NAME, Environment.DEVELOPMENT.getName()); 060 put(PRODUCTION_ENV_SHORT_NAME, Environment.PRODUCTION.getName()); 061 put(TEST_ENVIRONMENT_SHORT_NAME, Environment.TEST.getName()); 062 }}; 063 064 /** 065 * Returns the current environment which is typcally either DEVELOPMENT, PRODUCTION or TEST. 066 * For custom environments CUSTOM type is returned. 067 * 068 * @return The current environment. 069 */ 070 public static Environment getCurrent() { 071 String envName = System.getProperty(Environment.KEY); 072 Metadata metadata = Metadata.getCurrent(); 073 if (metadata!=null && isBlank(envName)) { 074 envName = metadata.getEnvironment(); 075 } 076 077 if (isBlank(envName)) { 078 return DEVELOPMENT; 079 } 080 081 Environment env = getEnvironment(envName); 082 if (env == null) { 083 try { 084 env = Environment.valueOf(envName.toUpperCase()); 085 } 086 catch (IllegalArgumentException e) { 087 // ignore 088 } 089 } 090 if (env == null) { 091 env = Environment.CUSTOM; 092 env.setName(envName); 093 } 094 return env; 095 } 096 097 /** 098 * @see #getCurrent() 099 * @return the current environment 100 */ 101 public static Environment getCurrentEnvironment() { 102 return getCurrent(); 103 } 104 105 /** 106 * @return Return true if the environment has been set as a System property 107 */ 108 public static boolean isSystemSet() { 109 return System.getProperty(KEY) != null; 110 } 111 112 /** 113 * Returns the environment for the given short name 114 * @param shortName The short name 115 * @return The Environment or null if not known 116 */ 117 public static Environment getEnvironment(String shortName) { 118 final String envName = envNameMappings.get(shortName); 119 if (envName != null) { 120 return Environment.valueOf(envName.toUpperCase()); 121 } 122 return null; 123 } 124 125 /** 126 * Takes an environment specific DSL block like: 127 * 128 * <code> 129 * environments { 130 * development {} 131 * production {} 132 * } 133 * </code> 134 * 135 * And returns the closure that relates to the current environment 136 * 137 * @param closure The top level closure 138 * @return The environment specific block or null if non exists 139 */ 140 public static Closure getEnvironmentSpecificBlock(Closure closure) { 141 final Environment env = getCurrent(); 142 return getEnvironmentSpecificBlock(env, closure); 143 } 144 145 /** 146 * Takes an environment specific DSL block like: 147 * 148 * <code> 149 * environments { 150 * development {} 151 * production {} 152 * } 153 * </code> 154 * 155 * And returns the closure that relates to the specified 156 * 157 * @param env The environment to use 158 * @param closure The top level closure 159 * @return The environment specific block or null if non exists 160 */ 161 public static Closure getEnvironmentSpecificBlock(Environment env, Closure closure) { 162 if (closure == null) { 163 return null; 164 } 165 166 final EnvironmentBlockEvaluator evaluator = evaluateEnvironmentSpecificBlock(env, closure); 167 return evaluator.getCallable(); 168 } 169 170 /** 171 * Takes an environment specific DSL block like: 172 * 173 * <code> 174 * environments { 175 * development {} 176 * production {} 177 * } 178 * </code> 179 * 180 * And executes the closure that relates to the current environment 181 * 182 * @param closure The top level closure 183 * @return The result of the closure execution 184 */ 185 public static Object executeForCurrentEnvironment(Closure closure) { 186 final Environment env = getCurrent(); 187 return executeForEnvironment(env, closure); 188 } 189 190 /** 191 * Takes an environment specific DSL block like: 192 * 193 * <code> 194 * environments { 195 * development {} 196 * production {} 197 * } 198 * </code> 199 * 200 * And executes the closure that relates to the specified environment 201 * 202 * @param env The environment to use 203 * @param closure The top level closure 204 * @return The result of the closure execution 205 */ 206 public static Object executeForEnvironment(Environment env, Closure closure) { 207 if (closure == null) { 208 return null; 209 } 210 211 final EnvironmentBlockEvaluator evaluator = evaluateEnvironmentSpecificBlock(env, closure); 212 return evaluator.execute(); 213 } 214 215 private static EnvironmentBlockEvaluator evaluateEnvironmentSpecificBlock(Environment environment, Closure closure) { 216 final EnvironmentBlockEvaluator evaluator = new EnvironmentBlockEvaluator(environment); 217 closure.setDelegate(evaluator); 218 closure.call(); 219 return evaluator; 220 } 221 222 private static class EnvironmentBlockEvaluator extends GroovyObjectSupport { 223 private Environment current; 224 private Closure callable; 225 226 public Closure getCallable() { 227 return callable; 228 } 229 230 Object execute() { 231 return callable == null ? null : callable.call(); 232 } 233 234 private EnvironmentBlockEvaluator(Environment e) { 235 this.current = e; 236 } 237 238 @SuppressWarnings("unused") 239 public void environments(Closure c) { 240 if (c != null) { 241 c.setDelegate(this); 242 c.call(); 243 } 244 } 245 @SuppressWarnings("unused") 246 public void production(Closure c) { 247 if (current == Environment.PRODUCTION) { 248 this.callable = c; 249 } 250 } 251 @SuppressWarnings("unused") 252 public void development(Closure c) { 253 if (current == Environment.DEVELOPMENT) { 254 this.callable = c; 255 } 256 } 257 @SuppressWarnings("unused") 258 public void test(Closure c) { 259 if (current == Environment.TEST) { 260 this.callable = c; 261 } 262 } 263 264 @SuppressWarnings("unused") 265 public Object methodMissing(String name, Object args) { 266 Object[] argsArray = (Object[])args; 267 if (args != null && argsArray.length > 0 && (argsArray[0] instanceof Closure)) { 268 if (current == Environment.CUSTOM && current.getName().equals(name)) { 269 this.callable = (Closure) argsArray[0]; 270 } 271 return null; 272 } 273 throw new MissingMethodException(name, Environment.class, argsArray); 274 } 275 } 276 277 private static boolean isBlank(String value) { 278 return value == null || value.trim().length() == 0; 279 } 280 281 282 private String name; 283 284 /** 285 * @return The name of the environment 286 */ 287 public String getName() { 288 if(name == null) { 289 return this.toString().toLowerCase(Locale.getDefault()); 290 } 291 return name; 292 } 293 294 public void setName(String name) { 295 this.name = name; 296 } 297 }`