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        public boolean allowNull() {
049            return false;
050        }
051    
052        @Override
053        protected Object doConvertTo(final Class<?> type, final Exchange exchange, final Object value, boolean tryConvert) {
054            Object answer = super.doConvertTo(type, exchange, value, tryConvert);
055            if (answer == null && !loaded.get()) {
056                // okay we could not convert, so try again, but load the converters up front
057                ensureLoaded();
058                answer = super.doConvertTo(type, exchange, value, tryConvert);
059            }
060            return answer;
061        }
062    
063        @Override
064        public TypeConverter getTypeConverter(Class<?> toType, Class<?> fromType) {
065            TypeConverter answer = super.getTypeConverter(toType, fromType);
066            if (answer == null && !loaded.get()) {
067                // okay we could not convert, so try again, but load the converters up front
068                ensureLoaded();
069                answer = super.getTypeConverter(toType, fromType);
070            }
071            return answer;
072        }
073    
074        @Override
075        public Set<Class<?>> getFromClassMappings() {
076            if (!loaded.get()) {
077                ensureLoaded();
078            }
079            return super.getFromClassMappings();
080        }
081    
082        @Override
083        public Map<Class<?>, TypeConverter> getToClassMappings(Class<?> fromClass) {
084            if (!loaded.get()) {
085                ensureLoaded();
086            }
087            return super.getToClassMappings(fromClass);
088        }
089    
090        @Override
091        public Map<TypeMapping, TypeConverter> getTypeMappings() {
092            if (!loaded.get()) {
093                ensureLoaded();
094            }
095            return super.getTypeMappings();
096        }
097    
098        @Override
099        protected TypeConverter doLookup(Class<?> toType, Class<?> fromType, boolean isSuper) {
100            TypeConverter answer = super.doLookup(toType, fromType, isSuper);
101            if (answer == null && !loaded.get()) {
102                // okay we could not convert, so try again, but load the converters up front
103                ensureLoaded();
104                answer = super.doLookup(toType, fromType, isSuper);
105            }
106            return answer;
107        }
108    
109        private synchronized void ensureLoaded() {
110            if (loaded.compareAndSet(false, true)) {
111                try {
112                    super.loadTypeConverters();
113                } catch (Exception e) {
114                    throw ObjectHelper.wrapRuntimeCamelException(e);
115                }
116            }
117        }
118    
119        @Override
120        protected void doStart() throws Exception {
121            super.doStart();
122            // must load core type converters
123            loadCoreTypeConverters();
124        }
125    
126        @Override
127        protected void doStop() throws Exception {
128            super.doStop();
129            // reset loaded flag
130            loaded.set(false);
131        }
132    }
133