    001    /*****************************************************************************
    002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
    003     * ------------------------------------------------------------------------- *
    004     * The software in this package is published under the terms of the BSD      *
    005     * style license a copy of which has been included with this distribution in *
    006     * the LICENSE.txt file.                                                     *
    007     *                                                                           *
    008     * Original code by                                                          *
    009     *****************************************************************************/
    010    package org.picocontainer;
    011
    012    import java.util.Map;
    013    import java.util.Properties;
    014
    015    /**
    016     * Collection of immutable properties, holding behaviour characteristics.  See
    017     * <a href="http://www.picocontainer.org/behaviors.html">The PicoContainer Website</a> for details on the usage
    018     * of Characteristics.
    019     *
    020     * @author Paul Hammant
    021     * @see org.picocontainer.ComponentAdapter
    022     * @see org.picocontainer.Behavior
    023     */
    024    @SuppressWarnings("serial")
    025    public final class Characteristics {
    026
    027        private static final String _INJECTION = "injection";
    028        private static final String _NONE = "none";
    029        private static final String _CONSTRUCTOR = "constructor";
    030        private static final String _METHOD = "method";
    031        private static final String _SETTER = "setter";
    032        private static final String _CACHE = "cache";
    033        private static final String _SYNCHRONIZING = "synchronizing";
    034        private static final String _LOCKING = "locking";
    035        private static final String _HIDE_IMPL = "hide-impl";
    036        private static final String _PROPERTY_APPLYING = "property-applying";
    037        private static final String _AUTOMATIC = "automatic";
    038        private static final String _USE_NAMES = "use-parameter-names";
    039        private static final String _ENABLE_CIRCULAR = "enable-circular";
    040        private static final String _GUARD = "guard";
    041
    042        /**
    043         * Since properties use strings, we supply String constants for Boolean conditions.
    044         */
    045        public static final String FALSE = "false";
    046
    047        /**
    048         * Since properties use strings, we supply String constants for Boolean conditions.
    049         */
    050        public static final String TRUE = "true";
    051
    052        /**
    053         * Turns on constructor injection.
    054         * @see org.picocontainer.injectors.ConstructorInjection
    055         */
    056        public static final Properties CDI = immutable(_INJECTION, _CONSTRUCTOR);
    057
    058        /**
    059         * Turns on Setter Injection.
    060         * @see org.picocontainer.injectors.SetterInjection
    061         */
    062        public static final Properties SDI = immutable(_INJECTION, _SETTER);
    063
    064        /**
    065         * Turns on Method Injection.
    066         */
    067        public static final Properties METHOD_INJECTION = immutable(_INJECTION, _METHOD);
    068
    069        /**
    070         * Turns off Caching of component instances.  (Often referred to in other circles
    071         * as singleton).
    072         * @see org.picocontainer.behaviors.Caching
    073         */
    074        public static final Properties NO_CACHE = immutable(_CACHE, FALSE);
    075
    076        /**
    077         * Turns on Caching of component instances.  (Often referred to in other circles
    078         * as singleton)
    079         * @see org.picocontainer.behaviors.Caching
    080         */
    081        public static final Properties CACHE = immutable(_CACHE, TRUE);
    082
    083        /**
    084         * Turns on synchronized access to the component instance.  (Under JDK 1.5 conditions,
    085         * it will be better to use {@link #LOCK} instead.
    086         * @see org.picocontainer.behaviors.Synchronizing
    087         */
    088        public static final Properties SYNCHRONIZE = immutable(_SYNCHRONIZING, TRUE);
    089
    090
    091        /**
    092         * Turns off synchronized access to the component instance.
    093         * @see org.picocontainer.behaviors.Synchronizing
    094         */
    095        public static final Properties NO_SYNCHRONIZE = immutable(_SYNCHRONIZING, FALSE);
    096
    097        /**
    098         * Uses a java.util.concurrent.Lock to provide faster access than synchronized.
    099         * @see org.picocontainer.behaviors.Locking
    100         */
    101        public static final Properties LOCK = immutable(_LOCKING, TRUE);
    102
    103        /**
    104         * Turns off locking synchronization.
    105         * @see org.picocontainer.behaviors.Locking
    106         */
    107        public static final Properties NO_LOCK = immutable(_LOCKING, FALSE);
    108
    109        /**
    110         * Synonym for {@link #CACHE CACHE}.
    111         * @see org.picocontainer.behaviors.Caching
    112         */
    113        public static final Properties SINGLE = CACHE;
    114
    115        /**
    116         * Synonym for {@link #NO_CACHE NO_CACHE}.
    117         * @see org.picocontainer.behaviors.Caching
    118         */
    119        public static final Properties NO_SINGLE = NO_CACHE;
    120
    121        /**
    122         * Turns on implementation hiding.  You may use the JDK Proxy implementation included
    123         * in this version, <strong>or</strong> the ASM-based implementation hiding method
    124         * included in PicoContainer Gems.  However, you cannot use both in a single PicoContainer
    125         * instance.
    126         */
    127        public static final Properties HIDE_IMPL = immutable(_HIDE_IMPL, TRUE);
    128
    129        /**
    130         * Turns off implementation hiding.
    131         * @see #HIDE_IMPL for more information.
    132         */
    133        public static final Properties NO_HIDE_IMPL = immutable(_HIDE_IMPL, FALSE);
    134
    135        public static final Properties ENABLE_CIRCULAR = immutable(_ENABLE_CIRCULAR, TRUE);
    136
    137        public static final Properties NONE = immutable(_NONE, "");
    138
    139        /**
    140         * Turns on bean-setting property applications where certain simple properties are set
    141         * after the object is created based.
    142         */
    143        public static final Properties PROPERTY_APPLYING = immutable(_PROPERTY_APPLYING, TRUE);
    144
    145        /**
    146         * Turns off bean-setting property applications.
    147         * @see org.picocontainer.behaviors.PropertyApplying
    148         */
    149        public static final Properties NO_PROPERTY_APPLYING = immutable(_PROPERTY_APPLYING, FALSE);
    150
    151        public static final Properties AUTOMATIC = immutable(_AUTOMATIC, TRUE);
    152
    153        public static final Properties USE_NAMES = immutable(_USE_NAMES, TRUE);
    154
    155        public static final Properties GUARD = immutable(_GUARD, "guard");
    156
    157        public static final Properties GUARD(String with) {
    158            return immutable(_GUARD, with);
    159        };
    160
    161        /**
    162         * Transforms a single name value pair unto a <em>read only</em> {@linkplain java.util.Properties}
    163         * instance.
    164         * <p>Example Usage:</p>
    165         * <pre>
    166         *          Properties readOnly = immutable("oneKey","oneValue"};
    167         *          assert readOnly.getProperty("oneKey") != null);
    168         * </pre>
    169         * @param name the property key.
    170         * @param value the property value.
    171         * @return Read Only properties instance.
    172         */
    173        public static Properties immutable(String name, String value) {
    174            return new ImmutableProperties(name, value);
    175        }
    176
    177        /**
    178         * Read only property set.  Once constructed, all methods that modify state will
    179         * throw UnsupportedOperationException.
    180         * @author Paul Hammant.
    181         */
    182        public static class ImmutableProperties extends Properties {
    183
    184            private boolean sealed = false;
    185
    186            public ImmutableProperties(String name, String value) {
    187                super.setProperty(name, value);
    188                sealed = true;
    189            }
    190
    191            /**
    192             * Read Only Object:  will throw UnsupportedOperationException.
    193             */
    194            @Override
    195            public Object remove(Object o) {
    196                throw new UnsupportedOperationException("immutable properties are read only");
    197            }
    198
    199            /**
    200             * Read Only Object:  will throw UnsupportedOperationException.
    201             */
    202            @Override
    203            public synchronized Object setProperty(String string, String string1) {
    204                throw new UnsupportedOperationException("immutable properties are read only");
    205            }
    206
    207            /**
    208             * Read Only Object:  will throw UnsupportedOperationException.
    209             */
    210                    @Override
    211                    public synchronized void clear() {
    212                throw new UnsupportedOperationException("immutable properties are read only");
    213                    }
    214
    215                    /**
    216                     * Once object is constructed, this will throw UnsupportedOperationException because
    217                     * this class is a read only wrapper.
    218                     */
    219                    @Override
    220                    public synchronized Object put(Object key, Object value) {
    221                            if (!sealed) {
    222                                    //setProperty calls put, so until the object is fully constructed, we
    223                                    //cannot seal it.
    224                                    return super.put(key, value);
    225                            }
    226
    227                throw new UnsupportedOperationException("immutable properties are read only");
    228                    }
    229
    230            /**
    231             * Read Only Object:  will throw UnsupportedOperationException.
    232             */
    233                    @Override
    234                    public synchronized void putAll(Map<? extends Object, ? extends Object> t) {
    235                throw new UnsupportedOperationException("immutable properties are read only");
    236                    }
    237
    238
    239        }
    240
    241    }