for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }

package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIsFrontCamera);
    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */

        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera() {
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */
    private void hidePictureTaken() {
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */
    private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }
        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}


package org.elasticsearch.xpack.core.ilm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.ilm.step.info.SingleMessageFieldInfo;
import java.time.Clock;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.xpack.core.ilm.LifecycleExecutionState.fromIndexMetadata;

/**
 * This step wraps an {@link ClusterStateWaitStep} in order to be able to manipulate what the next step will be, depending on the result of
 * the wrapped {@link ClusterStateWaitStep}.
 * <p>
 * If the action response is complete, the {@link ClusterStateWaitUntilThresholdStep}'s nextStepKey will be the nextStepKey of the
 * wrapped action. When the threshold level is surpassed, if the underlying step's condition was not met, the nextStepKey will be changed to
 * the provided {@link #nextKeyOnThresholdBreach} and this step will stop waiting.
 *
 * Failures encountered whilst executing the wrapped action will be propagated directly.
 */
public class ClusterStateWaitUntilThresholdStep extends ClusterStateWaitStep {

    private static final Logger logger = LogManager.getLogger(ClusterStateWaitUntilThresholdStep.class);

    private final ClusterStateWaitStep stepToExecute;

    private final StepKey nextKeyOnThresholdBreach;

    private final AtomicBoolean thresholdPassed = new AtomicBoolean(false);

    public ClusterStateWaitUntilThresholdStep(ClusterStateWaitStep stepToExecute, StepKey nextKeyOnThresholdBreach) {
        super(stepToExecute.getKey(), stepToExecute.getNextStepKey());
        this.stepToExecute = stepToExecute;
        this.nextKeyOnThresholdBreach = nextKeyOnThresholdBreach;
    }

    @Override
    public boolean isRetryable() {
        return true;
    }

    @Override
    public Result isConditionMet(Index index, ClusterState clusterState) {
        IndexMetadata idxMeta = clusterState.metadata().index(index);
        if (idxMeta == null) {
            // Index must have been since deleted, ignore it
            logger.debug("[{}] lifecycle action for index [{}] executed but index no longer exists", getKey().getAction(), index.getName());
            return new Result(false, null);
        }
        Result stepResult = stepToExecute.isConditionMet(index, clusterState);
        if (stepResult.isComplete() == false) {
            // checking the threshold after we execute the step to make sure we execute the wrapped step at least once (because time is a
            // wonderful thing)
            TimeValue retryThreshold = LifecycleSettings.LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING.get(idxMeta.getSettings());
            LifecycleExecutionState lifecycleState = fromIndexMetadata(idxMeta);
            if (stepToExecute.isCompletable() == false) {
                // we may not have passed the time threshold, but the step is not completable due to a different reason
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] Is not " + "completable, reason: [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), Strings.toString(stepResult.getInfomationContext()), nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
            if (waitedMoreThanThresholdLevel(retryThreshold, lifecycleState, Clock.systemUTC())) {
                // we retried this step enough, next step will be the configured to {@code nextKeyOnThresholdBreach}
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] executed for" + " more than [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), retryThreshold, nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
        }
        return stepResult;
    }

    static boolean waitedMoreThanThresholdLevel(@Nullable TimeValue retryThreshold, LifecycleExecutionState lifecycleState, Clock clock) {
        assert lifecycleState.getStepTime() != null : "lifecycle state [" + lifecycleState + "] does not have the step time set";
        if (retryThreshold != null) {
            // return true if the threshold was surpassed and false otherwise
            return (lifecycleState.getStepTime() + retryThreshold.millis()) < clock.millis();
        }
        return false;
    }

    @Override
    public StepKey getNextStepKey() {
        if (thresholdPassed.get()) {
            return nextKeyOnThresholdBreach;
        } else {
            return super.getNextStepKey();
        }
    }

    /**
     * Represents the {@link ClusterStateWaitStep} that's wrapped by this branching step.
     */

{
        return stepToExecute;
    }

    /**
     * The step key to be reported as the {@link ClusterStateWaitUntilThresholdStep#getNextStepKey()} if the index configured a max wait
     * time using {@link LifecycleSettings#LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING} and the threshold was passed.
     */
    StepKey getNextKeyOnThreshold() {
        return nextKeyOnThresholdBreach;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (super.equals(o) == false) {
            return false;
        }
        ClusterStateWaitUntilThresholdStep that = (ClusterStateWaitUntilThresholdStep) o;
        return super.equals(o) && Objects.equals(stepToExecute, that.stepToExecute) && Objects.equals(nextKeyOnThresholdBreach, that.nextKeyOnThresholdBreach);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), stepToExecute, nextKeyOnThresholdBreach);
    }
}


{
        assert lifecycleState.getStepTime() != null : "lifecycle state [" + lifecycleState + "] does not have the step time set";
        if (retryThreshold != null) {
            // return true if the threshold was surpassed and false otherwise
            return (lifecycleState.getStepTime() + retryThreshold.millis()) < clock.millis();
        }
        return false;
    }

package org.elasticsearch.xpack.core.ilm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.ilm.step.info.SingleMessageFieldInfo;
import java.time.Clock;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.xpack.core.ilm.LifecycleExecutionState.fromIndexMetadata;

/**
 * This step wraps an {@link ClusterStateWaitStep} in order to be able to manipulate what the next step will be, depending on the result of
 * the wrapped {@link ClusterStateWaitStep}.
 * <p>
 * If the action response is complete, the {@link ClusterStateWaitUntilThresholdStep}'s nextStepKey will be the nextStepKey of the
 * wrapped action. When the threshold level is surpassed, if the underlying step's condition was not met, the nextStepKey will be changed to
 * the provided {@link #nextKeyOnThresholdBreach} and this step will stop waiting.
 *
 * Failures encountered whilst executing the wrapped action will be propagated directly.
 */
public class ClusterStateWaitUntilThresholdStep extends ClusterStateWaitStep {

    private static final Logger logger = LogManager.getLogger(ClusterStateWaitUntilThresholdStep.class);

    private final ClusterStateWaitStep stepToExecute;

    private final StepKey nextKeyOnThresholdBreach;

    private final AtomicBoolean thresholdPassed = new AtomicBoolean(false);

    public ClusterStateWaitUntilThresholdStep(ClusterStateWaitStep stepToExecute, StepKey nextKeyOnThresholdBreach) {
        super(stepToExecute.getKey(), stepToExecute.getNextStepKey());
        this.stepToExecute = stepToExecute;
        this.nextKeyOnThresholdBreach = nextKeyOnThresholdBreach;
    }

    @Override
    public boolean isRetryable() {
        return true;
    }

    @Override
    public Result isConditionMet(Index index, ClusterState clusterState) {
        IndexMetadata idxMeta = clusterState.metadata().index(index);
        if (idxMeta == null) {
            // Index must have been since deleted, ignore it
            logger.debug("[{}] lifecycle action for index [{}] executed but index no longer exists", getKey().getAction(), index.getName());
            return new Result(false, null);
        }
        Result stepResult = stepToExecute.isConditionMet(index, clusterState);
        if (stepResult.isComplete() == false) {
            // checking the threshold after we execute the step to make sure we execute the wrapped step at least once (because time is a
            // wonderful thing)
            TimeValue retryThreshold = LifecycleSettings.LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING.get(idxMeta.getSettings());
            LifecycleExecutionState lifecycleState = fromIndexMetadata(idxMeta);
            if (stepToExecute.isCompletable() == false) {
                // we may not have passed the time threshold, but the step is not completable due to a different reason
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] Is not " + "completable, reason: [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), Strings.toString(stepResult.getInfomationContext()), nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
            if (waitedMoreThanThresholdLevel(retryThreshold, lifecycleState, Clock.systemUTC())) {
                // we retried this step enough, next step will be the configured to {@code nextKeyOnThresholdBreach}
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] executed for" + " more than [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), retryThreshold, nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
        }
        return stepResult;
    }

    static boolean waitedMoreThanThresholdLevel(@Nullable TimeValue retryThreshold, LifecycleExecutionState lifecycleState, Clock clock)

    @Override
    public StepKey getNextStepKey() {
        if (thresholdPassed.get()) {
            return nextKeyOnThresholdBreach;
        } else {
            return super.getNextStepKey();
        }
    }

    /**
     * Represents the {@link ClusterStateWaitStep} that's wrapped by this branching step.
     */
    ClusterStateWaitStep getStepToExecute() {
        return stepToExecute;
    }

    /**
     * The step key to be reported as the {@link ClusterStateWaitUntilThresholdStep#getNextStepKey()} if the index configured a max wait
     * time using {@link LifecycleSettings#LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING} and the threshold was passed.
     */
    StepKey getNextKeyOnThreshold() {
        return nextKeyOnThresholdBreach;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (super.equals(o) == false) {
            return false;
        }
        ClusterStateWaitUntilThresholdStep that = (ClusterStateWaitUntilThresholdStep) o;
        return super.equals(o) && Objects.equals(stepToExecute, that.stepToExecute) && Objects.equals(nextKeyOnThresholdBreach, that.nextKeyOnThresholdBreach);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), stepToExecute, nextKeyOnThresholdBreach);
    }
}


package org.elasticsearch.xpack.core.ilm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.ilm.step.info.SingleMessageFieldInfo;
import java.time.Clock;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.xpack.core.ilm.LifecycleExecutionState.fromIndexMetadata;

/**
 * This step wraps an {@link ClusterStateWaitStep} in order to be able to manipulate what the next step will be, depending on the result of
 * the wrapped {@link ClusterStateWaitStep}.
 * <p>
 * If the action response is complete, the {@link ClusterStateWaitUntilThresholdStep}'s nextStepKey will be the nextStepKey of the
 * wrapped action. When the threshold level is surpassed, if the underlying step's condition was not met, the nextStepKey will be changed to
 * the provided {@link #nextKeyOnThresholdBreach} and this step will stop waiting.
 *
 * Failures encountered whilst executing the wrapped action will be propagated directly.
 */
public class ClusterStateWaitUntilThresholdStep extends ClusterStateWaitStep {

    private static final Logger logger = LogManager.getLogger(ClusterStateWaitUntilThresholdStep.class);

    private final ClusterStateWaitStep stepToExecute;

    private final StepKey nextKeyOnThresholdBreach;

    private final AtomicBoolean thresholdPassed = new AtomicBoolean(false);

    public ClusterStateWaitUntilThresholdStep(ClusterStateWaitStep stepToExecute, StepKey nextKeyOnThresholdBreach) {
        super(stepToExecute.getKey(), stepToExecute.getNextStepKey());
        this.stepToExecute = stepToExecute;
        this.nextKeyOnThresholdBreach = nextKeyOnThresholdBreach;
    }

    @Override
    public boolean isRetryable() {
        return true;
    }

    @Override
    public Result isConditionMet(Index index, ClusterState clusterState) {
        IndexMetadata idxMeta = clusterState.metadata().index(index);
        if (idxMeta == null) {
            // Index must have been since deleted, ignore it
            logger.debug("[{}] lifecycle action for index [{}] executed but index no longer exists", getKey().getAction(), index.getName());
            return new Result(false, null);
        }
        Result stepResult = stepToExecute.isConditionMet(index, clusterState);
        if (stepResult.isComplete() == false) {
            // checking the threshold after we execute the step to make sure we execute the wrapped step at least once (because time is a
            // wonderful thing)
            TimeValue retryThreshold = LifecycleSettings.LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING.get(idxMeta.getSettings());
            LifecycleExecutionState lifecycleState = fromIndexMetadata(idxMeta);
            if (stepToExecute.isCompletable() == false) {
                // we may not have passed the time threshold, but the step is not completable due to a different reason
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] Is not " + "completable, reason: [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), Strings.toString(stepResult.getInfomationContext()), nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
            if (waitedMoreThanThresholdLevel(retryThreshold, lifecycleState, Clock.systemUTC())) {
                // we retried this step enough, next step will be the configured to {@code nextKeyOnThresholdBreach}
                thresholdPassed.set(true);
                String message = String.format(Locale.ROOT, "[%s] lifecycle step, as part of [%s] action, for index [%s] executed for" + " more than [%s]. Abandoning execution and moving to the next fallback step [%s]", getKey().getName(), getKey().getAction(), idxMeta.getIndex().getName(), retryThreshold, nextKeyOnThresholdBreach);
                logger.debug(message);
                return new Result(true, new SingleMessageFieldInfo(message));
            }
        }
        return stepResult;
    }

    static boolean waitedMoreThanThresholdLevel(@Nullable TimeValue retryThreshold, LifecycleExecutionState lifecycleState, Clock clock) {
        assert lifecycleState.getStepTime() != null : "lifecycle state [" + lifecycleState + "] does not have the step time set";
        if (retryThreshold != null) {
            // return true if the threshold was surpassed and false otherwise
            return (lifecycleState.getStepTime() + retryThreshold.millis()) < clock.millis();
        }
        return false;
    }

    @Override
    public StepKey getNextStepKey() {
        if (thresholdPassed.get()) {
            return nextKeyOnThresholdBreach;
        } else {
            return super.getNextStepKey();
        }
    }

    /**
     * Represents the {@link ClusterStateWaitStep} that's wrapped by this branching step.
     */
    ClusterStateWaitStep getStepToExecute() {
        return stepToExecute;
    }

    /**
     * The step key to be reported as the {@link ClusterStateWaitUntilThresholdStep#getNextStepKey()} if the index configured a max wait
     * time using {@link LifecycleSettings#LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING} and the threshold was passed.
     */
    StepKey getNextKeyOnThreshold() {
        return nextKeyOnThresholdBreach;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (super.equals(o) == false) {
            return false;
        }
        ClusterStateWaitUntilThresholdStep that = (ClusterStateWaitUntilThresholdStep) o;
        return super.equals(o) && Objects.equals(stepToExecute, that.stepToExecute) && Objects.equals(nextKeyOnThresholdBreach, that.nextKeyOnThresholdBreach);
    }

    @Override
    public int hashCode() {
        return Objects.hash


ClusterStateWaitStep getStepToExecute() {
        return stepToExecute;
    }

    /**
     * The step key to be reported as the {@link ClusterStateWaitUntilThresholdStep#getNextStepKey()} if the index configured a max wait
     * time using {@link LifecycleSettings#LIFECYCLE_STEP_WAIT_TIME_THRESHOLD_SETTING} and the threshold was passed.
     */
    StepKey getNextKeyOnThreshold() {
        return nextKeyOnThresholdBreach;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (super.equals(o) == false) {
            return false;
        }
        ClusterStateWaitUntilThresholdStep that = (ClusterStateWaitUntilThresholdStep) o;
        return super.equals(o) && Objects.equals(stepToExecute, that.stepToExecute) && Objects.equals(nextKeyOnThresholdBreach, that.nextKeyOnThresholdBreach);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), stepToExecute, nextKeyOnThresholdBreach);
    }
}


@Override
    public void renderInner(ServletMessage message, String defaultMessage)

package cn.ymotel.dactor.async.web.view;

import cn.ymotel.dactor.message.ServletMessage;
import java.io.File;

public class DownloadView extends StreamView {

    public static String FILE_NAME = "_FileName";

    public static String getFILE_NAME() {
        return FILE_NAME;
    }

{
        String fileName = "";
        if (message.getContext().containsKey(FILE_NAME)) {
            fileName = (String) message.getContext().get(FILE_NAME);
        } else {
            Object obj = message.getContext().get(this.getContent());
            if (obj instanceof File) {
                fileName = ((File) obj).getName();
            }
        }
        message.getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
        super.renderInner(message, defaultMessage);
    }
}


package cn.ymotel.dactor.async.web.view;

import cn.ymotel.dactor.message.ServletMessage;
import java.io.File;

public class DownloadView extends StreamView {

    public static String FILE_NAME = "_FileName";

    public static String getFILE_NAME()

    @Override
    public void renderInner(ServletMessage message, String defaultMessage) {
        String fileName = "";
        if (message.getContext().containsKey(FILE_NAME)) {
            fileName = (String) message.getContext().get(FILE_NAME);
        } else {
            Object obj = message.getContext().get(this.getContent());
            if (obj instanceof File) {
                fileName = ((File) obj).getName();
            }
        }
        message.getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
        super.renderInner(message, defaultMessage);
    }
}


package cn.ymotel.dactor.async.web.view;

import cn.ymotel.dactor.message.ServletMessage;
import java.io.File;

public class DownloadView extends StreamView {

    public static String FILE_NAME = "_FileName";

    public static String getFILE_NAME() {
        return FILE_NAME;
    }

    @Override
    public void renderInner(ServletMessage message, String defaultMessage) {
        String fileName = "";
        if (message.getContext().containsKey(FILE_NAME)) {
            fileName = (String) message.getContext().get(FILE_NAME);
        } else {
            Object obj = message.getContext().get(this.getContent());
            if (obj instanceof File) {
                fileName = ((File) obj).getName();
            }
        }
        message.getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
        super.renderInner(


@Override
    public String selectConfigByKey(String configKey)

package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
public class SysConfigServiceImpl implements ISysConfigService {

    @Autowired
    private SysConfigMapper configMapper;

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId) {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */

{
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : "";
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return configMapper.selectConfigList(config);
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        return configMapper.insertConfig(config);
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        return configMapper.updateConfig(config);
    }

    /**
     * 批量删除参数配置对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteConfigByIds(String ids) {
        return configMapper.deleteConfigByIds(Convert.toStrArray(ids));
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.CONFIG_KEY_NOT_UNIQUE;
        }
        return UserConstants.CONFIG_KEY_UNIQUE;
    }
}


{
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }

package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
public class SysConfigServiceImpl implements ISysConfigService {

    @Autowired
    private SysConfigMapper configMapper;

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId)

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey) {
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : "";
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return configMapper.selectConfigList(config);
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        return configMapper.insertConfig(config);
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        return configMapper.updateConfig(config);
    }

    /**
     * 批量删除参数配置对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteConfigByIds(String ids) {
        return configMapper.deleteConfigByIds(Convert.toStrArray(ids));
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.CONFIG_KEY_NOT_UNIQUE;
        }
        return UserConstants.CONFIG_KEY_UNIQUE;
    }
}


package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
public class SysConfigServiceImpl implements ISysConfigService {

    @Autowired
    private SysConfigMapper configMapper;

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId) {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey) {
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : "";
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return configMapper.selectConfigList(config);
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        return configMapper.insertConfig(config);
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        return configMapper.updateConfig(config);
    }

    /**
     * 批量删除参数配置对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteConfigByIds(String ids) {
        return configMapper.deleteConfigByIds(Convert.toStrArray(ids));
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.CONFIG_KEY_NOT_UNIQUE;
        }
        return UserConstants.CONFIG_KEY_UNIQU


@Override
    public int deleteConfigByIds(String ids) {
        return configMapper.deleteConfigByIds(Convert.toStrArray(ids));
    }

package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
public class SysConfigServiceImpl implements ISysConfigService {

    @Autowired
    private SysConfigMapper configMapper;

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId) {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey) {
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : "";
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return configMapper.selectConfigList(config);
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        return configMapper.insertConfig(config);
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        return configMapper.updateConfig(config);
    }

    /**
     * 批量删除参数配置对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.CONFIG_KEY_NOT_UNIQUE;
        }
        return UserConstants.CONFIG_KEY_UNIQUE;
    }
}


@Override
    public Expression optimize(ServerSession session)

/*
 * Initial Developer: H2 Group
 */
package org.lealone.sql.expression.subquery;

import java.util.ArrayList;
import org.lealone.common.exceptions.DbException;
import org.lealone.db.api.ErrorCode;
import org.lealone.db.result.Result;
import org.lealone.db.session.ServerSession;
import org.lealone.db.value.Value;
import org.lealone.db.value.ValueArray;
import org.lealone.db.value.ValueNull;
import org.lealone.sql.expression.Expression;
import org.lealone.sql.expression.ExpressionList;
import org.lealone.sql.expression.visitor.ExpressionVisitor;
import org.lealone.sql.query.Query;

/**
 * A query returning a single value.
 * Subqueries are used inside other statements.
 *
 * @author H2 Group
 * @author zhh
 */
public class SubQuery extends Expression {

    private final Query query;

    private Expression expression;

    public SubQuery(Query query) {
        this.query = query;
    }

    @Override
    public Value getValue(ServerSession session) {
        query.setSession(session);
        Result result = query.query(2);
        try {
            int rowcount = result.getRowCount();
            if (rowcount > 1) {
                throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW);
            }
            Value v;
            if (rowcount <= 0) {
                v = ValueNull.INSTANCE;
            } else {
                result.next();
                Value[] values = result.currentRow();
                if (result.getVisibleColumnCount() == 1) {
                    v = values[0];
                } else {
                    v = ValueArray.get(values);
                }
            }
            return v;
        } finally {
            result.close();
        }
    }

    @Override
    public int getType() {
        return getExpression().getType();
    }

{
        query.prepare();
        return this;
    }

    @Override
    public int getScale() {
        return getExpression().getScale();
    }

    @Override
    public long getPrecision() {
        return getExpression().getPrecision();
    }

    @Override
    public int getDisplaySize() {
        return getExpression().getDisplaySize();
    }

    @Override
    public String getSQL(boolean isDistributed) {
        return "(" + query.getPlanSQL() + ")";
    }

    private Expression getExpression() {
        if (expression == null) {
            ArrayList<Expression> expressions = query.getExpressions();
            int columnCount = query.getColumnCount();
            if (columnCount == 1) {
                expression = expressions.get(0);
            } else {
                Expression[] list = new Expression[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    list[i] = expressions.get(i);
                }
                expression = new ExpressionList(list);
            }
        }
        return expression;
    }

    public Query getQuery() {
        return query;
    }

    @Override
    public int getCost() {
        return query.getCostAsExpression();
    }

    @Override
    public Expression[] getExpressionColumns(ServerSession session) {
        return getExpression().getExpressionColumns(session);
    }

    @Override
    public <R> R accept(ExpressionVisitor<R> visitor) {
        return visitor.visitSubQuery(this);
    }
}


{
        return "(" + query.getPlanSQL() + ")";
    }

/*
 * Initial Developer: H2 Group
 */
package org.lealone.sql.expression.subquery;

import java.util.ArrayList;
import org.lealone.common.exceptions.DbException;
import org.lealone.db.api.ErrorCode;
import org.lealone.db.result.Result;
import org.lealone.db.session.ServerSession;
import org.lealone.db.value.Value;
import org.lealone.db.value.ValueArray;
import org.lealone.db.value.ValueNull;
import org.lealone.sql.expression.Expression;
import org.lealone.sql.expression.ExpressionList;
import org.lealone.sql.expression.visitor.ExpressionVisitor;
import org.lealone.sql.query.Query;

/**
 * A query returning a single value.
 * Subqueries are used inside other statements.
 *
 * @author H2 Group
 * @author zhh
 */
public class SubQuery extends Expression {

    private final Query query;

    private Expression expression;

    public SubQuery(Query query) {
        this.query = query;
    }

    @Override
    public Value getValue(ServerSession session) {
        query.setSession(session);
        Result result = query.query(2);
        try {
            int rowcount = result.getRowCount();
            if (rowcount > 1) {
                throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW);
            }
            Value v;
            if (rowcount <= 0) {
                v = ValueNull.INSTANCE;
            } else {
                result.next();
                Value[] values = result.currentRow();
                if (result.getVisibleColumnCount() == 1) {
                    v = values[0];
                } else {
                    v = ValueArray.get(values);
                }
            }
            return v;
        } finally {
            result.close();
        }
    }

    @Override
    public int getType() {
        return getExpression().getType();
    }

    @Override
    public Expression optimize(ServerSession session) {
        query.prepare();
        return this;
    }

    @Override
    public int getScale() {
        return getExpression().getScale();
    }

    @Override
    public long getPrecision() {
        return getExpression().getPrecision();
    }

    @Override
    public int getDisplaySize() {
        return getExpression().getDisplaySize();
    }

    @Override
    public String getSQL(boolean isDistributed)

    private Expression getExpression() {
        if (expression == null) {
            ArrayList<Expression> expressions = query.getExpressions();
            int columnCount = query.getColumnCount();
            if (columnCount == 1) {
                expression = expressions.get(0);
            } else {
                Expression[] list = new Expression[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    list[i] = expressions.get(i);
                }
                expression = new ExpressionList(list);
            }
        }
        return expression;
    }

    public Query getQuery() {
        return query;
    }

    @Override
    public int getCost() {
        return query.getCostAsExpression();
    }

    @Override
    public Expression[] getExpressionColumns(ServerSession session) {
        return getExpression().getExpressionColumns(session);
    }

    @Override
    public <R> R accept(ExpressionVisitor<R> visitor) {
        return visitor.visitSubQuery(this);
    }
}


/*
 * Initial Developer: H2 Group
 */
package org.lealone.sql.expression.subquery;

import java.util.ArrayList;
import org.lealone.common.exceptions.DbException;
import org.lealone.db.api.ErrorCode;
import org.lealone.db.result.Result;
import org.lealone.db.session.ServerSession;
import org.lealone.db.value.Value;
import org.lealone.db.value.ValueArray;
import org.lealone.db.value.ValueNull;
import org.lealone.sql.expression.Expression;
import org.lealone.sql.expression.ExpressionList;
import org.lealone.sql.expression.visitor.ExpressionVisitor;
import org.lealone.sql.query.Query;

/**
 * A query returning a single value.
 * Subqueries are used inside other statements.
 *
 * @author H2 Group
 * @author zhh
 */
public class SubQuery extends Expression {

    private final Query query;

    private Expression expression;

    public SubQuery(Query query) {
        this.query = query;
    }

    @Override
    public Value getValue(ServerSession session) {
        query.setSession(session);
        Result result = query.query(2);
        try {
            int rowcount = result.getRowCount();
            if (rowcount > 1) {
                throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW);
            }
            Value v;
            if (rowcount <= 0) {
                v = ValueNull.INSTANCE;
            } else {
                result.next();
                Value[] values = result.currentRow();
                if (result.getVisibleColumnCount() == 1) {
                    v = values[0];
                } else {
                    v = ValueArray.get(values);
                }
            }
            return v;
        } finally {
            result.close();
        }
    }

    @Override
    public int getType() {
        retur

    }

    @Override
    public Expression optimize(ServerSession session) {
        query.prepare();
        return this;
    }

    @Override
    public int getScale() {
        return getExpression().getScale();
    }

    @Override
    public long getPrecision() {
        return getExpression().getPrecision();
    }

    @Override
    public int getDisplaySize() {
        return getExpression().getDisplaySize();
    }

    @Override
    public String getSQL(boolean isDistributed) {
        return "(" + query.getPlanSQL() + ")";
    }

    private Expression getExpression() {
        if (expression == null) {
            ArrayList<Expression> expressions = query.getExpressions();
            int columnCount = query.getColumnCount();
            if (columnCount == 1) {
                expression = expressions.get(0);
            } else {
                Expression[] list = new Expression[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    list[i] = expressions.get(i);
                }
                expression = new ExpressionList(list);
            }
        }
        return expression;
    }

    public Query getQuery() {
        return query;
    }

    @Override
    public int getCost() {
        return query.getCostAsExpression();
    }

    @Override
    public Expression[] getExpressionColumns(ServerSession session) {
        return getExpression().getExpressionColumns(session);
    }

    @Override
    public <R> R accept(ExpressionVisitor<R> visitor) {
        return visitor.visitSubQuery(this);
    }
}


for (int i = 0; i < columnCount; i++) {
                    list[i] = expressions.get(i);
                }

/*
 * Initial Developer: H2 Group
 */
package org.lealone.sql.expression.subquery;

import java.util.ArrayList;
import org.lealone.common.exceptions.DbException;
import org.lealone.db.api.ErrorCode;
import org.lealone.db.result.Result;
import org.lealone.db.session.ServerSession;
import org.lealone.db.value.Value;
import org.lealone.db.value.ValueArray;
import org.lealone.db.value.ValueNull;
import org.lealone.sql.expression.Expression;
import org.lealone.sql.expression.ExpressionList;
import org.lealone.sql.expression.visitor.ExpressionVisitor;
import org.lealone.sql.query.Query;

/**
 * A query returning a single value.
 * Subqueries are used inside other statements.
 *
 * @author H2 Group
 * @author zhh
 */
public class SubQuery extends Expression {

    private final Query query;

    private Expression expression;

    public SubQuery(Query query) {
        this.query = query;
    }

    @Override
    public Value getValue(ServerSession session) {
        query.setSession(session);
        Result result = query.query(2);
        try {
            int rowcount = result.getRowCount();
            if (rowcount > 1) {
                throw DbException.get(ErrorCode.SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW);
            }
            Value v;
            if (rowcount <= 0) {
                v = ValueNull.INSTANCE;
            } else {
                result.next();
                Value[] values = result.currentRow();
                if (result.getVisibleColumnCount() == 1) {
                    v = values[0];
                } else {
                    v = ValueArray.get(values);
                }
            }
            return v;
        } finally {
            result.close();
        }
    }

    @Override
    public int getType() {
        return getExpression().getType();
    }

    @Override
    public Expression optimize(ServerSession session) {
        query.prepare();
        return this;
    }

    @Override
    public int getScale() {
        return getExpression().getScale();
    }

    @Override
    public long getPrecision() {
        return getExpression().getPrecision();
    }

    @Override
    public int getDisplaySize() {
        return getExpression().getDisplaySize();
    }

    @Override
    public String getSQL(boolean isDistributed) {
        return "(" + query.getPlanSQL() + ")";
    }

    private Expression getExpression() {
        if (expression == null) {
            ArrayList<Expression> expressions = query.getExpressions();
            int columnCount = query.getColumnCount();
            if (columnCount == 1) {
                expression = expressions.get(0);
            } else {
                Expression[] list = new Expression[columnCount];

                expression = new ExpressionList(list);
            }
        }
        return expression;
    }

    public Query getQuery() {
        return query;
    }

    @Override
    public int getCost() {
        return query.getCostAsExpression();
    }

    @Override
    public Expression[] getExpressionColumns(ServerSession session) {
        return getExpression().getExpressionColumns(session);
    }

    @Override
    public <R> R accept(ExpressionVisitor<R> visitor) {
        return visitor.visitSubQuery(this);
    }
}


package com.aliyuncs.hbr.model.v20170908;

import com.aliyuncs.AcsResponse;
import com.aliyuncs.hbr.transform.v20170908.UpdateVmClientFlowControlPolicyResponseUnmarshaller;
import com.aliyuncs.transform.UnmarshallerContext;

/**
 * @author auto create
 * @version
 */
public class UpdateVmClientFlowControlPolicyResponse extends AcsResponse {

    private String requestId;

    private Boolean success;

    private String code;

    private String message;

    public String getRequestId() {
        return this.requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public Boolean getSuccess() {
        return this.success;
    }

{
        this.success = success;
    }

    public String getCode() {
        return this.code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public UpdateVmClientFlowControlPolicyResponse getInstance(UnmarshallerContext context) {
        return UpdateVmClientFlowControlPolicyResponseUnmarshaller.unmarshall(this, context);
    }

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


package com.aliyuncs.hbr.model.v20170908;

import com.aliyuncs.AcsResponse;
import com.aliyuncs.hbr.transform.v20170908.UpdateVmClientFlowControlPolicyResponseUnmarshaller;
import com.aliyuncs.transform.UnmarshallerContext;

/**
 * @author auto create
 * @version
 */
public class UpdateVmClientFlowControlPolicyResponse extends AcsResponse {

    private String requestId;

    private Boolean success;

    private String code;

    private String message;

    public String getRequestId() {
        return this.requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public Boolean getSuccess() {
        return this.success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getCode() {
        return this.code;
    }

    public void setCode(String code)

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public UpdateVmClientFlowControlPolicyResponse getInstance(UnmarshallerContext context) {
        return UpdateVmClientFlowControlPolicyResponseUnmarshaller.unmarshall(this, context);
    }

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


package com.aliyuncs.hbr.model.v20170908;

import com.aliyuncs.AcsResponse;
import com.aliyuncs.hbr.transform.v20170908.UpdateVmClientFlowControlPolicyResponseUnmarshaller;
import com.aliyuncs.transform.UnmarshallerContext;

/**
 * @author auto create
 * @version
 */
public class UpdateVmClientFlowControlPolicyResponse extends AcsResponse {

    private String requestId;

    private Boolean success;

    private String code;

    private String message;

    public String getRequestId() {
        return this.requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public Boolean getSuccess() {
        return this.success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getCode() {
        return

    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public UpdateVmClientFlowControlPolicyResponse getInstance(UnmarshallerContext context) {
        return UpdateVmClientFlowControlPolicyResponseUnmarshaller.unmarshall(this, context);
    }

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


@Override
    public ClientResponse process(ClientConnectionContext ctx)

package org.apache.ignite.internal.processors.platform.client.cache;

import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
import org.apache.ignite.internal.processors.platform.client.ClientRequest;
import org.apache.ignite.internal.processors.platform.client.ClientResponse;

/**
 * Cache destroy request.
 */
public class ClientCacheDestroyRequest extends ClientRequest {

    /**
     * Cache ID.
     */
    private final int cacheId;

    /**
     * Constructor.
     *
     * @param reader Reader.
     */
    public ClientCacheDestroyRequest(BinaryRawReader reader) {
        super(reader);
        cacheId = reader.readInt();
    }

{
        String cacheName = ClientCacheRequest.cacheDescriptor(ctx, cacheId).cacheName();
        ctx.kernalContext().grid().destroyCache(cacheName);
        return super.process(ctx);
    }
}


{
        String cacheName = ClientCacheRequest.cacheDescriptor(ctx, cacheId).cacheName();
        ctx.kernalContext().grid().destroyCache(cacheName);
        return super.process(ctx);
    }

package org.apache.ignite.internal.processors.platform.client.cache;

import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
import org.apache.ignite.internal.processors.platform.client.ClientRequest;
import org.apache.ignite.internal.processors.platform.client.ClientResponse;

/**
 * Cache destroy request.
 */
public class ClientCacheDestroyRequest extends ClientRequest {

    /**
     * Cache ID.
     */
    private final int cacheId;

    /**
     * Constructor.
     *
     * @param reader Reader.
     */
    public ClientCacheDestroyRequest(BinaryRawReader reader) {
        super(reader);
        cacheId = reader.readInt();
    }

    @Override
    public ClientResponse process(ClientConnectionContext ctx)


String cacheName = ClientCacheRequest.cacheDescriptor(ctx, cacheId).cacheName();

package org.apache.ignite.internal.processors.platform.client.cache;

import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
import org.apache.ignite.internal.processors.platform.client.ClientRequest;
import org.apache.ignite.internal.processors.platform.client.ClientResponse;

/**
 * Cache destroy request.
 */
public class ClientCacheDestroyRequest extends ClientRequest {

    /**
     * Cache ID.
     */
    private final int cacheId;

    /**
     * Constructor.
     *
     * @param reader Reader.
     */
    public ClientCacheDestroyRequest(BinaryRawReader reader) {
        super(reader);
        cacheId = reader.readInt();
    }

    @Override
    public ClientResponse process(ClientConnectionContext ctx) {

        ctx.kernalContext().grid().destroyCache(cacheName);
        return super.process(ctx);
    }
}


package com.tencentcloudapi.apigateway.v20180808.models;

import com.tencentcloudapi.common.AbstractModel;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import java.util.HashMap;

public class Environment extends AbstractModel {

    /**
     * 环境名称。
     */
    @SerializedName("EnvironmentName")
    @Expose
    private String EnvironmentName;

    /**
     * 访问路径。
     */
    @SerializedName("Url")
    @Expose
    private String Url;

    /**
     * 发布状态，1 表示已发布，0 表示未发布。
     */
    @SerializedName("Status")
    @Expose
    private Long Status;

    /**
     * 运行版本。
     */
    @SerializedName("VersionName")
    @Expose
    private String VersionName;

    /**
     * Get 环境名称。
     * @return EnvironmentName 环境名称。
     */
    public String getEnvironmentName() {
        return this.EnvironmentName;
    }

    /**
     * Set 环境名称。
     * @param EnvironmentName 环境名称。
     */
    public void setEnvironmentName(String EnvironmentName) {
        this.EnvironmentName = EnvironmentName;
    }

    /**
     * Get 访问路径。
     * @return Url 访问路径。
     */
    public String getUrl() {
        return this.Url;
    }

    /**
     * Set 访问路径。
     * @param Url 访问路径。
     */
    public void setUrl(String Url) {
        this.Url = Url;
    }

    /**
     * Get 发布状态，1 表示已发布，0 表示未发布。
     * @return Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public Long getStatus() {
        return this.Status;
    }

    /**
     * Set 发布状态，1 表示已发布，0 表示未发布。
     * @param Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public void setStatus(Long Status) {
        this.Status = Status;
    }

    /**
     * Get 运行版本。
     * @return VersionName 运行版本。
     */

{
        return this.VersionName;
    }

    /**
     * Set 运行版本。
     * @param VersionName 运行版本。
     */
    public void setVersionName(String VersionName) {
        this.VersionName = VersionName;
    }

    public Environment() {
    }

    /**
     * NOTE: Any ambiguous key set via .set("AnyKey", "value") will be a shallow copy,
     *       and any explicit key, i.e Foo, set via .setFoo("value") will be a deep copy.
     */
    public Environment(Environment source) {
        if (source.EnvironmentName != null) {
            this.EnvironmentName = new String(source.EnvironmentName);
        }
        if (source.Url != null) {
            this.Url = new String(source.Url);
        }
        if (source.Status != null) {
            this.Status = new Long(source.Status);
        }
        if (source.VersionName != null) {
            this.VersionName = new String(source.VersionName);
        }
    }

    /**
     * Internal implementation, normal users should not use it.
     */
    public void toMap(HashMap<String, String> map, String prefix) {
        this.setParamSimple(map, prefix + "EnvironmentName", this.EnvironmentName);
        this.setParamSimple(map, prefix + "Url", this.Url);
        this.setParamSimple(map, prefix + "Status", this.Status);
        this.setParamSimple(map, prefix + "VersionName", this.VersionName);
    }
}


package com.tencentcloudapi.apigateway.v20180808.models;

import com.tencentcloudapi.common.AbstractModel;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import java.util.HashMap;

public class Environment extends AbstractModel {

    /**
     * 环境名称。
     */
    @SerializedName("EnvironmentName")
    @Expose
    private String EnvironmentName;

    /**
     * 访问路径。
     */
    @SerializedName("Url")
    @Expose
    private String Url;

    /**
     * 发布状态，1 表示已发布，0 表示未发布。
     */
    @SerializedName("Status")
    @Expose
    private Long Status;

    /**
     * 运行版本。
     */
    @SerializedName("VersionName")
    @Expose
    private String VersionName;

    /**
     * Get 环境名称。
     * @return EnvironmentName 环境名称。
     */
    public String getEnvironmentName() {
        return this.EnvironmentName;
    }

    /**
     * Set 环境名称。
     * @param EnvironmentName 环境名称。
     */
    public void setEnvironmentName(String EnvironmentName) {
        this.EnvironmentName = EnvironmentName;
    }

    /**
     * Get 访问路径。
     * @return Url 访问路径。
     */
    public String getUrl() {
        return this.Url;
    }

    /**
     * Set 访问路径。
     * @param Url 访问路径。
     */
    public void setUrl(String Url)

    /**
     * Get 发布状态，1 表示已发布，0 表示未发布。
     * @return Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public Long getStatus() {
        return this.Status;
    }

    /**
     * Set 发布状态，1 表示已发布，0 表示未发布。
     * @param Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public void setStatus(Long Status) {
        this.Status = Status;
    }

    /**
     * Get 运行版本。
     * @return VersionName 运行版本。
     */
    public String getVersionName() {
        return this.VersionName;
    }

    /**
     * Set 运行版本。
     * @param VersionName 运行版本。
     */
    public void setVersionName(String VersionName) {
        this.VersionName = VersionName;
    }

    public Environment() {
    }

    /**
     * NOTE: Any ambiguous key set via .set("AnyKey", "value") will be a shallow copy,
     *       and any explicit key, i.e Foo, set via .setFoo("value") will be a deep copy.
     */
    public Environment(Environment source) {
        if (source.EnvironmentName != null) {
            this.EnvironmentName = new String(source.EnvironmentName);
        }
        if (source.Url != null) {
            this.Url = new String(source.Url);
        }
        if (source.Status != null) {
            this.Status = new Long(source.Status);
        }
        if (source.VersionName != null) {
            this.VersionName = new String(source.VersionName);
        }
    }

    /**
     * Internal implementation, normal users should not use it.
     */
    public void toMap(HashMap<String, String> map, String prefix) {
        this.setParamSimple(map, prefix + "EnvironmentName", this.EnvironmentName);
        this.setParamSimple(map, prefix + "Url", this.Url);
        this.setParamSimple(map, prefix + "Status", this.Status);
        this.setParamSimple(map, prefix + "VersionName", this.VersionName);
    }
}


package com.tencentcloudapi.apigateway.v20180808.models;

import com.tencentcloudapi.common.AbstractModel;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import java.util.HashMap;

public class Environment extends AbstractModel {

    /**
     * 环境名称。
     */
    @SerializedName("EnvironmentName")
    @Expose
    private String EnvironmentName;

    /**
     * 访问路径。
     */
    @SerializedName("Url")
    @Expose
    private String Url;

    /**
     * 发布状态，1 表示已发布，0 表示未发布。
     */
    @SerializedName("Status")
    @Expose
    private Long Status;

    /**
     * 运行版本。
     */
    @SerializedName("VersionName")
    @Expose
    private String VersionName;

    /**
     * Get 环境名称。
     * @return EnvironmentName 环境名称。
     */
    public String getEnvironmentName() {
        return this.En

    }

    /**
     * Set 环境名称。
     * @param EnvironmentName 环境名称。
     */
    public void setEnvironmentName(String EnvironmentName) {
        this.EnvironmentName = EnvironmentName;
    }

    /**
     * Get 访问路径。
     * @return Url 访问路径。
     */
    public String getUrl() {
        return this.Url;
    }

    /**
     * Set 访问路径。
     * @param Url 访问路径。
     */
    public void setUrl(String Url) {
        this.Url = Url;
    }

    /**
     * Get 发布状态，1 表示已发布，0 表示未发布。
     * @return Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public Long getStatus() {
        return this.Status;
    }

    /**
     * Set 发布状态，1 表示已发布，0 表示未发布。
     * @param Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public void setStatus(Long Status) {
        this.Status = Status;
    }

    /**
     * Get 运行版本。
     * @return VersionName 运行版本。
     */
    public String getVersionName() {
        return this.VersionName;
    }

    /**
     * Set 运行版本。
     * @param VersionName 运行版本。
     */
    public void setVersionName(String VersionName) {
        this.VersionName = VersionName;
    }

    public Environment() {
    }

    /**
     * NOTE: Any ambiguous key set via .set("AnyKey", "value") will be a shallow copy,
     *       and any explicit key, i.e Foo, set via .setFoo("value") will be a deep copy.
     */
    public Environment(Environment source) {
        if (source.EnvironmentName != null) {
            this.EnvironmentName = new String(source.EnvironmentName);
        }
        if (source.Url != null) {
            this.Url = new String(source.Url);
        }
        if (source.Status != null) {
            this.Status = new Long(source.Status);
        }
        if (source.VersionName != null) {
            this.VersionName = new String(source.VersionName);
        }
    }

    /**
     * Internal implementation, normal users should not use it.
     */
    public void toMap(HashMap<String, String> map, String prefix) {
        this.setParamSimple(map, prefix + "EnvironmentName", this.EnvironmentName);
        this.setParamSimple(map, prefix + "Url", this.Url);
        this.setParamSimple(map, prefix + "Status", this.Status);
        this.setParamSimple(map, prefix + "VersionName", this.VersionName);
    }
}


public String getEnvironmentName() {
        return this.EnvironmentName;
    }

package com.tencentcloudapi.apigateway.v20180808.models;

import com.tencentcloudapi.common.AbstractModel;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import java.util.HashMap;

public class Environment extends AbstractModel {

    /**
     * 环境名称。
     */
    @SerializedName("EnvironmentName")
    @Expose
    private String EnvironmentName;

    /**
     * 访问路径。
     */
    @SerializedName("Url")
    @Expose
    private String Url;

    /**
     * 发布状态，1 表示已发布，0 表示未发布。
     */
    @SerializedName("Status")
    @Expose
    private Long Status;

    /**
     * 运行版本。
     */
    @SerializedName("VersionName")
    @Expose
    private String VersionName;

    /**
     * Get 环境名称。
     * @return EnvironmentName 环境名称。
     */

    /**
     * Set 环境名称。
     * @param EnvironmentName 环境名称。
     */
    public void setEnvironmentName(String EnvironmentName) {
        this.EnvironmentName = EnvironmentName;
    }

    /**
     * Get 访问路径。
     * @return Url 访问路径。
     */
    public String getUrl() {
        return this.Url;
    }

    /**
     * Set 访问路径。
     * @param Url 访问路径。
     */
    public void setUrl(String Url) {
        this.Url = Url;
    }

    /**
     * Get 发布状态，1 表示已发布，0 表示未发布。
     * @return Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public Long getStatus() {
        return this.Status;
    }

    /**
     * Set 发布状态，1 表示已发布，0 表示未发布。
     * @param Status 发布状态，1 表示已发布，0 表示未发布。
     */
    public void setStatus(Long Status) {
        this.Status = Status;
    }

    /**
     * Get 运行版本。
     * @return VersionName 运行版本。
     */
    public String getVersionName() {
        return this.VersionName;
    }

    /**
     * Set 运行版本。
     * @param VersionName 运行版本。
     */
    public void setVersionName(String VersionName) {
        this.VersionName = VersionName;
    }

    public Environment() {
    }

    /**
     * NOTE: Any ambiguous key set via .set("AnyKey", "value") will be a shallow copy,
     *       and any explicit key, i.e Foo, set via .setFoo("value") will be a deep copy.
     */
    public Environment(Environment source) {
        if (source.EnvironmentName != null) {
            this.EnvironmentName = new String(source.EnvironmentName);
        }
        if (source.Url != null) {
            this.Url = new String(source.Url);
        }
        if (source.Status != null) {
            this.Status = new Long(source.Status);
        }
        if (source.VersionName != null) {
            this.VersionName = new String(source.VersionName);
        }
    }

    /**
     * Internal implementation, normal users should not use it.
     */
    public void toMap(HashMap<String, String> map, String prefix) {
        this.setParamSimple(map, prefix + "EnvironmentName", this.EnvironmentName);
        this.setParamSimple(map, prefix + "Url", this.Url);
        this.setParamSimple(map, prefix + "Status", this.Status);
        this.setParamSimple(map, prefix + "VersionName", this.VersionName);
    }
}


@Override
    public void add(CharSequence key, CharSequence cmd)

/*
                   Egothor Software License version 1.00
                     on behalf of the Egothor Project.
                            All rights reserved.

  This  software  is  copyrighted  by  the "Egothor developers". If this
  license applies to a single file or document, the "Egothor developers"
  are the people or entities mentioned as copyright holders in that file
  or  document.  If  this  license  applies  to the Egothor project as a
  whole,  the  copyright holders are the people or entities mentioned in
  the  file CREDITS. This file can be found in the same location as this
  license in the distribution.

      written permission, please contact example@nnthink.com
   4. Products  derived  from this software may not be called "Egothor",
      nor  may  "Egothor"  appear  in  their name, without prior written
      permission from Leo.G@seznam.cz.

  In addition, we request that you include in the end-user documentation
  provided  with  the  redistribution  and/or  in the software itself an
  acknowledgement equivalent to the following:
  "This product includes software developed by the Egothor Project.
   http://example.com"

  created by Leo Galambos (Leo.G@seznam.cz).
*/
package org.egothor.stemmer;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * The MultiTrie is a Trie of Tries.
 *
 *
It stores words and their associated patch commands. The MultiTrie handles patch commands
 * broken into their constituent parts, as a MultiTrie does, but the commands are delimited by the
 * skip command.
 */
public class MultiTrie2 extends MultiTrie {

    /**
     * Constructor for the MultiTrie object.
     *
     * @param is the input stream
     * @exception IOException if an I/O error occurs
     */
    public MultiTrie2(DataInput is) throws IOException {
        super(is);
    }

    /**
     * Constructor for the MultiTrie2 object
     *
     * @param forward set to true if the elements should be read left to right
     */
    public MultiTrie2(boolean forward) {
        super(forward);
    }

    /**
     * Return the element that is stored in a cell associated with the given key.
     *
     * @param key the key to the cell holding the desired element
     * @return the element
     */
    @Override
    public CharSequence getFully(CharSequence key) {
        StringBuilder result = new StringBuilder(tries.size() * 2);
        try {
            CharSequence lastkey = key;
            CharSequence[] p = new CharSequence[tries.size()];
            char lastch = ' ';
            for (int i = 0; i < tries.size(); i++) {
                CharSequence r = tries.get(i).getFully(lastkey);
                if (r == null || (r.length() == 1 && r.charAt(0) == EOM)) {
                    return result;
                }
                if (cannotFollow(lastch, r.charAt(0))) {
                    return result;
                } else {
                    lastch = r.charAt(r.length() - 2);
                }
                p[i] = r;
                if (p[i].charAt(0) == '-') {
                    if (i > 0) {
                        key = skip(key, lengthPP(p[i - 1]));
                    }
                    key = skip(key, lengthPP(p[i]));
                }
                result.append(r);
                if (key.length() != 0) {
                    lastkey = key;
                }
            }
        } catch (@SuppressWarnings("unused") IndexOutOfBoundsException x) {
        }
        return result;
    }

    /**
     * Return the element that is stored as last on a path belonging to the given key.
     *
     * @param key the key associated with the desired element
     * @return the element that is stored as last on a path
     */
    @Override
    public CharSequence getLastOnPath(CharSequence key) {
        StringBuilder result = new StringBuilder(tries.size() * 2);
        try {
            CharSequence lastkey = key;
            CharSequence[] p = new CharSequence[tries.size()];
            char lastch = ' ';
            for (int i = 0; i < tries.size(); i++) {
                CharSequence r = tries.get(i).getLastOnPath(lastkey);
                if (r == null || (r.length() == 1 && r.charAt(0) == EOM)) {
                    return result;
                }
                if (cannotFollow(lastch, r.charAt(0))) {
                    return result;
                } else {
                    lastch = r.charAt(r.length() - 2);
                }
                p[i] = r;
                if (p[i].charAt(0) == '-') {
                    if (i > 0) {
                        key = skip(key, lengthPP(p[i - 1]));
                    }
                    key = skip(key, lengthPP(p[i]));
                }
                result.append(r);
                if (key.length() != 0) {
                    lastkey = key;
                }
            }
        } catch (@SuppressWarnings("unused") IndexOutOfBoundsException x) {
        }
        return result;
    }

    /**
     * Write this data structure to the given output stream.
     *
     * @param os the output stream
     * @exception IOException if an I/O error occurs
     */
    @Override
    public void store(DataOutput os) throws IOException {
        super.store(os);
    }

    /**
     * Add an element to this structure consisting of the given key and patch command.
     *
     *
This method will return without executing if the cmd parameter's length is 0.
     *
     * @param key the key
     * @param cmd the patch command
     */

{
        if (cmd.length() == 0) {
            return;
        }
        CharSequence[] p = decompose(cmd);
        int levels = p.length;
        while (levels >= tries.size()) {
            tries.add(new Trie(forward));
        }
        CharSequence lastkey = key;
        for (int i = 0; i < levels; i++) {
            if (key.length() > 0) {
                tries.get(i).add(key, p[i]);
                lastkey = key;
            } else {
                tries.get(i).add(lastkey, p[i]);
            }
            if (p[i].length() > 0 && p[i].charAt(0) == '-') {
                if (i > 0) {
                    key = skip(key, lengthPP(p[i - 1]));
                }
                key = skip(key, lengthPP(p[i]));
            }
        }
        if (key.length() > 0) {
            tries.get(levels).add(key, EOM_NODE);
        } else {
            tries.get(levels).add(lastkey, EOM_NODE);
        }
    }

    /**
     * Break the given patch command into its constituent pieces. The pieces are delimited by NOOP
     * commands.
     *
     * @param cmd the patch command
     * @return an array containing the pieces of the command
     */
    public CharSequence[] decompose(CharSequence cmd) {
        int parts = 0;
        for (int i = 0; 0 <= i && i < cmd.length(); ) {
            int next = dashEven(cmd, i);
            if (i == next) {
                parts++;
                i = next + 2;
            } else {
                parts++;
                i = next;
            }
        }
        CharSequence[] part = new CharSequence[parts];
        int x = 0;
        for (int i = 0; 0 <= i && i < cmd.length(); ) {
            int next = dashEven(cmd, i);
            if (i == next) {
                part[x++] = cmd.subSequence(i, i + 2);
                i = next + 2;
            } else {
                part[x++] = (next < 0) ? cmd.subSequence(i, cmd.length()) : cmd.subSequence(i, next);
                i = next;
            }
        }
        return part;
    }

    /**
     * Remove empty rows from the given Trie and return the newly reduced Trie.
     *
     * @param by the Trie to reduce
     * @return the newly reduced Trie
     */
    @Override
    public Trie reduce(Reduce by) {
        List<Trie> h = new ArrayList<>();
        for (Trie trie : tries) h.add(trie.reduce(by));
        MultiTrie2 m = new MultiTrie2(forward);
        m.tries = h;
        return m;
    }

    private boolean cannotFollow(char after, char goes) {
        switch(after) {
            case '-':
            case 'D':
                return after == goes;
        }
        return false;
    }

    private CharSequence skip(CharSequence in, int count) {
        if (forward) {
            return in.subSequence(count, in.length());
        } else {
            return in.subSequence(0, in.length() - count);
        }
    }

    private int dashEven(CharSequence in, int from) {
        while (from < in.length()) {
            if (in.charAt(from) == '-') {
                return from;
            } else {
                from += 2;
            }
        }
        return -1;
    }

    @SuppressWarnings("fallthrough")
    private int lengthPP(CharSequence cmd) {
        int len = 0;
        for (int i = 0; i < cmd.length(); i++) {
            switch(cmd.charAt(i++)) {
                case '-':
                case 'D':
                    len += cmd.charAt(i) - 'a' + 1;
                    break;
                case 'R':
                    len++;
                /* intentional fallthrough */
                case 'I':
                    break;
            }
        }
        return len;
    }
}


/*
                   Egothor Software License version 1.00
                     on behalf of the Egothor Project.
                            All rights reserved.

  This  software  is  copyrighted  by  the "Egothor developers". If this
  license applies to a single file or document, the "Egothor developers"
  are the people or entities mentioned as copyright holders in that file
  or  document.  If  this  license  applies  to the Egothor project as a
  whole,  the  copyright holders are the people or entities mentioned in
  the  file CREDITS. This file can be found in the same location as this
  license in the distribution.

      written permission, please contact example@nnthink.com
   4. Products  derived  from this software may not be called "Egothor",
      nor  may  "Egothor"  appear  in  their name, without prior written
      permission from Leo.G@seznam.cz.

  In addition, we request that you include in the end-user documentation
  provided  with  the  redistribution  and/or  in the software itself an
  acknowledgement equivalent to the following:
  "This product includes software developed by the Egothor Project.
   http://example.com"

  created by Leo Galambos (Leo.G@seznam.cz).
*/
package org.egothor.stemmer;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * The MultiTrie is a Trie of Tries.
 *
 *
It stores words and their associated patch commands. The MultiTrie handles patch commands
 * broken into their constituent parts, as a MultiTrie does, but the commands are delimited by the
 * skip command.
 */
public class MultiTrie2 extends MultiTrie {

    /**
     * Constructor for the MultiTrie object.
     *
     * @param is the input stream
     * @exception IOException if an I/O error occurs
     */
    public MultiTrie2(DataInput is) throws IOException {
        super(is);
    }

    /**
     * Constructor for the MultiTrie2 object
     *
     * @param forward set to true if the elements should be read left to right
     */
    public MultiTrie2(boolean forward) {
        super(forward);
    }

    /**
     * Return the element that is stored in a cell associated with the given key.
     *
     * @param key the key to the cell holding the desired element
     * @return the element
     */
    @Override
    public CharSequence getFully(CharSequence key) {
        StringBuilder result = new StringBuilder(tries.size() * 2);
        try {
            CharSequence lastkey = key;
            CharSequence[] p = new CharSequence[tries.size()];
            char lastch = ' ';
            for (int i = 0; i < tries.size(); i++) {
                CharSequence r = tries.get(i).getFully(lastkey);
                if (r == null || (r.length() == 1 && r.charAt(0) == EOM)) {
                    return result;
                }
                if (cannotFollow(lastch, r.charAt(0))) {
                    return result;
                } else {
                    lastch = r.charAt(r.length() - 2);
                }
                p[i] = r;
                if (p[i].charAt(0) == '-') {
                    if (i > 0) {
                        key = skip(key, lengthPP(p[i - 1]));
                    }
                    key = skip(key, lengthPP(p[i]));
                }
                result.append(r);
                if (key.length() != 0) {
                    lastkey = key;
                }
            }
        } catch (@SuppressWarnings("unused") IndexOutOfBoundsException x) {
        }
        return result;
    }

    /**
     * Return the element that is stored as last on a path belonging to the given key.
     *
     * @param key the key associated with the desired element
     * @return the element that is stored as last on a path
     */
    @Override
    public CharSequence getLastOnPath(CharSequence key) {
        StringBuilder result = new StringBuilder(tries.size() * 2);
        try {
            CharSequence lastkey = key;
            CharSequence[] p = new CharSequence[tries.size()];
            char lastch = ' ';
            for (int i = 0; i < tries.size(); i++) {
                CharSequence r = tries.get(i).getLastOnPath(lastkey);
                if (r == null || (r.length() == 1 && r.charAt(0) == EOM)) {
                    return result;
                }
                if (cannotFollow(lastch, r.charAt(0))) {
                    return result;
                } else {
                    lastch = r.charAt(r.length() - 2);
                }
                p[i] = r;
                if (p[i].charAt(0) == '-') {
                    if (i > 0) {
                        key = skip(key, lengthPP(p[i - 1]));
                    }
                    key = skip(key, lengthPP(p[i]));
                }
                result.append(r);
                if (key.length() != 0) {
                    lastkey = key;
                }
            }
        } catch (@SuppressWarnings("unused") IndexOutOfBoundsException x) {
        }
        return result;
    }

    /**
     * Write this data structure to the given output stream.
     *
     * @param os the output stream
     * @exception IOException if an I/O error occurs
     */
    @Override
    public void store(DataOutput os) throws IOException

/**
     * Add an element to this structure consisting of the given key and patch command.
     *
     *
This method will return without executing if the cmd parameter's length is 0.
     *
     * @param key the key
     * @param cmd the patch command
     */
    @Override
    public void add(CharSequence key, CharSequence cmd) {
        if (cmd.length() == 0) {
            return;
        }
        CharSequence[] p = decompose(cmd);
        int levels = p.length;
        while (levels >= tries.size()) {
            tries.add(new Trie(forward));
        }
        CharSequence lastkey = key;
        for (int i = 0; i < levels; i++) {
            if (key.length() > 0) {
                tries.get(i).add(key, p[i]);
                lastkey = key;
            } else {
                tries.get(i).add(lastkey, p[i]);
            }
            if (p[i].length() > 0 && p[i].charAt(0) == '-') {
                if (i > 0) {
                    key = skip(key, lengthPP(p[i - 1]));
                }
                key = skip(key, lengthPP(p[i]));
            }
        }
        if (key.length() > 0) {
            tries.get(levels).add(key, EOM_NODE);
        } else {
            tries.get(levels).add(lastkey, EOM_NODE);
        }
    }

    /**
     * Break the given patch command into its constituent pieces. The pieces are delimited by NOOP
     * commands.
     *
     * @param cmd the patch command
     * @return an array containing the pieces of the command
     */
    public CharSequence[] decompose(CharSequence cmd) {
        int parts = 0;
        for (int i = 0; 0 <= i && i < cmd.length(); ) {
            int next = dashEven(cmd, i);
            if (i == next) {
                parts++;
                i = next + 2;
            } else {
                parts++;
                i = next;
            }
        }
        CharSequence[] part = new CharSequence[parts];
        int x = 0;
        for (int i = 0; 0 <= i && i < cmd.length(); ) {
            int next = dashEven(cmd, i);
            if (i == next) {
                part[x++] = cmd.subSequence(i, i + 2);
                i = next + 2;
            } else {
                part[x++] = (next < 0) ? cmd.subSequence(i, cmd.length()) : cmd.subSequence(i, next);
                i = next;
            }
        }
        return part;
    }

    /**
     * Remove empty rows from the given Trie and return the newly reduced Trie.
     *
     * @param by the Trie to reduce
     * @return the newly reduced Trie
     */
    @Override
    public Trie reduce(Reduce by) {
        List<Trie> h = new ArrayList<>();
        for (Trie trie : tries) h.add(trie.reduce(by));
        MultiTrie2 m = new MultiTrie2(forward);
        m.tries = h;
        return m;
    }

    private boolean cannotFollow(char after, char goes) {
        switch(after) {
            case '-':
            case 'D':
                return after == goes;
        }
        return false;
    }

    private CharSequence skip(CharSequence in, int count) {
        if (forward) {
            return in.subSequence(count, in.length());
        } else {
            return in.subSequence(0, in.length() - count);
        }
    }

    private int dashEven(CharSequence in, int from) {
        while (from < in.length()) {
            if (in.charAt(from) == '-') {
                return from;
            } else {
                from += 2;
            }
        }
        return -1;
    }

    @SuppressWarnings("fallthrough")
    private int lengthPP(CharSequence cmd) {
        int len = 0;
        for (int i = 0; i < cmd.length(); i++) {
            switch(cmd.charAt(i++)) {
                case '-':
                case 'D':
                    len += cmd.charAt(i) - 'a' + 1;
                    break;
                case 'R':
                    len++;
                /* intentional fallthrough */
                case 'I':
                    break;
            }
        }
        return len;
    }
}