Coverage Report - org.seasar.uruma.binding.method.AsyncMethodBinding
 
Classes in this File Line Coverage Branch Coverage Complexity
AsyncMethodBinding
0%
0/31
0%
0/14
0
AsyncMethodBinding$AsyncJob
0%
0/28
0%
0/12
0
AsyncMethodBinding$AsyncJob$1
0%
0/3
N/A
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.binding.method;
 17  
 
 18  
 import java.lang.reflect.Method;
 19  
 
 20  
 import org.eclipse.core.runtime.IProgressMonitor;
 21  
 import org.eclipse.core.runtime.IStatus;
 22  
 import org.eclipse.core.runtime.Status;
 23  
 import org.eclipse.core.runtime.jobs.Job;
 24  
 import org.eclipse.swt.widgets.Display;
 25  
 import org.seasar.framework.beans.BeanDesc;
 26  
 import org.seasar.framework.beans.PropertyDesc;
 27  
 import org.seasar.framework.beans.factory.BeanDescFactory;
 28  
 import org.seasar.framework.util.MethodUtil;
 29  
 import org.seasar.uruma.core.UrumaConstants;
 30  
 import org.seasar.uruma.core.UrumaMessageCodes;
 31  
 import org.seasar.uruma.desc.PartActionDesc;
 32  
 import org.seasar.uruma.desc.PartActionDescFactory;
 33  
 import org.seasar.uruma.jobs.ProgressMonitor;
 34  
 import org.seasar.uruma.jobs.impl.RcpProgressMonitor;
 35  
 import org.seasar.uruma.log.UrumaLogger;
 36  
 
 37  
 /**
 38  
  * メソッドを非同期に実行するための {@link MethodBinding} です。<br />
 39  
  * 本メソッドでは、実行対象オブジェクトに {@link ProgressMonitor} 型のプロパティが存在する場合、
 40  
  * {@link ProgressMonitor} オブジェクトをインジェクションします。<br />
 41  
  * また、{@link Display#getCurrent()} によって {@link Display} オブジェクトが取得できる場合には、
 42  
  * {@link MethodCallback#callback(MethodBinding, Object[], Object)} メソッドの呼び出しを
 43  
  * UI スレッド側で実行します。
 44  
  * 
 45  
  * @author y-komori
 46  
  */
 47  0
 public class AsyncMethodBinding extends MethodBinding implements
 48  
         UrumaMessageCodes {
 49  0
     private static final UrumaLogger logger = UrumaLogger
 50  
             .getLogger(AsyncMethodBinding.class);
 51  
 
 52  
     private String taskNameProperty;
 53  
 
 54  
     private boolean cancelable;
 55  
 
 56  
     /**
 57  
      * {@link AsyncMethodBinding} を構築します。<br />
 58  
      * 
 59  
      * @param target
 60  
      *            ターゲットオブジェクト
 61  
      * @param method
 62  
      *            ターゲットメソッド
 63  
      * @param callback
 64  
      *            コールバックオブジェクト
 65  
      */
 66  
     AsyncMethodBinding(final Object target, final Method method,
 67  
             final MethodCallback callback) {
 68  0
         super(target, method, callback);
 69  0
     }
 70  
 
 71  
     /*
 72  
      * @see org.seasar.uruma.binding.method.MethodBinding#invoke(java.lang.Object[])
 73  
      */
 74  
     @Override
 75  
     public Object invoke(final Object[] args) {
 76  0
         Object[] filteredArgs = args;
 77  0
         for (ArgumentsFilter filter : argumentsFilterList) {
 78  0
             filteredArgs = filter.filter(filteredArgs);
 79  
         }
 80  
 
 81  0
         String taskName = getTaskName(taskNameProperty, target);
 82  0
         AsyncJob job = new AsyncJob(taskName, this, filteredArgs, Display
 83  
                 .getCurrent());
 84  0
         if (cancelable) {
 85  0
             job.setUser(true);
 86  
         }
 87  0
         job.schedule();
 88  
 
 89  0
         if (logger.isInfoEnabled()) {
 90  0
             logger.log(ASYNC_METHOD_SCHEDULED, UrumaLogger
 91  
                     .getObjectDescription(target), method.getName(), args);
 92  
         }
 93  
 
 94  0
         return null;
 95  
     }
 96  
 
 97  
     /**
 98  
      * タスク名称を保持するプロパティ名を設定します。<br />
 99  
      * 
 100  
      * @param taskNameProperty
 101  
      *            プロパティ名
 102  
      */
 103  
     public void setTaskNameProperty(final String taskNameProperty) {
 104  0
         this.taskNameProperty = taskNameProperty;
 105  0
     }
 106  
 
 107  
     /**
 108  
      * キャンセル可能かどうかを設定します。<br />
 109  
      * 
 110  
      * @param cancelable
 111  
      *            キャンセル可能な場合は <code>true</code>。
 112  
      */
 113  
     public void setCancelable(final boolean cancelable) {
 114  0
         this.cancelable = cancelable;
 115  0
     }
 116  
 
 117  
     protected String getTaskName(final String propName, final Object target) {
 118  0
         if (propName == null) {
 119  0
             return UrumaConstants.NULL_STRING;
 120  
         }
 121  
 
 122  0
         BeanDesc desc = BeanDescFactory.getBeanDesc(target.getClass());
 123  0
         if (desc.hasPropertyDesc(propName)) {
 124  0
             PropertyDesc pd = desc.getPropertyDesc(propName);
 125  0
             if (pd.isReadable()
 126  
                     && String.class.isAssignableFrom(pd.getPropertyType())) {
 127  0
                 return (String) pd.getValue(target);
 128  
             }
 129  
         }
 130  0
         return UrumaConstants.NULL_STRING;
 131  
     }
 132  
 
 133  
     protected void injectProgressMonitor(final Object target,
 134  
             final IProgressMonitor monitor) {
 135  0
         PartActionDesc desc = PartActionDescFactory.getPartActionDesc(target
 136  
                 .getClass());
 137  
 
 138  0
         ProgressMonitor uMonitor = new RcpProgressMonitor(monitor);
 139  0
         desc.injectProgressMonitor(target, uMonitor);
 140  0
     }
 141  
 
 142  
     /**
 143  
      * アクションを非同期実行するための {@link Job} です。<br />
 144  
      * 
 145  
      * @author y-komori
 146  
      */
 147  0
     class AsyncJob extends Job {
 148  
         private MethodBinding binding;
 149  
 
 150  
         private Object[] args;
 151  
 
 152  
         private Object returnValue;
 153  
 
 154  
         private Display display;
 155  
 
 156  
         /**
 157  
          * {@link AsyncJob} を構築します。<br />
 158  
          */
 159  
         AsyncJob(final String name, final MethodBinding binding,
 160  0
                 final Object[] args, final Display display) {
 161  0
             super(name);
 162  0
             this.binding = binding;
 163  0
             this.args = args;
 164  0
             this.display = display;
 165  0
         }
 166  
 
 167  
         /*
 168  
          * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
 169  
          */
 170  
         @Override
 171  
         protected IStatus run(final IProgressMonitor monitor) {
 172  0
             if (logger.isInfoEnabled()) {
 173  0
                 logger.log(ASYNC_METHOD_START, UrumaLogger
 174  
                         .getObjectDescription(target), method.getName(), args);
 175  
             }
 176  
 
 177  
             try {
 178  0
                 injectProgressMonitor(target, monitor);
 179  0
                 returnValue = MethodUtil.invoke(binding.getMethod(), binding
 180  
                         .getTarget(), args);
 181  
 
 182  0
                 if (callback != null) {
 183  0
                     if (display != null) {
 184  0
                         display.asyncExec(new Runnable() {
 185  0
                             public void run() {
 186  0
                                 returnValue = callback.callback(binding, args,
 187  
                                         returnValue);
 188  0
                             }
 189  
                         });
 190  
                     } else {
 191  0
                         returnValue = callback.callback(binding, args,
 192  
                                 returnValue);
 193  
                     }
 194  
                 }
 195  0
             } catch (Throwable ex) {
 196  0
                 logger.log(EXCEPTION_OCCURED_INVOKING_METHOD, ex, binding
 197  
                         .toString());
 198  0
             } finally {
 199  0
                 if (logger.isInfoEnabled()) {
 200  0
                     String desc = UrumaLogger.getObjectDescription(target);
 201  0
                     if (!monitor.isCanceled()) {
 202  0
                         logger.log(ASYNC_METHOD_END, desc, method.getName(),
 203  
                                 returnValue);
 204  
                     } else {
 205  0
                         logger.log(ASYNC_METHOD_CANCELED, desc, method
 206  
                                 .getName(), returnValue);
 207  
                     }
 208  0
                 }
 209  0
             }
 210  
 
 211  0
             if (!monitor.isCanceled()) {
 212  0
                 return Status.OK_STATUS;
 213  
             } else {
 214  0
                 return Status.CANCEL_STATUS;
 215  
             }
 216  
         }
 217  
     }
 218  
 }