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.impl.converter;
018    
019    import java.util.Map;
020    import java.util.Set;
021    import java.util.concurrent.atomic.AtomicBoolean;
022    
023    import org.apache.camel.Exchange;
024    import org.apache.camel.TypeConverter;
025    import org.apache.camel.spi.FactoryFinder;
026    import org.apache.camel.spi.Injector;
027    import org.apache.camel.spi.PackageScanClassResolver;
028    import org.apache.camel.util.ObjectHelper;
029    
030    /**
031     * Lazy implementation of a type converter registry used for
032     * <a href="http://camel.apache.org/type-converter.html">type converters</a> in Camel.
033     * <p/>
034     * This implementation will lazy load type converters on-demand.
035     *
036     * @version
037     * @deprecated will be removed in a future Camel release.
038     */
039    @Deprecated
040    public class LazyLoadingTypeConverter extends BaseTypeConverterRegistry {
041        private final AtomicBoolean loaded = new AtomicBoolean();
042    
043        public LazyLoadingTypeConverter(PackageScanClassResolver resolver, Injector injector, FactoryFinder factoryFinder) {
044            super(resolver, injector, factoryFinder);
045        }
046    
047        @Override
048        protected Object doConvertTo(final Class<?> type, final Exchange exchange, final Object value, boolean tryConvert) {
049            Object answer = super.doConvertTo(type, exchange, value, tryConvert);
050            if (answer == null && !loaded.get()) {
051                // okay we could not convert, so try again, but load the converters up front
052                ensureLoaded();
053                answer = super.doConvertTo(type, exchange, value, tryConvert);
054            }
055            return answer;
056        }
057    
058        @Override
059        public TypeConverter getTypeConverter(Class<?> toType, Class<?> fromType) {
060            TypeConverter answer = super.getTypeConverter(toType, fromType);
061            if (answer == null && !loaded.get()) {
062                // okay we could not convert, so try again, but load the converters up front
063                ensureLoaded();
064                answer = super.getTypeConverter(toType, fromType);
065            }
066            return answer;
067        }
068    
069        @Override
070        public Set<Class<?>> getFromClassMappings() {
071            if (!loaded.get()) {
072                ensureLoaded();
073            }
074            return super.getFromClassMappings();
075        }
076    
077        @Override
078        public Map<Class<?>, TypeConverter> getToClassMappings(Class<?> fromClass) {
079            if (!loaded.get()) {
080                ensureLoaded();
081            }
082            return super.getToClassMappings(fromClass);
083        }
084    
085        @Override
086        public Map<TypeMapping, TypeConverter> getTypeMappings() {
087            if (!loaded.get()) {
088                ensureLoaded();
089            }
090            return super.getTypeMappings();
091        }
092    
093        @Override
094        protected TypeConverter doLookup(Class<?> toType, Class<?> fromType, boolean isSuper) {
095            TypeConverter answer = super.doLookup(toType, fromType, isSuper);
096            if (answer == null && !loaded.get()) {
097                // okay we could not convert, so try again, but load the converters up front
098                ensureLoaded();
099                answer = super.doLookup(toType, fromType, isSuper);
100            }
101            return answer;
102        }
103    
104        private synchronized void ensureLoaded() {
105            if (loaded.compareAndSet(false, true)) {
106                try {
107                    super.loadTypeConverters();
108                } catch (Exception e) {
109                    throw ObjectHelper.wrapRuntimeCamelException(e);
110                }
111            }
112        }
113    
114        @Override
115        protected void doStart() throws Exception {
116            super.doStart();
117            // must load core type converters
118            loadCoreTypeConverters();
119        }
120    
121        @Override
122        protected void doStop() throws Exception {
123            super.doStop();
124            // reset loaded flag
125            loaded.set(false);
126        }
127    }
128