    001package org.apache.turbine.annotation;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import java.lang.reflect.Field;
    025
    026import org.apache.commons.configuration.Configuration;
    027import org.apache.commons.lang.StringUtils;
    028import org.apache.commons.logging.Log;
    029import org.apache.commons.logging.LogFactory;
    030import org.apache.turbine.Turbine;
    031import org.apache.turbine.modules.Loader;
    032import org.apache.turbine.services.ServiceManager;
    033import org.apache.turbine.services.TurbineServices;
    034import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
    035import org.apache.turbine.util.TurbineException;
    036
    037/**
    038 * AnnotationProcessor contains static helper methods that handle the
    039 * Turbine annotations for objects
    040 *
    041 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
    042 * @version $Id: TurbineAssemblerBrokerService.java 1521103 2013-09-09 13:38:07Z tv $
    043 */
    044public class AnnotationProcessor
    045{
    046    /** Logging */
    047    private static Log log
    048            = LogFactory.getLog(AnnotationProcessor.class);
    049
    050    /**
    051     * Search for annotated fields of the object and provide them with the
    052     * appropriate TurbineService
    053     *
    054     * @param object the object
    055     * @throws TurbineException if the service could not be injected
    056     */
    057    public static void process(Object object) throws TurbineException
    058    {
    059        ServiceManager manager = TurbineServices.getInstance();
    060        Class<?> clazz = object.getClass();
    061
    062        while (clazz != null)
    063        {
    064            Field[] fields = clazz.getDeclaredFields();
    065
    066            for (Field field : fields)
    067            {
    068                if (field.isAnnotationPresent(TurbineService.class))
    069                {
    070                    TurbineService sa = field.getAnnotation(TurbineService.class);
    071                    String serviceName = null;
    072                    // Check for annotation value
    073                    if (StringUtils.isNotEmpty(sa.value()))
    074                    {
    075                        serviceName = sa.value();
    076                    }
    077                    // Check for fields SERVICE_NAME and ROLE
    078                    else
    079                    {
    080                        Field[] typeFields = field.getType().getFields();
    081                        for (Field f : typeFields)
    082                        {
    083                            if (TurbineService.SERVICE_NAME.equals(f.getName()))
    084                            {
    085                                try
    086                                {
    087                                    serviceName = (String)f.get(null);
    088                                }
    089                                catch (Exception e)
    090                                {
    091                                    continue;
    092                                }
    093                                break;
    094                            }
    095                            else if (TurbineService.ROLE.equals(f.getName()))
    096                            {
    097                                try
    098                                {
    099                                    serviceName = (String)f.get(null);
    100                                }
    101                                catch (Exception e)
    102                                {
    103                                    continue;
    104                                }
    105                                break;
    106                            }
    107                        }
    108                    }
    109
    110                    if (StringUtils.isEmpty(serviceName))
    111                    {
    112                        // Try interface class name
    113                        serviceName = field.getType().getName();
    114                    }
    115
    116                    if (log.isDebugEnabled())
    117                    {
    118                        log.debug("Looking up service for injection: " + serviceName + " for object " + object);
    119                    }
    120
    121                    Object service = manager.getService(serviceName); // throws Exception on unknown service
    122                    field.setAccessible(true);
    123
    124                    try
    125                    {
    126                        if (log.isDebugEnabled())
    127                        {
    128                            log.debug("Injection of " + serviceName + " into object " + object);
    129                        }
    130
    131                        field.set(object, service);
    132                    }
    133                    catch (IllegalArgumentException e)
    134                    {
    135                        throw new TurbineException("Could not inject service "
    136                                + serviceName + " into object " + object, e);
    137                    }
    138                    catch (IllegalAccessException e)
    139                    {
    140                        throw new TurbineException("Could not inject service "
    141                                + serviceName + " into object " + object, e);
    142                    }
    143                }
    144                else if (field.isAnnotationPresent(TurbineConfiguration.class))
    145                {
    146                    TurbineConfiguration ca = field.getAnnotation(TurbineConfiguration.class);
    147                    Configuration conf = null;
    148
    149                    // Check for annotation value
    150                    if (StringUtils.isNotEmpty(ca.value()))
    151                    {
    152                        conf = Turbine.getConfiguration().subset(ca.value());
    153                    }
    154                    else
    155                    {
    156                        conf = Turbine.getConfiguration();
    157                    }
    158
    159                    field.setAccessible(true);
    160
    161                    try
    162                    {
    163                        if (log.isDebugEnabled())
    164                        {
    165                            log.debug("Injection of " + conf + " into object " + object);
    166                        }
    167
    168                        field.set(object, conf);
    169                    }
    170                    catch (IllegalArgumentException e)
    171                    {
    172                        throw new TurbineException("Could not inject configuration "
    173                                + conf + " into object " + object, e);
    174                    }
    175                    catch (IllegalAccessException e)
    176                    {
    177                        throw new TurbineException("Could not inject configuration "
    178                                + conf + " into object " + object, e);
    179                    }
    180                }
    181                else if (field.isAnnotationPresent(TurbineLoader.class))
    182                {
    183                    TurbineLoader la = field.getAnnotation(TurbineLoader.class);
    184                    Loader<?> loader = TurbineAssemblerBroker.getLoader(la.value());
    185                    field.setAccessible(true);
    186
    187                    try
    188                    {
    189                        if (log.isDebugEnabled())
    190                        {
    191                            log.debug("Injection of " + loader + " into object " + object);
    192                        }
    193
    194                        field.set(object, loader);
    195                    }
    196                    catch (IllegalArgumentException e)
    197                    {
    198                        throw new TurbineException("Could not inject loader "
    199                                + loader + " into object " + object, e);
    200                    }
    201                    catch (IllegalAccessException e)
    202                    {
    203                        throw new TurbineException("Could not inject loader "
    204                                + loader + " into object " + object, e);
    205                    }
    206                }
    207            }
    208
    209            clazz = clazz.getSuperclass();
    210        }
    211    }
    212}