001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel;
018    
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    /**
025     * Represents an instance and a type safe registry of well known Camel Exchange properties.
026     * <p/>
027     * <b>Usage pattern:</b>
028     * <br/>In your code register a property that you wish to pass via Camel Exchange:
029     * <pre>
030     *      public static final ExchangeProperty<Boolean> myProperty =
031     *            new ExchangeProperty<Boolean>("myProperty", "org.apache.myproject.mypackage.myproperty", Boolean.class);
032     *
033     *  Then in your code set this property's value:
034     *      myProperty.set(exchange, Boolean.TRUE);
035     *
036     *  Check the value of this property where required:
037     *      ExchangeProperty<?> property = ExchangeProperty.get("myProperty");
038     *      if (property != null && property.get(exchange) == Boolean.TRUE) {
039     *           // do your thing ...
040     *       }
041     *  Or
042     *      Boolean value = myProperty.get(exchange);
043     *      if (value == Boolean.TRUE) {
044     *          // do your thing
045     *      }
046     *
047     *  When your code no longer requires this property then deregister it:
048     *      ExchangeProperty.deregister(myProperty);
049     *  Or
050     *      ExchangeProperty.deregister("myProperty");
051     *  </pre>
052     *
053     *  <b>Note:</b> that if ExchangeProperty instance get or set methods are used then type checks
054     *  of property's value are performed and a runtime exception can be thrown if type
055     *  safety is violated.
056     *
057     * @deprecated will be removed in Camel 2.0
058     */
059    public class ExchangeProperty<T> {
060    
061        private static final List<ExchangeProperty<?>> VALUES =
062            new ArrayList<ExchangeProperty<?>>();
063    
064        private static final Map<String, ExchangeProperty<?>> LITERAL_MAP =
065            new HashMap<String, ExchangeProperty<?>>();
066    
067        private static final Map<String, ExchangeProperty<?>> NAME_MAP =
068            new HashMap<String, ExchangeProperty<?>>();
069    
070        private final String literal;
071        private final String name;
072        private final Class<T> type;
073    
074        public ExchangeProperty(String literal, String name, Class<T> type) {
075            this.literal = literal;
076            this.name = name;
077            this.type = type;
078            register(this);
079        }
080    
081        public String literal() {
082            return literal;
083        }
084    
085        public String name() {
086            return name;
087        }
088    
089        public Class<T> type() {
090            return type;
091        }
092    
093        public T get(Exchange exchange) {
094            return exchange.getProperty(name, type);
095        }
096    
097        public static ExchangeProperty<?> get(String literal) {
098            return LITERAL_MAP.get(literal);
099        }
100    
101        public static ExchangeProperty<?> getByName(String name) {
102            return NAME_MAP.get(name);
103        }
104    
105        public T set(Exchange exchange, T value) {
106            T oldValue = get(exchange);
107            exchange.setProperty(name, value);
108            return oldValue;
109        }
110    
111        public T remove(Exchange exchange) {
112            T oldValue = get(exchange);
113            exchange.removeProperty(name);
114            return oldValue;
115        }
116    
117        @Override
118        public String toString() {
119            return type().getCanonicalName() + " " + name + " (" + literal() + ")";
120        }
121    
122        public static synchronized void register(ExchangeProperty<?> property) {
123            ExchangeProperty<?> existingProperty = LITERAL_MAP.get(property.literal());
124            if (existingProperty != null && existingProperty != property) {
125                throw new RuntimeCamelException("An Exchange Property '" + property.literal()
126                        + "' has already been registered; its traits are: " + existingProperty.toString());
127            }
128            VALUES.add(property);
129            LITERAL_MAP.put(property.literal(), property);
130            NAME_MAP.put(property.name(), property);
131        }
132    
133        public static synchronized void deregister(ExchangeProperty<?> property) {
134            if (property != null) {
135                VALUES.remove(property);
136                LITERAL_MAP.remove(property.literal());
137                NAME_MAP.put(property.name(), property);
138            }
139        }
140    
141        public static synchronized void deregister(String literal) {
142            ExchangeProperty<?> property = LITERAL_MAP.get(literal);
143            if (property != null) {
144                VALUES.remove(property);
145                LITERAL_MAP.remove(property.literal());
146                NAME_MAP.put(property.name(), property);
147            }
148        }
149    
150        public static synchronized ExchangeProperty<?>[] values() {
151            return VALUES.toArray(new ExchangeProperty[0]);
152        }
153    
154    }