CAMEL-6094: Add option to type converter registry to control what to do if a type converter already exists.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d3f03cb8 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d3f03cb8 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d3f03cb8 Branch: refs/heads/master Commit: d3f03cb8d2922dea1bfbb4e373c9a7a107c569df Parents: ebcd4c9 Author: Claus Ibsen <[email protected]> Authored: Sat Aug 8 16:33:33 2015 +0200 Committer: Claus Ibsen <[email protected]> Committed: Sat Aug 8 16:33:33 2015 +0200 ---------------------------------------------------------------------- .../camel/TypeConverterExistsException.java | 42 +++++++++++++++++++ .../converter/BaseTypeConverterRegistry.java | 44 +++++++++++++++++--- .../apache/camel/spi/TypeConverterRegistry.java | 41 +++++++++++++++++- 3 files changed, 121 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/d3f03cb8/camel-core/src/main/java/org/apache/camel/TypeConverterExistsException.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/TypeConverterExistsException.java b/camel-core/src/main/java/org/apache/camel/TypeConverterExistsException.java new file mode 100644 index 0000000..c7a130c --- /dev/null +++ b/camel-core/src/main/java/org/apache/camel/TypeConverterExistsException.java @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel; + +/** + * Exception when failing to add type converters due there is already an existing type converter. + */ +public class TypeConverterExistsException extends RuntimeCamelException { + + private final transient Class<?> toType; + private final transient Class<?> fromType; + + public TypeConverterExistsException(Class<?> toType, Class<?> fromType) { + super("Failed to add type converter because a type converter exists. " + fromType + " -> " + toType); + this.toType = toType; + this.fromType = fromType; + } + + public Class<?> getToType() { + return toType; + } + + public Class<?> getFromType() { + return fromType; + } +} + + http://git-wip-us.apache.org/repos/asf/camel/blob/d3f03cb8/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java index 9650b24..06b4c20 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java +++ b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java @@ -31,10 +31,12 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.camel.CamelExecutionException; import org.apache.camel.Exchange; +import org.apache.camel.LoggingLevel; import org.apache.camel.NoFactoryAvailableException; import org.apache.camel.NoTypeConversionAvailableException; import org.apache.camel.TypeConversionException; import org.apache.camel.TypeConverter; +import org.apache.camel.TypeConverterExistsException; import org.apache.camel.TypeConverterLoaderException; import org.apache.camel.TypeConverters; import org.apache.camel.spi.FactoryFinder; @@ -44,6 +46,7 @@ import org.apache.camel.spi.TypeConverterAware; import org.apache.camel.spi.TypeConverterLoader; import org.apache.camel.spi.TypeConverterRegistry; import org.apache.camel.support.ServiceSupport; +import org.apache.camel.util.CamelLogger; import org.apache.camel.util.LRUSoftCache; import org.apache.camel.util.MessageHelper; import org.apache.camel.util.ObjectHelper; @@ -66,6 +69,8 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement protected final PackageScanClassResolver resolver; protected Injector injector; protected final FactoryFinder factoryFinder; + protected TypeConverterAddDuplicate addDuplicateTypeConverter = TypeConverterAddDuplicate.Overwrite; + protected LoggingLevel addDuplicateTypeConverterLoggingLevel = LoggingLevel.WARN; protected final Statistics statistics = new UtilizationStatistics(); protected final AtomicLong noopCounter = new AtomicLong(); protected final AtomicLong attemptCounter = new AtomicLong(); @@ -374,13 +379,26 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement TypeConverter converter = typeMappings.get(key); // only override it if its different // as race conditions can lead to many threads trying to promote the same fallback converter + if (typeConverter != converter) { - if (converter != null) { - log.warn("Overriding type converter from: " + converter + " to: " + typeConverter); + // duplicate detected + if (addDuplicateTypeConverter == TypeConverterAddDuplicate.Overwrite) { + if (converter != null) { + CamelLogger logger = new CamelLogger(log, addDuplicateTypeConverterLoggingLevel); + logger.log("Overriding type converter from: " + converter + " to: " + typeConverter); + } + typeMappings.put(key, typeConverter); + // remove any previous misses, as we added the new type converter + misses.remove(key); + } else if (addDuplicateTypeConverter == TypeConverterAddDuplicate.Ignore) { + if (converter != null) { + CamelLogger logger = new CamelLogger(log, addDuplicateTypeConverterLoggingLevel); + logger.log("Ignore duplicate type converter from: " + converter + " to: " + typeConverter); + } + } else { + // we should fail + throw new TypeConverterExistsException(toType, fromType); } - typeMappings.put(key, typeConverter); - // remove any previous misses, as we added the new type converter - misses.remove(key); } } @@ -595,6 +613,22 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement return typeMappings.size(); } + public LoggingLevel getAddDuplicateTypeConverterLoggingLevel() { + return addDuplicateTypeConverterLoggingLevel; + } + + public void setAddDuplicateTypeConverterLoggingLevel(LoggingLevel addTypeConverterExistsLoggingLevel) { + this.addDuplicateTypeConverterLoggingLevel = addTypeConverterExistsLoggingLevel; + } + + public TypeConverterAddDuplicate getAddDuplicateTypeConverter() { + return addDuplicateTypeConverter; + } + + public void setAddDuplicateTypeConverter(TypeConverterAddDuplicate addDuplicateTypeConverter) { + this.addDuplicateTypeConverter = addDuplicateTypeConverter; + } + @Override protected void doStart() throws Exception { // noop http://git-wip-us.apache.org/repos/asf/camel/blob/d3f03cb8/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java b/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java index eb0df81..a699636 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java +++ b/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java @@ -18,6 +18,7 @@ package org.apache.camel.spi; import java.util.List; +import org.apache.camel.LoggingLevel; import org.apache.camel.StaticService; import org.apache.camel.TypeConverter; import org.apache.camel.TypeConverters; @@ -81,7 +82,17 @@ public interface TypeConverterRegistry extends StaticService { } /** - * Registers a new type converter + * What to do if attempting to add a duplicate type converter + */ + enum TypeConverterAddDuplicate { + Overwrite, Ignore, Fail + } + + /** + * Registers a new type converter. + * <p/> + * This method may throw {@link org.apache.camel.TypeConverterExistsException} if configured to fail if an existing + * type converter already exists * * @param toType the type to convert to * @param fromType the type to convert from @@ -157,4 +168,32 @@ public interface TypeConverterRegistry extends StaticService { */ int size(); + /** + * The logging level to use when logging that a type converter already exists when attempting to add a duplicate type converter. + * <p/> + * The default logging level is <tt>WARN</tt> + */ + LoggingLevel getAddDuplicateTypeConverterLoggingLevel(); + + /** + * The logging level to use when logging that a type converter already exists when attempting to add a duplicate type converter. + * <p/> + * The default logging level is <tt>WARN</tt> + */ + void setAddDuplicateTypeConverterLoggingLevel(LoggingLevel loggingLevel); + + /** + * What should happen when attempting to add a duplicate type converter. + * <p/> + * The default behavior is to override the existing. + */ + TypeConverterAddDuplicate getAddDuplicateTypeConverter(); + + /** + * What should happen when attempting to add a duplicate type converter. + * <p/> + * The default behavior is to override the existing. + */ + void setAddDuplicateTypeConverter(TypeConverterAddDuplicate addDuplicateTypeConverter); + }
