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}