package aima.core.learning.reinforcement.agent;

import aima.core.agent.Action;
import aima.core.learning.reinforcement.PerceptStateReward;
import aima.core.probability.mdp.ActionsFunction;
import aima.core.probability.mdp.PolicyEvaluation;
import aima.core.probability.mdp.RewardFunction;
import aima.core.probability.mdp.TransitionProbabilityFunction;
import aima.core.probability.mdp.impl.MDP;
import aima.core.util.FrequencyCounter;
import aima.core.util.datastructure.Pair;
import java.util.*;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): page 834.

 *

 *
 *

 * function PASSIVE-ADP-AGENT(percept) returns an action
 *   inputs: percept, a percept indicating the current state s' and reward signal r'
 *   persistent: π, a fixed policy
 *               mdp, an MDP with model P, rewards R, discount γ
 *               U, a table of utilities, initially empty
 *               Nsa, a table of frequencies for state-action pairs, initially zero
 *               Ns'|sa, a table of outcome frequencies give state-action pairs, initially zero
 *               s, a, the previous state and action, initially null
 *
 *   if s' is new then U[s'] <- r'; R[s'] <- r'
 *   if s is not null then
 *        increment Nsa[s,a] and Ns'|sa[s',s,a]
 *        for each t such that Ns'|sa[t,s,a] is nonzero do
 *            P(t|s,a) <-  Ns'|sa[t,s,a] / Nsa[s,a]
 *   U <- POLICY-EVALUATION(π, U, mdp)
 *   if s'.TERMINAL? then s,a <- null else s,a <- s',π[s']
 *   return a
 *

 *
 * Figure 21.2 A passive reinforcement learning agent based on adaptive dynamic
 * programming. The POLICY-EVALUATION function solves the fixed-policy Bellman
 * equations, as described on page 657.
 *
 * @param <S>
 *            the state type.
 * @param
 *            the action type.
 *
 * @author Ciaran O'Reilly
 * @author Ravi Mohan
 * @author Ruediger Lunde
 */
public class PassiveADPAgent<S, A extends Action> extends ReinforcementAgent<S, A> {

    // persistent: π, a fixed policy
    private Map<S, A> pi = new HashMap<>();

    // mdp, an MDP with model P, rewards R, discount γ
    private MDP<S, A> mdp = null;

    private Map<Pair<S, Pair<S, A>>, Double> P = new HashMap<>();

    private Map<S, Double> R = new HashMap<>();

    private PolicyEvaluation<S, A> policyEvaluation = null;

    // U, a table of utilities, initially empty
    private Map<S, Double> U = new HashMap<>();

    // Nsa, a table of frequencies for state-action pairs, initially
    // zero
    private FrequencyCounter<Pair<S, A>> Nsa = new FrequencyCounter<>();

    // Ns'|sa, a table of outcome frequencies give state-action
    // pairs, initially zero
    private FrequencyCounter<Pair<S, Pair<S, A>>> NsDelta_sa = new FrequencyCounter<>();

    // s, a, the previous state and action, initially null
    private S s = null;

    private A a = null;

    /**
     * Constructor.
     *
     * @param fixedPolicy
     *            π a fixed policy.
     * @param states
     *            the possible states in the world (i.e. fully observable).
     * @param initialState
     *            the initial state for the agent.
     * @param actionsFunction
     *            a function that lists the legal actions from a state.
     * @param policyEvaluation
     *            a function for evaluating a policy.
     */
    public PassiveADPAgent(Map<S, A> fixedPolicy, Set<S> states, S initialState, ActionsFunction<S, A> actionsFunction, PolicyEvaluation<S, A> policyEvaluation) {
        this.pi.putAll(fixedPolicy);
        RewardFunction<S> rewardfn = (s) -> R.get(s);
        this.mdp = new MDP<>(states, initialState, actionsFunction, (sDelta, s, a) -> Optional.ofNullable(P.get(new Pair<>(sDelta, new Pair<>(s, a)))).orElse(0.0), rewardfn);
        this.policyEvaluation = policyEvaluation;
    }

    /**
     * Passive reinforcement learning based on adaptive dynamic programming.
     *
     * @param percept
     *            a percept indicating the current state s' and reward signal
     *            r'.
     * @return an action
     */
    @Override
    public Optional act(PerceptStateReward<S> percept) {
        S sDelta = percept.state();
        double rDelta = percept.reward();
        if (!U.containsKey(sDelta)) {
            U.put(sDelta, rDelta);
            R.put(sDelta, rDelta);
        }
        // if s is not null then
        if (s != null) {
            Pair<S, A> sa = new Pair<>(s, a);
            Nsa.incrementFor(sa);
            NsDelta_sa.incrementFor(new Pair<>(sDelta, sa));
            // for each t such that Ns'|sa[t,s,a] is nonzero do
            for (S t : mdp.states()) {
                Pair<S, Pair<S, A>> t_sa = new Pair<>(t, sa);
                if (NsDelta_sa.getCount(t_sa) != 0) {
                    P.put(t_sa, NsDelta_sa.getCount(t_sa).doubleValue() / Nsa.getCount(sa).doubleValue());
                }
            }
        }
        U = policyEvaluation.evaluate(pi, U, mdp);
        if (isTerminal(sDelta)) {
            s = null;
            a = null;
        } else {
            s = sDelta;
            a = pi.get(sDelta);
        }
        return Optional.ofNullable(a);
    }

    @Override
    public Map<S, Double> getUtility() {
        return Collections.unmodifiableMap(U);
    }

    @Override
    public void reset() {
        P.clear();
        R.clear();
        U = new HashMap<>();
        Nsa.clear();
        NsDelta_sa.c

        s = null;
        a = null;
    }

    // PRIVATE METHODS
    private boolean isTerminal(S s) {
        // A state with no possible actions is considered terminal.
        return mdp.actions(s).isEmpty();
    }
}


package com.ning.atlas;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.ning.atlas.spi.Identity;
import com.ning.atlas.spi.My;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class SystemTemplate extends Template {

    private final List<Template> children;

    public SystemTemplate(String name, Map<String, Object> my, List<?> cardinality, List<Template> children) {
        super(name, new My(my), cardinality);
        this.children = ImmutableList.copyOf(children);
    }

    public Collection<? extends Template> getChildren()

    public List<Element> _normalize(Identity parent, Environment env) {
        List<Element> rs = Lists.newArrayList();
        List<String> node_names = env.overrideCardinality(parent, getType(), getCardinality());
        for (String node_name : node_names) {
            Identity id = parent.createChild(getType(), node_name);
            List<Element> chillins = Lists.newArrayListWithCapacity(getChildren().size());
            for (Template child : getChildren()) {
                Iterable<Element> r2 = child._normalize(id, env);
                Iterables.addAll(chillins, r2);
            }
            Bunch me = new Bunch(id, getMy(), chillins);
            rs.add(me);
        }
        return rs;
    }
}


package com.ning.atlas;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.ning.atlas.spi.Identity;
import com.ning.atlas.spi.My;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class SystemTemplate extends Template {

    private final List<Template> children;

    public SystemTemplate(String name, Map<String, Object> my, List<?> cardinality, List<Template> children) {
        super(name, new My(my), cardinality);
        this.children = ImmutableList.copyOf(children);
    }

    public Collection<? extends Template> getChildren() {
        return children;
    }

    public List<Element> _normalize(Identity parent, Environment env) {
        List<Element> rs = Lists.newArrayList();
        List<String> node_names = env.overrideCard

        for (String node_name : node_names) {
            Identity id = parent.createChild(getType(), node_name);
            List<Element> chillins = Lists.newArrayListWithCapacity(getChildren().size());
            for (Template child : getChildren()) {
                Iterable<Element> r2 = child._normalize(id, env);
                Iterables.addAll(chillins, r2);
            }
            Bunch me = new Bunch(id, getMy(), chillins);
            rs.add(me);
        }
        return rs;
    }
}


{
        x -= vec.x;
        y -= vec.y;
        z -= vec.z;
    }

package com.enderio.core.common.vecmath;

import javax.annotation.Nonnull;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

public class Vector3d {

    public double x;

    public double y;

    public double z;

    public Vector3d() {
        x = 0;
        y = 0;
        z = 0;
    }

    public Vector3d(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Vector3d(Vector3d other) {
        this(other.x, other.y, other.z);
    }

    public Vector3d(Vector3f corner) {
        this(corner.x, corner.y, corner.z);
    }

    public Vector3d(BlockPos blockPos) {
        this(blockPos.getX(), blockPos.getY(), blockPos.getZ());
    }

    public void set(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void set(Vector3f v) {
        set(v.x, v.y, v.z);
    }

    public void set(Vector3d vec) {
        x = vec.x;
        y = vec.y;
        z = vec.z;
    }

    public Vector3d add(Vector3d vec) {
        x += vec.x;
        y += vec.y;
        z += vec.z;
        return this;
    }

    public Vector3d add(Vector3f vec) {
        x += vec.x;
        y += vec.y;
        z += vec.z;
        return this;
    }

    @Nonnull
    public Vector3d add(double x2, double y2, double z2) {
        x += x2;
        y += y2;
        z += z2;
        return this;
    }

    public void sub(Vector3d vec)

    public void sub(Vector3f vec) {
        x -= vec.x;
        y -= vec.y;
        z -= vec.z;
    }

    @Nonnull
    public Vector3d negate() {
        x = -x;
        y = -y;
        z = -z;
        return this;
    }

    public void scale(double s) {
        x *= s;
        y *= s;
        z *= s;
    }

    public void scale(double sx, double sy, double sz) {
        x *= sx;
        y *= sy;
        z *= sz;
    }

    public void normalize() {
        double scale = 1.0 / Math.sqrt(x * x + y * y + z * z);
        scale(scale);
    }

    public double dot(Vector3d other) {
        return x * other.x + y * other.y + z * other.z;
    }

    public void cross(Vector3d v1, Vector3d v2) {
        x = v1.y * v2.z - v1.z * v2.y;
        y = v2.x * v1.z - v2.z * v1.x;
        z = v1.x * v2.y - v1.y * v2.x;
    }

    public double lengthSquared() {
        return x * x + y * y + z * z;
    }

    public double length() {
        return Math.sqrt(lengthSquared());
    }

    public double distanceSquared(Vector3d v) {
        double dx, dy, dz;
        dx = x - v.x;
        dy = y - v.y;
        dz = z - v.z;
        return (dx * dx + dy * dy + dz * dz);
    }

    public double distance(Vector3d v) {
        return Math.sqrt(distanceSquared(v));
    }

    @Override
    public String toString() {
        return "Vector3d(" + x + ", " + y + ", " + z + ")";
    }

    public void abs() {
        x = Math.abs(x);
        y = Math.abs(y);
        z = Math.abs(z);
    }

    @Nonnull
    public Vec3d getVec3() {
        return new Vec3d(x, y, z);
    }
}


package com.enderio.core.common.vecmath;

import javax.annotation.Nonnull;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

public class Vector3d {

    public double x;

    public double y;

    public double z;

    public Vector3d() {
        x = 0;
        y = 0;
        z = 0;
    }

    public Vector3d(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Vector3d(Vector3d other) {
        this(other.x, other.y, other.z);
    }

    public Vector3d(Vector3f corner) {
        this(corner.x, corner.y, corner.z);
    }

    public Vector3d(BlockPos blockPos) {
        this(blockPos.getX(), blockPos.getY(), blockPos.getZ());
    }

    public void set(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void set(Vector3f v) {
        set(v.x, v.y, v.z);
    }

    public void set(Vector3d vec) {
        x = vec.x;
        y = vec.y;
        z = vec.z;
    }

    public Vector3d add(Vector3d vec) {
        x += vec.x;
        y += vec.y;
        z += vec.z;
        return this;
    }

    public Vector3d add(Vector3f vec) {
        x += vec.x;
        y += vec.y;
        z += vec.z;
        return this;
    }

    @Nonnull
    public Vector3d add(double x2, double y2, double z2) {

        y += y2;
        z += z2;
        return this;
    }

    public void sub(Vector3d vec) {
        x -= vec.x;
        y -= vec.y;
        z -= vec.z;
    }

    public void sub(Vector3f vec) {
        x -= vec.x;
        y -= vec.y;
        z -= vec.z;
    }

    @Nonnull
    public Vector3d negate() {
        x = -x;
        y = -y;
        z = -z;
        return this;
    }

    public void scale(double s) {
        x *= s;
        y *= s;
        z *= s;
    }

    public void scale(double sx, double sy, double sz) {
        x *= sx;
        y *= sy;
        z *= sz;
    }

    public void normalize() {
        double scale = 1.0 / Math.sqrt(x * x + y * y + z * z);
        scale(scale);
    }

    public double dot(Vector3d other) {
        return x * other.x + y * other.y + z * other.z;
    }

    public void cross(Vector3d v1, Vector3d v2) {
        x = v1.y * v2.z - v1.z * v2.y;
        y = v2.x * v1.z - v2.z * v1.x;
        z = v1.x * v2.y - v1.y * v2.x;
    }

    public double lengthSquared() {
        return x * x + y * y + z * z;
    }

    public double length() {
        return Math.sqrt(lengthSquared());
    }

    public double distanceSquared(Vector3d v) {
        double dx, dy, dz;
        dx = x - v.x;
        dy = y - v.y;
        dz = z - v.z;
        return (dx * dx + dy * dy + dz * dz);
    }

    public double distance(Vector3d v) {
        return Math.sqrt(distanceSquared(v));
    }

    @Override
    public String toString() {
        return "Vector3d(" + x + ", " + y + ", " + z + ")";
    }

    public void abs() {
        x = Math.abs(x);
        y = Math.abs(y);
        z = Math.abs(z);
    }

    @Nonnull
    public Vec3d getVec3() {
        return new Vec3d(x, y, z);
    }
}


{
            throw new RuntimeException("The thread " + runnable + "will be abort.");
        }

@FunctionalInterface
public interface DenyPolicy {

    void reject(Runnable runnable, ThreadPool threadPool);

    class DiscardDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
        }
    }

    class AbortDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool)

    }

    class RunnerDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            if (!threadPool.isShutdown()) {
                runnable.run();
            }
        }
    }
}


eException("The thread " + runnable + "will be abort.");

@FunctionalInterface
public interface DenyPolicy {

    void reject(Runnable runnable, ThreadPool threadPool);

    class DiscardDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
        }
    }

    class AbortDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            throw new Runtim

        }
    }

    class RunnerDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            if (!threadPool.isShutdown()) {
                runnable.run();
            }
        }
    }
}


{
        this.prodCode = prodCode;
    }

package com.alipay.api.request;

import com.alipay.api.domain.ZhimaMerchantContractCommonQueryModel;
import java.util.Map;
import com.alipay.api.AlipayRequest;
import com.alipay.api.internal.util.AlipayHashMap;
import com.alipay.api.response.ZhimaMerchantContractCommonQueryResponse;
import com.alipay.api.AlipayObject;

/**
 * ALIPAY API: zhima.merchant.contract.common.query request
 *
 * @author auto create
 * @since 1.0, 2021-05-17 10:39:38
 */
public class ZhimaMerchantContractCommonQueryRequest implements AlipayRequest<ZhimaMerchantContractCommonQueryResponse> {

    // add user-defined text parameters
    private AlipayHashMap udfParams;

    private String apiVersion = "1.0";

    private String bizContent;

    public void setBizContent(String bizContent) {
        this.bizContent = bizContent;
    }

    public String getBizContent() {
        return this.bizContent;
    }

    private String terminalType;

    private String terminalInfo;

    private String prodCode;

    private String notifyUrl;

    private String returnUrl;

    private boolean needEncrypt = false;

    private AlipayObject bizModel = null;

    public String getNotifyUrl() {
        return this.notifyUrl;
    }

    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    public String getReturnUrl() {
        return this.returnUrl;
    }

    public void setReturnUrl(String returnUrl) {
        this.returnUrl = returnUrl;
    }

    public String getApiVersion() {
        return this.apiVersion;
    }

    public void setApiVersion(String apiVersion) {
        this.apiVersion = apiVersion;
    }

    public void setTerminalType(String terminalType) {
        this.terminalType = terminalType;
    }

    public String getTerminalType() {
        return this.terminalType;
    }

    public void setTerminalInfo(String terminalInfo) {
        this.terminalInfo = terminalInfo;
    }

    public String getTerminalInfo() {
        return this.terminalInfo;
    }

    public void setProdCode(String prodCode)

    public String getProdCode() {
        return this.prodCode;
    }

    public String getApiMethodName() {
        return "zhima.merchant.contract.common.query";
    }

    public Map<String, String> getTextParams() {
        AlipayHashMap txtParams = new AlipayHashMap();
        txtParams.put("biz_content", this.bizContent);
        if (udfParams != null) {
            txtParams.putAll(this.udfParams);
        }
        return txtParams;
    }

    public void putOtherTextParam(String key, String value) {
        if (this.udfParams == null) {
            this.udfParams = new AlipayHashMap();
        }
        this.udfParams.put(key, value);
    }

    public Class<ZhimaMerchantContractCommonQueryResponse> getResponseClass() {
        return ZhimaMerchantContractCommonQueryResponse.class;
    }

    public boolean isNeedEncrypt() {
        return this.needEncrypt;
    }

    public void setNeedEncrypt(boolean needEncrypt) {
        this.needEncrypt = needEncrypt;
    }

    public AlipayObject getBizModel() {
        return this.bizModel;
    }

    public void setBizModel(AlipayObject bizModel) {
        this.bizModel = bizModel;
    }
}


package com.alipay.api.request;

import com.alipay.api.domain.ZhimaMerchantContractCommonQueryModel;
import java.util.Map;
import com.alipay.api.AlipayRequest;
import com.alipay.api.internal.util.AlipayHashMap;
import com.alipay.api.response.ZhimaMerchantContractCommonQueryResponse;
import com.alipay.api.AlipayObject;

/**
 * ALIPAY API: zhima.merchant.contract.common.query request
 *
 * @author auto create
 * @since 1.0, 2021-05-17 10:39:38
 */
public class ZhimaMerchantContractCommonQueryRequest implements AlipayRequest<ZhimaMerchantContractCommonQueryResponse> {

    // add user-defined text parameters
    private AlipayHashMap udfParams;

    private String apiVersion = "1.0";

    private String bizContent;

    public void setBizContent(String bizContent) {
        this.bizContent = bizContent;
    }

    public String getBizContent() {
        return this.bizContent;
    }

    private String terminalType;

    private String terminalInfo;

    private String prodCode;

    private String notifyUrl;

    private String returnUrl;

    private boolean needEncrypt = false;

    private AlipayObject bizModel = null;

    public String getNotifyUrl() {
        return this.notifyUrl;
    }

    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    public String getReturnUrl() {
        return this.returnUrl;
    }

    public void setReturnUrl(String returnUrl) {
        this.returnUrl = returnUrl;
    }

    public String getApiVersion() {
        return this.apiVersion;
    }

    public void setApiVersion(String apiVersion) {
        this.apiVersion = apiVersion;
    }

    public void setTerminalType(String terminalType) {
        this.terminalType = terminalType;
    }

    public String getTerminalType() {
        return this.terminalType;
    }

    public void setTerminalInfo(String terminalInfo) {
        this.terminalInfo = terminalInfo;
    }

    public String getTerminalInfo() {
        return this.terminalInfo;
    }

    public void setProdCode(String prodCode) {
        this.prodCode = prodCode;
    }

    public String getProdCode() {
        return this.prodCode;
    }

    public String getApiMethodName() {
        return "zhima.merchant.contract.common.query";
    }

    public Map<String, String> getTextParams() {
        AlipayHashMap txtParams = new AlipayHashMap();
        txtParams.put("biz_content", this.bizContent);
        if (udfParams != null) {
            txtParams.putAll(this.udfParams);
        }
        return txtParams;
    }

    public void putOtherTextParam(String key, String value) {
        if (this.udfParams == null) {
            this.udfParams = new AlipayHashMap();
        }
        this.udfParams.put(key, value);
    }

    public Class<ZhimaMerchantContractCommonQueryResponse> getResponseClass() {
        return ZhimaMerchantContractCommonQueryResponse.class;
    }

    public boolean isNeedEncrypt() {
        return this.needEncrypt;
    }

    public void setNeedEncrypt(boolean needEncrypt) {
        this.needEncrypt

    }

    public AlipayObject getBizModel() {
        return this.bizModel;
    }

    public void setBizModel(AlipayObject bizModel) {
        this.bizModel = bizModel;
    }
}


public void deleteExpiredSAML2Tokens() throws StoreException;

/**
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * $Id: SAML2RepositoryFactory.java,v 1.1 2008/07/22 18:08:20 weisun2 Exp $
 */
package com.sun.identity.coretoken.interfaces;

import com.iplanet.dpro.session.exceptions.StoreException;
import java.util.List;

/**
 * This class is used in SAML2 Token Persistence to store/recover serialized
 * state of IDPSession/Response objects.
 */
public interface AMTokenSAML2Repository {

    /**
     * Retrives existing SAML2 object from persistent Repository.
     *
     * @param samlKey primary key
     * @return Object - SAML2 unMarshaled Object, if failed, return null.
     */
    public Object retrieveSAML2Token(String samlKey) throws StoreException;

    /**
     * Retrieves a list of existing SAML2 object from persistent Repository with the Secondary Key.
     *
     * @param secKey Secondary Key
     * @return List<Object> - List of SAML2 unMarshaled Objects, if failed, return null.
     */
    public List<Object> retrieveSAML2TokenWithSecondaryKey(String secKey) throws StoreException;

    /**
     * Deletes the SAML2 object by given primary key from the repository
     * @param samlKey primary key
     */
    public void deleteSAML2Token(String samlKey) throws StoreException;

    /**
     * Deletes expired SAML2 object from the repository
     */

    /**
     * Saves SAML2 data into the SAML2 Repository.
     *
     * @param samlKey Primary key.
     * @param samlObj SAML object such as Response, IDPSession.
     * @param expirationTime Expiration time in seconds from epoch.
     * @param secKey Secondary Key.
     */
    public void saveSAML2Token(String samlKey, Object samlObj, long expirationTime, String secKey) throws StoreException;
}


package com.opendoorlogistics.studio.components.map.plugins.snapshot;

import java.awt.Dimension;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAttribute;
import com.opendoorlogistics.core.utils.strings.Strings;

public class CreateImageConfig implements Serializable {

    private int width = 600;

    private int height = 400;

    private ImageType imageType = ImageType.PNG;

    private CaptureMode captureMode = CaptureMode.CURRENT_ZOOM;

    public enum CaptureMode {

        CURRENT_ZOOM(0, false),
        ZOOM_PLUS_1(1, false),
        ZOOM_PLUS_2(2, false),
        ZOOM_PLUS_3(3, false),
        ZOOM_PLUS_4(4, false),
        ZOOM_PLUS_5(5, false),
        CURRENT_ZOOM_CUSTOM_SIZE(0, true);

        @Override
        public String toString() {
            return Strings.convertEnumToDisplayFriendly(this);
        }

        private CaptureMode(int zoomDiff, boolean setSize) {
            this.zoomDiff = zoomDiff;
            this.isCustomSize = setSize;
        }

        public final int zoomDiff;

        public final boolean isCustomSize;

        public Dimension getDimension(Dimension defaultDimension) {
            if (isCustomSize) {
                return null;
            }
            int diff = (int) Math.pow(2, zoomDiff);
            return new Dimension(defaultDimension.width * diff, defaultDimension.height * diff);
        }
    }

    public enum ImageType {

        JPEG, PNG, GIF, BMP
    }

    public CreateImageConfig() {
        super();
    }

    public int getWidth() {
        return width;
    }

    @XmlAttribute
    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    @XmlAttribute
    public void setHeight(int height) {
        this.height = height;
    }

    public ImageType getImageType() {
        return imageType;
    }

    @XmlAttribute
    public void setImageType(ImageType imageType) {
        this.imageType = imageType;
    }

    public CaptureMode getCaptureMode()

    @XmlAttribute
    public void setCaptureMode(CaptureMode captureMode) {
        this.captureMode = captureMode;
    }
}


package com.opendoorlogistics.studio.components.map.plugins.snapshot;

import java.awt.Dimension;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAttribute;
import com.opendoorlogistics.core.utils.strings.Strings;

public class CreateImageConfig implements Serializable {

    private int width = 600;

    private int height = 400;

    private ImageType imageType = ImageType.PNG;

    private CaptureMode captureMode = CaptureMode.CURRENT_ZOOM;

    public enum CaptureMode {

        CURRENT_ZOOM(0, false),
        ZOOM_PLUS_1(1, false),
        ZOOM_PLUS_2(2, false),
        ZOOM_PLUS_3(3, false),
        ZOOM_PLUS_4(4, false),
        ZOOM_PLUS_5(5, false),
        CURRENT_ZOOM_CUSTOM_SIZE(0, true);

        @Override
        public String toString() {
            return Strings.convertEnumToDisplayFriendly(this);
        }

        private CaptureMode(int zoomDiff, boolean setSize) {
            this.zoomDiff = zoomDiff;
            this.isCustomSize = setSize;
        }

        public final int zoomDiff;

        public final boolean isCustomSize;

        public Dimension getDimension(Dimension defaultDimension) {
            if (isCustomSize) {
                return null;
            }
            int diff = (int) Math.pow(2, zoomDiff);
            return new Dimension(defaultDimension.width * diff, defaultDimension.height * diff);
        }
    }

    public enum ImageType {

        JPEG, PNG, GIF, BMP
    }

    public CreateImageConfig() {
        super();
    }

    public int getWidth() {
        return width;
    }

    @XmlAttribute
    public void setWidth(int width) {
        t

    }

    public int getHeight() {
        return height;
    }

    @XmlAttribute
    public void setHeight(int height) {
        this.height = height;
    }

    public ImageType getImageType() {
        return imageType;
    }

    @XmlAttribute
    public void setImageType(ImageType imageType) {
        this.imageType = imageType;
    }

    public CaptureMode getCaptureMode() {
        return captureMode;
    }

    @XmlAttribute
    public void setCaptureMode(CaptureMode captureMode) {
        this.captureMode = captureMode;
    }
}


{
        return FastFileUtils.isImageFile(uploadFileName) || FastFileUtils.isImageFile(fileName) || FastFileUtils.isImageFileByMimeType(contentType);
    }

package com.fastchar.core;

import com.fastchar.exception.FastFileException;
import com.fastchar.local.FastCharLocal;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastFileUtils;
import com.fastchar.utils.FastMD5Utils;
import com.fastchar.utils.FastStringUtils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * FastChar核心文件操作类
 * @author 沈建（Janesen）
 * @param <T>
 */
@SuppressWarnings("unchecked")
public class FastFile<T> {

    public static FastFile<?> newInstance(String paramName, String attachDirectory, String fileName, String originalFileName, String contentType) {
        return FastChar.getOverrides().newInstance(FastFile.class).setParamName(paramName).setAttachDirectory(attachDirectory).setFileName(fileName).setUploadFileName(originalFileName).setContentType(contentType);
    }

    public static FastFile<?> newInstance(String attachDirectory, String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(attachDirectory).setFileName(fileName).setParamName(fileName);
    }

    public static FastFile<?> newInstance(String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(FastChar.getConstant().getAttachDirectory()).setParamName(fileName).setFileName(fileName);
    }

    public static FastFile<?> newInstance(File file) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(file.getParent()).setParamName(file.getName()).setFileName(file.getName());
    }

    protected FastFile() {
    }

    private String key;

    private String paramName;

    private String fileName;

    private String attachDirectory;

    private String uploadFileName;

    private String contentType;

    private final ConcurrentHashMap<String, Object> attrs = new ConcurrentHashMap<>();

    private final FastMapWrap mapWrap = FastMapWrap.newInstance(attrs);

    /**
     * 获取文件的唯一标识key
     * @return 字符串
     */
    public String getKey() {
        if (FastStringUtils.isEmpty(key)) {
            this.key = FastChar.getSecurity().MD5_Encrypt(FastStringUtils.buildOnlyCode(paramName));
        }
        return key;
    }

    /**
     * 设置文件的唯一标识key
     * @param key 唯一标识string
     * @return 当前对象
     */
    public FastFile<T> setKey(String key) {
        this.key = key;
        return this;
    }

    /**
     * 获取附件post提交的参数名
     * @return 字符串
     */
    public String getParamName() {
        return paramName;
    }

    /**
     * 设置附件post提交的参数名
     * @param paramName 参数名
     * @return 当前对象
     */
    public FastFile<T> setParamName(String paramName) {
        this.paramName = paramName;
        return this;
    }

    public String getFileName() {
        return fileName;
    }

    /**
     * 设置附件保存后的文件名
     * @param fileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public String getAttachDirectory() {
        return attachDirectory;
    }

    /**
     * 设置附件保存到文件夹目录地址
     * @param attachDirectory 目录地址
     * @return 当前对象
     */
    public FastFile<T> setAttachDirectory(String attachDirectory) {
        this.attachDirectory = attachDirectory;
        return this;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    /**
     * 设置附件的原始文件名
     * @param uploadFileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
        if (FastChar.getConstant().isDecodeUploadFileName()) {
            if (FastStringUtils.isNotEmpty(this.uploadFileName)) {
                try {
                    this.uploadFileName = URLDecoder.decode(this.uploadFileName, FastChar.getConstant().getDecodeUploadFileNameEncoding());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return this;
    }

    /**
     * 获取附件的content-type类型
     * @return 字符串
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * 设置附件的content-type类型
     * @param contentType 文件类型
     * @return 当前对象
     */
    public FastFile<T> setContentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    /**
     * 获得文件扩展名，包含(.) 例如：.png
     * @return 字符串
     */
    public String getExtensionName() {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(fileName.lastIndexOf("."));
        }
        return "";
    }

    /**
     * 获取短文件名,不带扩展名，原始文件名：test.png 获取后为：test
     * @param fileName 文件名
     * @return 字符串
     */
    public static String getShortName(String fileName) {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    public boolean isImageFile()

    public boolean isTxtFile() {
        return FastFileUtils.isTxtFile(uploadFileName) || FastFileUtils.isTxtFile(fileName) || FastFileUtils.isTxtFileByMimeType(contentType);
    }

    public boolean isExcelFile() {
        return FastFileUtils.isExcelFile(uploadFileName) || FastFileUtils.isExcelFile(fileName) || FastFileUtils.isExcelFileByMimeType(contentType);
    }

    public boolean isWordFile() {
        return FastFileUtils.isWordFile(uploadFileName) || FastFileUtils.isWordFile(fileName) || FastFileUtils.isWordFileByMimeType(contentType);
    }

    public boolean isPDFFile() {
        return FastFileUtils.isPDFFile(uploadFileName) || FastFileUtils.isPDFFile(fileName) || FastFileUtils.isPDFFileByMimeType(contentType);
    }

    public boolean isPPTFile() {
        return FastFileUtils.isPPTFile(uploadFileName) || FastFileUtils.isPPTFile(fileName) || FastFileUtils.isPPTFileByMimeType(contentType);
    }

    public boolean isMP4File() {
        return FastFileUtils.isMP4File(uploadFileName) || FastFileUtils.isMP4File(fileName) || FastFileUtils.isMP4FileByMimeType(contentType);
    }

    public boolean isMOVFile() {
        return FastFileUtils.isMOVFile(uploadFileName) || FastFileUtils.isMOVFile(fileName) || FastFileUtils.isMOVFileByMimeType(contentType);
    }

    public boolean isAVIFile() {
        return FastFileUtils.isAVIFile(uploadFileName) || FastFileUtils.isAVIFile(fileName) || FastFileUtils.isAVIFileByMimeType(contentType);
    }

    public boolean isMP3File() {
        return FastFileUtils.isMP3File(uploadFileName) || FastFileUtils.isMP3File(fileName) || FastFileUtils.isMP3FileByMimeType(contentType);
    }

    public boolean isTargetFile(String... extensions) {
        return FastFileUtils.isTargetFile(uploadFileName, extensions) || FastFileUtils.isTargetFile(fileName, extensions);
    }

    public boolean isTargetFileByMimeType(String... mimeTypes) {
        return FastFileUtils.isTargetFileByMimeType(contentType, mimeTypes);
    }

    public File getFile() {
        return this.attachDirectory != null && this.fileName != null ? new File(this.attachDirectory, this.fileName) : null;
    }

    public boolean exists() {
        return getFile().exists();
    }

    public <E extends FastFile> E moveFile(File targetDirectory) throws FastFileException, IOException {
        return moveFile(targetDirectory.getAbsolutePath());
    }

    public <E extends FastFile> E moveFile(String targetDirectory) throws FastFileException, IOException {
        File targetFile = new File(targetDirectory, fileName);
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetDirectory + "'"));
            }
        }
        File rename = FastChar.getFileRename().rename(targetFile, false);
        if (rename.exists()) {
            rename.delete();
        }
        FastFileUtils.moveFile(getFile(), rename);
        return (E) FastFile.newInstance(paramName, targetDirectory, rename.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E renameTo(File targetFile) throws FastFileException, IOException {
        return renameTo(targetFile, false);
    }

    public <E extends FastFile> E renameTo(File targetFile, boolean force) throws FastFileException, IOException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.moveFile(getFile(), targetFile, force);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E copyTo(File targetFile) throws IOException, FastFileException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.copyFile(getFile(), targetFile);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    /**
     * 删除附件
     * @throws IOException 异常信息
     */
    public void delete() throws IOException {
        FastFileUtils.forceDelete(getFile());
    }

    /**
     * 获取附件的访问地址
     * @return 字符串
     * @throws Exception 异常信息
     */
    public String getUrl() throws Exception {
        if (getFile() == null) {
            return null;
        }
        String replace = getFile().getAbsolutePath().replace(FastChar.getPath().getWebRootPath(), "");
        return FastStringUtils.strip(replace, "/");
    }

    /**
     * 设置附件的扩展属性
     * @param name 属性名
     * @param value 属性值
     */
    public void setAttr(String name, Object value) {
        this.attrs.put(name, value);
    }

    /**
     * 判断是否存在扩展属性
     * @param name 属性名
     * @return 布尔值
     */
    public boolean existAttr(String name) {
        return this.attrs.contains(name);
    }

    /**
     * 获取扩展属性值
     * @param name 属性名
     * @return Object
     */
    public Object getAttr(String name) {
        return this.attrs.get(name);
    }

    /**
     * 获取附件扩展属性Map对象
     * @return FastMapWrap对象
     */
    public FastMapWrap getAttrWrap() {
        return mapWrap;
    }

    /**
     * 获取附件所有的扩展属性值
     * @return ConcurrentHashMap对象
     */
    public ConcurrentHashMap<String, Object> getAttrs() {
        return attrs;
    }
}


package com.fastchar.core;

import com.fastchar.exception.FastFileException;
import com.fastchar.local.FastCharLocal;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastFileUtils;
import com.fastchar.utils.FastMD5Utils;
import com.fastchar.utils.FastStringUtils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * FastChar核心文件操作类
 * @author 沈建（Janesen）
 * @param <T>
 */
@SuppressWarnings("unchecked")
public class FastFile<T> {

    public static FastFile<?> newInstance(String paramName, String attachDirectory, String fileName, String originalFileName, String contentType) {
        return FastChar.getOverrides().newInstance(FastFile.class).setParamName(paramName).setAttachDirectory(attachDirectory).setFileName(fileName).setUploadFileName(originalFileName).setContentType(contentType);
    }

    public static FastFile<?> newInstance(String attachDirectory, String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(attachDirectory).setFileName(fileName).setParamName(fileName);
    }

    public static FastFile<?> newInstance(String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(FastChar.getConstant().getAttachDirectory()).setParamName(fileName).setFileName(fileName);
    }

    public static FastFile<?> newInstance(File file) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(file.getParent()).setParamName(file.getName()).setFileName(file.getName());
    }

    protected FastFile() {
    }

    private String key;

    private String paramName;

    private String fileName;

    private String attachDirectory;

    private String uploadFileName;

    private String contentType;

    private final ConcurrentHashMap<String, Object> attrs = new ConcurrentHashMap<>();

    private final FastMapWrap mapWrap = FastMapWrap.newInstance(attrs);

    /**
     * 获取文件的唯一标识key
     * @return 字符串
     */
    public String getKey() {
        if (FastStringUtils.isEmpty(key)) {
            this.key = FastChar.getSecurity().MD5_Encrypt(FastStringUtils.buildOnlyCode(paramName));
        }
        return ke

    }

    /**
     * 设置文件的唯一标识key
     * @param key 唯一标识string
     * @return 当前对象
     */
    public FastFile<T> setKey(String key) {
        this.key = key;
        return this;
    }

    /**
     * 获取附件post提交的参数名
     * @return 字符串
     */
    public String getParamName() {
        return paramName;
    }

    /**
     * 设置附件post提交的参数名
     * @param paramName 参数名
     * @return 当前对象
     */
    public FastFile<T> setParamName(String paramName) {
        this.paramName = paramName;
        return this;
    }

    public String getFileName() {
        return fileName;
    }

    /**
     * 设置附件保存后的文件名
     * @param fileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public String getAttachDirectory() {
        return attachDirectory;
    }

    /**
     * 设置附件保存到文件夹目录地址
     * @param attachDirectory 目录地址
     * @return 当前对象
     */
    public FastFile<T> setAttachDirectory(String attachDirectory) {
        this.attachDirectory = attachDirectory;
        return this;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    /**
     * 设置附件的原始文件名
     * @param uploadFileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
        if (FastChar.getConstant().isDecodeUploadFileName()) {
            if (FastStringUtils.isNotEmpty(this.uploadFileName)) {
                try {
                    this.uploadFileName = URLDecoder.decode(this.uploadFileName, FastChar.getConstant().getDecodeUploadFileNameEncoding());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return this;
    }

    /**
     * 获取附件的content-type类型
     * @return 字符串
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * 设置附件的content-type类型
     * @param contentType 文件类型
     * @return 当前对象
     */
    public FastFile<T> setContentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    /**
     * 获得文件扩展名，包含(.) 例如：.png
     * @return 字符串
     */
    public String getExtensionName() {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(fileName.lastIndexOf("."));
        }
        return "";
    }

    /**
     * 获取短文件名,不带扩展名，原始文件名：test.png 获取后为：test
     * @param fileName 文件名
     * @return 字符串
     */
    public static String getShortName(String fileName) {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    public boolean isImageFile() {
        return FastFileUtils.isImageFile(uploadFileName) || FastFileUtils.isImageFile(fileName) || FastFileUtils.isImageFileByMimeType(contentType);
    }

    public boolean isTxtFile() {
        return FastFileUtils.isTxtFile(uploadFileName) || FastFileUtils.isTxtFile(fileName) || FastFileUtils.isTxtFileByMimeType(contentType);
    }

    public boolean isExcelFile() {
        return FastFileUtils.isExcelFile(uploadFileName) || FastFileUtils.isExcelFile(fileName) || FastFileUtils.isExcelFileByMimeType(contentType);
    }

    public boolean isWordFile() {
        return FastFileUtils.isWordFile(uploadFileName) || FastFileUtils.isWordFile(fileName) || FastFileUtils.isWordFileByMimeType(contentType);
    }

    public boolean isPDFFile() {
        return FastFileUtils.isPDFFile(uploadFileName) || FastFileUtils.isPDFFile(fileName) || FastFileUtils.isPDFFileByMimeType(contentType);
    }

    public boolean isPPTFile() {
        return FastFileUtils.isPPTFile(uploadFileName) || FastFileUtils.isPPTFile(fileName) || FastFileUtils.isPPTFileByMimeType(contentType);
    }

    public boolean isMP4File() {
        return FastFileUtils.isMP4File(uploadFileName) || FastFileUtils.isMP4File(fileName) || FastFileUtils.isMP4FileByMimeType(contentType);
    }

    public boolean isMOVFile() {
        return FastFileUtils.isMOVFile(uploadFileName) || FastFileUtils.isMOVFile(fileName) || FastFileUtils.isMOVFileByMimeType(contentType);
    }

    public boolean isAVIFile() {
        return FastFileUtils.isAVIFile(uploadFileName) || FastFileUtils.isAVIFile(fileName) || FastFileUtils.isAVIFileByMimeType(contentType);
    }

    public boolean isMP3File() {
        return FastFileUtils.isMP3File(uploadFileName) || FastFileUtils.isMP3File(fileName) || FastFileUtils.isMP3FileByMimeType(contentType);
    }

    public boolean isTargetFile(String... extensions) {
        return FastFileUtils.isTargetFile(uploadFileName, extensions) || FastFileUtils.isTargetFile(fileName, extensions);
    }

    public boolean isTargetFileByMimeType(String... mimeTypes) {
        return FastFileUtils.isTargetFileByMimeType(contentType, mimeTypes);
    }

    public File getFile() {
        return this.attachDirectory != null && this.fileName != null ? new File(this.attachDirectory, this.fileName) : null;
    }

    public boolean exists() {
        return getFile().exists();
    }

    public <E extends FastFile> E moveFile(File targetDirectory) throws FastFileException, IOException {
        return moveFile(targetDirectory.getAbsolutePath());
    }

    public <E extends FastFile> E moveFile(String targetDirectory) throws FastFileException, IOException {
        File targetFile = new File(targetDirectory, fileName);
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetDirectory + "'"));
            }
        }
        File rename = FastChar.getFileRename().rename(targetFile, false);
        if (rename.exists()) {
            rename.delete();
        }
        FastFileUtils.moveFile(getFile(), rename);
        return (E) FastFile.newInstance(paramName, targetDirectory, rename.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E renameTo(File targetFile) throws FastFileException, IOException {
        return renameTo(targetFile, false);
    }

    public <E extends FastFile> E renameTo(File targetFile, boolean force) throws FastFileException, IOException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.moveFile(getFile(), targetFile, force);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E copyTo(File targetFile) throws IOException, FastFileException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.copyFile(getFile(), targetFile);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    /**
     * 删除附件
     * @throws IOException 异常信息
     */
    public void delete() throws IOException {
        FastFileUtils.forceDelete(getFile());
    }

    /**
     * 获取附件的访问地址
     * @return 字符串
     * @throws Exception 异常信息
     */
    public String getUrl() throws Exception {
        if (getFile() == null) {
            return null;
        }
        String replace = getFile().getAbsolutePath().replace(FastChar.getPath().getWebRootPath(), "");
        return FastStringUtils.strip(replace, "/");
    }

    /**
     * 设置附件的扩展属性
     * @param name 属性名
     * @param value 属性值
     */
    public void setAttr(String name, Object value) {
        this.attrs.put(name, value);
    }

    /**
     * 判断是否存在扩展属性
     * @param name 属性名
     * @return 布尔值
     */
    public boolean existAttr(String name) {
        return this.attrs.contains(name);
    }

    /**
     * 获取扩展属性值
     * @param name 属性名
     * @return Object
     */
    public Object getAttr(String name) {
        return this.attrs.get(name);
    }

    /**
     * 获取附件扩展属性Map对象
     * @return FastMapWrap对象
     */
    public FastMapWrap getAttrWrap() {
        return mapWrap;
    }

    /**
     * 获取附件所有的扩展属性值
     * @return ConcurrentHashMap对象
     */
    public ConcurrentHashMap<String, Object> getAttrs() {
        return attrs;
    }
}


public String getExtensionName() {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(fileName.lastIndexOf("."));
        }
        return "";
    }

package com.fastchar.core;

import com.fastchar.exception.FastFileException;
import com.fastchar.local.FastCharLocal;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastFileUtils;
import com.fastchar.utils.FastMD5Utils;
import com.fastchar.utils.FastStringUtils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * FastChar核心文件操作类
 * @author 沈建（Janesen）
 * @param <T>
 */
@SuppressWarnings("unchecked")
public class FastFile<T> {

    public static FastFile<?> newInstance(String paramName, String attachDirectory, String fileName, String originalFileName, String contentType) {
        return FastChar.getOverrides().newInstance(FastFile.class).setParamName(paramName).setAttachDirectory(attachDirectory).setFileName(fileName).setUploadFileName(originalFileName).setContentType(contentType);
    }

    public static FastFile<?> newInstance(String attachDirectory, String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(attachDirectory).setFileName(fileName).setParamName(fileName);
    }

    public static FastFile<?> newInstance(String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(FastChar.getConstant().getAttachDirectory()).setParamName(fileName).setFileName(fileName);
    }

    public static FastFile<?> newInstance(File file) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(file.getParent()).setParamName(file.getName()).setFileName(file.getName());
    }

    protected FastFile() {
    }

    private String key;

    private String paramName;

    private String fileName;

    private String attachDirectory;

    private String uploadFileName;

    private String contentType;

    private final ConcurrentHashMap<String, Object> attrs = new ConcurrentHashMap<>();

    private final FastMapWrap mapWrap = FastMapWrap.newInstance(attrs);

    /**
     * 获取文件的唯一标识key
     * @return 字符串
     */
    public String getKey() {
        if (FastStringUtils.isEmpty(key)) {
            this.key = FastChar.getSecurity().MD5_Encrypt(FastStringUtils.buildOnlyCode(paramName));
        }
        return key;
    }

    /**
     * 设置文件的唯一标识key
     * @param key 唯一标识string
     * @return 当前对象
     */
    public FastFile<T> setKey(String key) {
        this.key = key;
        return this;
    }

    /**
     * 获取附件post提交的参数名
     * @return 字符串
     */
    public String getParamName() {
        return paramName;
    }

    /**
     * 设置附件post提交的参数名
     * @param paramName 参数名
     * @return 当前对象
     */
    public FastFile<T> setParamName(String paramName) {
        this.paramName = paramName;
        return this;
    }

    public String getFileName() {
        return fileName;
    }

    /**
     * 设置附件保存后的文件名
     * @param fileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public String getAttachDirectory() {
        return attachDirectory;
    }

    /**
     * 设置附件保存到文件夹目录地址
     * @param attachDirectory 目录地址
     * @return 当前对象
     */
    public FastFile<T> setAttachDirectory(String attachDirectory) {
        this.attachDirectory = attachDirectory;
        return this;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    /**
     * 设置附件的原始文件名
     * @param uploadFileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
        if (FastChar.getConstant().isDecodeUploadFileName()) {
            if (FastStringUtils.isNotEmpty(this.uploadFileName)) {
                try {
                    this.uploadFileName = URLDecoder.decode(this.uploadFileName, FastChar.getConstant().getDecodeUploadFileNameEncoding());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return this;
    }

    /**
     * 获取附件的content-type类型
     * @return 字符串
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * 设置附件的content-type类型
     * @param contentType 文件类型
     * @return 当前对象
     */
    public FastFile<T> setContentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    /**
     * 获得文件扩展名，包含(.) 例如：.png
     * @return 字符串
     */

    /**
     * 获取短文件名,不带扩展名，原始文件名：test.png 获取后为：test
     * @param fileName 文件名
     * @return 字符串
     */
    public static String getShortName(String fileName) {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    public boolean isImageFile() {
        return FastFileUtils.isImageFile(uploadFileName) || FastFileUtils.isImageFile(fileName) || FastFileUtils.isImageFileByMimeType(contentType);
    }

    public boolean isTxtFile() {
        return FastFileUtils.isTxtFile(uploadFileName) || FastFileUtils.isTxtFile(fileName) || FastFileUtils.isTxtFileByMimeType(contentType);
    }

    public boolean isExcelFile() {
        return FastFileUtils.isExcelFile(uploadFileName) || FastFileUtils.isExcelFile(fileName) || FastFileUtils.isExcelFileByMimeType(contentType);
    }

    public boolean isWordFile() {
        return FastFileUtils.isWordFile(uploadFileName) || FastFileUtils.isWordFile(fileName) || FastFileUtils.isWordFileByMimeType(contentType);
    }

    public boolean isPDFFile() {
        return FastFileUtils.isPDFFile(uploadFileName) || FastFileUtils.isPDFFile(fileName) || FastFileUtils.isPDFFileByMimeType(contentType);
    }

    public boolean isPPTFile() {
        return FastFileUtils.isPPTFile(uploadFileName) || FastFileUtils.isPPTFile(fileName) || FastFileUtils.isPPTFileByMimeType(contentType);
    }

    public boolean isMP4File() {
        return FastFileUtils.isMP4File(uploadFileName) || FastFileUtils.isMP4File(fileName) || FastFileUtils.isMP4FileByMimeType(contentType);
    }

    public boolean isMOVFile() {
        return FastFileUtils.isMOVFile(uploadFileName) || FastFileUtils.isMOVFile(fileName) || FastFileUtils.isMOVFileByMimeType(contentType);
    }

    public boolean isAVIFile() {
        return FastFileUtils.isAVIFile(uploadFileName) || FastFileUtils.isAVIFile(fileName) || FastFileUtils.isAVIFileByMimeType(contentType);
    }

    public boolean isMP3File() {
        return FastFileUtils.isMP3File(uploadFileName) || FastFileUtils.isMP3File(fileName) || FastFileUtils.isMP3FileByMimeType(contentType);
    }

    public boolean isTargetFile(String... extensions) {
        return FastFileUtils.isTargetFile(uploadFileName, extensions) || FastFileUtils.isTargetFile(fileName, extensions);
    }

    public boolean isTargetFileByMimeType(String... mimeTypes) {
        return FastFileUtils.isTargetFileByMimeType(contentType, mimeTypes);
    }

    public File getFile() {
        return this.attachDirectory != null && this.fileName != null ? new File(this.attachDirectory, this.fileName) : null;
    }

    public boolean exists() {
        return getFile().exists();
    }

    public <E extends FastFile> E moveFile(File targetDirectory) throws FastFileException, IOException {
        return moveFile(targetDirectory.getAbsolutePath());
    }

    public <E extends FastFile> E moveFile(String targetDirectory) throws FastFileException, IOException {
        File targetFile = new File(targetDirectory, fileName);
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetDirectory + "'"));
            }
        }
        File rename = FastChar.getFileRename().rename(targetFile, false);
        if (rename.exists()) {
            rename.delete();
        }
        FastFileUtils.moveFile(getFile(), rename);
        return (E) FastFile.newInstance(paramName, targetDirectory, rename.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E renameTo(File targetFile) throws FastFileException, IOException {
        return renameTo(targetFile, false);
    }

    public <E extends FastFile> E renameTo(File targetFile, boolean force) throws FastFileException, IOException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.moveFile(getFile(), targetFile, force);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E copyTo(File targetFile) throws IOException, FastFileException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.copyFile(getFile(), targetFile);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    /**
     * 删除附件
     * @throws IOException 异常信息
     */
    public void delete() throws IOException {
        FastFileUtils.forceDelete(getFile());
    }

    /**
     * 获取附件的访问地址
     * @return 字符串
     * @throws Exception 异常信息
     */
    public String getUrl() throws Exception {
        if (getFile() == null) {
            return null;
        }
        String replace = getFile().getAbsolutePath().replace(FastChar.getPath().getWebRootPath(), "");
        return FastStringUtils.strip(replace, "/");
    }

    /**
     * 设置附件的扩展属性
     * @param name 属性名
     * @param value 属性值
     */
    public void setAttr(String name, Object value) {
        this.attrs.put(name, value);
    }

    /**
     * 判断是否存在扩展属性
     * @param name 属性名
     * @return 布尔值
     */
    public boolean existAttr(String name) {
        return this.attrs.contains(name);
    }

    /**
     * 获取扩展属性值
     * @param name 属性名
     * @return Object
     */
    public Object getAttr(String name) {
        return this.attrs.get(name);
    }

    /**
     * 获取附件扩展属性Map对象
     * @return FastMapWrap对象
     */
    public FastMapWrap getAttrWrap() {
        return mapWrap;
    }

    /**
     * 获取附件所有的扩展属性值
     * @return ConcurrentHashMap对象
     */
    public ConcurrentHashMap<String, Object> getAttrs() {
        return attrs;
    }
}


try {
                    this.uploadFileName = URLDecoder.decode(this.uploadFileName, FastChar.getConstant().getDecodeUploadFileNameEncoding());
                } catch (Exception e) {
                    e.printStackTrace();
                }

package com.fastchar.core;

import com.fastchar.exception.FastFileException;
import com.fastchar.local.FastCharLocal;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastFileUtils;
import com.fastchar.utils.FastMD5Utils;
import com.fastchar.utils.FastStringUtils;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * FastChar核心文件操作类
 * @author 沈建（Janesen）
 * @param <T>
 */
@SuppressWarnings("unchecked")
public class FastFile<T> {

    public static FastFile<?> newInstance(String paramName, String attachDirectory, String fileName, String originalFileName, String contentType) {
        return FastChar.getOverrides().newInstance(FastFile.class).setParamName(paramName).setAttachDirectory(attachDirectory).setFileName(fileName).setUploadFileName(originalFileName).setContentType(contentType);
    }

    public static FastFile<?> newInstance(String attachDirectory, String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(attachDirectory).setFileName(fileName).setParamName(fileName);
    }

    public static FastFile<?> newInstance(String fileName) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(FastChar.getConstant().getAttachDirectory()).setParamName(fileName).setFileName(fileName);
    }

    public static FastFile<?> newInstance(File file) {
        return FastChar.getOverrides().newInstance(FastFile.class).setAttachDirectory(file.getParent()).setParamName(file.getName()).setFileName(file.getName());
    }

    protected FastFile() {
    }

    private String key;

    private String paramName;

    private String fileName;

    private String attachDirectory;

    private String uploadFileName;

    private String contentType;

    private final ConcurrentHashMap<String, Object> attrs = new ConcurrentHashMap<>();

    private final FastMapWrap mapWrap = FastMapWrap.newInstance(attrs);

    /**
     * 获取文件的唯一标识key
     * @return 字符串
     */
    public String getKey() {
        if (FastStringUtils.isEmpty(key)) {
            this.key = FastChar.getSecurity().MD5_Encrypt(FastStringUtils.buildOnlyCode(paramName));
        }
        return key;
    }

    /**
     * 设置文件的唯一标识key
     * @param key 唯一标识string
     * @return 当前对象
     */
    public FastFile<T> setKey(String key) {
        this.key = key;
        return this;
    }

    /**
     * 获取附件post提交的参数名
     * @return 字符串
     */
    public String getParamName() {
        return paramName;
    }

    /**
     * 设置附件post提交的参数名
     * @param paramName 参数名
     * @return 当前对象
     */
    public FastFile<T> setParamName(String paramName) {
        this.paramName = paramName;
        return this;
    }

    public String getFileName() {
        return fileName;
    }

    /**
     * 设置附件保存后的文件名
     * @param fileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public String getAttachDirectory() {
        return attachDirectory;
    }

    /**
     * 设置附件保存到文件夹目录地址
     * @param attachDirectory 目录地址
     * @return 当前对象
     */
    public FastFile<T> setAttachDirectory(String attachDirectory) {
        this.attachDirectory = attachDirectory;
        return this;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    /**
     * 设置附件的原始文件名
     * @param uploadFileName 文件名
     * @return 当前对象
     */
    public FastFile<T> setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
        if (FastChar.getConstant().isDecodeUploadFileName()) {
            if (FastStringUtils.isNotEmpty(this.uploadFileName)) {

            }
        }
        return this;
    }

    /**
     * 获取附件的content-type类型
     * @return 字符串
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * 设置附件的content-type类型
     * @param contentType 文件类型
     * @return 当前对象
     */
    public FastFile<T> setContentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    /**
     * 获得文件扩展名，包含(.) 例如：.png
     * @return 字符串
     */
    public String getExtensionName() {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(fileName.lastIndexOf("."));
        }
        return "";
    }

    /**
     * 获取短文件名,不带扩展名，原始文件名：test.png 获取后为：test
     * @param fileName 文件名
     * @return 字符串
     */
    public static String getShortName(String fileName) {
        if (fileName != null && fileName.length() > 0 && fileName.lastIndexOf(".") > -1) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    public boolean isImageFile() {
        return FastFileUtils.isImageFile(uploadFileName) || FastFileUtils.isImageFile(fileName) || FastFileUtils.isImageFileByMimeType(contentType);
    }

    public boolean isTxtFile() {
        return FastFileUtils.isTxtFile(uploadFileName) || FastFileUtils.isTxtFile(fileName) || FastFileUtils.isTxtFileByMimeType(contentType);
    }

    public boolean isExcelFile() {
        return FastFileUtils.isExcelFile(uploadFileName) || FastFileUtils.isExcelFile(fileName) || FastFileUtils.isExcelFileByMimeType(contentType);
    }

    public boolean isWordFile() {
        return FastFileUtils.isWordFile(uploadFileName) || FastFileUtils.isWordFile(fileName) || FastFileUtils.isWordFileByMimeType(contentType);
    }

    public boolean isPDFFile() {
        return FastFileUtils.isPDFFile(uploadFileName) || FastFileUtils.isPDFFile(fileName) || FastFileUtils.isPDFFileByMimeType(contentType);
    }

    public boolean isPPTFile() {
        return FastFileUtils.isPPTFile(uploadFileName) || FastFileUtils.isPPTFile(fileName) || FastFileUtils.isPPTFileByMimeType(contentType);
    }

    public boolean isMP4File() {
        return FastFileUtils.isMP4File(uploadFileName) || FastFileUtils.isMP4File(fileName) || FastFileUtils.isMP4FileByMimeType(contentType);
    }

    public boolean isMOVFile() {
        return FastFileUtils.isMOVFile(uploadFileName) || FastFileUtils.isMOVFile(fileName) || FastFileUtils.isMOVFileByMimeType(contentType);
    }

    public boolean isAVIFile() {
        return FastFileUtils.isAVIFile(uploadFileName) || FastFileUtils.isAVIFile(fileName) || FastFileUtils.isAVIFileByMimeType(contentType);
    }

    public boolean isMP3File() {
        return FastFileUtils.isMP3File(uploadFileName) || FastFileUtils.isMP3File(fileName) || FastFileUtils.isMP3FileByMimeType(contentType);
    }

    public boolean isTargetFile(String... extensions) {
        return FastFileUtils.isTargetFile(uploadFileName, extensions) || FastFileUtils.isTargetFile(fileName, extensions);
    }

    public boolean isTargetFileByMimeType(String... mimeTypes) {
        return FastFileUtils.isTargetFileByMimeType(contentType, mimeTypes);
    }

    public File getFile() {
        return this.attachDirectory != null && this.fileName != null ? new File(this.attachDirectory, this.fileName) : null;
    }

    public boolean exists() {
        return getFile().exists();
    }

    public <E extends FastFile> E moveFile(File targetDirectory) throws FastFileException, IOException {
        return moveFile(targetDirectory.getAbsolutePath());
    }

    public <E extends FastFile> E moveFile(String targetDirectory) throws FastFileException, IOException {
        File targetFile = new File(targetDirectory, fileName);
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetDirectory + "'"));
            }
        }
        File rename = FastChar.getFileRename().rename(targetFile, false);
        if (rename.exists()) {
            rename.delete();
        }
        FastFileUtils.moveFile(getFile(), rename);
        return (E) FastFile.newInstance(paramName, targetDirectory, rename.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E renameTo(File targetFile) throws FastFileException, IOException {
        return renameTo(targetFile, false);
    }

    public <E extends FastFile> E renameTo(File targetFile, boolean force) throws FastFileException, IOException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.moveFile(getFile(), targetFile, force);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    public <E extends FastFile> E copyTo(File targetFile) throws IOException, FastFileException {
        if (!targetFile.getParentFile().exists()) {
            if (!targetFile.getParentFile().mkdirs()) {
                throw new FastFileException(FastChar.getLocal().getInfo(FastCharLocal.FILE_ERROR1, "'" + targetFile.getParent() + "'"));
            }
        }
        FastFileUtils.copyFile(getFile(), targetFile);
        return (E) FastFile.newInstance(paramName, targetFile.getParent(), targetFile.getName(), uploadFileName, contentType);
    }

    /**
     * 删除附件
     * @throws IOException 异常信息
     */
    public void delete() throws IOException {
        FastFileUtils.forceDelete(getFile());
    }

    /**
     * 获取附件的访问地址
     * @return 字符串
     * @throws Exception 异常信息
     */
    public String getUrl() throws Exception {
        if (getFile() == null) {
            return null;
        }
        String replace = getFile().getAbsolutePath().replace(FastChar.getPath().getWebRootPath(), "");
        return FastStringUtils.strip(replace, "/");
    }

    /**
     * 设置附件的扩展属性
     * @param name 属性名
     * @param value 属性值
     */
    public void setAttr(String name, Object value) {
        this.attrs.put(name, value);
    }

    /**
     * 判断是否存在扩展属性
     * @param name 属性名
     * @return 布尔值
     */
    public boolean existAttr(String name) {
        return this.attrs.contains(name);
    }

    /**
     * 获取扩展属性值
     * @param name 属性名
     * @return Object
     */
    public Object getAttr(String name) {
        return this.attrs.get(name);
    }

    /**
     * 获取附件扩展属性Map对象
     * @return FastMapWrap对象
     */
    public FastMapWrap getAttrWrap() {
        return mapWrap;
    }

    /**
     * 获取附件所有的扩展属性值
     * @return ConcurrentHashMap对象
     */
    public ConcurrentHashMap<String, Object> getAttrs() {
        return attrs;
    }
}