Coverage Report - org.seasar.uruma.desc.impl.PartActionDescImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
PartActionDescImpl
84%
93/111
67%
35/52
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.uruma.desc.impl;
 17  
 
 18  
 import java.lang.reflect.Field;
 19  
 import java.lang.reflect.Method;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collections;
 22  
 import java.util.HashMap;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.Map.Entry;
 26  
 
 27  
 import org.seasar.framework.beans.BeanDesc;
 28  
 import org.seasar.framework.beans.PropertyDesc;
 29  
 import org.seasar.framework.beans.factory.BeanDescFactory;
 30  
 import org.seasar.framework.exception.EmptyRuntimeException;
 31  
 import org.seasar.framework.util.StringUtil;
 32  
 import org.seasar.uruma.annotation.ApplicationContext;
 33  
 import org.seasar.uruma.annotation.AsyncMethod;
 34  
 import org.seasar.uruma.annotation.EventListener;
 35  
 import org.seasar.uruma.annotation.InitializeMethod;
 36  
 import org.seasar.uruma.annotation.PostOpenMethod;
 37  
 import org.seasar.uruma.binding.context.ApplicationContextDef;
 38  
 import org.seasar.uruma.binding.method.EventListenerDef;
 39  
 import org.seasar.uruma.core.UrumaMessageCodes;
 40  
 import org.seasar.uruma.desc.PartActionDesc;
 41  
 import org.seasar.uruma.exception.IllegalMethodException;
 42  
 import org.seasar.uruma.exception.InitializeMethodException;
 43  
 import org.seasar.uruma.exception.MethodInvocationException;
 44  
 import org.seasar.uruma.jobs.ProgressMonitor;
 45  
 import org.seasar.uruma.util.AssertionUtil;
 46  
 
 47  
 /**
 48  
  * {@link PartActionDesc} の実装クラスです。<br />
 49  
  * 
 50  
  * @author y-komori
 51  
  */
 52  
 public class PartActionDescImpl implements PartActionDesc, UrumaMessageCodes {
 53  
 
 54  
     private Class<?> partActionClass;
 55  
 
 56  
     private BeanDesc beanDesc;
 57  
 
 58  
     private Method initializeMethod;
 59  
 
 60  
     private Method postOpenMethod;
 61  
 
 62  132
     private Map<String, List<Method>> methodsCache = new HashMap<String, List<Method>>();
 63  
 
 64  132
     private Map<String, Field> fieldsCache = new HashMap<String, Field>();
 65  
 
 66  132
     private List<EventListenerDef> eventListenerDefs = new ArrayList<EventListenerDef>();
 67  
 
 68  132
     private List<ApplicationContextDef> appContextDefs = new ArrayList<ApplicationContextDef>();
 69  
 
 70  
     private boolean isAsyncAction;
 71  
 
 72  
     private PropertyDesc progressMonitorProperty;
 73  
 
 74  
     /**
 75  
      * {@link PartActionDescImpl} を構築します。<br />
 76  
      * 
 77  
      * @param partActionClass
 78  
      *            対応するクラスオブジェクト
 79  
      */
 80  132
     public PartActionDescImpl(final Class<?> partActionClass) {
 81  132
         if (partActionClass == null) {
 82  0
             throw new EmptyRuntimeException("partActionClass");
 83  
         }
 84  
 
 85  132
         this.partActionClass = partActionClass;
 86  132
         this.beanDesc = BeanDescFactory.getBeanDesc(partActionClass);
 87  
 
 88  132
         setupIsAsyncMethod();
 89  132
         setupMethods();
 90  124
         setupFields();
 91  124
         setupProgressMonitorProperty();
 92  124
     }
 93  
 
 94  
     /*
 95  
      * @see org.seasar.uruma.desc.PartActionDesc#getInitializeMethod()
 96  
      */
 97  
     public Method getInitializeMethod() {
 98  4
         return this.initializeMethod;
 99  
     }
 100  
 
 101  
     /*
 102  
      * @see org.seasar.uruma.desc.PartActionDesc#invokeInitializeMethod(java.lang.Object)
 103  
      */
 104  
     public void invokeInitializeMethod(final Object target) {
 105  120
         if (initializeMethod != null) {
 106  24
             AssertionUtil.assertNotNull("target", target);
 107  
             try {
 108  24
                 initializeMethod.invoke(target, (Object[]) null);
 109  4
             } catch (Throwable ex) {
 110  4
                 throw new InitializeMethodException(ex.getCause(),
 111  
                         partActionClass, initializeMethod, target);
 112  20
             }
 113  
         }
 114  116
     }
 115  
 
 116  
     /*
 117  
      * @see org.seasar.uruma.desc.PartActionDesc#getPostOpenMethod()
 118  
      */
 119  
     public Method getPostOpenMethod() {
 120  0
         return this.postOpenMethod;
 121  
     }
 122  
 
 123  
     /*
 124  
      * @see org.seasar.uruma.desc.PartActionDesc#invokePostOpenMethod(java.lang.Object)
 125  
      */
 126  
     public void invokePostOpenMethod(final Object target) {
 127  112
         if (postOpenMethod != null) {
 128  112
             AssertionUtil.assertNotNull("target", target);
 129  
             try {
 130  112
                 postOpenMethod.invoke(target, (Object[]) null);
 131  0
             } catch (Throwable ex) {
 132  0
                 throw new MethodInvocationException(ex);
 133  112
             }
 134  
         }
 135  112
     }
 136  
 
 137  
     /*
 138  
      * @see org.seasar.uruma.desc.PartActionDesc#getEventListenerDefList()
 139  
      */
 140  
     public List<EventListenerDef> getEventListenerDefList() {
 141  112
         return Collections.unmodifiableList(eventListenerDefs);
 142  
     }
 143  
 
 144  
     /*
 145  
      * @see org.seasar.uruma.desc.PartActionDesc#getApplicationContextDefList()
 146  
      */
 147  
     public List<ApplicationContextDef> getApplicationContextDefList() {
 148  336
         return Collections.unmodifiableList(appContextDefs);
 149  
     }
 150  
 
 151  
     /*
 152  
      * @see org.seasar.uruma.desc.PartActionDesc#getBeanDesc()
 153  
      */
 154  
     public BeanDesc getBeanDesc() {
 155  380
         return this.beanDesc;
 156  
     }
 157  
 
 158  
     /*
 159  
      * @see org.seasar.uruma.desc.PartActionDesc#getPartActionClass()
 160  
      */
 161  
     public Class<?> getPartActionClass() {
 162  112
         return this.partActionClass;
 163  
     }
 164  
 
 165  
     /*
 166  
      * @see org.seasar.uruma.desc.PartActionDesc#injectProgressMonitor(java.lang.Object,
 167  
      *      org.seasar.uruma.jobs.ProgressMonitor)
 168  
      */
 169  
     public void injectProgressMonitor(final Object target,
 170  
             final ProgressMonitor monitor) {
 171  0
         if (progressMonitorProperty != null) {
 172  0
             progressMonitorProperty.setValue(target, monitor);
 173  
         }
 174  0
     }
 175  
 
 176  
     protected void setupMethods() {
 177  132
         Map<String, List<Method>> methodListMap = new HashMap<String, List<Method>>();
 178  132
         Method[] methods = partActionClass.getMethods();
 179  8428
         for (int i = 0; i < methods.length; i++) {
 180  8304
             List<Method> methodList = methodListMap.get(methods[i].getName());
 181  8304
             if (methodList == null) {
 182  4352
                 methodList = new ArrayList<Method>();
 183  4352
                 methodListMap.put(methods[i].getName(), methodList);
 184  
             }
 185  8304
             methodList.add(methods[i]);
 186  
 
 187  8304
             setupInitializeMethod(methods[i]);
 188  8296
             setupPostOpenMethod(methods[i]);
 189  8296
             setupEventListenerMethod(methods[i]);
 190  
         }
 191  
 
 192  124
         for (Entry<String, List<Method>> entry : methodListMap.entrySet()) {
 193  4340
             String methodName = entry.getKey();
 194  4340
             List<Method> methodList = entry.getValue();
 195  4340
             methodsCache.put(methodName, methodList);
 196  4340
         }
 197  124
     }
 198  
 
 199  
     protected void setupInitializeMethod(final Method method) {
 200  8304
         if (method.isAnnotationPresent(InitializeMethod.class)) {
 201  40
             if ((method.getReturnType() == Void.TYPE)
 202  
                     && (method.getParameterTypes().length == 0)) {
 203  36
                 if (initializeMethod == null) {
 204  32
                     initializeMethod = method;
 205  
                 } else {
 206  4
                     throw new IllegalMethodException(
 207  
                             DUPLICATE_ANNOTATED_METHOD, partActionClass, method);
 208  
                 }
 209  
             } else {
 210  4
                 throw new IllegalMethodException(ILLEGAL_METHOD_SIGNATURE,
 211  
                         partActionClass, method);
 212  
             }
 213  
         }
 214  8296
     }
 215  
 
 216  
     protected void setupPostOpenMethod(final Method method) {
 217  8296
         if (method.isAnnotationPresent(PostOpenMethod.class)) {
 218  112
             if ((method.getReturnType() == Void.TYPE)
 219  
                     && (method.getParameterTypes().length == 0)) {
 220  112
                 if (postOpenMethod == null) {
 221  112
                     postOpenMethod = method;
 222  
                 } else {
 223  0
                     throw new InitializeMethodException(
 224  
                             DUPLICATE_ANNOTATED_METHOD, partActionClass, method);
 225  
                 }
 226  
             } else {
 227  0
                 throw new InitializeMethodException(ILLEGAL_METHOD_SIGNATURE,
 228  
                         partActionClass, method);
 229  
             }
 230  
         }
 231  8296
     }
 232  
 
 233  
     protected void setupEventListenerMethod(final Method method) {
 234  8296
         EventListener anno = method.getAnnotation(EventListener.class);
 235  8296
         if (anno != null) {
 236  428
             AsyncMethod asyncMethod = method.getAnnotation(AsyncMethod.class);
 237  428
             EventListenerDef def = new EventListenerDef(method, anno,
 238  
                     asyncMethod);
 239  428
             eventListenerDefs.add(def);
 240  
         }
 241  8296
     }
 242  
 
 243  
     protected void setupApplicationContext(final Field field) {
 244  2564
         ApplicationContext anno = field.getAnnotation(ApplicationContext.class);
 245  2564
         if (anno != null) {
 246  0
             String name = anno.name();
 247  0
             if (StringUtil.isEmpty(name)) {
 248  0
                 name = field.getName();
 249  
             }
 250  
 
 251  0
             PropertyDesc pd = beanDesc.getPropertyDesc(field.getName());
 252  0
             ApplicationContextDef def = new ApplicationContextDef(pd, name);
 253  0
             appContextDefs.add(def);
 254  
         }
 255  2564
     }
 256  
 
 257  
     protected void setupFields() {
 258  124
         setupFieldsByClass(partActionClass);
 259  124
         Class<?> superClass = partActionClass.getSuperclass();
 260  572
         while (superClass != Object.class && superClass != null) {
 261  448
             setupFieldsByClass(superClass);
 262  448
             superClass = superClass.getSuperclass();
 263  
         }
 264  124
     }
 265  
 
 266  
     protected void setupFieldsByClass(final Class<?> targetClass) {
 267  572
         Field[] fields = targetClass.getDeclaredFields();
 268  3136
         for (int i = 0; i < fields.length; i++) {
 269  2564
             Field field = fields[i];
 270  2564
             String fieldName = field.getName();
 271  2564
             if (!fieldsCache.containsKey(fieldName)) {
 272  2564
                 field.setAccessible(true);
 273  2564
                 fieldsCache.put(fieldName, field);
 274  
 
 275  2564
                 setupApplicationContext(field);
 276  
             }
 277  
         }
 278  572
     }
 279  
 
 280  
     protected void setupIsAsyncMethod() {
 281  132
         if (partActionClass.isAnnotationPresent(AsyncMethod.class)) {
 282  0
             this.isAsyncAction = true;
 283  
         } else {
 284  132
             this.isAsyncAction = false;
 285  
         }
 286  132
     }
 287  
 
 288  
     protected void setupProgressMonitorProperty() {
 289  124
         BeanDesc desc = BeanDescFactory.getBeanDesc(partActionClass);
 290  124
         int size = desc.getPropertyDescSize();
 291  768
         for (int i = 0; i < size; i++) {
 292  644
             PropertyDesc pd = desc.getPropertyDesc(i);
 293  644
             Class<?> type = pd.getPropertyType();
 294  644
             if (type.isAssignableFrom(ProgressMonitor.class) && pd.isWritable()) {
 295  0
                 this.progressMonitorProperty = pd;
 296  0
                 break;
 297  
             }
 298  
         }
 299  124
     }
 300  
 }