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