2016-04-22 14 views
0

Play Frameworkを使用してサーバーを開発しています。いくつかの私の方法では、これまでのいくつかのアクション(基本的に入力チェック)を行う必要があるので、これを実行する最善の方法はAction Compositionだと思います。Play Frameworkの合成アクションのときと同じアクションを繰り返します。

私は問題なく

@Action1 // <---------------------------------------- This action is executed 
@Action2(value = "someValue") // <------------------- This action is executed 
public CompletionStage<Result> doSomething() { 
    ... 
} 

をいくつかのアノテーションを使用しますが、すぐに、私は具体的な行動が実行されないことをこれらのいずれかの操作を繰り返ししようとすることができます

@Action1 // <---------------------------------------- This action is executed 
@Action2(value = "someValue") // <------------------- This action is not executed 
@Action2(value = "someOtherValue") // <-------------- This action is not executed 
public CompletionStage<Result> doSomething() { 
    ... 
} 

マイAction1注釈がどのように見えますPlay Framework exampleVerboseAnnotationだから、私はそれをここに書く価値があるとは思わない。私Action2注釈を繰り返すことができるように私はこのようRepeatableAction2注釈を宣言した:

@Target({ElementType.TYPE, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface RepeatableAction2 { 
    Action2[] value() default {}; 
} 

Action2は次のようになります。

@With(Action2Impl.class) 
@Target({ElementType.TYPE, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Repeatable(value = RepeatableAction2.class) 
public @interface Action2 { 
    String value(); 
} 

方法が正しく注釈されています。私が追加した場合:

for (Method m : Application.class.getDeclaredMethods()) { 
    RequiredJsonValues reqs = m.getAnnotation(RequiredJsonValues.class); 
    for (RequiredJsonValue req : reqs.value()) { 
     System.out.println("Method: " + m + " annotation: " + req); 
    } 
} 

のメソッドの開始時に私はだから私は間違って何をやっている

Method: public java.util.concurrent.CompletionStage controllers.SomeController.doSomething() annotation: @util.Action2(value=someValue) 
Method: public java.util.concurrent.CompletionStage controllers.SomeController.doSomething() annotation: @util.Action2(value=someOtherValue) 

を取得しますか?同じアクションを異なる値で何度も連鎖させる方法はありますか?

答えて

0

最後に、私はそれが

ように働かせたは、Java 8コンパイラが書き込まれるRepeatableAction2を必要としませんが、それはので、私はその注釈の実装を追加するために必要なコンパイル時にそれを追加しますin hereは説明:

@With(RepeatableAction2Impl.class) 
@Target({ElementType.TYPE, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface RepeatableAction2 { 
    Action2[] value() default {}; 
} 

と実装に私は手動ですべてのアクションチェーン:

public class RepeatableAction2Impl extends Action<RepeatableAction2> { 

    @Override 
    public CompletionStage<Result> call(Http.Context ctx) { 
     if (configuration.value().length > 0) { 
      int actions = configuration.value().length; 
      List<Action<Action2>> actionList = new ArrayList<>(); 
      // Create actions 
      for (int i = 0; i < actions; i++) { 
       Action2Impl action2Impl = new Action2Impl(); 
       action2Impl.configuration = configuration.value()[i]; 
       actionList.add(action2Impl); 
      } 
      // Chaining 
      actionList.get(actions - 1).delegate = delegate; 
      for (int i = 0; i < actions - 1; i++) { 
       actionList.get(i).delegate = actionList.get(i + 1); 
      } 
      // Delegate the work to actions 
      return actionList.get(0).call(ctx); 
     } else { 
      return delegate.call(ctx); 
     } 
    } 

} 

それはSTILの作業ソリューションですが、私は少し醜いようです。私が行方不明の他の方法はありますか?

関連する問題