com.log4ic.compressor.utils.MemcachedUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.log4ic.compressor.utils.MemcachedUtils.java

Source

/*
 * Dynamic Compressor - Java Library
 * Copyright (c) 2011-2012, IntelligentCode ZhangLixin.
 * All rights reserved.
 * intelligentcodemail@gmail.com
 *
 * GUN GPL 3.0 License
 *
 * http://www.gnu.org/licenses/gpl.html
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.log4ic.compressor.utils;

import com.google.code.yanf4j.core.SocketOption;
import net.rubyeye.xmemcached.CommandFactory;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.transcoders.Transcoder;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.TimeoutException;

/**
 * @author  IntelligentCode
 * @since 2012-03-14
 */
public class MemcachedUtils {
    private MemcachedUtils() throws IOException {
    }

    private static final Logger logger = LoggerFactory.getLogger(MemcachedUtils.class);

    private static String CONFIG_FILE_PATH = "/memcached.xml";

    private static MemcachedClient client;

    private static final byte[] lock = new byte[0];

    public static void setConfigFile(File file) throws FileNotFoundException {
        if (file.exists() && file.isFile()) {
            CONFIG_FILE_PATH = file.getPath();
        } else {
            throw new FileNotFoundException("??");
        }
    }

    private static class MemcachedConfig {
        MemcachedClientBuilder builder;
        boolean enableHeartBeat = true;
        int mergeFactor = 150;
        boolean optimizeMergeBuffer = true;
    }

    private static InetSocketAddress biludAddr(Node node) {
        Node hostNode = node.selectSingleNode("host");
        Node portNode = node.selectSingleNode("port");
        if (hostNode != null && StringUtils.isNotBlank(hostNode.getText()) && portNode != null
                && StringUtils.isNotBlank(portNode.getText())) {
            return new InetSocketAddress(hostNode.getText(), Integer.parseInt(portNode.getText()));
        }
        return null;
    }

    private static class AddressConfig {
        Map<InetSocketAddress, InetSocketAddress> addressMap;
        int[] widgets;
    }

    private static AddressConfig biludAddrMapConfig(List<Node> nodeList) {
        AddressConfig config = new AddressConfig();
        config.addressMap = new LinkedHashMap<InetSocketAddress, InetSocketAddress>();
        List<Integer> weightsList = new ArrayList<Integer>();
        for (Node node : nodeList) {
            Node masterNode = node.selectSingleNode("master");
            Node weightsNode = ((Element) node).attribute("weights");
            int weights = 1;
            if (weightsNode != null) {
                try {
                    weights = Integer.parseInt(weightsNode.getText());
                } catch (Exception e) {
                    //fuck ide
                }
            }
            weightsList.add(weights);
            InetSocketAddress masterAddr;
            if (masterNode != null) {
                masterAddr = biludAddr(masterNode);
            } else {
                masterAddr = biludAddr(node);
            }
            Node standbyNode = node.selectSingleNode("standby");
            InetSocketAddress standbyAddr = null;
            if (standbyNode != null) {
                standbyAddr = biludAddr(standbyNode);
            }
            config.addressMap.put(masterAddr, standbyAddr);
        }
        config.widgets = ArrayUtils.toPrimitive(weightsList.toArray(new Integer[weightsList.size()]));
        return config;
    }

    @SuppressWarnings("unchecked")
    private static MemcachedConfig getMemcachedConfig(InputStream in) throws DocumentException {
        SAXReader reader = new SAXReader();

        MemcachedConfig config = new MemcachedConfig();

        Document doc = reader.read(in);

        logger.debug("??...");
        List<Node> nodeList = doc.selectNodes("/memcached/servers/server");
        if (nodeList.isEmpty()) {
            throw new DocumentException(CONFIG_FILE_PATH + " file memcached.servers server element empty!");
        } else {
            logger.debug("???" + nodeList.size() + ".");
        }

        AddressConfig addrConf = biludAddrMapConfig(nodeList);

        config.builder = new XMemcachedClientBuilder(addrConf.addressMap, addrConf.widgets);

        Element el = (Element) doc.selectSingleNode("/memcached");
        logger.debug("??...");
        Attribute attr = el.attribute("connectionPoolSize");
        if (attr != null) {
            String connPoolSize = attr.getValue();
            if (StringUtils.isNotBlank(connPoolSize)) {
                try {
                    config.builder.setConnectionPoolSize(Integer.parseInt(connPoolSize));
                    logger.debug("?" + connPoolSize);
                } catch (Exception e) {
                    logger.error("???", e);
                }
            } else {
                logger.error("???");
            }
        } else {
            logger.warn("??");
        }
        logger.debug("??...");
        attr = el.attribute("enableHeartBeat");
        if (attr != null) {
            String enableHeartBeatS = attr.getValue();
            if (StringUtils.isNotBlank(enableHeartBeatS)) {
                try {
                    config.enableHeartBeat = Boolean.parseBoolean(enableHeartBeatS);
                    logger.debug("???" + enableHeartBeatS);
                } catch (Exception e) {
                    logger.error("?????", e);
                }
            } else {
                logger.error("?????");
            }
        } else {
            logger.warn("????");
        }
        logger.debug("?...");
        attr = el.attribute("sessionIdleTimeout");
        if (attr != null) {
            String sessionIdleTimeout = attr.getValue();
            if (StringUtils.isNotBlank(sessionIdleTimeout)) {
                try {
                    config.builder.getConfiguration().setSessionIdleTimeout(Long.parseLong(sessionIdleTimeout));
                    logger.debug("?" + sessionIdleTimeout);
                } catch (Exception e) {
                    logger.error("???", e);
                }
            } else {
                logger.error("???");
            }
        } else {
            logger.warn("??");
        }
        //?
        logger.debug("?...");
        attr = el.attribute("statisticsServer");
        if (attr != null) {
            String statisticsServer = attr.getValue();
            if (StringUtils.isNotBlank(statisticsServer)) {
                try {
                    config.builder.getConfiguration().setStatisticsServer(Boolean.parseBoolean(statisticsServer));
                    logger.debug("?" + statisticsServer);
                } catch (Exception e) {
                    logger.error("???", e);
                }
            } else {
                logger.error("???");
            }
        } else {
            logger.warn("??");
        }
        logger.debug("?...");
        attr = el.attribute("statisticsInterval");
        if (attr != null) {
            String statisticsInterval = attr.getValue();
            if (StringUtils.isNotBlank(statisticsInterval)) {
                try {
                    config.builder.getConfiguration().setStatisticsInterval(Long.parseLong(statisticsInterval));
                    logger.debug("?" + statisticsInterval);
                } catch (Exception e) {
                    logger.error("???", e);
                }
            } else {
                logger.error("???");
            }
        } else {
            logger.warn("??");
        }
        logger.debug("????...");
        attr = el.attribute("optimizeMergeBuffer");
        if (attr != null) {
            String optimizeMergeBufferS = attr.getValue();
            if (StringUtils.isNotBlank(optimizeMergeBufferS)) {
                try {
                    config.optimizeMergeBuffer = Boolean.parseBoolean(optimizeMergeBufferS);
                    logger.debug("????" + optimizeMergeBufferS);
                } catch (Exception e) {
                    logger.error("??????", e);
                }
            } else {
                logger.error("??????");
            }
        } else {
            logger.warn("?????");
        }
        logger.debug("??...");
        attr = el.attribute("mergeFactor");
        if (attr != null) {
            String mergeFactorS = attr.getValue();
            if (StringUtils.isNotBlank(mergeFactorS)) {
                try {
                    config.mergeFactor = Integer.parseInt(mergeFactorS);
                    logger.debug("?" + mergeFactorS);
                } catch (Exception e) {
                    logger.error("???", e);
                }
            } else {
                logger.error("???");
            }
        } else {
            logger.warn("??");
        }
        logger.debug("??...");
        attr = el.attribute("commandFactory");
        if (attr != null) {
            String commandFactory = attr.getValue();
            if (StringUtils.isNotBlank(commandFactory)) {
                try {
                    config.builder.setCommandFactory((CommandFactory) Class.forName(commandFactory).newInstance());
                    logger.debug("??" + commandFactory);
                } catch (Exception e) {
                    logger.error("????", e);
                }
            } else {
                logger.error("????");
            }
        } else {
            logger.warn("???");
        }
        config.builder.setCommandFactory(new BinaryCommandFactory());
        logger.debug("...");
        nodeList = doc.selectNodes("/memcached/socketOption/*");
        if (!nodeList.isEmpty()) {
            for (Node n : nodeList) {
                try {
                    attr = ((Element) n).attribute("type");
                    if (attr == null) {
                        logger.error("type attribute undefined");
                    } else {
                        String type = attr.getValue();
                        if (StringUtils.isNotBlank(type)) {
                            String name = n.getName();
                            String value = n.getStringValue();
                            Class valueType = Class.forName(type);
                            Constructor constructor = SocketOption.class.getConstructor(String.class, Class.class);
                            SocketOption socketOption = (SocketOption) constructor.newInstance(name, valueType);
                            constructor = valueType.getConstructor(String.class);
                            config.builder.setSocketOption(socketOption, constructor.newInstance(value));
                            logger.debug("[" + name + "]" + value);
                        }
                    }
                } catch (NoSuchMethodException e) {
                    logger.error("NoSuchMethodException", e);
                } catch (InvocationTargetException e) {
                    logger.error("InvocationTargetException", e);
                } catch (InstantiationException e) {
                    logger.error("InstantiationException", e);
                } catch (IllegalAccessException e) {
                    logger.error("IllegalAccessException", e);
                } catch (ClassNotFoundException e) {
                    logger.error("ClassNotFoundException", e);
                }
            }
        } else {
            logger.warn("?");
        }
        logger.debug("Failure?...");
        attr = el.attribute("failureMode");
        if (attr != null) {
            String failureMode = attr.getValue();
            if (StringUtils.isNotBlank(failureMode)) {
                try {
                    config.builder.setFailureMode(Boolean.parseBoolean(failureMode));
                    logger.debug("Failure?" + failureMode);
                } catch (Exception e) {
                    logger.error("Failure???", e);
                }
            } else {
                logger.error("Failure???");
            }
        } else {
            logger.warn("Failure??");
        }
        return config;
    }

    public static MemcachedClient getMemcachedClient(InputStream in) throws DocumentException, IOException {
        MemcachedConfig config = getMemcachedConfig(in);
        MemcachedClient mc = config.builder.build();
        mc.setEnableHeartBeat(config.enableHeartBeat);
        mc.setOptimizeMergeBuffer(config.optimizeMergeBuffer);
        mc.setMergeFactor(config.mergeFactor);
        return mc;
    }

    public static MemcachedClient getSingleMemcachedClient() {
        if (client == null) {
            synchronized (lock) {
                if (client == null || client.isShutdown()) {
                    try {
                        logger.debug("?Memcached?:" + CONFIG_FILE_PATH);
                        InputStream in = FileUtils.getResourceAsStream(CONFIG_FILE_PATH);
                        if (in == null) {
                            CONFIG_FILE_PATH = "/conf" + CONFIG_FILE_PATH;
                            logger.debug("?Memcached?:" + CONFIG_FILE_PATH);
                            in = FileUtils.getResourceAsStream(CONFIG_FILE_PATH);
                        }
                        if (in == null) {
                            logger.error(CONFIG_FILE_PATH + " file not exists!");
                        } else {
                            try {
                                client = getMemcachedClient(in);
                            } catch (DocumentException e) {
                                logger.error("", e);
                            } finally {
                                in.close();
                            }
                        }
                    } catch (IOException e) {
                        logger.error("memcached?", e);
                    }
                }
            }
        }
        return client;
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(final String key, final long timeout, final Transcoder<T> transcoder)
            throws MemcachedException, TimeoutException, InterruptedException {
        return (T) getSingleMemcachedClient().get(key, timeout, transcoder);
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(final String key, final Transcoder<T> transcoder)
            throws MemcachedException, TimeoutException, InterruptedException {
        return (T) getSingleMemcachedClient().get(key, transcoder);
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(final String key) throws MemcachedException, TimeoutException, InterruptedException {
        return (T) getSingleMemcachedClient().get(key);
    }

    public static <T> Map<String, T> get(final Collection<String> keyCollections)
            throws TimeoutException, InterruptedException, MemcachedException {
        return getSingleMemcachedClient().get(keyCollections);
    }

    public static boolean set(final String key, final int exp, final Object value)
            throws TimeoutException, InterruptedException, MemcachedException {
        return getSingleMemcachedClient().set(key, exp, value);
    }

    public static void setWithNoReply(final String key, final int exp, final Object value)
            throws InterruptedException, MemcachedException {
        getSingleMemcachedClient().setWithNoReply(key, exp, value);
    }

    public static boolean delete(final String key)
            throws TimeoutException, InterruptedException, MemcachedException {
        return getSingleMemcachedClient().delete(key);
    }

    public static boolean touch(final String key, int exp)
            throws TimeoutException, InterruptedException, MemcachedException {
        return getSingleMemcachedClient().touch(key, exp);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getAndTouch(final String key, int newExp)
            throws TimeoutException, InterruptedException, MemcachedException {
        return (T) getSingleMemcachedClient().getAndTouch(key, newExp);
    }

    public static void shutdown() throws IOException {
        getSingleMemcachedClient().shutdown();
    }

}