package com.nineoldandroids.view;

import java.lang.ref.WeakReference;
import android.view.View;
import android.view.animation.Interpolator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

/**
 * *******************************************************
 *  @文件名称：ViewPropertyAnimatorICS.java
 *  @文件作者：renzhiqiang
 *  @创建时间：2015年9月28日 下午11:11:12
 *  @文件描述：API11以后实现view.ViewPropertyAnimator
 *  @修改历史：2015年9月28日创建初始版本
 * ********************************************************
 */
class ViewPropertyAnimatorICS extends ViewPropertyAnimator {

    /**
     * A value to be returned when the WeakReference holding the native implementation
     * returns null
     */
    private final static long RETURN_WHEN_NULL = -1L;

    /**
     * A WeakReference holding the native implementation of ViewPropertyAnimator
     */
    private final WeakReference<android.view.ViewPropertyAnimator> mNative;

    ViewPropertyAnimatorICS(View view) {
        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
    }

    @Override
    public ViewPropertyAnimator setDuration(long duration) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setDuration(duration);
        }
        return this;
    }

    @Override
    public long getDuration() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getDuration();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setStartDelay(long startDelay) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setStartDelay(startDelay);
        }
        return this;
    }

    @Override
    public long getStartDelay() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getStartDelay();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setInterpolator(interpolator);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            if (listener == null) {
                n.setListener(null);
            } else {
                n.setListener(new android.animation.Animator.AnimatorListener() {

                    @Override
                    public void onAnimationStart(android.animation.Animator animation) {
                        listener.onAnimationStart(null);
                    }

                    @Override
                    public void onAnimationRepeat(android.animation.Animator animation) {
                        listener.onAnimationRepeat(null);
                    }

                    @Override
                    public void onAnimationEnd(android.animation.Animator animation) {
                        listener.onAnimationEnd(null);
                    }

                    @Override
                    public void onAnimationCancel(android.animation.Animator animation) {
                        listener.onAnimationCancel(null);
                    }
                });
            }
        }
        return this;
    }

    @Override
    public void start() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.start();
        }
    }

    @Override
    public void cancel() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.cancel();
        }
    }

    @Override
    public ViewPropertyAnimator x(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.x(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator xBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.xBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator y(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.y(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator yBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.yBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotation(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotation(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationX(float value) {

        if (n != null) {
            n.rotationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alpha(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alpha(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alphaBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alphaBy(value);
        }
        return this;
    }
}


if (n != null) {
            n.rotationX(value);
        }

package com.nineoldandroids.view;

import java.lang.ref.WeakReference;
import android.view.View;
import android.view.animation.Interpolator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

/**
 * *******************************************************
 *  @文件名称：ViewPropertyAnimatorICS.java
 *  @文件作者：renzhiqiang
 *  @创建时间：2015年9月28日 下午11:11:12
 *  @文件描述：API11以后实现view.ViewPropertyAnimator
 *  @修改历史：2015年9月28日创建初始版本
 * ********************************************************
 */
class ViewPropertyAnimatorICS extends ViewPropertyAnimator {

    /**
     * A value to be returned when the WeakReference holding the native implementation
     * returns null
     */
    private final static long RETURN_WHEN_NULL = -1L;

    /**
     * A WeakReference holding the native implementation of ViewPropertyAnimator
     */
    private final WeakReference<android.view.ViewPropertyAnimator> mNative;

    ViewPropertyAnimatorICS(View view) {
        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
    }

    @Override
    public ViewPropertyAnimator setDuration(long duration) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setDuration(duration);
        }
        return this;
    }

    @Override
    public long getDuration() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getDuration();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setStartDelay(long startDelay) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setStartDelay(startDelay);
        }
        return this;
    }

    @Override
    public long getStartDelay() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getStartDelay();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setInterpolator(interpolator);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            if (listener == null) {
                n.setListener(null);
            } else {
                n.setListener(new android.animation.Animator.AnimatorListener() {

                    @Override
                    public void onAnimationStart(android.animation.Animator animation) {
                        listener.onAnimationStart(null);
                    }

                    @Override
                    public void onAnimationRepeat(android.animation.Animator animation) {
                        listener.onAnimationRepeat(null);
                    }

                    @Override
                    public void onAnimationEnd(android.animation.Animator animation) {
                        listener.onAnimationEnd(null);
                    }

                    @Override
                    public void onAnimationCancel(android.animation.Animator animation) {
                        listener.onAnimationCancel(null);
                    }
                });
            }
        }
        return this;
    }

    @Override
    public void start() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.start();
        }
    }

    @Override
    public void cancel() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.cancel();
        }
    }

    @Override
    public ViewPropertyAnimator x(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.x(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator xBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.xBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator y(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.y(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator yBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.yBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotation(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotation(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();

        return this;
    }

    @Override
    public ViewPropertyAnimator rotationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alpha(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alpha(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alphaBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alphaBy(value);
        }
        return this;
    }
}


package com.nineoldandroids.view;

import java.lang.ref.WeakReference;
import android.view.View;
import android.view.animation.Interpolator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

/**
 * *******************************************************
 *  @文件名称：ViewPropertyAnimatorICS.java
 *  @文件作者：renzhiqiang
 *  @创建时间：2015年9月28日 下午11:11:12
 *  @文件描述：API11以后实现view.ViewPropertyAnimator
 *  @修改历史：2015年9月28日创建初始版本
 * ********************************************************
 */
class ViewPropertyAnimatorICS extends ViewPropertyAnimator {

    /**
     * A value to be returned when the WeakReference holding the native implementation
     * returns null
     */
    private final static long RETURN_WHEN_NULL = -1L;

    /**
     * A WeakReference holding the native implementation of ViewPropertyAnimator
     */
    private final WeakReference<android.view.ViewPropertyAnimator> mNative;

    ViewPropertyAnimatorICS(View view) {
        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
    }

    @Override
    public ViewPropertyAnimator setDuration(long duration) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setDuration(duration);
        }
        return this;
    }

    @Override
    public long getDuration() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getDuration();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setStartDelay(long startDelay) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setStartDelay(startDelay);
        }
        return this;
    }

    @Override
    public long getStartDelay() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getStartDelay();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setInterpolator(interpolator);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            if (listener == null) {
                n.setListener(null);
            } else {
                n.setListener(new android.animation.Animator.AnimatorListener() {

                    @Override
                    public void onAnimationStart(android.animation.Animator animation) {
                        listener.onAnimationStart(null);
                    }

                    @Override
                    public void onAnimationRepeat(android.animation.Animator animation) {
                        listener.onAnimationRepeat(null);
                    }

                    @Override
                    public void onAnimationEnd(android.animation.Animator animation) {
                        listener.onAnimationEnd(null);
                    }

                    @Override
                    public void onAnimationCancel(android.animation.Animator animation) {
                        listener.onAnimationCancel(null);
                    }
                });
            }
        }
        return this;
    }

    @Override
    public void start() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.start();
        }
    }

    @Override
    public void cancel() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.cancel();
        }
    }

    @Override
    public ViewPropertyAnimator x(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.x(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator xBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.xBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator y(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.y(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator yBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.yBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotation(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotation(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationX(value);
        }

    @Override
    public ViewPropertyAnimator rotationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alpha(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alpha(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alphaBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alphaBy(value);
        }
        return this;
    }
}


package com.nineoldandroids.view;

import java.lang.ref.WeakReference;
import android.view.View;
import android.view.animation.Interpolator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

/**
 * *******************************************************
 *  @文件名称：ViewPropertyAnimatorICS.java
 *  @文件作者：renzhiqiang
 *  @创建时间：2015年9月28日 下午11:11:12
 *  @文件描述：API11以后实现view.ViewPropertyAnimator
 *  @修改历史：2015年9月28日创建初始版本
 * ********************************************************
 */
class ViewPropertyAnimatorICS extends ViewPropertyAnimator {

    /**
     * A value to be returned when the WeakReference holding the native implementation
     * returns null
     */
    private final static long RETURN_WHEN_NULL = -1L;

    /**
     * A WeakReference holding the native implementation of ViewPropertyAnimator
     */
    private final WeakReference<android.view.ViewPropertyAnimator> mNative;

    ViewPropertyAnimatorICS(View view) {
        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
    }

    @Override
    public ViewPropertyAnimator setDuration(long duration) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setDuration(duration);
        }
        return this;
    }

    @Override
    public long getDuration() {
        android.view.ViewPropertyAni

        if (n != null) {
            return n.getDuration();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setStartDelay(long startDelay) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setStartDelay(startDelay);
        }
        return this;
    }

    @Override
    public long getStartDelay() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getStartDelay();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setInterpolator(interpolator);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            if (listener == null) {
                n.setListener(null);
            } else {
                n.setListener(new android.animation.Animator.AnimatorListener() {

                    @Override
                    public void onAnimationStart(android.animation.Animator animation) {
                        listener.onAnimationStart(null);
                    }

                    @Override
                    public void onAnimationRepeat(android.animation.Animator animation) {
                        listener.onAnimationRepeat(null);
                    }

                    @Override
                    public void onAnimationEnd(android.animation.Animator animation) {
                        listener.onAnimationEnd(null);
                    }

                    @Override
                    public void onAnimationCancel(android.animation.Animator animation) {
                        listener.onAnimationCancel(null);
                    }
                });
            }
        }
        return this;
    }

    @Override
    public void start() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.start();
        }
    }

    @Override
    public void cancel() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.cancel();
        }
    }

    @Override
    public ViewPropertyAnimator x(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.x(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator xBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.xBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator y(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.y(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator yBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.yBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotation(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotation(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alpha(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alpha(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alphaBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alphaBy(value);
        }
        return this;
    }
}


package com.nineoldandroids.view;

import java.lang.ref.WeakReference;
import android.view.View;
import android.view.animation.Interpolator;
import com.nineoldandroids.animation.Animator.AnimatorListener;

/**
 * *******************************************************
 *  @文件名称：ViewPropertyAnimatorICS.java
 *  @文件作者：renzhiqiang
 *  @创建时间：2015年9月28日 下午11:11:12
 *  @文件描述：API11以后实现view.ViewPropertyAnimator
 *  @修改历史：2015年9月28日创建初始版本
 * ********************************************************
 */
class ViewPropertyAnimatorICS extends ViewPropertyAnimator {

    /**
     * A value to be returned when the WeakReference holding the native implementation
     * returns null
     */
    private final static long RETURN_WHEN_NULL = -1L;

    /**
     * A WeakReference holding the native implementation of ViewPropertyAnimator
     */
    private final WeakReference<android.view.ViewPropertyAnimator> mNative;

    ViewPropertyAnimatorICS(View view) {
        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
    }

    @Override
    public ViewPropertyAnimator setDuration(long duration) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setDuration(duration);
        }
        return this;
    }

    @Override
    public long getDuration() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getDuration();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setStartDelay(long startDelay) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setStartDelay(startDelay);
        }
        return this;
    }

    @Override
    public long getStartDelay() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            return n.getStartDelay();
        }
        return RETURN_WHEN_NULL;
    }

    @Override
    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.setInterpolator(interpolator);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            if (listener == null) {
                n.setListener(null);
            } else {
                n.setListener(new android.animation.Animator.AnimatorListener() {

                    @Override
                    public void onAnimationStart(android.animation.Animator animation) {
                        listener.onAnimationStart(null);
                    }

                    @Override
                    public void onAnimationRepeat(android.animation.Animator animation) {
                        listener.onAnimationRepeat(null);
                    }

                    @Override
                    public void onAnimationEnd(android.animation.Animator animation) {
                        listener.onAnimationEnd(null);
                    }

                    @Override
                    public void onAnimationCancel(android.animation.Animator animation) {
                        listener.onAnimationCancel(null);
                    }
                });
            }
        }
        return this;
    }

    @Override
    public void start() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.start();
        }
    }

    @Override
    public void cancel() {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.cancel();
        }
    }

    @Override
    public ViewPropertyAnimator x(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.x(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator xBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.xBy(value);
        }

    return this;
    }

    @Override
    public ViewPropertyAnimator y(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.y(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator yBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.yBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotation(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotation(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator rotationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.rotationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator translationYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.translationYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleX(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleX(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleXBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleXBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleY(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleY(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator scaleYBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.scaleYBy(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alpha(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alpha(value);
        }
        return this;
    }

    @Override
    public ViewPropertyAnimator alphaBy(float value) {
        android.view.ViewPropertyAnimator n = mNative.get();
        if (n != null) {
            n.alphaBy(value);
        }
        return this;
    }
}


package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

{
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();
        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }
        SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }
}


        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();

package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {

        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }
        SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }
}


int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }

package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();

        SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }
}


SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }

package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();
        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }


package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();
        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize

        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }
        SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }
}


for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }

package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();
        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();


package modern.challenge;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;

public class Main {

    privat

e static final Logger logger = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tT] [%4$-7s] %5$s %n");
        int noOfProcessors = Runtime.getRuntime().availableProcessors();
        logger.info(() -> "Available processors: " + noOfProcessors);
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        int initialPoolSize = forkJoinPool.getPoolSize();
        int commonPoolParallelism = ForkJoinPool.getCommonPoolParallelism();
        logger.info(() -> "Common Pool parallelism :" + commonPoolParallelism);
        logger.info(() -> "Common Pool size before:" + initialPoolSize);
        Random rnd = new Random();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            list.add(1 + rnd.nextInt(10));
        }
        SumRecursiveTask sumRecursiveTask = new SumRecursiveTask(list);
        Integer sumAll = forkJoinPool.invoke(sumRecursiveTask);
        logger.info(() -> "Final sum: " + sumAll);
        int afterPoolSize = forkJoinPool.getPoolSize();
        logger.info(() -> "Common Pool size after  :" + afterPoolSize);
    }
}


@Override
    public boolean isHotBackupEnabled()

package com.hazelcast.internal.hotrestart;

import com.hazelcast.hotrestart.HotRestartService;
import com.hazelcast.persistence.BackupTaskState;
import com.hazelcast.persistence.BackupTaskStatus;

/**
 * Empty implementation of HotRestartService to avoid null checks. This will provide default behaviour when hot restart is
 * not available or not enabled.
 */
public class NoOpHotRestartService implements HotRestartService {

    private static final BackupTaskStatus NO_TASK_BACKUP_STATUS = new BackupTaskStatus(BackupTaskState.NO_TASK, 0, 0);

    @Override
    public void backup() {
    }

    @Override
    public void backup(long backupSeq) {
    }

    @Override
    public BackupTaskStatus getBackupTaskStatus() {
        return NO_TASK_BACKUP_STATUS;
    }

    @Override
    public void interruptLocalBackupTask() {
    }

    @Override
    public void interruptBackupTask() {
    }

{
        return false;
    }

    @Override
    public boolean isBackupEnabled() {
        return false;
    }

    @Override
    public String getBackupDirectory() {
        return null;
    }
}


package com.hazelcast.internal.hotrestart;

import com.hazelcast.hotrestart.HotRestartService;
import com.hazelcast.persistence.BackupTaskState;
import com.hazelcast.persistence.BackupTaskStatus;

/**
 * Empty implementation of HotRestartService to avoid null checks. This will provide default behaviour when hot restart is
 * not available or not enabled.
 */
public class NoOpHotRestartService implements HotRestartService {

    private static final BackupTaskStatus NO_TASK_BACKUP_STATUS = new BackupTaskStatus(BackupTaskState.NO_TASK, 0, 0);

    @Override
    public void backup() {
    }

    @Override
    public void backup(long backupSeq) {
    }

    @Override
    public BackupTaskStatus getBackupTaskStatus() {
        return NO_TASK_BACKUP_STATUS;
    }

    @Override
    public void interruptLocalBackupTask()

    @Override
    public void interruptBackupTask() {
    }

    @Override
    public boolean isHotBackupEnabled() {
        return false;
    }

    @Override
    public boolean isBackupEnabled() {
        return false;
    }

    @Override
    public String getBackupDirectory() {
        return null;
    }
}


package com.hazelcast.internal.hotrestart;

import com.hazelcast.hotrestart.HotRestartService;
import com.hazelcast.persistence.BackupTaskState;
import com.hazelcast.persistence.BackupTaskStatus;

/**
 * Empty implementation of HotRestartService to avoid null checks. This will provide default behaviour when hot restart is
 * not available or not enabled.
 */
public class NoOpHotRestartService implements HotRestartService {

    private static final BackupTaskStatus NO_TASK_BACKUP_STATUS = new BackupTaskStatus(BackupTaskState.NO_TASK, 0, 0);

    @Override
    public void backup() {
    }

    @Override
    public void backup(long backupSeq) {
    }

    @Override
    public BackupTaskStatus getBackupTaskStatus() {
        return NO_TASK_BACKUP_STATUS;
    }

    @Override
    public void interruptLocalBackupTask() {
    }

    @Override
    public void interruptBackupTask() {
    }

    @Override
    public boolean isHotBackupEnabled() {

    }

    @Override
    public boolean isBackupEnabled() {
        return false;
    }

    @Override
    public String getBackupDirectory() {
        return null;
    }
}


package com.hazelcast.internal.hotrestart;

import com.hazelcast.hotrestart.HotRestartService;
import com.hazelcast.persistence.BackupTaskState;
import com.hazelcast.persistence.BackupTaskStatus;

/**
 * Empty implementation of HotRestartService to avoid null checks. This will provide default behaviour when hot restart is
 * not available or not enabled.
 */
public class NoOpHotRestartService implements HotRestartService {

    private static final BackupTaskStatus NO_TASK_BACKUP_STATUS = new BackupTaskStatus(BackupTaskState.NO_TASK, 0, 0);

    @Override
    public void backup() {
    }

    @Override
    public void backu

p(long backupSeq) {
    }

    @Override
    public BackupTaskStatus getBackupTaskStatus() {
        return NO_TASK_BACKUP_STATUS;
    }

    @Override
    public void interruptLocalBackupTask() {
    }

    @Override
    public void interruptBackupTask() {
    }

    @Override
    public boolean isHotBackupEnabled() {
        return false;
    }

    @Override
    public boolean isBackupEnabled() {
        return false;
    }

    @Override
    public String getBackupDirectory() {
        return null;
    }
}


<DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel)

package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

{
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();
        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction
        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


{
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv)

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();
        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction
        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();

package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {

        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction
        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction

package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();

        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


// first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();
        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();
        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository

        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction
        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}


package org.estatio.module.task.dom.policy;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import org.axonframework.eventhandling.annotation.EventHandler;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.DomainServiceLayout;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.services.metamodel.MetaModelService3;
import org.estatio.module.base.spiimpl.togglz.EstatioTogglzFeature;
import org.estatio.module.task.dom.state.State;
import org.estatio.module.task.dom.state.StateTransition;
import org.estatio.module.task.dom.state.StateTransitionService;
import org.estatio.module.task.dom.state.StateTransitionType;
import org.estatio.module.task.dom.task.Task;
import org.estatio.module.task.dom.task.Task_mixinActAbstract;
import org.estatio.module.task.dom.triggers.DomainObject_triggerAbstract;
import org.estatio.module.party.dom.Person;
import org.estatio.module.party.dom.PersonRepository;
import org.estatio.module.party.dom.role.PartyRole;
import org.estatio.module.party.dom.role.PartyRoleType;
import org.estatio.module.party.dom.role.PartyRoleTypeRepository;

@DomainService(nature = NatureOfService.DOMAIN)
@DomainServiceLayout(menuOrder = "1")
public class EnforceTaskAssignmentPolicySubscriber extends org.apache.isis.applib.AbstractSubscriber {

    public static interface WithStateTransitionClass {

        Class<?> getStateTransitionClass();
    }

    @EventHandler
    @Subscribe
    public void on(Task_mixinActAbstract.ActionDomainEvent ev) {
        if (ev.getSemantics().isSafeInNature()) {
            return;
        }
        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Task task = (Task) ev.getMixedIn();
        final StateTransition transition = stateTransitionService.findFor(task);
        if (transition == null) {
            // shouldn't occur
            return;
        }
        final Class taskTransitionClass = stateTransitionService.transitionClassFor(transition.getTransitionType());
        if (stateTransitionClass != taskTransitionClass) {
            // just ignore; this mixin action on task doesn't apply to the domain object that the task applies to.
            // or, maybe should hide (and then we can delete code in the subtypes of the mixinAbstract
            return;
        }
        final Object domainObject = transition.getDomainObject();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    @EventHandler
    @Subscribe
    public void on(DomainObject_triggerAbstract.ActionDomainEvent ev) {

        final Class stateTransitionClass = ev.getStateTransitionClass();
        final Object domainObject = ev.getMixedIn();
        applyPolicy(stateTransitionClass, domainObject, ev);
    }

    private void applyPolicy(final Class stateTransitionClass, final Object domainObject, final org.apache.isis.applib.services.eventbus.ActionDomainEvent<?> evv) {
        Optional<String> reasonIfAny = applyPolicy(stateTransitionClass, domainObject);
        reasonIfAny.ifPresent(evv::disable);
    }

    <DO, ST extends StateTransition<DO, ST, STT, S>, STT extends StateTransitionType<DO, ST, STT, S>, S extends State<S>> Optional<String> applyPolicy(final Class<ST> stateTransitionClass, final DO entityOrViewModel) {
        if (EstatioTogglzFeature.ApproveByProxy.isActive()) {
            return Optional.empty();
        }
        final DO entity = unwrapIfRequired(entityOrViewModel);
        final ST pendingTransition = stateTransitionService.pendingTransitionOf(entity, stateTransitionClass);
        if (pendingTransition == null) {
            return Optional.empty();
        }
        final Task task = pendingTransition.getTask();
        if (task == null) {
            return Optional.empty();
        }
        final Person meAsPerson = personRepository.me();
        if (meAsPerson == null) {
            return Optional.of("Could not locate Person for current user");
        }
        List<PartyRoleType> meAsPersonRoleTypes = Lists.newArrayList(meAsPerson.getRoles()).stream().map(PartyRole::getRoleType).collect(Collectors.toList());
        // // if meAsPerson is incoming invoice manager and was allowed to reject previous state, still allow for correction
        // first guard: meAsPerson always needs the PartyRoleType the task is assigned to
        if (!meAsPersonRoleTypes.contains(task.getAssignedTo())) {
            return Optional.of(String.format("Task assigned to '%s' role", task.getAssignedTo().getKey()));
        }
        // second guard: if the task is assigned to a specific person it needs to be meAsPerson
        final Person taskAssignedTo = task.getPersonAssignedTo();
        if (taskAssignedTo == null || taskAssignedTo == meAsPerson) {
            return Optional.empty();
        } else {
            return Optional.of(String.format("Task assigned to %s", taskAssignedTo.getReference()));
        }
    }

    private <DO> DO unwrapIfRequired(final DO entityOrViewModel) {
        final DO entity;
        if (entityOrViewModel instanceof ViewModelWrapper) {
            final ViewModelWrapper entityOrViewModel1 = (ViewModelWrapper) entityOrViewModel;
            entity = (DO) entityOrViewModel1.getDomainObject();
        } else {
            entity = entityOrViewModel;
        }
        return entity;
    }

    @Inject
    MetaModelService3 metaModelService3;

    @Inject
    StateTransitionService stateTransitionService;

    @Inject
    PersonRepository personRepository;

    @Inject
    PartyRoleTypeRepository partyRoleTypeRepository;
}