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 public class ExchangeProperty<T> {
058
059 private static final List<ExchangeProperty<?>> VALUES =
060 new ArrayList<ExchangeProperty<?>>();
061
062 private static final Map<String, ExchangeProperty<?>> LITERAL_MAP =
063 new HashMap<String, ExchangeProperty<?>>();
064
065 private static final Map<String, ExchangeProperty<?>> NAME_MAP =
066 new HashMap<String, ExchangeProperty<?>>();
067
068 private final String literal;
069 private final String name;
070 private final Class<T> type;
071
072 public ExchangeProperty(String literal, String name, Class<T> type) {
073 this.literal = literal;
074 this.name = name;
075 this.type = type;
076 register(this);
077 }
078
079 public String literal() {
080 return literal;
081 }
082
083 public String name() {
084 return name;
085 }
086
087 public Class<T> type() {
088 return type;
089 }
090
091 public T get(Exchange exchange) {
092 return exchange.getProperty(name, type);
093 }
094
095 public static ExchangeProperty<?> get(String literal) {
096 return LITERAL_MAP.get(literal);
097 }
098
099 public static ExchangeProperty<?> getByName(String name) {
100 return NAME_MAP.get(name);
101 }
102
103 public T set(Exchange exchange, T value) {
104 T oldValue = get(exchange);
105 exchange.setProperty(name, value);
106 return oldValue;
107 }
108
109 public T remove(Exchange exchange) {
110 T oldValue = get(exchange);
111 exchange.removeProperty(name);
112 return oldValue;
113 }
114
115 @Override
116 public String toString() {
117 return type().getCanonicalName() + " " + name + " (" + literal() + ")";
118 }
119
120 public static synchronized void register(ExchangeProperty<?> property) {
121 ExchangeProperty<?> existingProperty = LITERAL_MAP.get(property.literal());
122 if (existingProperty != null && existingProperty != property) {
123 throw new RuntimeCamelException("An Exchange Property '" + property.literal()
124 + "' has already been registered; its traits are: " + existingProperty.toString());
125 }
126 VALUES.add(property);
127 LITERAL_MAP.put(property.literal(), property);
128 NAME_MAP.put(property.name(), property);
129 }
130
131 public static synchronized void deregister(ExchangeProperty<?> property) {
132 if (property != null) {
133 VALUES.remove(property);
134 LITERAL_MAP.remove(property.literal());
135 NAME_MAP.put(property.name(), property);
136 }
137 }
138
139 public static synchronized void deregister(String literal) {
140 ExchangeProperty<?> property = LITERAL_MAP.get(literal);
141 if (property != null) {
142 VALUES.remove(property);
143 LITERAL_MAP.remove(property.literal());
144 NAME_MAP.put(property.name(), property);
145 }
146 }
147
148 public static synchronized ExchangeProperty<?>[] values() {
149 return VALUES.toArray(new ExchangeProperty[0]);
150 }
151
152 }