001/**
002 * Copyright 2010-2014 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 */
016package org.kuali.common.util.spring;
017
018import static org.codehaus.plexus.util.StringUtils.isBlank;
019
020import java.io.File;
021import java.util.ArrayList;
022import java.util.Arrays;
023import java.util.Collections;
024import java.util.Comparator;
025import java.util.HashMap;
026import java.util.List;
027import java.util.Map;
028import java.util.Properties;
029
030import org.codehaus.plexus.util.StringUtils;
031import org.kuali.common.util.Assert;
032import org.kuali.common.util.CollectionUtils;
033import org.kuali.common.util.FormatUtils;
034import org.kuali.common.util.LocationUtils;
035import org.kuali.common.util.Mode;
036import org.kuali.common.util.PropertyUtils;
037import org.kuali.common.util.ReflectionUtils;
038import org.kuali.common.util.execute.Executable;
039import org.kuali.common.util.log.LoggerLevel;
040import org.kuali.common.util.log.LoggerUtils;
041import org.kuali.common.util.nullify.NullUtils;
042import org.kuali.common.util.property.Constants;
043import org.kuali.common.util.property.PropertiesContext;
044import org.kuali.common.util.spring.env.EnvironmentService;
045import org.slf4j.Logger;
046import org.slf4j.LoggerFactory;
047import org.springframework.beans.factory.BeanFactoryUtils;
048import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
049import org.springframework.context.ApplicationContext;
050import org.springframework.context.ConfigurableApplicationContext;
051import org.springframework.context.annotation.AnnotationConfigApplicationContext;
052import org.springframework.context.support.AbstractApplicationContext;
053import org.springframework.context.support.ClassPathXmlApplicationContext;
054import org.springframework.context.support.GenericXmlApplicationContext;
055import org.springframework.core.env.ConfigurableEnvironment;
056import org.springframework.core.env.EnumerablePropertySource;
057import org.springframework.core.env.Environment;
058import org.springframework.core.env.PropertiesPropertySource;
059import org.springframework.core.env.PropertySource;
060
061import com.google.common.base.Optional;
062import com.google.common.collect.ImmutableList;
063
064public class SpringUtils {
065
066        private static final Logger logger = LoggerFactory.getLogger(SpringUtils.class);
067
068        private static final String GLOBAL_SPRING_PROPERTY_SOURCE_NAME = "springPropertySource";
069
070        public static <T> T getProperty(Optional<EnvironmentService> env, List<String> keys, Class<T> type, T provided) {
071                return getProperty(env, keys, type, Optional.fromNullable(provided)).orNull();
072        }
073
074        public static <T> Optional<T> getProperty(Optional<EnvironmentService> env, String key, Class<T> type, Optional<T> provided) {
075                return getProperty(env, ImmutableList.of(key), type, provided);
076        }
077
078        public static <T> Optional<T> getProperty(Optional<EnvironmentService> env, List<String> keys, Class<T> type, Optional<T> provided) {
079                if (!env.isPresent()) {
080                        return provided;
081                }
082                for (String key : keys) {
083                        Optional<T> value = getOptionalProperty(env.get(), key, type);
084                        if (value.isPresent()) {
085                                return value;
086                        }
087                }
088                return provided;
089        }
090
091        public static Optional<String> getString(Optional<EnvironmentService> env, List<String> keys, Optional<String> provided) {
092                if (!env.isPresent()) {
093                        return provided;
094                }
095                for (String key : keys) {
096                        Optional<String> value = getOptionalString(env.get(), key);
097                        if (value.isPresent()) {
098                                return value;
099                        }
100                }
101                return provided;
102        }
103
104        public static String getString(EnvironmentService env, List<String> keys) {
105                return getString(Optional.of(env), keys, Optional.<String> absent()).get();
106        }
107
108        public static Optional<String> getString(EnvironmentService env, List<String> keys, Optional<String> provided) {
109                return getString(Optional.of(env), keys, provided);
110        }
111
112        public static Optional<String> getString(EnvironmentService env, String key, Optional<String> provided) {
113                return getString(env, ImmutableList.of(key), provided);
114        }
115
116        public static Optional<Boolean> getBoolean(EnvironmentService env, String key, Optional<Boolean> provided) {
117                Optional<Boolean> value = getOptionalBoolean(env, key);
118                if (value.isPresent()) {
119                        return value;
120                } else {
121                        return provided;
122                }
123        }
124
125        public static Optional<Integer> getInteger(EnvironmentService env, String key, Optional<Integer> provided) {
126                Optional<Integer> value = getOptionalInteger(env, key);
127                if (value.isPresent()) {
128                        return value;
129                } else {
130                        return provided;
131                }
132        }
133
134        public static Optional<Integer> getOptionalInteger(EnvironmentService env, String key) {
135                if (!env.containsProperty(key)) {
136                        return Optional.absent();
137                } else {
138                        return Optional.of(env.getInteger(key));
139                }
140        }
141
142        /**
143         * If there is no value for <code>key</code> return Optional.absent(), otherwise return Optional.of(value)
144         */
145        public static <T> Optional<T> getOptionalProperty(EnvironmentService env, List<String> keys, Class<T> type) {
146                for (String key : keys) {
147                        Optional<T> value = getOptionalProperty(env, key, type);
148                        if (value.isPresent()) {
149                                return value;
150                        }
151                }
152                return Optional.absent();
153        }
154
155        /**
156         * If there is no value for <code>key</code> return Optional.absent(), otherwise return Optional.of(value)
157         */
158        public static <T> Optional<T> getOptionalProperty(EnvironmentService env, String key, Class<T> type) {
159                if (!env.containsProperty(key)) {
160                        return Optional.absent();
161                } else {
162                        T value = env.getProperty(key, type);
163                        return Optional.of(value);
164                }
165        }
166
167        /**
168         * If there is no value for <code>key</code> or the value is NULL or NONE, return Optional.absent(), otherwise return Optional.of(value)
169         */
170        public static Optional<String> getOptionalString(EnvironmentService env, String key) {
171                if (!env.containsProperty(key)) {
172                        return Optional.absent();
173                } else {
174                        return NullUtils.toAbsent(env.getString(key));
175                }
176        }
177
178        public static Optional<Boolean> getOptionalBoolean(EnvironmentService env, String key) {
179                if (!env.containsProperty(key)) {
180                        return Optional.absent();
181                } else {
182                        return Optional.of(env.getBoolean(key));
183                }
184        }
185
186        @Deprecated
187        public static org.kuali.common.util.service.SpringContext getSpringContext(List<Class<?>> annotatedClasses, org.kuali.common.util.ProjectContext project,
188                        List<org.kuali.common.util.ProjectContext> others) {
189                // This PropertySource object is backed by a set of properties that has been
190                // 1 - fully resolved
191                // 2 - contains all properties needed by Spring
192                // 3 - contains system/environment properties where system/env properties override loaded properties
193                PropertySource<?> source = getGlobalPropertySource(project, others);
194
195                // Setup a property source context such that our single property source is the only one registered with Spring
196                // This will make it so our PropertySource is the ONLY thing used to resolve placeholders
197                org.kuali.common.util.service.PropertySourceContext psc = new org.kuali.common.util.service.PropertySourceContext(source, true);
198
199                // Setup a Spring context
200                org.kuali.common.util.service.SpringContext context = new org.kuali.common.util.service.SpringContext();
201
202                // Supply Spring with our PropertySource
203                context.setPropertySourceContext(psc);
204
205                // Supply Spring with java classes containing annotated config
206                context.setAnnotatedClasses(annotatedClasses);
207
208                // Return a Spring context configured with a single property source
209                return context;
210        }
211
212        @Deprecated
213        public static org.kuali.common.util.service.SpringContext getSpringContext(Class<?> annotatedClass, org.kuali.common.util.ProjectContext project,
214                        List<org.kuali.common.util.ProjectContext> others) {
215                return getSpringContext(CollectionUtils.asList(annotatedClass), project, others);
216        }
217
218        /**
219         * 
220         */
221        @Deprecated
222        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, org.kuali.common.util.ProjectContext other) {
223                return getGlobalPropertySource(project, Arrays.asList(other));
224        }
225
226        /**
227         * 
228         */
229        @Deprecated
230        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, List<org.kuali.common.util.ProjectContext> others) {
231                return getGlobalPropertySource(project, others, null);
232        }
233
234        /**
235         * 
236         */
237        @Deprecated
238        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, Mode missingLocationsMode) {
239                return getGlobalPropertySource(project, missingLocationsMode, Collections.<org.kuali.common.util.ProjectContext> emptyList());
240        }
241
242        /**
243         * 
244         */
245        @Deprecated
246        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, Mode missingLocationsMode, org.kuali.common.util.ProjectContext... others) {
247                return getGlobalPropertySource(project, missingLocationsMode, Arrays.asList(others));
248        }
249
250        /**
251         * 
252         */
253        @Deprecated
254        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, Mode missingLocationsMode,
255                        List<org.kuali.common.util.ProjectContext> others) {
256                org.kuali.common.util.property.ProjectProperties pp = ConfigUtils.getProjectProperties(project);
257                pp.getPropertiesContext().setMissingLocationsMode(missingLocationsMode);
258                return getGlobalPropertySource(pp, others, null);
259        }
260
261        @Deprecated
262        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.property.ProjectProperties projectProperties, List<org.kuali.common.util.ProjectContext> others,
263                        Properties properties) {
264                ConfigUtils.combine(projectProperties, properties);
265                List<org.kuali.common.util.property.ProjectProperties> otherProjectProperties = ConfigUtils.getProjectProperties(others);
266                // Get a PropertySource object backed by the properties loaded from the list as well as system/environment properties
267                return getGlobalPropertySource(projectProperties, otherProjectProperties);
268        }
269
270        /**
271         * <code>project</code> needs to be a top level project eg rice-sampleapp, olefs-webapp. <code>others</code> is projects for submodules organized into a list where the last one
272         * in wins.
273         */
274        @Deprecated
275        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext project, List<org.kuali.common.util.ProjectContext> others, Properties properties) {
276
277                org.kuali.common.util.property.ProjectProperties projectProperties = ConfigUtils.getProjectProperties(project, properties);
278
279                List<org.kuali.common.util.property.ProjectProperties> otherProjectProperties = ConfigUtils.getProjectProperties(others);
280
281                // Get a PropertySource object backed by the properties loaded from the list as well as system/environment properties
282                return getGlobalPropertySource(projectProperties, otherProjectProperties);
283        }
284
285        /**
286         * <code>project</code> needs to be a top level project eg rice-sampleapp, olefs-webapp. <code>others</code> is projects for submodules organized into a list where the last one
287         * in wins.
288         */
289        @Deprecated
290        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.property.ProjectProperties project) {
291                return getGlobalPropertySource(project, null);
292        }
293
294        /**
295         * <code>project</code> needs to be a top level project eg rice-sampleapp, olefs-webapp. <code>others</code> is projects for submodules organized into a list where the last one
296         * in wins.
297         */
298        @Deprecated
299        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.property.ProjectProperties project, List<org.kuali.common.util.property.ProjectProperties> others) {
300                // Property loading uses a "last one in wins" strategy
301                List<org.kuali.common.util.property.ProjectProperties> list = new ArrayList<org.kuali.common.util.property.ProjectProperties>();
302
303                // Add project properties first so they can be used to resolve locations
304                list.add(project);
305
306                if (!CollectionUtils.isEmpty(others)) {
307                        // Load in other project properties
308                        list.addAll(others);
309
310                        // Add project properties last so they override loaded properties
311                        list.add(project);
312                }
313
314                // Get a PropertySource object backed by the properties loaded from the list as well as system/environment properties
315                return getGlobalPropertySource(GLOBAL_SPRING_PROPERTY_SOURCE_NAME, list);
316        }
317
318        public static List<String> getIncludes(Environment env, String key, String defaultValue) {
319                String includes = SpringUtils.getProperty(env, key, defaultValue);
320                if (NullUtils.isNull(includes) || StringUtils.equals(includes, Constants.WILDCARD)) {
321                        return new ArrayList<String>();
322                } else {
323                        return CollectionUtils.getTrimmedListFromCSV(includes);
324                }
325        }
326
327        public static List<String> getIncludes(Environment env, String key) {
328                return getIncludes(env, key, null);
329        }
330
331        public static List<String> getExcludes(Environment env, String key, String defaultValue) {
332                String excludes = SpringUtils.getProperty(env, key, defaultValue);
333                if (NullUtils.isNullOrNone(excludes)) {
334                        return new ArrayList<String>();
335                } else {
336                        return CollectionUtils.getTrimmedListFromCSV(excludes);
337                }
338        }
339
340        public static List<String> getExcludes(Environment env, String key) {
341                return getExcludes(env, key, null);
342        }
343
344        /**
345         * Given a property holding the name of a class, return an instance of that class
346         */
347        public static <T> T getInstance(Environment env, String key, Class<T> defaultValue) {
348                String className = getProperty(env, key, defaultValue.getCanonicalName());
349                return ReflectionUtils.newInstance(className);
350        }
351
352        /**
353         * Given a property holding the name of a class, return an instance of that class
354         */
355        public static <T> T getInstance(Environment env, String key) {
356                String className = getProperty(env, key, null);
357                return ReflectionUtils.newInstance(className);
358        }
359
360        public static List<String> getListFromCSV(Environment env, String key, String defaultValue) {
361                String csv = SpringUtils.getProperty(env, key, defaultValue);
362                return CollectionUtils.getTrimmedListFromCSV(csv);
363        }
364
365        public static List<String> getListFromCSV(Environment env, String key) {
366                String csv = SpringUtils.getProperty(env, key);
367                return CollectionUtils.getTrimmedListFromCSV(csv);
368        }
369
370        /**
371         * If the CSV value evaluates to <code>null</code>, <code>"null"</code>, <code>"none"</code> or the empty string, return an empty list.
372         */
373        public static List<String> getNoneSensitiveListFromCSV(Environment env, String key) {
374                String csv = SpringUtils.getProperty(env, key);
375                return CollectionUtils.getNoneSensitiveListFromCSV(csv);
376        }
377
378        /**
379         * If the CSV value evaluates to <code>null</code>, <code>"null"</code>, <code>"none"</code> or the empty string, return an empty list.
380         */
381        public static List<String> getNoneSensitiveListFromCSV(EnvironmentService env, String key, String defaultValue) {
382                String csv = env.getString(key, defaultValue);
383                return CollectionUtils.getNoneSensitiveListFromCSV(csv);
384        }
385
386        /**
387         * If the CSV value evaluates to <code>null</code>, <code>"null"</code>, <code>"none"</code> or the empty string, return an empty list.
388         */
389        public static List<String> getNoneSensitiveListFromCSV(EnvironmentService env, String key) {
390                return getNoneSensitiveListFromCSV(env, key, null);
391        }
392
393        /**
394         * If the environment contains a value for <code>key</code> (NONE sensitive) use the environment value, otherwise use the defaults.
395         */
396        public static List<String> getStrings(EnvironmentService env, String key, List<String> defaults) {
397                if (env.containsProperty(key)) {
398                        return getNoneSensitiveListFromCSV(env, key);
399                } else {
400                        return defaults;
401                }
402        }
403
404        /**
405         * If the environment contains a value for any of the elements in <code>keys</code> (NONE sensitive) use the environment value, otherwise return <code>Optional.absent()</code>
406         */
407        public static Optional<List<String>> getOptionalStrings(EnvironmentService env, List<String> keys) {
408                for (String key : keys) {
409                        if (env.containsProperty(key)) {
410                                return Optional.of(getNoneSensitiveListFromCSV(env, key));
411                        }
412                }
413                return Optional.absent();
414        }
415
416        /**
417         * If the CSV value evaluates to <code>null</code>, <code>"null"</code>, <code>"none"</code> or the empty string, return an empty list.
418         */
419        public static List<String> getNoneSensitiveListFromCSV(Environment env, String key, String defaultValue) {
420                String csv = SpringUtils.getProperty(env, key, defaultValue);
421                return CollectionUtils.getNoneSensitiveListFromCSV(csv);
422        }
423
424        @Deprecated
425        public static List<PropertySource<?>> getPropertySources(org.kuali.common.util.service.SpringService service, Class<?> annotatedClass, String propertiesBeanName,
426                        Properties properties) {
427                return getPropertySources(annotatedClass, propertiesBeanName, properties);
428        }
429
430        /**
431         * Scan the annotated class to find the single bean registered in the context that implements <code>PropertySource</code>. If more than one bean is located, throw
432         * <code>IllegalStateException</code>.
433         */
434        @Deprecated
435        public static PropertySource<?> getSinglePropertySource(Class<?> annotatedClass) {
436                return getSinglePropertySource(annotatedClass, null, null);
437        }
438
439        /**
440         * Scan the annotated class to find the single bean registered in the context that implements <code>PropertySource</code>. If more than one bean is located, throw
441         * <code>IllegalStateException</code>.
442         */
443        @Deprecated
444        public static PropertySource<?> getSinglePropertySource(Class<?> annotatedClass, String propertiesBeanName, Properties properties) {
445                List<PropertySource<?>> sources = getPropertySources(annotatedClass, propertiesBeanName, properties);
446                Assert.isTrue(sources.size() == 1, "Must be exactly one PropertySource registered in the context");
447                return sources.get(0);
448        }
449
450        @Deprecated
451        public static List<PropertySource<?>> getPropertySources(Class<?> annotatedClass, String propertiesBeanName, Properties properties) {
452                return getPropertySources(annotatedClass, propertiesBeanName, properties, null, null);
453        }
454
455        public static void setupProfiles(ConfigurableApplicationContext ctx, List<String> activeProfiles, List<String> defaultProfiles) {
456                if (!CollectionUtils.isEmpty(activeProfiles)) {
457                        ConfigurableEnvironment env = ctx.getEnvironment();
458                        env.setActiveProfiles(CollectionUtils.toStringArray(activeProfiles));
459                }
460                if (!CollectionUtils.isEmpty(defaultProfiles)) {
461                        ConfigurableEnvironment env = ctx.getEnvironment();
462                        env.setDefaultProfiles(CollectionUtils.toStringArray(defaultProfiles));
463                }
464        }
465
466        @Deprecated
467        public static List<PropertySource<?>> getPropertySources(Class<?> annotatedClass, String propertiesBeanName, Properties properties, List<String> activeProfiles,
468                        List<String> defaultProfiles) {
469                ConfigurableApplicationContext parent = null;
470                if (properties == null) {
471                        parent = getConfigurableApplicationContext();
472                } else {
473                        parent = getContextWithPreRegisteredBean(propertiesBeanName, properties);
474                }
475                AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
476                child.setParent(parent);
477                setupProfiles(child, activeProfiles, defaultProfiles);
478                child.register(annotatedClass);
479                child.refresh();
480                return getPropertySources(child);
481        }
482
483        @Deprecated
484        public static List<PropertySource<?>> getPropertySources(org.kuali.common.util.service.SpringService service, String location, String mavenPropertiesBeanName,
485                        Properties mavenProperties) {
486                return getPropertySources(location, mavenPropertiesBeanName, mavenProperties);
487        }
488
489        @Deprecated
490        public static List<PropertySource<?>> getPropertySources(String location, String propertiesBeanName, Properties properties) {
491                return getPropertySources(location, propertiesBeanName, properties, null, null);
492        }
493
494        @Deprecated
495        public static List<PropertySource<?>> getPropertySources(String location, String propertiesBeanName, Properties properties, List<String> activeProfiles,
496                        List<String> defaultProfiles) {
497                String[] locationsArray = { location };
498                ConfigurableApplicationContext parent = getContextWithPreRegisteredBean(propertiesBeanName, properties);
499                ConfigurableApplicationContext child = new ClassPathXmlApplicationContext(locationsArray, false, parent);
500                setupProfiles(child, activeProfiles, defaultProfiles);
501                child.refresh();
502                return getPropertySources(child);
503        }
504
505        @Deprecated
506        public static Executable getSpringExecutable(Environment env, boolean skip, PropertySource<?> ps, List<Class<?>> annotatedClasses) {
507                /**
508                 * This line creates a property source containing 100% of the properties needed by Spring to resolve any/all placeholders. It will be the only property source available to
509                 * Spring so it needs to include system properties and environment variables
510                 */
511                org.kuali.common.util.service.PropertySourceContext psc = new org.kuali.common.util.service.PropertySourceContext(ps, true);
512
513                // Setup the Spring context
514                org.kuali.common.util.service.SpringContext context = new org.kuali.common.util.service.SpringContext();
515                context.setAnnotatedClasses(annotatedClasses);
516                context.setPropertySourceContext(psc);
517
518                // Load the context
519                org.kuali.common.util.execute.SpringExecutable se = new org.kuali.common.util.execute.SpringExecutable();
520                se.setService(new org.kuali.common.util.service.DefaultSpringService());
521                se.setContext(context);
522                se.setSkip(skip);
523                return se;
524        }
525
526        public static int getInteger(Environment env, String key) {
527                String value = getProperty(env, key);
528                return Integer.parseInt(value);
529        }
530
531        public static int getInteger(Environment env, String key, int defaultValue) {
532                String value = getProperty(env, key, Integer.toString(defaultValue));
533                return Integer.parseInt(value);
534        }
535
536        public static long getLong(Environment env, String key) {
537                String value = getProperty(env, key);
538                return Long.parseLong(value);
539        }
540
541        public static long getLong(Environment env, String key, long defaultValue) {
542                String value = getProperty(env, key, Long.toString(defaultValue));
543                return Long.parseLong(value);
544        }
545
546        public static double getDouble(Environment env, String key) {
547                String value = getProperty(env, key);
548                return Double.parseDouble(value);
549        }
550
551        public static double getDouble(Environment env, String key, double defaultValue) {
552                String value = getProperty(env, key, Double.toString(defaultValue));
553                return Double.parseDouble(value);
554        }
555
556        /**
557         * Parse milliseconds from a time string that ends with a unit of measure. If no unit of measure is provided, milliseconds is assumed. Unit of measure is case insensitive.
558         * 
559         * @see FormatUtils.getMillis(String time)
560         */
561        public static long getMillis(EnvironmentService env, String key, String defaultValue) {
562                String value = env.getString(key, defaultValue);
563                return FormatUtils.getMillis(value);
564        }
565
566        /**
567         * Parse milliseconds from a time string that ends with a unit of measure. If no unit of measure is provided, milliseconds is assumed. Unit of measure is case insensitive.
568         * 
569         * @see FormatUtils.getMillis(String time)
570         */
571        public static Optional<Integer> getMillisAsInt(EnvironmentService env, String key, Optional<Integer> provided) {
572                if (env.containsProperty(key)) {
573                        String defaultValue = FormatUtils.getTime(provided.get());
574                        Long millis = getMillis(env, key, defaultValue);
575                        return Optional.of(millis.intValue());
576                } else {
577                        return provided;
578                }
579        }
580
581        /**
582         * Parse milliseconds from a time string that ends with a unit of measure. If no unit of measure is provided, milliseconds is assumed. Unit of measure is case insensitive.
583         * 
584         * @see FormatUtils.getMillis(String time)
585         */
586        public static int getMillisAsInt(EnvironmentService env, String key, String defaultValue) {
587                return new Long(getMillis(env, key, defaultValue)).intValue();
588        }
589
590        /**
591         * Parse milliseconds from a time string that ends with a unit of measure. If no unit of measure is provided, milliseconds is assumed. Unit of measure is case insensitive.
592         * 
593         * @see FormatUtils.getMillis(String time)
594         */
595        public static int getMillisAsInt(EnvironmentService env, String key, int defaultValue) {
596                return getMillisAsInt(env, key, FormatUtils.getTime(defaultValue));
597        }
598
599        /**
600         * Parse milliseconds from a time string that ends with a unit of measure. If no unit of measure is provided, milliseconds is assumed. Unit of measure is case insensitive.
601         * 
602         * @see FormatUtils.getMillis(String time)
603         */
604        public static long getMillis(Environment env, String key, String defaultValue) {
605                String value = getProperty(env, key, defaultValue);
606                return FormatUtils.getMillis(value);
607        }
608
609        /**
610         * Parse bytes from a size string that ends with a unit of measure. If no unit of measure is provided, bytes is assumed. Unit of measure is case insensitive.
611         * 
612         * @see FormatUtils.getBytes(String size)
613         */
614        public static int getBytesInteger(Environment env, String key, String defaultValue) {
615                Long value = getBytes(env, key, defaultValue);
616                return getValidatedIntValue(value);
617        }
618
619        /**
620         * Parse bytes from a size string that ends with a unit of measure. If no unit of measure is provided, bytes is assumed. Unit of measure is case insensitive.
621         * 
622         * @see FormatUtils.getBytes(String size)
623         */
624        public static int getBytesInteger(Environment env, String key) {
625                Long value = getBytes(env, key);
626                return getValidatedIntValue(value);
627        }
628
629        /**
630         * Throw IllegalArgumentException if value is outside the range of an Integer, otherwise return the Integer value.
631         */
632        public static int getValidatedIntValue(Long value) {
633                if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
634                        throw new IllegalArgumentException(value + " is outside the range of an integer");
635                } else {
636                        return value.intValue();
637                }
638        }
639
640        /**
641         * Parse bytes from a size string that ends with a unit of measure. If no unit of measure is provided, bytes is assumed. Unit of measure is case insensitive.
642         * 
643         * @see FormatUtils.getBytes(String size)
644         */
645        public static long getBytes(Environment env, String key, String defaultValue) {
646                String value = getProperty(env, key, defaultValue);
647                return FormatUtils.getBytes(value);
648        }
649
650        /**
651         * Parse bytes from a size string that ends with a unit of measure. If no unit of measure is provided, bytes is assumed. Unit of measure is case insensitive.
652         * 
653         * @see FormatUtils.getBytes(String size)
654         */
655        public static long getBytes(Environment env, String key) {
656                String value = getProperty(env, key);
657                return FormatUtils.getBytes(value);
658        }
659
660        public static File getFile(Environment env, String key) {
661                String value = getProperty(env, key);
662                return new File(value);
663        }
664
665        public static List<File> getFilesFromCSV(Environment env, String key, String defaultValue) {
666                List<String> strings = getNoneSensitiveListFromCSV(env, key, defaultValue);
667                List<File> files = new ArrayList<File>();
668                for (String string : strings) {
669                        File file = new File(string);
670                        files.add(file);
671                }
672                return files;
673        }
674
675        public static List<File> getFilesFromCSV(Environment env, String key) {
676                return getFilesFromCSV(env, key, null);
677        }
678
679        public static File getFile(Environment env, String key, File defaultValue) {
680                String value = getProperty(env, key, LocationUtils.getCanonicalPath(defaultValue));
681                return new File(value);
682        }
683
684        public static boolean getBoolean(Environment env, String key, boolean defaultValue) {
685                String value = getProperty(env, key, Boolean.toString(defaultValue));
686                return Boolean.parseBoolean(value);
687        }
688
689        public static boolean getBoolean(Environment env, String key) {
690                String value = getProperty(env, key);
691                return Boolean.parseBoolean(value);
692        }
693
694        @Deprecated
695        public static PropertySource<?> getGlobalPropertySource(String name, List<org.kuali.common.util.property.ProjectProperties> pps) {
696                // Load them from disk
697                Properties source = PropertyUtils.load(pps);
698
699                // Add in system/environment properties
700                Properties globalSource = PropertyUtils.getGlobalProperties(source);
701
702                logger.debug("Before prepareContextProperties()");
703                PropertyUtils.debug(globalSource);
704
705                // Prepare them so they are ready for use
706                PropertyUtils.prepareContextProperties(globalSource);
707
708                logger.debug("After prepareContextProperties()");
709                PropertyUtils.debug(globalSource);
710
711                // Return a PropertySource backed by the properties
712                return new PropertiesPropertySource(name, globalSource);
713        }
714
715        @Deprecated
716        public static PropertySource<?> getGlobalPropertySource(Properties properties) {
717                return new PropertiesPropertySource(GLOBAL_SPRING_PROPERTY_SOURCE_NAME, properties);
718        }
719
720        /**
721         * Return a SpringContext that resolves all placeholders from the PropertySource passed in
722         */
723        @Deprecated
724        public static PropertySource<?> getGlobalPropertySource(List<String> locations, String encoding) {
725                Properties loaded = PropertyUtils.load(locations, encoding);
726                Properties global = PropertyUtils.getGlobalProperties(loaded);
727                PropertyUtils.prepareContextProperties(global);
728                return getGlobalPropertySource(global);
729        }
730
731        /**
732         * Return a SpringContext that resolves all placeholders from the list of property locations passed in + System/Environment properties
733         */
734        @Deprecated
735        public static org.kuali.common.util.service.SpringContext getSinglePropertySourceContext(org.kuali.common.util.ProjectContext context, String location) {
736                PropertySource<?> source = getGlobalPropertySource(context, location);
737                return getSinglePropertySourceContext(source);
738        }
739
740        /**
741         * Return a SpringExecutable for the project, properties location, and config passed in.
742         */
743        @Deprecated
744        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(org.kuali.common.util.ProjectContext project, String location, List<Class<?>> annotatedClasses) {
745                org.kuali.common.util.service.SpringContext context = getSinglePropertySourceContext(project, location);
746                context.setAnnotatedClasses(annotatedClasses);
747
748                org.kuali.common.util.execute.SpringExecutable executable = new org.kuali.common.util.execute.SpringExecutable();
749                executable.setContext(context);
750                return executable;
751        }
752
753        /**
754         * Return a SpringExecutable for the org.kuali.common.util.config.supplier.PropertiesSupplier and annotatedClass passed in
755         */
756        @Deprecated
757        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(org.kuali.common.util.config.supplier.PropertiesSupplier supplier, Class<?> annotatedClass) {
758                return getSpringExecutable(supplier, CollectionUtils.asList(annotatedClass));
759        }
760
761        /**
762         * Return a SpringExecutable for the org.kuali.common.util.config.supplier.PropertiesSupplier and annotatedClasses passed in
763         */
764        @Deprecated
765        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(org.kuali.common.util.config.supplier.PropertiesSupplier supplier,
766                        List<Class<?>> annotatedClasses) {
767                Properties properties = supplier.getProperties();
768                PropertySource<?> source = getGlobalPropertySource(properties);
769                org.kuali.common.util.service.SpringContext context = getSinglePropertySourceContext(source);
770                context.setAnnotatedClasses(annotatedClasses);
771                return new org.kuali.common.util.execute.SpringExecutable(context);
772        }
773
774        /**
775         * Return a SpringExecutable for the PropertySource and annotatedClass passed in
776         */
777        @Deprecated
778        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(PropertySource<?> source, Class<?> annotatedClass) {
779                org.kuali.common.util.service.SpringContext context = getSinglePropertySourceContext(source);
780                context.setAnnotatedClasses(CollectionUtils.asList(annotatedClass));
781                return new org.kuali.common.util.execute.SpringExecutable(context);
782        }
783
784        /**
785         * Return a SpringExecutable for the project, properties location, and config passed in.
786         */
787        @Deprecated
788        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(org.kuali.common.util.ProjectContext project, String location, Class<?> annotatedClass) {
789                return getSpringExecutable(project, location, CollectionUtils.asList(annotatedClass));
790        }
791
792        /**
793         * Return a SpringExecutable for the project, properties location, and config passed in.
794         */
795        @Deprecated
796        public static org.kuali.common.util.execute.SpringExecutable getSpringExecutable(Class<?> annotatedClass, String location, org.kuali.common.util.ProjectContext... projects) {
797                List<org.kuali.common.util.property.ProjectProperties> list = ConfigUtils.getProjectProperties(projects);
798                org.kuali.common.util.property.ProjectProperties last = list.get(list.size() - 1);
799                PropertiesContext pc = last.getPropertiesContext();
800                if (!StringUtils.isBlank(location)) {
801                        List<String> locations = new ArrayList<String>(CollectionUtils.toEmptyList(pc.getLocations()));
802                        locations.add(location);
803                        pc.setLocations(locations);
804                }
805                PropertySource<?> source = getGlobalPropertySource(GLOBAL_SPRING_PROPERTY_SOURCE_NAME, list);
806                org.kuali.common.util.service.SpringContext context = getSinglePropertySourceContext(source);
807                context.setAnnotatedClasses(CollectionUtils.asList(annotatedClass));
808                return new org.kuali.common.util.execute.SpringExecutable(context);
809        }
810
811        /**
812         * Return a SpringContext that resolves all placeholders from the list of property locations passed in + System/Environment properties
813         */
814        @Deprecated
815        public static org.kuali.common.util.service.SpringContext getSinglePropertySourceContext(List<String> locations, String encoding) {
816                PropertySource<?> source = getGlobalPropertySource(locations, encoding);
817                return getSinglePropertySourceContext(source);
818        }
819
820        /**
821         * Return a SpringContext that resolves all placeholders from the PropertySource passed in
822         */
823        @Deprecated
824        public static org.kuali.common.util.service.SpringContext getSinglePropertySourceContext(PropertySource<?> source) {
825                // Setup a property source context such that our single property source is the only one registered with Spring
826                // This will make it so our PropertySource is the ONLY thing used to resolve placeholders
827                org.kuali.common.util.service.PropertySourceContext psc = new org.kuali.common.util.service.PropertySourceContext(source, true);
828
829                // Setup a Spring context
830                org.kuali.common.util.service.SpringContext context = new org.kuali.common.util.service.SpringContext();
831
832                // Supply Spring with our PropertySource
833                context.setPropertySourceContext(psc);
834
835                // Return a Spring context configured with a single property source
836                return context;
837        }
838
839        @Deprecated
840        public static PropertySource<?> getGlobalPropertySource(org.kuali.common.util.ProjectContext context, String... locations) {
841                org.kuali.common.util.property.ProjectProperties pp = org.kuali.common.util.ProjectUtils.getProjectProperties(context);
842                PropertiesContext pc = pp.getPropertiesContext();
843                List<String> existingLocations = CollectionUtils.toEmptyList(pc.getLocations());
844                if (locations != null) {
845                        for (String location : locations) {
846                                existingLocations.add(location);
847                        }
848                }
849                pc.setLocations(existingLocations);
850                return getGlobalPropertySource(pp);
851        }
852
853        @Deprecated
854        public static PropertySource<?> getPropertySource(String name, List<org.kuali.common.util.property.ProjectProperties> pps) {
855                // Load them from disk
856                Properties source = PropertyUtils.load(pps);
857
858                // Prepare them so they are ready for use
859                PropertyUtils.prepareContextProperties(source);
860
861                // Return a PropertySource backed by the properties
862                return new PropertiesPropertySource(name, source);
863        }
864
865        /**
866         * Converts a GAV into Spring's classpath style notation for the default project properties context.
867         * 
868         * <pre>
869         *  org.kuali.common:kuali-jdbc -> classpath:org/kuali/common/kuali-jdbc/properties-context.xml
870         * </pre>
871         */
872        @Deprecated
873        public static String getDefaultPropertyContextLocation(String gav) {
874                Assert.hasText(gav, "gav has no text");
875                org.kuali.common.util.Project p = org.kuali.common.util.ProjectUtils.getProject(gav);
876                return org.kuali.common.util.ProjectUtils.getClassPathPrefix(p) + "/properties-context.xml";
877        }
878
879        /**
880         * Make sure all of the locations actually exist.<br>
881         */
882        @Deprecated
883        public static void validateExists(List<String> locations) {
884                LocationUtils.validateExists(locations);
885        }
886
887        public static AbstractApplicationContext getContextWithPreRegisteredBeans(String id, String displayName, Map<String, ?> beans) {
888                GenericXmlApplicationContext appContext = new GenericXmlApplicationContext();
889                if (!isBlank(id)) {
890                        appContext.setId(id);
891                }
892                if (!isBlank(displayName)) {
893                        appContext.setDisplayName(displayName);
894                }
895                appContext.refresh();
896                ConfigurableListableBeanFactory factory = appContext.getBeanFactory();
897                for (String beanName : beans.keySet()) {
898                        Object bean = beans.get(beanName);
899                        logger.debug("Registering bean - [{}] -> [{}]", beanName, bean.getClass().getName());
900                        factory.registerSingleton(beanName, bean);
901                }
902                return appContext;
903        }
904
905        @Deprecated
906        public static ConfigurableApplicationContext getContextWithPreRegisteredBeans(String id, String displayName, List<String> beanNames, List<Object> beans) {
907                Map<String, Object> contextBeans = new HashMap<String, Object>();
908                CollectionUtils.combine(contextBeans, beanNames, beans);
909                return getContextWithPreRegisteredBeans(id, displayName, contextBeans);
910        }
911
912        @Deprecated
913        public static ConfigurableApplicationContext getContextWithPreRegisteredBeans(List<String> beanNames, List<Object> beans) {
914                return getContextWithPreRegisteredBeans(null, null, beanNames, beans);
915        }
916
917        @Deprecated
918        public static ConfigurableApplicationContext getConfigurableApplicationContext() {
919                return new GenericXmlApplicationContext();
920        }
921
922        /**
923         * Null safe refresh for a context
924         */
925        public static void refreshQuietly(ConfigurableApplicationContext context) {
926                if (context != null) {
927                        context.refresh();
928                }
929        }
930
931        /**
932         * Null safe close for a context
933         */
934        public static void closeQuietly(ConfigurableApplicationContext context) {
935                if (context != null) {
936                        context.close();
937                }
938        }
939
940        @Deprecated
941        public static ConfigurableApplicationContext getContextWithPreRegisteredBean(String beanName, Object bean) {
942                return getContextWithPreRegisteredBeans(Arrays.asList(beanName), Arrays.asList(bean));
943        }
944
945        @Deprecated
946        public static List<PropertySource<?>> getPropertySourcesFromAnnotatedClass(String annotatedClassName) {
947                Class<?> annotatedClass = ReflectionUtils.getClass(annotatedClassName);
948                return getPropertySources(annotatedClass);
949        }
950
951        @Deprecated
952        public static List<PropertySource<?>> getPropertySources(Class<?> annotatedClass) {
953                return PropertySourceUtils.getPropertySources(annotatedClass);
954        }
955
956        @Deprecated
957        public static List<PropertySource<?>> extractPropertySourcesAndClose(ConfigurableApplicationContext context) {
958                return PropertySourceUtils.extractPropertySourcesAndClose(context);
959        }
960
961        /**
962         * Scan the XML Spring context for any beans that implement <code>PropertySource</code>
963         */
964        @Deprecated
965        public static List<PropertySource<?>> getPropertySources(String location) {
966                ConfigurableApplicationContext context = new GenericXmlApplicationContext(location);
967                return extractPropertySourcesAndClose(context);
968        }
969
970        /**
971         * This method returns a list of any PropertySource objects registered in the indicated context. They are sorted by property source name.
972         */
973        @Deprecated
974        public static List<PropertySource<?>> getPropertySources(ConfigurableApplicationContext context) {
975                return PropertySourceUtils.getPropertySources(context);
976        }
977
978        public static <T> Map<String, T> getAllBeans(List<String> locations, Class<T> type) {
979                String[] locationsArray = locations.toArray(new String[locations.size()]);
980                ConfigurableApplicationContext ctx = new GenericXmlApplicationContext(locationsArray);
981                Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
982                ctx.close();
983                return map;
984        }
985
986        public static <T> Map<String, T> getAllBeans(String location, Class<T> type) {
987                ConfigurableApplicationContext ctx = new GenericXmlApplicationContext(location);
988                Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
989                ctx.close();
990                return map;
991        }
992
993        public static <T> Map<String, T> getAllBeans(ConfigurableApplicationContext ctx, Class<T> type) {
994                return BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
995        }
996
997        /**
998         * This method returns a list of any PropertySource objects registered in the indicated context. The comparator is responsible for putting them in correct order.
999         */
1000        @Deprecated
1001        public static List<PropertySource<?>> getPropertySources(ConfigurableApplicationContext context, Comparator<PropertySource<?>> comparator) {
1002                return PropertySourceUtils.getPropertySources(context, comparator);
1003        }
1004
1005        /**
1006         * Null safe method for converting an untyped array of property sources into a list. Never returns null.
1007         */
1008        @Deprecated
1009        public static List<PropertySource<?>> asList(PropertySource<?>... sources) {
1010                return PropertySourceUtils.asList(sources);
1011        }
1012
1013        public static void debugQuietly(ApplicationContext ctx) {
1014                if (!logger.isDebugEnabled() || ctx == null) {
1015                        return;
1016                }
1017                if (ctx.getParent() != null) {
1018                        debug(ctx.getParent());
1019                }
1020                debug(ctx);
1021        }
1022
1023        public static void debug(ApplicationContext ctx) {
1024                logger.debug("------------------------ Spring Context ------------------------------");
1025                logger.debug("Id: [{}]", ctx.getId());
1026                logger.debug("Display Name: [{}]", ctx.getDisplayName());
1027                logger.debug("Application Name: [{}]", ctx.getApplicationName());
1028                logger.debug("----------------------------------------------------------------------");
1029                List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesIncludingAncestors(ctx));
1030                List<String> columns = Arrays.asList("Name", "Type", "Hashcode");
1031                List<Object[]> rows = new ArrayList<Object[]>();
1032                Collections.sort(names);
1033                for (String name : names) {
1034                        Object bean = ctx.getBean(name);
1035                        String instance = (bean == null) ? NullUtils.NULL : bean.getClass().getSimpleName();
1036                        String hashcode = (bean == null) ? NullUtils.NULL : Integer.toHexString(bean.hashCode());
1037                        Object[] row = { name, instance, hashcode };
1038                        rows.add(row);
1039                }
1040                LoggerUtils.logTable(columns, rows, LoggerLevel.DEBUG, logger, true);
1041                logger.debug("----------------------------------------------------------------------");
1042        }
1043
1044        @Deprecated
1045        public static void showPropertySources(List<PropertySource<?>> propertySources) {
1046                List<String> columns = Arrays.asList("Name", "Impl", "Source");
1047                List<Object[]> rows = new ArrayList<Object[]>();
1048                for (PropertySource<?> propertySource : propertySources) {
1049                        String name = propertySource.getName();
1050                        String impl = propertySource.getClass().getName();
1051                        String source = propertySource.getSource().getClass().getName();
1052                        Object[] row = { name, impl, source };
1053                        rows.add(row);
1054                }
1055                LoggerUtils.logTable(columns, rows, LoggerLevel.INFO, logger, true);
1056        }
1057
1058        @Deprecated
1059        public static void showPropertySources(ConfigurableEnvironment env) {
1060                showPropertySources(getPropertySources(env));
1061        }
1062
1063        /**
1064         * Get a fully resolved property value from the environment. If the property is not found or contains unresolvable placeholders an exception is thrown.
1065         */
1066        public static String getProperty(Environment env, String key) {
1067                String value = env.getRequiredProperty(key);
1068                return env.resolveRequiredPlaceholders(value);
1069        }
1070
1071        /**
1072         * Return true if the environment value for key is not null.
1073         */
1074        public static boolean exists(Environment env, String key) {
1075                return env.getProperty(key) != null;
1076        }
1077
1078        /**
1079         * Always return a fully resolved value. Use <code>defaultValue</code> if a value cannot be located in the environment. Throw an exception if the return value contains
1080         * unresolvable placeholders.
1081         */
1082        public static String getProperty(Environment env, String key, String defaultValue) {
1083                if (defaultValue == null) {
1084                        // No default value supplied, we must be able to locate this property in the environment
1085                        return getProperty(env, key);
1086                } else {
1087                        // Look up a value from the environment
1088                        String value = env.getProperty(key);
1089                        if (value == null) {
1090                                // Resolve the default value against the environment
1091                                return env.resolveRequiredPlaceholders(defaultValue);
1092                        } else {
1093                                // Resolve the located value against the environment
1094                                return env.resolveRequiredPlaceholders(value);
1095                        }
1096                }
1097        }
1098
1099        /**
1100         * Examine <code>ConfigurableEnvironment</code> for <code>PropertySource</code>'s that extend <code>EnumerablePropertySource</code> and aggregate them into a single
1101         * <code>Properties</code> object
1102         */
1103        @Deprecated
1104        public static Properties getAllEnumerableProperties(ConfigurableEnvironment env) {
1105
1106                // Extract the list of PropertySources from the environment
1107                List<PropertySource<?>> sources = getPropertySources(env);
1108
1109                // Spring provides PropertySource objects ordered from highest priority to lowest priority
1110                // We reverse the order here so things follow the typical "last one in wins" strategy
1111                Collections.reverse(sources);
1112
1113                // Convert the list of PropertySource's to a list of Properties objects
1114                PropertySourceConversionResult result = convertEnumerablePropertySources(sources);
1115
1116                // Combine them into a single Properties object
1117                return PropertyUtils.combine(result.getPropertiesList());
1118        }
1119
1120        /**
1121         * Remove any existing property sources and add one property source backed by the properties passed in
1122         */
1123        @Deprecated
1124        public static void reconfigurePropertySources(ConfigurableEnvironment env, String name, Properties properties) {
1125                PropertySourceUtils.reconfigurePropertySources(env, name, properties);
1126        }
1127
1128        /**
1129         * Remove any existing property sources
1130         */
1131        @Deprecated
1132        public static void removeAllPropertySources(ConfigurableEnvironment env) {
1133                PropertySourceUtils.removeAllPropertySources(env);
1134        }
1135
1136        /**
1137         * Get all PropertySource objects from the environment as a List.
1138         */
1139        @Deprecated
1140        public static List<PropertySource<?>> getPropertySources(ConfigurableEnvironment env) {
1141                return PropertySourceUtils.getPropertySources(env);
1142        }
1143
1144        /**
1145         * Convert any PropertySources that extend EnumerablePropertySource into Properties object's
1146         */
1147        @Deprecated
1148        public static PropertySourceConversionResult convertEnumerablePropertySources(List<PropertySource<?>> sources) {
1149                PropertySourceConversionResult result = new PropertySourceConversionResult();
1150                List<Properties> list = new ArrayList<Properties>();
1151                List<PropertySource<?>> converted = new ArrayList<PropertySource<?>>();
1152                List<PropertySource<?>> skipped = new ArrayList<PropertySource<?>>();
1153                // Extract property values from the sources and place them in a Properties object
1154                for (PropertySource<?> source : sources) {
1155                        Assert.isTrue(source instanceof EnumerablePropertySource, "[" + source + "] is not enumerable");
1156                        EnumerablePropertySource<?> eps = (EnumerablePropertySource<?>) source;
1157                        Properties sourceProperties = convert(eps);
1158                        list.add(sourceProperties);
1159                        converted.add(source);
1160                }
1161                result.setConverted(converted);
1162                result.setSkipped(skipped);
1163                result.setPropertiesList(list);
1164                return result;
1165        }
1166
1167        /**
1168         * Convert an EnumerablePropertySource into a Properties object.
1169         */
1170        @Deprecated
1171        public static Properties convert(EnumerablePropertySource<?> source) {
1172                Properties properties = new Properties();
1173                String[] names = source.getPropertyNames();
1174                for (String name : names) {
1175                        Object object = source.getProperty(name);
1176                        if (object != null) {
1177                                String value = object.toString();
1178                                properties.setProperty(name, value);
1179                        } else {
1180                                logger.warn("Property [{}] is null", name);
1181                        }
1182                }
1183                return properties;
1184        }
1185
1186        /**
1187         * Return true if, and only if, <code>property</code> is set in the environment and evaluates to true.
1188         */
1189        public static boolean isTrue(Environment env, String property) {
1190                String value = env.getProperty(property);
1191                if (StringUtils.isBlank(value)) {
1192                        return false;
1193                } else {
1194                        return new Boolean(value);
1195                }
1196        }
1197
1198}