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 */
017package org.apache.camel.util;
018
019import org.apache.camel.CamelContext;
020import org.apache.camel.Component;
021import org.apache.camel.spi.DataFormat;
022import org.apache.camel.spi.Language;
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025
026/**
027 * Some helper methods for new resolvers (like {@link org.apache.camel.spi.ComponentResolver}, {@link org.apache.camel.spi.DataFormatResolver}, etc.).
028 *
029 * @version
030 */
031public final class ResolverHelper {
032
033    public static final String COMPONENT_FALLBACK_SUFFIX = "-component";
034
035    public static final String DATA_FORMAT_FALLBACK_SUFFIX = "-dataformat";
036
037    public static final String LANGUAGE_FALLBACK_SUFFIX = "-language";
038
039    private static final Logger LOG = LoggerFactory.getLogger(ResolverHelper.class);
040
041    private static final LookupExceptionHandler EXCEPTION_HANDLER = new LookupExceptionHandler();
042
043    /**
044     * Utility classes should not have a public constructor.
045     */
046    private ResolverHelper() {
047    }
048
049    public static Component lookupComponentInRegistryWithFallback(CamelContext context, String name) {
050        return lookupComponentInRegistryWithFallback(context, name, EXCEPTION_HANDLER);
051    }
052
053    public static Component lookupComponentInRegistryWithFallback(CamelContext context, String name, LookupExceptionHandler exceptionHandler) {
054        Object bean = lookupInRegistry(context, Component.class, false, exceptionHandler, name, name + COMPONENT_FALLBACK_SUFFIX);
055        if (bean != null) {
056            if (bean instanceof Component) {
057                return (Component) bean;
058            } else {
059                // let's use Camel's type conversion mechanism to convert things like CamelContext
060                // and other types into a valid Component
061                Component component = CamelContextHelper.convertTo(context, Component.class, bean);
062                if (component != null) {
063                    return component;
064                }
065            }
066        }
067
068        if (bean != null) {
069            LOG.debug("Found Component with incompatible class: {}", bean.getClass().getName());
070        }
071        return null;
072    }
073
074    public static DataFormat lookupDataFormatInRegistryWithFallback(CamelContext context, String name) {
075        return lookupDataFormatInRegistryWithFallback(context, name, EXCEPTION_HANDLER);
076    }
077
078    public static DataFormat lookupDataFormatInRegistryWithFallback(CamelContext context, String name, LookupExceptionHandler exceptionHandler) {
079        Object bean = lookupInRegistry(context, DataFormat.class, false, exceptionHandler, name, name + DATA_FORMAT_FALLBACK_SUFFIX);
080        if (bean instanceof DataFormat) {
081            return (DataFormat) bean;
082        }
083
084        if (bean != null) {
085            LOG.debug("Found DataFormat with incompatible class: {}", bean.getClass().getName());
086        }
087        return null;
088    }
089
090    public static Language lookupLanguageInRegistryWithFallback(CamelContext context, String name) {
091        return lookupLanguageInRegistryWithFallback(context, name, EXCEPTION_HANDLER);
092    }
093
094    public static Language lookupLanguageInRegistryWithFallback(CamelContext context, String name, LookupExceptionHandler exceptionHandler) {
095        Object bean = lookupInRegistry(context, Language.class, false, exceptionHandler, name, name + LANGUAGE_FALLBACK_SUFFIX);
096        if (bean instanceof Language) {
097            return (Language) bean;
098        }
099
100        if (bean != null) {
101            LOG.debug("Found Language with incompatible class: {}", bean.getClass().getName());
102        }
103        return null;
104    }
105
106
107    public static class LookupExceptionHandler {
108
109        public void handleException(Exception e, Logger log, String name) {
110            log.debug("Ignored error looking up bean: " + name, e);
111        }
112
113    }
114
115    private static Object lookupInRegistry(CamelContext context, Class<?> type, boolean lookupByNameAndType, LookupExceptionHandler exceptionHandler, String... names) {
116        for (String name : names) {
117            try {
118                Object bean;
119                if (lookupByNameAndType) {
120                    bean = context.getRegistry().lookupByNameAndType(name, type);
121                } else {
122                    bean = context.getRegistry().lookupByName(name);
123                }
124                LOG.debug("Lookup {} with name {} in registry. Found: {}", type.getSimpleName(), name, bean);
125                if (bean != null) {
126                    return bean;
127                }
128            } catch (Exception e) {
129                exceptionHandler.handleException(e, LOG, name);
130            }
131        }
132
133        return null;
134    }
135
136}