xueli.xue hace 9 años
padre
commit
0e80541360
Se han modificado 25 ficheros con 11223 adiciones y 284 borrados
  1. 0 0
      doc/db/tables_xxl_job.sql
  2. 22 0
      xxl-job-admin/src/main/java/com/xxl/job/controller/JobCodeController.java
  3. 32 41
      xxl-job-admin/src/main/java/com/xxl/job/controller/JobInfoController.java
  4. 93 92
      xxl-job-admin/src/main/java/com/xxl/job/service/job/LocalNomalJobBean.java
  5. 29 28
      xxl-job-admin/src/main/java/com/xxl/job/service/job/impl/DemoConcurrentJobBean.java
  6. 31 30
      xxl-job-admin/src/main/java/com/xxl/job/service/job/impl/DemoNomalJobBean.java
  7. 1 1
      xxl-job-admin/src/main/resources/jdbc.properties
  8. 1 1
      xxl-job-admin/src/main/webapp/WEB-INF/template/common/common.exception.ftl
  9. 4 2
      xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl
  10. 105 0
      xxl-job-admin/src/main/webapp/WEB-INF/template/jobcode/index.ftl
  11. 29 45
      xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/index.ftl
  12. 4 2
      xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/index.ftl
  13. 1 1
      xxl-job-admin/src/main/webapp/static/js/common.1.js
  14. 16 0
      xxl-job-admin/src/main/webapp/static/js/jobcode.index.1.js
  15. 18 35
      xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js
  16. 41 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/anyword-hint.js
  17. 38 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/show-hint.css
  18. 447 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/show-hint.js
  19. 338 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/lib/codemirror.css
  20. 8895 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/lib/codemirror.js
  21. 781 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/clike/clike.js
  22. 51 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/clike/test.js
  23. 230 0
      xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/groovy/groovy.js
  24. 10 6
      xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerThread.java
  25. 6 0
      xxl-job-client/src/main/java/com/xxl/job/client/util/HttpUtil.java

doc/db/tables_xxl_log.sql → doc/db/tables_xxl_job.sql Ver fichero


+ 22 - 0
xxl-job-admin/src/main/java/com/xxl/job/controller/JobCodeController.java Ver fichero

@@ -0,0 +1,22 @@
1
+package com.xxl.job.controller;
2
+
3
+import javax.servlet.http.HttpServletRequest;
4
+
5
+import org.springframework.stereotype.Controller;
6
+import org.springframework.ui.Model;
7
+import org.springframework.web.bind.annotation.RequestMapping;
8
+
9
+/**
10
+ * job code controller
11
+ * @author xuxueli 2015-12-19 16:13:16
12
+ */
13
+@Controller
14
+@RequestMapping("/jobcode")
15
+public class JobCodeController {
16
+
17
+	@RequestMapping
18
+	public String index(Model model, HttpServletRequest request) {
19
+		return "jobcode/index";
20
+	}
21
+	
22
+}

+ 32 - 41
xxl-job-admin/src/main/java/com/xxl/job/controller/JobInfoController.java Ver fichero

@@ -1,6 +1,5 @@
1 1
 package com.xxl.job.controller;
2 2
 
3
-import java.util.ArrayList;
4 3
 import java.util.HashMap;
5 4
 import java.util.List;
6 5
 import java.util.Map;
@@ -9,7 +8,6 @@ import javax.annotation.Resource;
9 8
 
10 9
 import org.apache.commons.lang.StringUtils;
11 10
 import org.quartz.CronExpression;
12
-import org.quartz.Job;
13 11
 import org.quartz.SchedulerException;
14 12
 import org.springframework.stereotype.Controller;
15 13
 import org.springframework.ui.Model;
@@ -25,14 +23,11 @@ import com.xxl.job.core.model.XxlJobInfo;
25 23
 import com.xxl.job.core.util.DynamicSchedulerUtil;
26 24
 import com.xxl.job.dao.IXxlJobInfoDao;
27 25
 import com.xxl.job.service.job.RemoteHttpJobBean;
28
-import com.xxl.job.service.job.impl.DemoConcurrentJobBean;
29
-import com.xxl.job.service.job.impl.DemoNomalJobBean;
30 26
 
31 27
 /**
32 28
  * index controller
33 29
  * @author xuxueli 2015-12-19 16:13:16
34 30
  */
35
-@SuppressWarnings("unchecked")
36 31
 @Controller
37 32
 @RequestMapping("/jobinfo")
38 33
 public class JobInfoController {
@@ -40,19 +35,8 @@ public class JobInfoController {
40 35
 	@Resource
41 36
 	private IXxlJobInfoDao xxlJobInfoDao;
42 37
 	
43
-	// remote job bean
44
-	public static Class <? extends Job> remoteJobBean = RemoteHttpJobBean.class;
45
-	// loacal job bean
46
-	public static List<Class <? extends Job>> localJobBeanList = new ArrayList<Class<? extends Job>>();
47
-	static{
48
-		localJobBeanList.add((Class<? extends Job>) DemoNomalJobBean.class);
49
-		localJobBeanList.add((Class<? extends Job>) DemoConcurrentJobBean.class);
50
-	}
51
-	
52 38
 	@RequestMapping
53 39
 	public String index(Model model) {
54
-		model.addAttribute("localJobBeanList", localJobBeanList);			// 本地任务-列表
55
-		model.addAttribute("remoteJobBean", remoteJobBean);	// 远程任务-jobBean
56 40
 		model.addAttribute("JobGroupList", JobGroupEnum.values());			// 任务组列表
57 41
 		return "jobinfo/index";
58 42
 	}
@@ -84,8 +68,8 @@ public class JobInfoController {
84 68
 	
85 69
 	@RequestMapping("/add")
86 70
 	@ResponseBody
87
-	public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc, String jobClass,
88
-			String handler_params, String handler_address, String handler_name, 
71
+	public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc,
72
+			String handler_address, String handler_name, String handler_params, 
89 73
 			String author, String alarmEmail, int alarmThreshold) {
90 74
 		
91 75
 		// valid
@@ -101,25 +85,11 @@ public class JobInfoController {
101 85
 		if (StringUtils.isBlank(jobDesc)) {
102 86
 			return new ReturnT<String>(500, "请输入“任务描述”");
103 87
 		}
104
-		Class<? extends Job> jobClass_ = null;
105
-		try {
106
-			Class<?> clazz = Class.forName(jobClass);
107
-			if (clazz!=null) {
108
-				jobClass_ = (Class<? extends Job>) clazz;
109
-			}
110
-		} catch (ClassNotFoundException e1) {
111
-			e1.printStackTrace();
88
+		if (StringUtils.isBlank(handler_address)) {
89
+			return new ReturnT<String>(500, "请输入“机器地址”");
112 90
 		}
113
-		if (jobClass_ == null) {
114
-			return new ReturnT<String>(500, "请选择“JobBean”");
115
-		}
116
-		if (jobClass_.getClass().getName().equals(remoteJobBean.getName())) {
117
-			if (StringUtils.isBlank(handler_address)) {
118
-				return new ReturnT<String>(500, "请输入“远程-机器地址”");
119
-			}
120
-			if (StringUtils.isBlank(handler_name)) {
121
-				return new ReturnT<String>(500, "请输入“远程-执行器”");
122
-			}
91
+		if (StringUtils.isBlank(handler_name)) {
92
+			return new ReturnT<String>(500, "请输入“执行器”");
123 93
 		}
124 94
 		if (StringUtils.isBlank(author)) {
125 95
 			return new ReturnT<String>(500, "请输入“负责人”");
@@ -127,6 +97,9 @@ public class JobInfoController {
127 97
 		if (StringUtils.isBlank(alarmEmail)) {
128 98
 			return new ReturnT<String>(500, "请输入“报警邮件”");
129 99
 		}
100
+		if (alarmThreshold < 0) {
101
+			alarmThreshold = 0;
102
+		}
130 103
 		
131 104
 		try {
132 105
 			if (DynamicSchedulerUtil.checkExists(jobName, jobGroup)) {
@@ -139,9 +112,9 @@ public class JobInfoController {
139 112
 		
140 113
 		// parse jobDataMap
141 114
 		HashMap<String, String> jobDataMap = new HashMap<String, String>();
142
-		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
143 115
 		jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
144 116
 		jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
117
+		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
145 118
 		
146 119
 		// Backup to the database
147 120
 		XxlJobInfo jobInfo = new XxlJobInfo();
@@ -149,7 +122,7 @@ public class JobInfoController {
149 122
 		jobInfo.setJobName(jobName);
150 123
 		jobInfo.setJobCron(jobCron);
151 124
 		jobInfo.setJobDesc(jobDesc);
152
-		jobInfo.setJobClass(jobClass);
125
+		jobInfo.setJobClass(RemoteHttpJobBean.class.getName());
153 126
 		jobInfo.setJobData(JacksonUtil.writeValueAsString(jobDataMap));
154 127
 		jobInfo.setAuthor(author);
155 128
 		jobInfo.setAlarmEmail(alarmEmail);
@@ -173,8 +146,8 @@ public class JobInfoController {
173 146
 	
174 147
 	@RequestMapping("/reschedule")
175 148
 	@ResponseBody
176
-	public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String jobClass,
177
-			String handler_params, String handler_address, String handler_name, 
149
+	public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc,
150
+			String handler_address, String handler_name, String handler_params, 
178 151
 			String author, String alarmEmail, int alarmThreshold) {
179 152
 		
180 153
 		// valid
@@ -187,12 +160,30 @@ public class JobInfoController {
187 160
 		if (!CronExpression.isValidExpression(jobCron)) {
188 161
 			return new ReturnT<String>(500, "“corn”不合法");
189 162
 		}
163
+		if (StringUtils.isBlank(jobDesc)) {
164
+			return new ReturnT<String>(500, "请输入“任务描述”");
165
+		}
166
+		if (StringUtils.isBlank(handler_address)) {
167
+			return new ReturnT<String>(500, "请输入“机器地址”");
168
+		}
169
+		if (StringUtils.isBlank(handler_name)) {
170
+			return new ReturnT<String>(500, "请输入“执行器”");
171
+		}
172
+		if (StringUtils.isBlank(author)) {
173
+			return new ReturnT<String>(500, "请输入“负责人”");
174
+		}
175
+		if (StringUtils.isBlank(alarmEmail)) {
176
+			return new ReturnT<String>(500, "请输入“报警邮件”");
177
+		}
178
+		if (alarmThreshold < 0) {
179
+			alarmThreshold = 0;
180
+		}
190 181
 		
191 182
 		// parse jobDataMap
192 183
 		HashMap<String, String> jobDataMap = new HashMap<String, String>();
193
-		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
194 184
 		jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
195 185
 		jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
186
+		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
196 187
 		
197 188
 		XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
198 189
 		jobInfo.setJobCron(jobCron);

+ 93 - 92
xxl-job-admin/src/main/java/com/xxl/job/service/job/LocalNomalJobBean.java Ver fichero

@@ -1,92 +1,93 @@
1
-package com.xxl.job.service.job;
2
-
3
-import java.io.PrintWriter;
4
-import java.io.StringWriter;
5
-import java.util.Date;
6
-import java.util.HashMap;
7
-import java.util.Map;
8
-
9
-import org.apache.commons.lang.StringUtils;
10
-import org.quartz.JobExecutionContext;
11
-import org.quartz.JobExecutionException;
12
-import org.quartz.JobKey;
13
-import org.slf4j.Logger;
14
-import org.slf4j.LoggerFactory;
15
-import org.springframework.scheduling.quartz.QuartzJobBean;
16
-
17
-import com.xxl.job.client.handler.HandlerRepository;
18
-import com.xxl.job.client.util.HttpUtil.RemoteCallBack;
19
-import com.xxl.job.client.util.JacksonUtil;
20
-import com.xxl.job.core.model.XxlJobInfo;
21
-import com.xxl.job.core.model.XxlJobLog;
22
-import com.xxl.job.core.thread.JobMonitorHelper;
23
-import com.xxl.job.core.util.DynamicSchedulerUtil;
24
-
25
-/**
26
- * http job bean
27
- * @author xuxueli 2015-12-17 18:20:34
28
- */
29
-public abstract class LocalNomalJobBean extends QuartzJobBean {
30
-	private static Logger logger = LoggerFactory.getLogger(LocalNomalJobBean.class);
31
-
32
-	@Override
33
-	protected void executeInternal(JobExecutionContext context)
34
-			throws JobExecutionException {
35
-		JobKey jobKey = context.getTrigger().getJobKey();
36
-		
37
-		XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKey.getGroup(), jobKey.getName());
38
-		@SuppressWarnings("unchecked")
39
-		HashMap<String, String> jobDataMap = (HashMap<String, String>) JacksonUtil.readValueRefer(jobInfo.getJobData(), Map.class);
40
-		
41
-		// save log
42
-		XxlJobLog jobLog = new XxlJobLog();
43
-		jobLog.setJobGroup(jobInfo.getJobGroup());
44
-		jobLog.setJobName(jobInfo.getJobName());
45
-		jobLog.setJobCron(jobInfo.getJobCron());
46
-		jobLog.setJobDesc(jobInfo.getJobDesc());
47
-		jobLog.setJobClass(jobInfo.getJobClass());
48
-		jobLog.setJobData(jobInfo.getJobData());
49
-		
50
-		jobLog.setJobClass(RemoteHttpJobBean.class.getName());
51
-		jobLog.setJobData(jobInfo.getJobData());
52
-		DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
53
-		logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
54
-		
55
-		// trigger request
56
-		String handler_params = jobDataMap.get(HandlerRepository.HANDLER_PARAMS);
57
-		String[] handlerParams = null;
58
-		if (StringUtils.isNotBlank(handler_params)) {
59
-			handlerParams = handler_params.split(",");
60
-		}
61
-		
62
-		jobLog.setTriggerTime(new Date());
63
-		jobLog.setTriggerStatus(RemoteCallBack.SUCCESS);
64
-		jobLog.setTriggerMsg(null);
65
-		
66
-		try {
67
-			Object responseMsg = this.handle(handlerParams);
68
-			
69
-			jobLog.setHandleTime(new Date());
70
-			jobLog.setHandleStatus(RemoteCallBack.SUCCESS);
71
-			jobLog.setHandleMsg(JacksonUtil.writeValueAsString(responseMsg));
72
-		} catch (Exception e) {
73
-			logger.info("HandlerThread Exception:", e);
74
-			StringWriter out = new StringWriter();
75
-			e.printStackTrace(new PrintWriter(out));
76
-			
77
-			jobLog.setHandleTime(new Date());
78
-			jobLog.setHandleStatus(RemoteCallBack.FAIL);
79
-			jobLog.setHandleMsg(out.toString());
80
-		}
81
-		
82
-		// update trigger info
83
-		DynamicSchedulerUtil.xxlJobLogDao.updateTriggerInfo(jobLog);
84
-		DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(jobLog);
85
-		JobMonitorHelper.monitor(jobLog.getId());
86
-		logger.info(">>>>>>>>>>> xxl-job trigger end, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
87
-		
88
-    }
89
-	
90
-	public abstract Object handle(String... param);
91
-	
92
-}
1
+//package com.xxl.job.service.job;
2
+//
3
+//import java.io.PrintWriter;
4
+//import java.io.StringWriter;
5
+//import java.util.Date;
6
+//import java.util.HashMap;
7
+//import java.util.Map;
8
+//
9
+//import org.apache.commons.lang.StringUtils;
10
+//import org.quartz.JobExecutionContext;
11
+//import org.quartz.JobExecutionException;
12
+//import org.quartz.JobKey;
13
+//import org.slf4j.Logger;
14
+//import org.slf4j.LoggerFactory;
15
+//import org.springframework.scheduling.quartz.QuartzJobBean;
16
+//
17
+//import com.xxl.job.client.handler.HandlerRepository;
18
+//import com.xxl.job.client.util.HttpUtil.RemoteCallBack;
19
+//import com.xxl.job.client.util.JacksonUtil;
20
+//import com.xxl.job.core.model.XxlJobInfo;
21
+//import com.xxl.job.core.model.XxlJobLog;
22
+//import com.xxl.job.core.thread.JobMonitorHelper;
23
+//import com.xxl.job.core.util.DynamicSchedulerUtil;
24
+//
25
+///**
26
+// * http job bean
27
+// * @author xuxueli 2015-12-17 18:20:34
28
+// */
29
+//@Deprecated
30
+//public abstract class LocalNomalJobBean extends QuartzJobBean {
31
+//	private static Logger logger = LoggerFactory.getLogger(LocalNomalJobBean.class);
32
+//
33
+//	@Override
34
+//	protected void executeInternal(JobExecutionContext context)
35
+//			throws JobExecutionException {
36
+//		JobKey jobKey = context.getTrigger().getJobKey();
37
+//		
38
+//		XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKey.getGroup(), jobKey.getName());
39
+//		@SuppressWarnings("unchecked")
40
+//		HashMap<String, String> jobDataMap = (HashMap<String, String>) JacksonUtil.readValueRefer(jobInfo.getJobData(), Map.class);
41
+//		
42
+//		// save log
43
+//		XxlJobLog jobLog = new XxlJobLog();
44
+//		jobLog.setJobGroup(jobInfo.getJobGroup());
45
+//		jobLog.setJobName(jobInfo.getJobName());
46
+//		jobLog.setJobCron(jobInfo.getJobCron());
47
+//		jobLog.setJobDesc(jobInfo.getJobDesc());
48
+//		jobLog.setJobClass(jobInfo.getJobClass());
49
+//		jobLog.setJobData(jobInfo.getJobData());
50
+//		
51
+//		jobLog.setJobClass(RemoteHttpJobBean.class.getName());
52
+//		jobLog.setJobData(jobInfo.getJobData());
53
+//		DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
54
+//		logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
55
+//		
56
+//		// trigger request
57
+//		String handler_params = jobDataMap.get(HandlerRepository.HANDLER_PARAMS);
58
+//		String[] handlerParams = null;
59
+//		if (StringUtils.isNotBlank(handler_params)) {
60
+//			handlerParams = handler_params.split(",");
61
+//		}
62
+//		
63
+//		jobLog.setTriggerTime(new Date());
64
+//		jobLog.setTriggerStatus(RemoteCallBack.SUCCESS);
65
+//		jobLog.setTriggerMsg(null);
66
+//		
67
+//		try {
68
+//			Object responseMsg = this.handle(handlerParams);
69
+//			
70
+//			jobLog.setHandleTime(new Date());
71
+//			jobLog.setHandleStatus(RemoteCallBack.SUCCESS);
72
+//			jobLog.setHandleMsg(JacksonUtil.writeValueAsString(responseMsg));
73
+//		} catch (Exception e) {
74
+//			logger.info("HandlerThread Exception:", e);
75
+//			StringWriter out = new StringWriter();
76
+//			e.printStackTrace(new PrintWriter(out));
77
+//			
78
+//			jobLog.setHandleTime(new Date());
79
+//			jobLog.setHandleStatus(RemoteCallBack.FAIL);
80
+//			jobLog.setHandleMsg(out.toString());
81
+//		}
82
+//		
83
+//		// update trigger info
84
+//		DynamicSchedulerUtil.xxlJobLogDao.updateTriggerInfo(jobLog);
85
+//		DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(jobLog);
86
+//		JobMonitorHelper.monitor(jobLog.getId());
87
+//		logger.info(">>>>>>>>>>> xxl-job trigger end, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
88
+//		
89
+//    }
90
+//	
91
+//	public abstract Object handle(String... param);
92
+//	
93
+//}

+ 29 - 28
xxl-job-admin/src/main/java/com/xxl/job/service/job/impl/DemoConcurrentJobBean.java Ver fichero

@@ -1,28 +1,29 @@
1
-package com.xxl.job.service.job.impl;
2
-
3
-import java.util.concurrent.TimeUnit;
4
-
5
-import org.quartz.DisallowConcurrentExecution;
6
-
7
-import com.xxl.job.service.job.LocalNomalJobBean;
8
-
9
-/**
10
- * demo job bean for no-concurrent
11
- * @author xuxueli 2016-3-12 14:25:14
12
- */
13
-@DisallowConcurrentExecution	// 串行;线程数要多配置几个,否则不生效;
14
-public class DemoConcurrentJobBean extends LocalNomalJobBean {
15
-
16
-	@Override
17
-	public Object handle(String... param) {
18
-		
19
-		try {
20
-			TimeUnit.SECONDS.sleep(10);
21
-		} catch (InterruptedException e) {
22
-			e.printStackTrace();
23
-		}
24
-		
25
-		return false;
26
-	}
27
-
28
-}
1
+//package com.xxl.job.service.job.impl;
2
+//
3
+//import java.util.concurrent.TimeUnit;
4
+//
5
+//import org.quartz.DisallowConcurrentExecution;
6
+//
7
+//import com.xxl.job.service.job.LocalNomalJobBean;
8
+//
9
+///**
10
+// * demo job bean for no-concurrent
11
+// * @author xuxueli 2016-3-12 14:25:14
12
+// */
13
+//@Deprecated
14
+//@DisallowConcurrentExecution	// 串行;线程数要多配置几个,否则不生效;
15
+//public class DemoConcurrentJobBean extends LocalNomalJobBean {
16
+//
17
+//	@Override
18
+//	public Object handle(String... param) {
19
+//		
20
+//		try {
21
+//			TimeUnit.SECONDS.sleep(10);
22
+//		} catch (InterruptedException e) {
23
+//			e.printStackTrace();
24
+//		}
25
+//		
26
+//		return false;
27
+//	}
28
+//
29
+//}

+ 31 - 30
xxl-job-admin/src/main/java/com/xxl/job/service/job/impl/DemoNomalJobBean.java Ver fichero

@@ -1,30 +1,31 @@
1
-package com.xxl.job.service.job.impl;
2
-
3
-import java.util.concurrent.TimeUnit;
4
-
5
-import org.slf4j.Logger;
6
-import org.slf4j.LoggerFactory;
7
-
8
-import com.xxl.job.service.job.LocalNomalJobBean;
9
-
10
-/**
11
- * demo job bean for concurrent
12
- * @author xuxueli 2016-3-12 14:25:57
13
- */
14
-public class DemoNomalJobBean extends LocalNomalJobBean {
15
-	private static Logger Logger = LoggerFactory.getLogger(DemoNomalJobBean.class);
16
-	
17
-	@Override
18
-	public Object handle(String... param) {
19
-		Logger.info("DemoNomalJobBean run :" + param);
20
-		
21
-		try {
22
-			TimeUnit.SECONDS.sleep(10);
23
-		} catch (InterruptedException e) {
24
-			e.printStackTrace();
25
-		}
26
-		
27
-		return false;
28
-	}
29
-
30
-}
1
+//package com.xxl.job.service.job.impl;
2
+//
3
+//import java.util.concurrent.TimeUnit;
4
+//
5
+//import org.slf4j.Logger;
6
+//import org.slf4j.LoggerFactory;
7
+//
8
+//import com.xxl.job.service.job.LocalNomalJobBean;
9
+//
10
+///**
11
+// * demo job bean for concurrent
12
+// * @author xuxueli 2016-3-12 14:25:57
13
+// */
14
+//@Deprecated
15
+//public class DemoNomalJobBean extends LocalNomalJobBean {
16
+//	private static Logger Logger = LoggerFactory.getLogger(DemoNomalJobBean.class);
17
+//	
18
+//	@Override
19
+//	public Object handle(String... param) {
20
+//		Logger.info("DemoNomalJobBean run :" + param);
21
+//		
22
+//		try {
23
+//			TimeUnit.SECONDS.sleep(10);
24
+//		} catch (InterruptedException e) {
25
+//			e.printStackTrace();
26
+//		}
27
+//		
28
+//		return false;
29
+//	}
30
+//
31
+//}

+ 1 - 1
xxl-job-admin/src/main/resources/jdbc.properties Ver fichero

@@ -1,4 +1,4 @@
1 1
 c3p0.driverClass=com.mysql.jdbc.Driver
2
-c3p0.url=jdbc:mysql://localhost:3306/test?Unicode=true&amp;characterEncoding=UTF-8
2
+c3p0.url=jdbc:mysql://localhost:3306/xxl-job?Unicode=true&amp;characterEncoding=UTF-8
3 3
 c3p0.user=root
4 4
 c3p0.password=root_pwd

+ 1 - 1
xxl-job-admin/src/main/webapp/WEB-INF/template/common/common.exception.ftl Ver fichero

@@ -24,7 +24,7 @@
24 24
 	    <h1>应用程序异常</h1> 
25 25
 	    <p>抱歉!您访问的页面出现异常,请稍后重试或联系管理员。</p> 
26 26
 	    <p><a href="javascript:showErr();">详 情</a> 
27
-		<a href="javascript:window.location.href='${request.contextPath}'">返 回</a> 
27
+		<a href="javascript:window.location.href='${request.contextPath}/'">返 回</a> 
28 28
 	    </p> 
29 29
 	    <div style="display:none;text-align: left;" id="err">${exceptionMsg}</div>
30 30
 	</div>

+ 4 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl Ver fichero

@@ -1,7 +1,7 @@
1 1
 <!DOCTYPE html>
2 2
 <html>
3 3
 <head>
4
-  	<title>调度中心</title>
4
+  	<title>任务调度中心</title>
5 5
   	<#import "/common/common.macro.ftl" as netCommon>
6 6
 	<@netCommon.commonStyle />
7 7
 </head>
@@ -16,11 +16,13 @@
16 16
 	<div class="content-wrapper">
17 17
 		<!-- Content Header (Page header) -->
18 18
 		<section class="content-header">
19
-			<h1>使用教程<small>调度管理平台</small></h1>
19
+			<h1>任务调度中心<small>使用教程</small></h1>
20
+			<!--
20 21
 			<ol class="breadcrumb">
21 22
 				<li><a><i class="fa fa-dashboard"></i>调度中心</a></li>
22 23
 				<li class="active">使用教程</li>
23 24
 			</ol>
25
+			-->
24 26
 		</section>
25 27
 
26 28
 		<!-- Main content -->

+ 105 - 0
xxl-job-admin/src/main/webapp/WEB-INF/template/jobcode/index.ftl Ver fichero

@@ -0,0 +1,105 @@
1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+  	<title>任务调度中心</title>
5
+  	<#import "/common/common.macro.ftl" as netCommon>
6
+	<@netCommon.commonStyle />
7
+	<link rel="stylesheet" href="${request.contextPath}/static/plugins/codemirror/lib/codemirror.css">
8
+	<link rel="stylesheet" href="${request.contextPath}/static/plugins/codemirror/addon/hint/show-hint.css">
9
+	<style type="text/css">
10
+		.CodeMirror {
11
+      		border: 0px solid black;
12
+      		font-size:16px;
13
+      		height: 95%;
14
+      		row:200;
15
+		}
16
+    </style>
17
+</head>
18
+<body>
19
+
20
+<div class="wrapper">
21
+	
22
+	<div class="content-wrapper">
23
+		<!-- Content Header (Page header) -->
24
+		<section class="content-header">
25
+			<h1>任务调度中心<small>任务CODE管理</small></h1>
26
+		</section>
27
+		
28
+		<!-- Main content -->
29
+	    <section class="content">
30
+	    
31
+	    	<div class="row">
32
+	    		<div class="col-xs-4">
33
+					<div class="input-group margin">
34
+                    	<div class="input-group-btn">
35
+                      		<button type="button" class="btn btn-default">版本回溯</button>
36
+                    	</div>
37
+                    	<select class="form-control" id="jobGroup" >
38
+            				<option value="999" >逻辑调整版本C</option>
39
+            				<option value="999" >逻辑调整版本B</option>
40
+            				<option value="999" >逻辑调整版本A</option>
41
+            				<option value="999" >代码初始化</option>
42
+	                  	</select>
43
+					</div>
44
+	            </div>
45
+	            <div class="col-xs-4">
46
+	            	<div class="input-group margin">
47
+                    	<div class="input-group-btn">
48
+                      		<button type="button" class="btn btn-default">Action</button>
49
+                    	</div>
50
+                    	<input type="text" class="form-control" id="jobName" value="${jobName}" autocomplete="on" >
51
+                  	</div>
52
+	            </div>
53
+	            <div class="col-xs-2">
54
+	            	<div class="input-group margin">
55
+                    	<div class="input-group-btn">
56
+                      		<button type="button" class="btn btn-info">保存</button>
57
+                    	</div>
58
+                  	</div>
59
+	            </div>
60
+          	</div>
61
+	    	
62
+			<div class="row">
63
+				<div class="col-xs-12">
64
+					<div class="box">
65
+						<textarea id="editor" >
66
+package com.xxl.job.service.handler;
67
+
68
+import org.slf4j.Logger;
69
+import org.slf4j.LoggerFactory;
70
+
71
+import com.xxl.job.client.handler.IJobHandler;
72
+
73
+public class DemoJobHandler extends IJobHandler {
74
+	private static transient Logger logger = LoggerFactory.getLogger(DemoJobHandler.class);
75
+	
76
+	@Override
77
+	public JobHandleStatus handle(String... params) throws Exception {
78
+		logger.info(" ... params:" + params);
79
+		for (int i = 0; i < 5; i++) {
80
+			TimeUnit.SECONDS.sleep(1);
81
+			logger.info("handler run:{}", i);
82
+		}
83
+		return JobHandleStatus.SUCCESS;
84
+	}
85
+}
86
+						</textarea>
87
+					</div>
88
+				</div>
89
+			</div>
90
+	    </section>
91
+	</div>
92
+	
93
+	<!-- footer -->
94
+	<@netCommon.commonFooter />
95
+</div>
96
+	
97
+<@netCommon.comAlert />
98
+<@netCommon.commonScript />
99
+<script src="${request.contextPath}/static/plugins/codemirror/lib/codemirror.js"></script>
100
+<script src="${request.contextPath}/static/plugins/codemirror/mode/clike/clike.js"></script>
101
+<script src="${request.contextPath}/static/plugins/codemirror/addon/hint/show-hint.js"></script>
102
+<script src="${request.contextPath}/static/plugins/codemirror/addon/hint/anyword-hint.js"></script>
103
+<script src="${request.contextPath}/static/js/jobcode.index.1.js"></script>
104
+</body>
105
+</html>

+ 29 - 45
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/index.ftl Ver fichero

@@ -1,7 +1,7 @@
1 1
 <!DOCTYPE html>
2 2
 <html>
3 3
 <head>
4
-  	<title>调度中心</title>
4
+  	<title>任务调度中心</title>
5 5
   	<#import "/common/common.macro.ftl" as netCommon>
6 6
 	<@netCommon.commonStyle />
7 7
 	<!-- DataTables -->
@@ -19,11 +19,13 @@
19 19
 	<div class="content-wrapper">
20 20
 		<!-- Content Header (Page header) -->
21 21
 		<section class="content-header">
22
-			<h1>调度管理<small>调度中心</small></h1>
22
+			<h1>任务调度中心<small>调度管理</small></h1>
23
+			<!--
23 24
 			<ol class="breadcrumb">
24 25
 				<li><a><i class="fa fa-dashboard"></i>调度管理</a></li>
25 26
 				<li class="active">调度中心</li>
26 27
 			</ol>
28
+			-->
27 29
 		</section>
28 30
 		
29 31
 		<!-- Main content -->
@@ -104,7 +106,7 @@
104 106
          	<div class="modal-body">
105 107
 				<form class="form-horizontal form" role="form" >
106 108
 					<div class="form-group">
107
-						<label for="firstname" class="col-sm-2 control-label">任务组</label>
109
+						<label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
108 110
 						<div class="col-sm-4">
109 111
 							<select class="form-control" name="jobGroup" >
110 112
 		            			<#list JobGroupList as group>
@@ -112,46 +114,31 @@
112 114
 		            			</#list>
113 115
 		                  	</select>
114 116
 						</div>
115
-						<label for="firstname" class="col-sm-2 control-label">任务名</label>
117
+						<label for="firstname" class="col-sm-2 control-label">任务名<font color="red">*</font></label>
116 118
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobName" placeholder="请输入“任务名”" minlength="4" maxlength="100" ></div>
117 119
 					</div>
118 120
 					<div class="form-group">
119
-						<label for="lastname" class="col-sm-2 control-label">Corn</label>
121
+						<label for="lastname" class="col-sm-2 control-label">Corn<font color="red">*</font></label>
120 122
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Corn”" maxlength="100" ></div>
121
-						<label for="lastname" class="col-sm-2 control-label">描述</label>
123
+						<label for="lastname" class="col-sm-2 control-label">描述<font color="red">*</font></label>
122 124
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="200" ></div>
123 125
 					</div>
124 126
 					<div class="form-group">
125
-						<label for="firstname" class="col-sm-2 control-label">JobBean</label>
126
-						<div class="col-sm-4">
127
-							<select class="form-control" name="jobClass" >
128
-								<#if remoteJobBean?exists >
129
-								<option value="${remoteJobBean.name}" jobClassType="remote" >【远程任务】</option>
130
-								</#if>
131
-								<#if localJobBeanList?exists && localJobBeanList?size gt 0 >
132
-								<#list localJobBeanList as localJobBean>
133
-									<option value="${localJobBean.name}" jobClassType="local" >${localJobBean.name}</option>
134
-								</#list>
135
-								</#if>
136
-		                  	</select>
137
-						</div>
138
-						<label for="firstname" class="col-sm-2 control-label">执行参数</label>
139
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
140
-					</div>
141
-					<div class="form-group remote_panel">
142
-						<label for="lastname" class="col-sm-2 control-label">远程-机器地址</label>
127
+						<label for="lastname" class="col-sm-2 control-label">机器地址<font color="red">*</font></label>
143 128
 						<div class="col-sm-4"><input type="text" class="form-control" name="handler_address" placeholder="请输入“远程-机器地址”" maxlength="200" ></div>
144
-						<label for="lastname" class="col-sm-2 control-label">远程-执行器</label>
129
+						<label for="lastname" class="col-sm-2 control-label">执行器<font color="red">*</font></label>
145 130
 						<div class="col-sm-4"><input type="text" class="form-control" name="handler_name" placeholder="请输入“远程-执行器”" maxlength="200" ></div>
146 131
 					</div>
147 132
 					<div class="form-group">
148
-						<label for="lastname" class="col-sm-2 control-label">负责人</label>
133
+						<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
134
+						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
135
+						<label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
149 136
 						<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="200" ></div>
150
-						<label for="lastname" class="col-sm-2 control-label">报警邮件</label>
151
-						<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="200" ></div>
152 137
 					</div>
153 138
 					<div class="form-group">
154
-						<label for="lastname" class="col-sm-2 control-label">报警阈值</label>
139
+						<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
140
+						<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="200" ></div>
141
+						<label for="lastname" class="col-sm-2 control-label">报警阈值<font color="red">*</font></label>
155 142
 						<div class="col-sm-4"><input type="text" class="form-control" name="alarmThreshold" placeholder="请输入“报警阈值”" maxlength="200" ></div>
156 143
 					</div>
157 144
 					<div class="form-group">
@@ -176,37 +163,34 @@
176 163
          	<div class="modal-body">
177 164
 				<form class="form-horizontal form" role="form" >
178 165
 					<div class="form-group">
179
-						<label for="firstname" class="col-sm-2 control-label">任务组</label>
166
+						<label for="firstname" class="col-sm-2 control-label">任务组<font color="red">*</font></label>
180 167
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobGroup" placeholder="请输入“任务组”" minlength="4" maxlength="100" readonly ></div>
181
-						<label for="firstname" class="col-sm-2 control-label">任务名</label>
168
+						<label for="firstname" class="col-sm-2 control-label">任务名<font color="red">*</font></label>
182 169
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobName" placeholder="请输入“任务名”" minlength="4" maxlength="100" readonly ></div>
183 170
 					</div>
184 171
 					<div class="form-group">
185
-						<label for="lastname" class="col-sm-2 control-label">Corn</label>
172
+						<label for="lastname" class="col-sm-2 control-label">Corn<font color="red">*</font></label>
186 173
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Corn”" maxlength="100" ></div>
187
-						<label for="lastname" class="col-sm-2 control-label">描述</label>
174
+						<label for="lastname" class="col-sm-2 control-label">描述<font color="red">*</font></label>
188 175
 						<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="200" ></div>
189 176
 					</div>
177
+					
190 178
 					<div class="form-group">
191
-						<label for="firstname" class="col-sm-2 control-label">JobBean</label>
192
-						<div class="col-sm-4"><input type="text" class="form-control" name="jobClass" placeholder="请输入“执行参数”" maxlength="100" readonly ></div>
193
-						<label for="firstname" class="col-sm-2 control-label">执行参数</label>
194
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
195
-					</div>
196
-					<div class="form-group remote_panel">
197
-						<label for="lastname" class="col-sm-2 control-label">远程-机器地址</label>
179
+						<label for="lastname" class="col-sm-2 control-label">机器地址<font color="red">*</font></label>
198 180
 						<div class="col-sm-4"><input type="text" class="form-control" name="handler_address" placeholder="请输入“远程-机器地址”" maxlength="200" ></div>
199
-						<label for="lastname" class="col-sm-2 control-label">远程-执行器</label>
181
+						<label for="lastname" class="col-sm-2 control-label">执行器<font color="red">*</font></label>
200 182
 						<div class="col-sm-4"><input type="text" class="form-control" name="handler_name" placeholder="请输入“远程-执行器”" maxlength="200" ></div>
201 183
 					</div>
202 184
 					<div class="form-group">
203
-						<label for="lastname" class="col-sm-2 control-label">负责人</label>
185
+						<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
186
+						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
187
+						<label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
204 188
 						<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="200" ></div>
205
-						<label for="lastname" class="col-sm-2 control-label">报警邮件</label>
206
-						<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="200" ></div>
207 189
 					</div>
208 190
 					<div class="form-group">
209
-						<label for="lastname" class="col-sm-2 control-label">报警阈值</label>
191
+						<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
192
+						<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="200" ></div>
193
+						<label for="lastname" class="col-sm-2 control-label">报警阈值<font color="red">*</font></label>
210 194
 						<div class="col-sm-4"><input type="text" class="form-control" name="alarmThreshold" placeholder="请输入“报警阈值”" maxlength="200" ></div>
211 195
 					</div>
212 196
 					<div class="form-group">

+ 4 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/index.ftl Ver fichero

@@ -1,7 +1,7 @@
1 1
 <!DOCTYPE html>
2 2
 <html>
3 3
 <head>
4
-  	<title>调度日志</title>
4
+  	<title>任务调度中心</title>
5 5
   	<#import "/common/common.macro.ftl" as netCommon>
6 6
 	<@netCommon.commonStyle />
7 7
 	<!-- DataTables -->
@@ -20,11 +20,13 @@
20 20
 	<div class="content-wrapper">
21 21
 		<!-- Content Header (Page header) -->
22 22
 		<section class="content-header">
23
-			<h1>调度日志<small>调度中心</small></h1>
23
+			<h1>任务调度中心<small>调度日志</small></h1>
24
+			<!--
24 25
 			<ol class="breadcrumb">
25 26
 				<li><a><i class="fa fa-dashboard"></i>调度日志</a></li>
26 27
 				<li class="active">调度管理</li>
27 28
 			</ol>
29
+			-->
28 30
 		</section>
29 31
 		
30 32
 		<!-- Main content -->

+ 1 - 1
xxl-job-admin/src/main/webapp/static/js/common.1.js Ver fichero

@@ -21,7 +21,7 @@ $(function(){
21 21
 			$.post(base_url + "/logout", function(data, status) {
22 22
 				if (data.code == "200") {
23 23
 					ComAlert.show(1, "注销成功", function(){
24
-						window.location.href = base_url;
24
+						window.location.href = base_url + "/";
25 25
 					});
26 26
 				} else {
27 27
 					ComAlert.show(1, data.msg);

+ 16 - 0
xxl-job-admin/src/main/webapp/static/js/jobcode.index.1.js Ver fichero

@@ -0,0 +1,16 @@
1
+$(function() {
2
+
3
+	var javaEditor = CodeMirror.fromTextArea(document.getElementById("editor"), {
4
+		mode : "text/x-java",
5
+		lineNumbers : true,
6
+		matchBrackets : true,
7
+		extraKeys: {
8
+			"F11": function(cm) {
9
+				cm.setOption("fullScreen", !cm.getOption("fullScreen"));
10
+			},
11
+	        "Esc": function(cm) {
12
+	        	if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
13
+	        }
14
+		}
15
+	});
16
+});

+ 18 - 35
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js Ver fichero

@@ -81,12 +81,14 @@ $(function() {
81 81
 	                			// status
82 82
 	                			var pause_resume = "";
83 83
 	                			if ('NORMAL' == row.jobStatus) {
84
-	                				pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_pause" type="button">暂停</button>  ';
84
+	                				pause_resume = '<button class="btn btn-primary btn-xs job_operate" type="job_pause" type="button">暂停</button>  ';
85 85
 								} else if ('PAUSED' == row.jobStatus){
86
-									pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_resume" type="button">恢复</button>  ';
86
+									pause_resume = '<button class="btn btn-primary btn-xs job_operate" type="job_resume" type="button">恢复</button>  ';
87 87
 								}
88 88
 	                			// log url
89 89
 	                			var logUrl = base_url +'/joblog?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
90
+	                			// log url
91
+	                			var codeUrl = base_url +'/jobcode?id='+ row.id;
90 92
 	                			
91 93
 	                			// job data
92 94
 	                			var jobDataMap = eval('(' + row.jobData + ')');
@@ -105,11 +107,11 @@ $(function() {
105 107
 	                							' handler_address="'+ jobDataMap.handler_address +'" '+
106 108
 	                							' handler_name="'+ jobDataMap.handler_name +'" '+
107 109
 	                							'>'+
108
-	                					pause_resume +
109
-										'<button class="btn btn-info btn-xs job_operate" type="job_trigger" type="button">执行</button>'+
110
-										'<button class="btn btn-warning btn-xs update" type="button">编辑</button><br>'+
111
-									  	'<button class="btn btn-warning btn-xs" type="job_del" type="button" '+
112
-									  		'onclick="javascript:window.open(\'' + logUrl + '\')" >查看日志</button> '+
110
+										'<button class="btn btn-primary btn-xs job_operate" type="job_trigger" type="button">执行</button>  '+
111
+										pause_resume +
112
+										'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br>  '+
113
+										'<button class="btn btn-warning btn-xs update" type="button">编辑</button>  '+
114
+										'<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >CODE</button>  '+
113 115
 								  		'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button>  '+
114 116
 									'</p>';
115 117
 									
@@ -263,12 +265,12 @@ $(function() {
263 265
                 maxlength:"“任务描述”长度不应超过200位"
264 266
             },  
265 267
             handler_address : {
266
-            	required :"请输入“远程-机器地址”."  ,
267
-                maxlength:"“远程-机器地址”长度不应超过200位"
268
+            	required :"请输入“机器地址”."  ,
269
+                maxlength:"“机器地址”长度不应超过200位"
268 270
             },
269 271
             handler_name : {
270
-            	required : "请输入“远程-执行器”."  ,
271
-                maxlength: "“远程-执行器”长度不应超过200位"
272
+            	required : "请输入“执行器”."  ,
273
+                maxlength: "“执行器”长度不应超过200位"
272 274
             },
273 275
             author : {
274 276
             	required : "请输入“负责人”."  ,
@@ -316,38 +318,19 @@ $(function() {
316 318
 		$(".remote_panel").show();	// remote
317 319
 	});
318 320
 	
319
-	// 远程任务/本地任务,切换
320
-	$("#addModal select[name='jobClass']").change(function() {
321
-		//console.log( $(this).val().indexOf('RemoteHttpJobBean') );
322
-		
323
-		if($(this).val().indexOf('RemoteHttpJobBean') > -1){
324
-			$(".remote_panel").show();	// remote
325
-		} else if($(this).val().indexOf('RemoteHttpJobBean') == -1){
326
-			$(".remote_panel").hide();	// local
327
-		}
328
-    });
329
-	
330 321
 	// 更新
331 322
 	$("#job_list").on('click', '.update',function() {
332 323
 		$("#updateModal .form input[name='jobGroup']").val($(this).parent('p').attr("jobGroup"));
333 324
 		$("#updateModal .form input[name='jobName']").val($(this).parent('p').attr("jobName"));
334 325
 		$("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron"));
335 326
 		$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
336
-		$("#updateModal .form input[name='jobClass']").val($(this).parent('p').attr("jobClass"));
337
-		$("#updateModal .form input[name='handler_params']").val($(this).parent('p').attr("handler_params"));
338 327
 		$("#updateModal .form input[name='handler_address']").val($(this).parent('p').attr("handler_address"));
339 328
 		$("#updateModal .form input[name='handler_name']").val($(this).parent('p').attr("handler_name"));
329
+		$("#updateModal .form input[name='handler_params']").val($(this).parent('p').attr("handler_params"));
340 330
 		$("#updateModal .form input[name='author']").val($(this).parent('p').attr("author"));
341 331
 		$("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail"));
342 332
 		$("#updateModal .form input[name='alarmThreshold']").val($(this).parent('p').attr("alarmThreshold"));
343 333
 		
344
-		var _jobClass = $(this).parent('p').attr("jobClass");
345
-		if(_jobClass.indexOf('RemoteHttpJobBean') > -1){
346
-			$(".remote_panel").show();	// remote
347
-		} else if($(this).val().indexOf('RemoteHttpJobBean') == -1){
348
-			$(".remote_panel").hide();	// local
349
-		}
350
-		
351 334
 		$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
352 335
 	});
353 336
 	var updateModalValidate = $("#updateModal .form").validate({
@@ -394,12 +377,12 @@ $(function() {
394 377
                 maxlength:"“任务描述”长度不应超过200位"
395 378
             },  
396 379
             handler_address : {
397
-            	required :"请输入“远程-机器地址”."  ,
398
-                maxlength:"“远程-机器地址”长度不应超过200位"
380
+            	required :"请输入“机器地址”."  ,
381
+                maxlength:"“机器地址”长度不应超过200位"
399 382
             },
400 383
             handler_name : {
401
-            	required : "请输入“远程-执行器”."  ,
402
-                maxlength: "“远程-执行器”长度不应超过200位"
384
+            	required : "请输入“执行器”."  ,
385
+                maxlength: "“执行器”长度不应超过200位"
403 386
             },
404 387
             author : {
405 388
             	required : "请输入“负责人”."  ,

+ 41 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/anyword-hint.js Ver fichero

@@ -0,0 +1,41 @@
1
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+// Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+(function(mod) {
5
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+    mod(require("../../lib/codemirror"));
7
+  else if (typeof define == "function" && define.amd) // AMD
8
+    define(["../../lib/codemirror"], mod);
9
+  else // Plain browser env
10
+    mod(CodeMirror);
11
+})(function(CodeMirror) {
12
+  "use strict";
13
+
14
+  var WORD = /[\w$]+/, RANGE = 500;
15
+
16
+  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
17
+    var word = options && options.word || WORD;
18
+    var range = options && options.range || RANGE;
19
+    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
20
+    var end = cur.ch, start = end;
21
+    while (start && word.test(curLine.charAt(start - 1))) --start;
22
+    var curWord = start != end && curLine.slice(start, end);
23
+
24
+    var list = options && options.list || [], seen = {};
25
+    var re = new RegExp(word.source, "g");
26
+    for (var dir = -1; dir <= 1; dir += 2) {
27
+      var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
28
+      for (; line != endLine; line += dir) {
29
+        var text = editor.getLine(line), m;
30
+        while (m = re.exec(text)) {
31
+          if (line == cur.line && m[0] === curWord) continue;
32
+          if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
33
+            seen[m[0]] = true;
34
+            list.push(m[0]);
35
+          }
36
+        }
37
+      }
38
+    }
39
+    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
40
+  });
41
+});

+ 38 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/show-hint.css Ver fichero

@@ -0,0 +1,38 @@
1
+.CodeMirror-hints {
2
+  position: absolute;
3
+  z-index: 10;
4
+  overflow: hidden;
5
+  list-style: none;
6
+
7
+  margin: 0;
8
+  padding: 2px;
9
+
10
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
11
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
12
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
13
+  border-radius: 3px;
14
+  border: 1px solid silver;
15
+
16
+  background: white;
17
+  font-size: 90%;
18
+  font-family: monospace;
19
+
20
+  max-height: 20em;
21
+  overflow-y: auto;
22
+}
23
+
24
+.CodeMirror-hint {
25
+  margin: 0;
26
+  padding: 0 4px;
27
+  border-radius: 2px;
28
+  max-width: 19em;
29
+  overflow: hidden;
30
+  white-space: pre;
31
+  color: black;
32
+  cursor: pointer;
33
+}
34
+
35
+li.CodeMirror-hint-active {
36
+  background: #08f;
37
+  color: white;
38
+}

+ 447 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/addon/hint/show-hint.js Ver fichero

@@ -0,0 +1,447 @@
1
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+// Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+(function(mod) {
5
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+    mod(require("../../lib/codemirror"));
7
+  else if (typeof define == "function" && define.amd) // AMD
8
+    define(["../../lib/codemirror"], mod);
9
+  else // Plain browser env
10
+    mod(CodeMirror);
11
+})(function(CodeMirror) {
12
+  "use strict";
13
+
14
+  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
15
+  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
16
+
17
+  // This is the old interface, kept around for now to stay
18
+  // backwards-compatible.
19
+  CodeMirror.showHint = function(cm, getHints, options) {
20
+    if (!getHints) return cm.showHint(options);
21
+    if (options && options.async) getHints.async = true;
22
+    var newOpts = {hint: getHints};
23
+    if (options) for (var prop in options) newOpts[prop] = options[prop];
24
+    return cm.showHint(newOpts);
25
+  };
26
+
27
+  CodeMirror.defineExtension("showHint", function(options) {
28
+    options = parseOptions(this, this.getCursor("start"), options);
29
+    var selections = this.listSelections()
30
+    if (selections.length > 1) return;
31
+    // By default, don't allow completion when something is selected.
32
+    // A hint function can have a `supportsSelection` property to
33
+    // indicate that it can handle selections.
34
+    if (this.somethingSelected()) {
35
+      if (!options.hint.supportsSelection) return;
36
+      // Don't try with cross-line selections
37
+      for (var i = 0; i < selections.length; i++)
38
+        if (selections[i].head.line != selections[i].anchor.line) return;
39
+    }
40
+
41
+    if (this.state.completionActive) this.state.completionActive.close();
42
+    var completion = this.state.completionActive = new Completion(this, options);
43
+    if (!completion.options.hint) return;
44
+
45
+    CodeMirror.signal(this, "startCompletion", this);
46
+    completion.update(true);
47
+  });
48
+
49
+  function Completion(cm, options) {
50
+    this.cm = cm;
51
+    this.options = options;
52
+    this.widget = null;
53
+    this.debounce = 0;
54
+    this.tick = 0;
55
+    this.startPos = this.cm.getCursor("start");
56
+    this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
57
+
58
+    var self = this;
59
+    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
60
+  }
61
+
62
+  var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
63
+    return setTimeout(fn, 1000/60);
64
+  };
65
+  var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
66
+
67
+  Completion.prototype = {
68
+    close: function() {
69
+      if (!this.active()) return;
70
+      this.cm.state.completionActive = null;
71
+      this.tick = null;
72
+      this.cm.off("cursorActivity", this.activityFunc);
73
+
74
+      if (this.widget && this.data) CodeMirror.signal(this.data, "close");
75
+      if (this.widget) this.widget.close();
76
+      CodeMirror.signal(this.cm, "endCompletion", this.cm);
77
+    },
78
+
79
+    active: function() {
80
+      return this.cm.state.completionActive == this;
81
+    },
82
+
83
+    pick: function(data, i) {
84
+      var completion = data.list[i];
85
+      if (completion.hint) completion.hint(this.cm, data, completion);
86
+      else this.cm.replaceRange(getText(completion), completion.from || data.from,
87
+                                completion.to || data.to, "complete");
88
+      CodeMirror.signal(data, "pick", completion);
89
+      this.close();
90
+    },
91
+
92
+    cursorActivity: function() {
93
+      if (this.debounce) {
94
+        cancelAnimationFrame(this.debounce);
95
+        this.debounce = 0;
96
+      }
97
+
98
+      var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
99
+      if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
100
+          pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
101
+          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
102
+        this.close();
103
+      } else {
104
+        var self = this;
105
+        this.debounce = requestAnimationFrame(function() {self.update();});
106
+        if (this.widget) this.widget.disable();
107
+      }
108
+    },
109
+
110
+    update: function(first) {
111
+      if (this.tick == null) return;
112
+      if (!this.options.hint.async) {
113
+        this.finishUpdate(this.options.hint(this.cm, this.options), first);
114
+      } else {
115
+        var myTick = ++this.tick, self = this;
116
+        this.options.hint(this.cm, function(data) {
117
+          if (self.tick == myTick) self.finishUpdate(data, first);
118
+        }, this.options);
119
+      }
120
+    },
121
+
122
+    finishUpdate: function(data, first) {
123
+      if (this.data) CodeMirror.signal(this.data, "update");
124
+
125
+      var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
126
+      if (this.widget) this.widget.close();
127
+
128
+      if (data && this.data && isNewCompletion(this.data, data)) return;
129
+      this.data = data;
130
+
131
+      if (data && data.list.length) {
132
+        if (picked && data.list.length == 1) {
133
+          this.pick(data, 0);
134
+        } else {
135
+          this.widget = new Widget(this, data);
136
+          CodeMirror.signal(data, "shown");
137
+        }
138
+      }
139
+    }
140
+  };
141
+
142
+  function isNewCompletion(old, nw) {
143
+    var moved = CodeMirror.cmpPos(nw.from, old.from)
144
+    return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
145
+  }
146
+
147
+  function parseOptions(cm, pos, options) {
148
+    var editor = cm.options.hintOptions;
149
+    var out = {};
150
+    for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
151
+    if (editor) for (var prop in editor)
152
+      if (editor[prop] !== undefined) out[prop] = editor[prop];
153
+    if (options) for (var prop in options)
154
+      if (options[prop] !== undefined) out[prop] = options[prop];
155
+    if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
156
+    return out;
157
+  }
158
+
159
+  function getText(completion) {
160
+    if (typeof completion == "string") return completion;
161
+    else return completion.text;
162
+  }
163
+
164
+  function buildKeyMap(completion, handle) {
165
+    var baseMap = {
166
+      Up: function() {handle.moveFocus(-1);},
167
+      Down: function() {handle.moveFocus(1);},
168
+      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
169
+      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
170
+      Home: function() {handle.setFocus(0);},
171
+      End: function() {handle.setFocus(handle.length - 1);},
172
+      Enter: handle.pick,
173
+      Tab: handle.pick,
174
+      Esc: handle.close
175
+    };
176
+    var custom = completion.options.customKeys;
177
+    var ourMap = custom ? {} : baseMap;
178
+    function addBinding(key, val) {
179
+      var bound;
180
+      if (typeof val != "string")
181
+        bound = function(cm) { return val(cm, handle); };
182
+      // This mechanism is deprecated
183
+      else if (baseMap.hasOwnProperty(val))
184
+        bound = baseMap[val];
185
+      else
186
+        bound = val;
187
+      ourMap[key] = bound;
188
+    }
189
+    if (custom)
190
+      for (var key in custom) if (custom.hasOwnProperty(key))
191
+        addBinding(key, custom[key]);
192
+    var extra = completion.options.extraKeys;
193
+    if (extra)
194
+      for (var key in extra) if (extra.hasOwnProperty(key))
195
+        addBinding(key, extra[key]);
196
+    return ourMap;
197
+  }
198
+
199
+  function getHintElement(hintsElement, el) {
200
+    while (el && el != hintsElement) {
201
+      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
202
+      el = el.parentNode;
203
+    }
204
+  }
205
+
206
+  function Widget(completion, data) {
207
+    this.completion = completion;
208
+    this.data = data;
209
+    this.picked = false;
210
+    var widget = this, cm = completion.cm;
211
+
212
+    var hints = this.hints = document.createElement("ul");
213
+    hints.className = "CodeMirror-hints";
214
+    this.selectedHint = data.selectedHint || 0;
215
+
216
+    var completions = data.list;
217
+    for (var i = 0; i < completions.length; ++i) {
218
+      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
219
+      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
220
+      if (cur.className != null) className = cur.className + " " + className;
221
+      elt.className = className;
222
+      if (cur.render) cur.render(elt, data, cur);
223
+      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
224
+      elt.hintId = i;
225
+    }
226
+
227
+    var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
228
+    var left = pos.left, top = pos.bottom, below = true;
229
+    hints.style.left = left + "px";
230
+    hints.style.top = top + "px";
231
+    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
232
+    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
233
+    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
234
+    (completion.options.container || document.body).appendChild(hints);
235
+    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
236
+    if (overlapY > 0) {
237
+      var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
238
+      if (curTop - height > 0) { // Fits above cursor
239
+        hints.style.top = (top = pos.top - height) + "px";
240
+        below = false;
241
+      } else if (height > winH) {
242
+        hints.style.height = (winH - 5) + "px";
243
+        hints.style.top = (top = pos.bottom - box.top) + "px";
244
+        var cursor = cm.getCursor();
245
+        if (data.from.ch != cursor.ch) {
246
+          pos = cm.cursorCoords(cursor);
247
+          hints.style.left = (left = pos.left) + "px";
248
+          box = hints.getBoundingClientRect();
249
+        }
250
+      }
251
+    }
252
+    var overlapX = box.right - winW;
253
+    if (overlapX > 0) {
254
+      if (box.right - box.left > winW) {
255
+        hints.style.width = (winW - 5) + "px";
256
+        overlapX -= (box.right - box.left) - winW;
257
+      }
258
+      hints.style.left = (left = pos.left - overlapX) + "px";
259
+    }
260
+
261
+    cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
262
+      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
263
+      setFocus: function(n) { widget.changeActive(n); },
264
+      menuSize: function() { return widget.screenAmount(); },
265
+      length: completions.length,
266
+      close: function() { completion.close(); },
267
+      pick: function() { widget.pick(); },
268
+      data: data
269
+    }));
270
+
271
+    if (completion.options.closeOnUnfocus) {
272
+      var closingOnBlur;
273
+      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
274
+      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
275
+    }
276
+
277
+    var startScroll = cm.getScrollInfo();
278
+    cm.on("scroll", this.onScroll = function() {
279
+      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
280
+      var newTop = top + startScroll.top - curScroll.top;
281
+      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
282
+      if (!below) point += hints.offsetHeight;
283
+      if (point <= editor.top || point >= editor.bottom) return completion.close();
284
+      hints.style.top = newTop + "px";
285
+      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
286
+    });
287
+
288
+    CodeMirror.on(hints, "dblclick", function(e) {
289
+      var t = getHintElement(hints, e.target || e.srcElement);
290
+      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
291
+    });
292
+
293
+    CodeMirror.on(hints, "click", function(e) {
294
+      var t = getHintElement(hints, e.target || e.srcElement);
295
+      if (t && t.hintId != null) {
296
+        widget.changeActive(t.hintId);
297
+        if (completion.options.completeOnSingleClick) widget.pick();
298
+      }
299
+    });
300
+
301
+    CodeMirror.on(hints, "mousedown", function() {
302
+      setTimeout(function(){cm.focus();}, 20);
303
+    });
304
+
305
+    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
306
+    return true;
307
+  }
308
+
309
+  Widget.prototype = {
310
+    close: function() {
311
+      if (this.completion.widget != this) return;
312
+      this.completion.widget = null;
313
+      this.hints.parentNode.removeChild(this.hints);
314
+      this.completion.cm.removeKeyMap(this.keyMap);
315
+
316
+      var cm = this.completion.cm;
317
+      if (this.completion.options.closeOnUnfocus) {
318
+        cm.off("blur", this.onBlur);
319
+        cm.off("focus", this.onFocus);
320
+      }
321
+      cm.off("scroll", this.onScroll);
322
+    },
323
+
324
+    disable: function() {
325
+      this.completion.cm.removeKeyMap(this.keyMap);
326
+      var widget = this;
327
+      this.keyMap = {Enter: function() { widget.picked = true; }};
328
+      this.completion.cm.addKeyMap(this.keyMap);
329
+    },
330
+
331
+    pick: function() {
332
+      this.completion.pick(this.data, this.selectedHint);
333
+    },
334
+
335
+    changeActive: function(i, avoidWrap) {
336
+      if (i >= this.data.list.length)
337
+        i = avoidWrap ? this.data.list.length - 1 : 0;
338
+      else if (i < 0)
339
+        i = avoidWrap ? 0  : this.data.list.length - 1;
340
+      if (this.selectedHint == i) return;
341
+      var node = this.hints.childNodes[this.selectedHint];
342
+      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
343
+      node = this.hints.childNodes[this.selectedHint = i];
344
+      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
345
+      if (node.offsetTop < this.hints.scrollTop)
346
+        this.hints.scrollTop = node.offsetTop - 3;
347
+      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
348
+        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
349
+      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
350
+    },
351
+
352
+    screenAmount: function() {
353
+      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
354
+    }
355
+  };
356
+
357
+  function applicableHelpers(cm, helpers) {
358
+    if (!cm.somethingSelected()) return helpers
359
+    var result = []
360
+    for (var i = 0; i < helpers.length; i++)
361
+      if (helpers[i].supportsSelection) result.push(helpers[i])
362
+    return result
363
+  }
364
+
365
+  function resolveAutoHints(cm, pos) {
366
+    var helpers = cm.getHelpers(pos, "hint"), words
367
+    if (helpers.length) {
368
+      var async = false, resolved
369
+      for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
370
+      if (async) {
371
+        resolved = function(cm, callback, options) {
372
+          var app = applicableHelpers(cm, helpers)
373
+          function run(i, result) {
374
+            if (i == app.length) return callback(null)
375
+            var helper = app[i]
376
+            if (helper.async) {
377
+              helper(cm, function(result) {
378
+                if (result) callback(result)
379
+                else run(i + 1)
380
+              }, options)
381
+            } else {
382
+              var result = helper(cm, options)
383
+              if (result) callback(result)
384
+              else run(i + 1)
385
+            }
386
+          }
387
+          run(0)
388
+        }
389
+        resolved.async = true
390
+      } else {
391
+        resolved = function(cm, options) {
392
+          var app = applicableHelpers(cm, helpers)
393
+          for (var i = 0; i < app.length; i++) {
394
+            var cur = app[i](cm, options)
395
+            if (cur && cur.list.length) return cur
396
+          }
397
+        }
398
+      }
399
+      resolved.supportsSelection = true
400
+      return resolved
401
+    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
402
+      return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
403
+    } else if (CodeMirror.hint.anyword) {
404
+      return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
405
+    } else {
406
+      return function() {}
407
+    }
408
+  }
409
+
410
+  CodeMirror.registerHelper("hint", "auto", {
411
+    resolve: resolveAutoHints
412
+  });
413
+
414
+  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
415
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
416
+    var to = CodeMirror.Pos(cur.line, token.end);
417
+    if (token.string && /\w/.test(token.string[token.string.length - 1])) {
418
+      var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
419
+    } else {
420
+      var term = "", from = to;
421
+    }
422
+    var found = [];
423
+    for (var i = 0; i < options.words.length; i++) {
424
+      var word = options.words[i];
425
+      if (word.slice(0, term.length) == term)
426
+        found.push(word);
427
+    }
428
+
429
+    if (found.length) return {list: found, from: from, to: to};
430
+  });
431
+
432
+  CodeMirror.commands.autocomplete = CodeMirror.showHint;
433
+
434
+  var defaultOptions = {
435
+    hint: CodeMirror.hint.auto,
436
+    completeSingle: true,
437
+    alignWithWord: true,
438
+    closeCharacters: /[\s()\[\]{};:>,]/,
439
+    closeOnUnfocus: true,
440
+    completeOnSingleClick: true,
441
+    container: null,
442
+    customKeys: null,
443
+    extraKeys: null
444
+  };
445
+
446
+  CodeMirror.defineOption("hintOptions", null);
447
+});

+ 338 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/lib/codemirror.css Ver fichero

@@ -0,0 +1,338 @@
1
+/* BASICS */
2
+
3
+.CodeMirror {
4
+  /* Set height, width, borders, and global font properties here */
5
+  font-family: monospace;
6
+  height: 300px;
7
+  color: black;
8
+}
9
+
10
+/* PADDING */
11
+
12
+.CodeMirror-lines {
13
+  padding: 4px 0; /* Vertical padding around content */
14
+}
15
+.CodeMirror pre {
16
+  padding: 0 4px; /* Horizontal padding of content */
17
+}
18
+
19
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
20
+  background-color: white; /* The little square between H and V scrollbars */
21
+}
22
+
23
+/* GUTTER */
24
+
25
+.CodeMirror-gutters {
26
+  border-right: 1px solid #ddd;
27
+  background-color: #f7f7f7;
28
+  white-space: nowrap;
29
+}
30
+.CodeMirror-linenumbers {}
31
+.CodeMirror-linenumber {
32
+  padding: 0 3px 0 5px;
33
+  min-width: 20px;
34
+  text-align: right;
35
+  color: #999;
36
+  white-space: nowrap;
37
+}
38
+
39
+.CodeMirror-guttermarker { color: black; }
40
+.CodeMirror-guttermarker-subtle { color: #999; }
41
+
42
+/* CURSOR */
43
+
44
+.CodeMirror-cursor {
45
+  border-left: 1px solid black;
46
+  border-right: none;
47
+  width: 0;
48
+}
49
+/* Shown when moving in bi-directional text */
50
+.CodeMirror div.CodeMirror-secondarycursor {
51
+  border-left: 1px solid silver;
52
+}
53
+.cm-fat-cursor .CodeMirror-cursor {
54
+  width: auto;
55
+  border: 0;
56
+  background: #7e7;
57
+}
58
+.cm-fat-cursor div.CodeMirror-cursors {
59
+  z-index: 1;
60
+}
61
+
62
+.cm-animate-fat-cursor {
63
+  width: auto;
64
+  border: 0;
65
+  -webkit-animation: blink 1.06s steps(1) infinite;
66
+  -moz-animation: blink 1.06s steps(1) infinite;
67
+  animation: blink 1.06s steps(1) infinite;
68
+  background-color: #7e7;
69
+}
70
+@-moz-keyframes blink {
71
+  0% {}
72
+  50% { background-color: transparent; }
73
+  100% {}
74
+}
75
+@-webkit-keyframes blink {
76
+  0% {}
77
+  50% { background-color: transparent; }
78
+  100% {}
79
+}
80
+@keyframes blink {
81
+  0% {}
82
+  50% { background-color: transparent; }
83
+  100% {}
84
+}
85
+
86
+/* Can style cursor different in overwrite (non-insert) mode */
87
+.CodeMirror-overwrite .CodeMirror-cursor {}
88
+
89
+.cm-tab { display: inline-block; text-decoration: inherit; }
90
+
91
+.CodeMirror-ruler {
92
+  border-left: 1px solid #ccc;
93
+  position: absolute;
94
+}
95
+
96
+/* DEFAULT THEME */
97
+
98
+.cm-s-default .cm-header {color: blue;}
99
+.cm-s-default .cm-quote {color: #090;}
100
+.cm-negative {color: #d44;}
101
+.cm-positive {color: #292;}
102
+.cm-header, .cm-strong {font-weight: bold;}
103
+.cm-em {font-style: italic;}
104
+.cm-link {text-decoration: underline;}
105
+.cm-strikethrough {text-decoration: line-through;}
106
+
107
+.cm-s-default .cm-keyword {color: #708;}
108
+.cm-s-default .cm-atom {color: #219;}
109
+.cm-s-default .cm-number {color: #164;}
110
+.cm-s-default .cm-def {color: #00f;}
111
+.cm-s-default .cm-variable,
112
+.cm-s-default .cm-punctuation,
113
+.cm-s-default .cm-property,
114
+.cm-s-default .cm-operator {}
115
+.cm-s-default .cm-variable-2 {color: #05a;}
116
+.cm-s-default .cm-variable-3 {color: #085;}
117
+.cm-s-default .cm-comment {color: #a50;}
118
+.cm-s-default .cm-string {color: #a11;}
119
+.cm-s-default .cm-string-2 {color: #f50;}
120
+.cm-s-default .cm-meta {color: #555;}
121
+.cm-s-default .cm-qualifier {color: #555;}
122
+.cm-s-default .cm-builtin {color: #30a;}
123
+.cm-s-default .cm-bracket {color: #997;}
124
+.cm-s-default .cm-tag {color: #170;}
125
+.cm-s-default .cm-attribute {color: #00c;}
126
+.cm-s-default .cm-hr {color: #999;}
127
+.cm-s-default .cm-link {color: #00c;}
128
+
129
+.cm-s-default .cm-error {color: #f00;}
130
+.cm-invalidchar {color: #f00;}
131
+
132
+.CodeMirror-composing { border-bottom: 2px solid; }
133
+
134
+/* Default styles for common addons */
135
+
136
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
137
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
138
+.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139
+.CodeMirror-activeline-background {background: #e8f2ff;}
140
+
141
+/* STOP */
142
+
143
+/* The rest of this file contains styles related to the mechanics of
144
+   the editor. You probably shouldn't touch them. */
145
+
146
+.CodeMirror {
147
+  position: relative;
148
+  overflow: hidden;
149
+  background: white;
150
+}
151
+
152
+.CodeMirror-scroll {
153
+  overflow: scroll !important; /* Things will break if this is overridden */
154
+  /* 30px is the magic margin used to hide the element's real scrollbars */
155
+  /* See overflow: hidden in .CodeMirror */
156
+  margin-bottom: -30px; margin-right: -30px;
157
+  padding-bottom: 30px;
158
+  height: 100%;
159
+  outline: none; /* Prevent dragging from highlighting the element */
160
+  position: relative;
161
+}
162
+.CodeMirror-sizer {
163
+  position: relative;
164
+  border-right: 30px solid transparent;
165
+}
166
+
167
+/* The fake, visible scrollbars. Used to force redraw during scrolling
168
+   before actual scrolling happens, thus preventing shaking and
169
+   flickering artifacts. */
170
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
171
+  position: absolute;
172
+  z-index: 6;
173
+  display: none;
174
+}
175
+.CodeMirror-vscrollbar {
176
+  right: 0; top: 0;
177
+  overflow-x: hidden;
178
+  overflow-y: scroll;
179
+}
180
+.CodeMirror-hscrollbar {
181
+  bottom: 0; left: 0;
182
+  overflow-y: hidden;
183
+  overflow-x: scroll;
184
+}
185
+.CodeMirror-scrollbar-filler {
186
+  right: 0; bottom: 0;
187
+}
188
+.CodeMirror-gutter-filler {
189
+  left: 0; bottom: 0;
190
+}
191
+
192
+.CodeMirror-gutters {
193
+  position: absolute; left: 0; top: 0;
194
+  min-height: 100%;
195
+  z-index: 3;
196
+}
197
+.CodeMirror-gutter {
198
+  white-space: normal;
199
+  height: 100%;
200
+  display: inline-block;
201
+  vertical-align: top;
202
+  margin-bottom: -30px;
203
+  /* Hack to make IE7 behave */
204
+  *zoom:1;
205
+  *display:inline;
206
+}
207
+.CodeMirror-gutter-wrapper {
208
+  position: absolute;
209
+  z-index: 4;
210
+  background: none !important;
211
+  border: none !important;
212
+}
213
+.CodeMirror-gutter-background {
214
+  position: absolute;
215
+  top: 0; bottom: 0;
216
+  z-index: 4;
217
+}
218
+.CodeMirror-gutter-elt {
219
+  position: absolute;
220
+  cursor: default;
221
+  z-index: 4;
222
+}
223
+.CodeMirror-gutter-wrapper {
224
+  -webkit-user-select: none;
225
+  -moz-user-select: none;
226
+  user-select: none;
227
+}
228
+
229
+.CodeMirror-lines {
230
+  cursor: text;
231
+  min-height: 1px; /* prevents collapsing before first draw */
232
+}
233
+.CodeMirror pre {
234
+  /* Reset some styles that the rest of the page might have set */
235
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
236
+  border-width: 0;
237
+  background: transparent;
238
+  font-family: inherit;
239
+  font-size: inherit;
240
+  margin: 0;
241
+  white-space: pre;
242
+  word-wrap: normal;
243
+  line-height: inherit;
244
+  color: inherit;
245
+  z-index: 2;
246
+  position: relative;
247
+  overflow: visible;
248
+  -webkit-tap-highlight-color: transparent;
249
+  -webkit-font-variant-ligatures: none;
250
+  font-variant-ligatures: none;
251
+}
252
+.CodeMirror-wrap pre {
253
+  word-wrap: break-word;
254
+  white-space: pre-wrap;
255
+  word-break: normal;
256
+}
257
+
258
+.CodeMirror-linebackground {
259
+  position: absolute;
260
+  left: 0; right: 0; top: 0; bottom: 0;
261
+  z-index: 0;
262
+}
263
+
264
+.CodeMirror-linewidget {
265
+  position: relative;
266
+  z-index: 2;
267
+  overflow: auto;
268
+}
269
+
270
+.CodeMirror-widget {}
271
+
272
+.CodeMirror-code {
273
+  outline: none;
274
+}
275
+
276
+/* Force content-box sizing for the elements where we expect it */
277
+.CodeMirror-scroll,
278
+.CodeMirror-sizer,
279
+.CodeMirror-gutter,
280
+.CodeMirror-gutters,
281
+.CodeMirror-linenumber {
282
+  -moz-box-sizing: content-box;
283
+  box-sizing: content-box;
284
+}
285
+
286
+.CodeMirror-measure {
287
+  position: absolute;
288
+  width: 100%;
289
+  height: 0;
290
+  overflow: hidden;
291
+  visibility: hidden;
292
+}
293
+
294
+.CodeMirror-cursor { position: absolute; }
295
+.CodeMirror-measure pre { position: static; }
296
+
297
+div.CodeMirror-cursors {
298
+  visibility: hidden;
299
+  position: relative;
300
+  z-index: 3;
301
+}
302
+div.CodeMirror-dragcursors {
303
+  visibility: visible;
304
+}
305
+
306
+.CodeMirror-focused div.CodeMirror-cursors {
307
+  visibility: visible;
308
+}
309
+
310
+.CodeMirror-selected { background: #d9d9d9; }
311
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
312
+.CodeMirror-crosshair { cursor: crosshair; }
313
+.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
314
+.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
315
+
316
+.cm-searching {
317
+  background: #ffa;
318
+  background: rgba(255, 255, 0, .4);
319
+}
320
+
321
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */
322
+.CodeMirror span { *vertical-align: text-bottom; }
323
+
324
+/* Used to force a border model for a node */
325
+.cm-force-border { padding-right: .1px; }
326
+
327
+@media print {
328
+  /* Hide the cursor when printing */
329
+  .CodeMirror div.CodeMirror-cursors {
330
+    visibility: hidden;
331
+  }
332
+}
333
+
334
+/* See issue #2901 */
335
+.cm-tab-wrap-hack:after { content: ''; }
336
+
337
+/* Help users use markselection to safely style text background */
338
+span.CodeMirror-selectedtext { background: none; }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 8895 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/lib/codemirror.js


+ 781 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/clike/clike.js Ver fichero

@@ -0,0 +1,781 @@
1
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+// Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+(function(mod) {
5
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+    mod(require("../../lib/codemirror"));
7
+  else if (typeof define == "function" && define.amd) // AMD
8
+    define(["../../lib/codemirror"], mod);
9
+  else // Plain browser env
10
+    mod(CodeMirror);
11
+})(function(CodeMirror) {
12
+"use strict";
13
+
14
+function Context(indented, column, type, align, prev) {
15
+  this.indented = indented;
16
+  this.column = column;
17
+  this.type = type;
18
+  this.align = align;
19
+  this.prev = prev;
20
+}
21
+function isStatement(type) {
22
+  return type == "statement" || type == "switchstatement" || type == "namespace";
23
+}
24
+function pushContext(state, col, type) {
25
+  var indent = state.indented;
26
+  if (state.context && isStatement(state.context.type) && !isStatement(type))
27
+    indent = state.context.indented;
28
+  return state.context = new Context(indent, col, type, null, state.context);
29
+}
30
+function popContext(state) {
31
+  var t = state.context.type;
32
+  if (t == ")" || t == "]" || t == "}")
33
+    state.indented = state.context.indented;
34
+  return state.context = state.context.prev;
35
+}
36
+
37
+function typeBefore(stream, state) {
38
+  if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
39
+  if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
40
+}
41
+
42
+function isTopScope(context) {
43
+  for (;;) {
44
+    if (!context || context.type == "top") return true;
45
+    if (context.type == "}" && context.prev.type != "namespace") return false;
46
+    context = context.prev;
47
+  }
48
+}
49
+
50
+CodeMirror.defineMode("clike", function(config, parserConfig) {
51
+  var indentUnit = config.indentUnit,
52
+      statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
53
+      dontAlignCalls = parserConfig.dontAlignCalls,
54
+      keywords = parserConfig.keywords || {},
55
+      types = parserConfig.types || {},
56
+      builtin = parserConfig.builtin || {},
57
+      blockKeywords = parserConfig.blockKeywords || {},
58
+      defKeywords = parserConfig.defKeywords || {},
59
+      atoms = parserConfig.atoms || {},
60
+      hooks = parserConfig.hooks || {},
61
+      multiLineStrings = parserConfig.multiLineStrings,
62
+      indentStatements = parserConfig.indentStatements !== false,
63
+      indentSwitch = parserConfig.indentSwitch !== false,
64
+      namespaceSeparator = parserConfig.namespaceSeparator,
65
+      isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
66
+      numberStart = parserConfig.numberStart || /[\d\.]/,
67
+      number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
68
+      isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
69
+      endStatement = parserConfig.endStatement || /^[;:,]$/;
70
+
71
+  var curPunc, isDefKeyword;
72
+
73
+  function tokenBase(stream, state) {
74
+    var ch = stream.next();
75
+    if (hooks[ch]) {
76
+      var result = hooks[ch](stream, state);
77
+      if (result !== false) return result;
78
+    }
79
+    if (ch == '"' || ch == "'") {
80
+      state.tokenize = tokenString(ch);
81
+      return state.tokenize(stream, state);
82
+    }
83
+    if (isPunctuationChar.test(ch)) {
84
+      curPunc = ch;
85
+      return null;
86
+    }
87
+    if (numberStart.test(ch)) {
88
+      stream.backUp(1)
89
+      if (stream.match(number)) return "number"
90
+      stream.next()
91
+    }
92
+    if (ch == "/") {
93
+      if (stream.eat("*")) {
94
+        state.tokenize = tokenComment;
95
+        return tokenComment(stream, state);
96
+      }
97
+      if (stream.eat("/")) {
98
+        stream.skipToEnd();
99
+        return "comment";
100
+      }
101
+    }
102
+    if (isOperatorChar.test(ch)) {
103
+      while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
104
+      return "operator";
105
+    }
106
+    stream.eatWhile(/[\w\$_\xa1-\uffff]/);
107
+    if (namespaceSeparator) while (stream.match(namespaceSeparator))
108
+      stream.eatWhile(/[\w\$_\xa1-\uffff]/);
109
+
110
+    var cur = stream.current();
111
+    if (contains(keywords, cur)) {
112
+      if (contains(blockKeywords, cur)) curPunc = "newstatement";
113
+      if (contains(defKeywords, cur)) isDefKeyword = true;
114
+      return "keyword";
115
+    }
116
+    if (contains(types, cur)) return "variable-3";
117
+    if (contains(builtin, cur)) {
118
+      if (contains(blockKeywords, cur)) curPunc = "newstatement";
119
+      return "builtin";
120
+    }
121
+    if (contains(atoms, cur)) return "atom";
122
+    return "variable";
123
+  }
124
+
125
+  function tokenString(quote) {
126
+    return function(stream, state) {
127
+      var escaped = false, next, end = false;
128
+      while ((next = stream.next()) != null) {
129
+        if (next == quote && !escaped) {end = true; break;}
130
+        escaped = !escaped && next == "\\";
131
+      }
132
+      if (end || !(escaped || multiLineStrings))
133
+        state.tokenize = null;
134
+      return "string";
135
+    };
136
+  }
137
+
138
+  function tokenComment(stream, state) {
139
+    var maybeEnd = false, ch;
140
+    while (ch = stream.next()) {
141
+      if (ch == "/" && maybeEnd) {
142
+        state.tokenize = null;
143
+        break;
144
+      }
145
+      maybeEnd = (ch == "*");
146
+    }
147
+    return "comment";
148
+  }
149
+
150
+  // Interface
151
+
152
+  return {
153
+    startState: function(basecolumn) {
154
+      return {
155
+        tokenize: null,
156
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
157
+        indented: 0,
158
+        startOfLine: true,
159
+        prevToken: null
160
+      };
161
+    },
162
+
163
+    token: function(stream, state) {
164
+      var ctx = state.context;
165
+      if (stream.sol()) {
166
+        if (ctx.align == null) ctx.align = false;
167
+        state.indented = stream.indentation();
168
+        state.startOfLine = true;
169
+      }
170
+      if (stream.eatSpace()) return null;
171
+      curPunc = isDefKeyword = null;
172
+      var style = (state.tokenize || tokenBase)(stream, state);
173
+      if (style == "comment" || style == "meta") return style;
174
+      if (ctx.align == null) ctx.align = true;
175
+
176
+      if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
177
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
178
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
179
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
180
+      else if (curPunc == "}") {
181
+        while (isStatement(ctx.type)) ctx = popContext(state);
182
+        if (ctx.type == "}") ctx = popContext(state);
183
+        while (isStatement(ctx.type)) ctx = popContext(state);
184
+      }
185
+      else if (curPunc == ctx.type) popContext(state);
186
+      else if (indentStatements &&
187
+               (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
188
+                (isStatement(ctx.type) && curPunc == "newstatement"))) {
189
+        var type = "statement";
190
+        if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
191
+          type = "switchstatement";
192
+        else if (style == "keyword" && stream.current() == "namespace")
193
+          type = "namespace";
194
+        pushContext(state, stream.column(), type);
195
+      }
196
+
197
+      if (style == "variable" &&
198
+          ((state.prevToken == "def" ||
199
+            (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
200
+             isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
201
+        style = "def";
202
+
203
+      if (hooks.token) {
204
+        var result = hooks.token(stream, state, style);
205
+        if (result !== undefined) style = result;
206
+      }
207
+
208
+      if (style == "def" && parserConfig.styleDefs === false) style = "variable";
209
+
210
+      state.startOfLine = false;
211
+      state.prevToken = isDefKeyword ? "def" : style || curPunc;
212
+      return style;
213
+    },
214
+
215
+    indent: function(state, textAfter) {
216
+      if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
217
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
218
+      if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
219
+      if (hooks.indent) {
220
+        var hook = hooks.indent(state, ctx, textAfter);
221
+        if (typeof hook == "number") return hook
222
+      }
223
+      var closing = firstChar == ctx.type;
224
+      var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
225
+      if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226
+        while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227
+        return ctx.indented
228
+      }
229
+      if (isStatement(ctx.type))
230
+        return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
231
+      if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
232
+        return ctx.column + (closing ? 0 : 1);
233
+      if (ctx.type == ")" && !closing)
234
+        return ctx.indented + statementIndentUnit;
235
+
236
+      return ctx.indented + (closing ? 0 : indentUnit) +
237
+        (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
238
+    },
239
+
240
+    electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
241
+    blockCommentStart: "/*",
242
+    blockCommentEnd: "*/",
243
+    lineComment: "//",
244
+    fold: "brace"
245
+  };
246
+});
247
+
248
+  function words(str) {
249
+    var obj = {}, words = str.split(" ");
250
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
251
+    return obj;
252
+  }
253
+  function contains(words, word) {
254
+    if (typeof words === "function") {
255
+      return words(word);
256
+    } else {
257
+      return words.propertyIsEnumerable(word);
258
+    }
259
+  }
260
+  var cKeywords = "auto if break case register continue return default do sizeof " +
261
+    "static else struct switch extern typedef union for goto while enum const volatile";
262
+  var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
263
+
264
+  function cppHook(stream, state) {
265
+    if (!state.startOfLine) return false
266
+    for (var ch, next = null; ch = stream.peek();) {
267
+      if (ch == "\\" && stream.match(/^.$/)) {
268
+        next = cppHook
269
+        break
270
+      } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
271
+        break
272
+      }
273
+      stream.next()
274
+    }
275
+    state.tokenize = next
276
+    return "meta"
277
+  }
278
+
279
+  function pointerHook(_stream, state) {
280
+    if (state.prevToken == "variable-3") return "variable-3";
281
+    return false;
282
+  }
283
+
284
+  function cpp14Literal(stream) {
285
+    stream.eatWhile(/[\w\.']/);
286
+    return "number";
287
+  }
288
+
289
+  function cpp11StringHook(stream, state) {
290
+    stream.backUp(1);
291
+    // Raw strings.
292
+    if (stream.match(/(R|u8R|uR|UR|LR)/)) {
293
+      var match = stream.match(/"([^\s\\()]{0,16})\(/);
294
+      if (!match) {
295
+        return false;
296
+      }
297
+      state.cpp11RawStringDelim = match[1];
298
+      state.tokenize = tokenRawString;
299
+      return tokenRawString(stream, state);
300
+    }
301
+    // Unicode strings/chars.
302
+    if (stream.match(/(u8|u|U|L)/)) {
303
+      if (stream.match(/["']/, /* eat */ false)) {
304
+        return "string";
305
+      }
306
+      return false;
307
+    }
308
+    // Ignore this hook.
309
+    stream.next();
310
+    return false;
311
+  }
312
+
313
+  function cppLooksLikeConstructor(word) {
314
+    var lastTwo = /(\w+)::(\w+)$/.exec(word);
315
+    return lastTwo && lastTwo[1] == lastTwo[2];
316
+  }
317
+
318
+  // C#-style strings where "" escapes a quote.
319
+  function tokenAtString(stream, state) {
320
+    var next;
321
+    while ((next = stream.next()) != null) {
322
+      if (next == '"' && !stream.eat('"')) {
323
+        state.tokenize = null;
324
+        break;
325
+      }
326
+    }
327
+    return "string";
328
+  }
329
+
330
+  // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
331
+  // <delim> can be a string up to 16 characters long.
332
+  function tokenRawString(stream, state) {
333
+    // Escape characters that have special regex meanings.
334
+    var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
335
+    var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
336
+    if (match)
337
+      state.tokenize = null;
338
+    else
339
+      stream.skipToEnd();
340
+    return "string";
341
+  }
342
+
343
+  function def(mimes, mode) {
344
+    if (typeof mimes == "string") mimes = [mimes];
345
+    var words = [];
346
+    function add(obj) {
347
+      if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
348
+        words.push(prop);
349
+    }
350
+    add(mode.keywords);
351
+    add(mode.types);
352
+    add(mode.builtin);
353
+    add(mode.atoms);
354
+    if (words.length) {
355
+      mode.helperType = mimes[0];
356
+      CodeMirror.registerHelper("hintWords", mimes[0], words);
357
+    }
358
+
359
+    for (var i = 0; i < mimes.length; ++i)
360
+      CodeMirror.defineMIME(mimes[i], mode);
361
+  }
362
+
363
+  def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
364
+    name: "clike",
365
+    keywords: words(cKeywords),
366
+    types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
367
+                 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
368
+                 "uint32_t uint64_t"),
369
+    blockKeywords: words("case do else for if switch while struct"),
370
+    defKeywords: words("struct"),
371
+    typeFirstDefinitions: true,
372
+    atoms: words("null true false"),
373
+    hooks: {"#": cppHook, "*": pointerHook},
374
+    modeProps: {fold: ["brace", "include"]}
375
+  });
376
+
377
+  def(["text/x-c++src", "text/x-c++hdr"], {
378
+    name: "clike",
379
+    keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
380
+                    "static_cast typeid catch operator template typename class friend private " +
381
+                    "this using const_cast inline public throw virtual delete mutable protected " +
382
+                    "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
383
+                    "static_assert override"),
384
+    types: words(cTypes + " bool wchar_t"),
385
+    blockKeywords: words("catch class do else finally for if struct switch try while"),
386
+    defKeywords: words("class namespace struct enum union"),
387
+    typeFirstDefinitions: true,
388
+    atoms: words("true false null"),
389
+    hooks: {
390
+      "#": cppHook,
391
+      "*": pointerHook,
392
+      "u": cpp11StringHook,
393
+      "U": cpp11StringHook,
394
+      "L": cpp11StringHook,
395
+      "R": cpp11StringHook,
396
+      "0": cpp14Literal,
397
+      "1": cpp14Literal,
398
+      "2": cpp14Literal,
399
+      "3": cpp14Literal,
400
+      "4": cpp14Literal,
401
+      "5": cpp14Literal,
402
+      "6": cpp14Literal,
403
+      "7": cpp14Literal,
404
+      "8": cpp14Literal,
405
+      "9": cpp14Literal,
406
+      token: function(stream, state, style) {
407
+        if (style == "variable" && stream.peek() == "(" &&
408
+            (state.prevToken == ";" || state.prevToken == null ||
409
+             state.prevToken == "}") &&
410
+            cppLooksLikeConstructor(stream.current()))
411
+          return "def";
412
+      }
413
+    },
414
+    namespaceSeparator: "::",
415
+    modeProps: {fold: ["brace", "include"]}
416
+  });
417
+
418
+  def("text/x-java", {
419
+    name: "clike",
420
+    keywords: words("abstract assert break case catch class const continue default " +
421
+                    "do else enum extends final finally float for goto if implements import " +
422
+                    "instanceof interface native new package private protected public " +
423
+                    "return static strictfp super switch synchronized this throw throws transient " +
424
+                    "try volatile while"),
425
+    types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
426
+                 "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
427
+    blockKeywords: words("catch class do else finally for if switch try while"),
428
+    defKeywords: words("class interface package enum"),
429
+    typeFirstDefinitions: true,
430
+    atoms: words("true false null"),
431
+    endStatement: /^[;:]$/,
432
+    hooks: {
433
+      "@": function(stream) {
434
+        stream.eatWhile(/[\w\$_]/);
435
+        return "meta";
436
+      }
437
+    },
438
+    modeProps: {fold: ["brace", "import"]}
439
+  });
440
+
441
+  def("text/x-csharp", {
442
+    name: "clike",
443
+    keywords: words("abstract as async await base break case catch checked class const continue" +
444
+                    " default delegate do else enum event explicit extern finally fixed for" +
445
+                    " foreach goto if implicit in interface internal is lock namespace new" +
446
+                    " operator out override params private protected public readonly ref return sealed" +
447
+                    " sizeof stackalloc static struct switch this throw try typeof unchecked" +
448
+                    " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
449
+                    " global group into join let orderby partial remove select set value var yield"),
450
+    types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
451
+                 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
452
+                 " UInt64 bool byte char decimal double short int long object"  +
453
+                 " sbyte float string ushort uint ulong"),
454
+    blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
455
+    defKeywords: words("class interface namespace struct var"),
456
+    typeFirstDefinitions: true,
457
+    atoms: words("true false null"),
458
+    hooks: {
459
+      "@": function(stream, state) {
460
+        if (stream.eat('"')) {
461
+          state.tokenize = tokenAtString;
462
+          return tokenAtString(stream, state);
463
+        }
464
+        stream.eatWhile(/[\w\$_]/);
465
+        return "meta";
466
+      }
467
+    }
468
+  });
469
+
470
+  function tokenTripleString(stream, state) {
471
+    var escaped = false;
472
+    while (!stream.eol()) {
473
+      if (!escaped && stream.match('"""')) {
474
+        state.tokenize = null;
475
+        break;
476
+      }
477
+      escaped = stream.next() == "\\" && !escaped;
478
+    }
479
+    return "string";
480
+  }
481
+
482
+  def("text/x-scala", {
483
+    name: "clike",
484
+    keywords: words(
485
+
486
+      /* scala */
487
+      "abstract case catch class def do else extends final finally for forSome if " +
488
+      "implicit import lazy match new null object override package private protected return " +
489
+      "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
490
+      "<% >: # @ " +
491
+
492
+      /* package scala */
493
+      "assert assume require print println printf readLine readBoolean readByte readShort " +
494
+      "readChar readInt readLong readFloat readDouble " +
495
+
496
+      ":: #:: "
497
+    ),
498
+    types: words(
499
+      "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
500
+      "Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " +
501
+      "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
502
+      "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
503
+      "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
504
+
505
+      /* package java.lang */
506
+      "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
507
+      "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
508
+      "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
509
+      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
510
+    ),
511
+    multiLineStrings: true,
512
+    blockKeywords: words("catch class do else finally for forSome if match switch try while"),
513
+    defKeywords: words("class def object package trait type val var"),
514
+    atoms: words("true false null"),
515
+    indentStatements: false,
516
+    indentSwitch: false,
517
+    hooks: {
518
+      "@": function(stream) {
519
+        stream.eatWhile(/[\w\$_]/);
520
+        return "meta";
521
+      },
522
+      '"': function(stream, state) {
523
+        if (!stream.match('""')) return false;
524
+        state.tokenize = tokenTripleString;
525
+        return state.tokenize(stream, state);
526
+      },
527
+      "'": function(stream) {
528
+        stream.eatWhile(/[\w\$_\xa1-\uffff]/);
529
+        return "atom";
530
+      },
531
+      "=": function(stream, state) {
532
+        var cx = state.context
533
+        if (cx.type == "}" && cx.align && stream.eat(">")) {
534
+          state.context = new Context(cx.indented, cx.column, cx.type, null, cx.prev)
535
+          return "operator"
536
+        } else {
537
+          return false
538
+        }
539
+      }
540
+    },
541
+    modeProps: {closeBrackets: {triples: '"'}}
542
+  });
543
+
544
+  function tokenKotlinString(tripleString){
545
+    return function (stream, state) {
546
+      var escaped = false, next, end = false;
547
+      while (!stream.eol()) {
548
+        if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
549
+        if (tripleString && stream.match('"""')) {end = true; break;}
550
+        next = stream.next();
551
+        if(!escaped && next == "$" && stream.match('{'))
552
+          stream.skipTo("}");
553
+        escaped = !escaped && next == "\\" && !tripleString;
554
+      }
555
+      if (end || !tripleString)
556
+        state.tokenize = null;
557
+      return "string";
558
+    }
559
+  }
560
+
561
+  def("text/x-kotlin", {
562
+    name: "clike",
563
+    keywords: words(
564
+      /*keywords*/
565
+      "package as typealias class interface this super val " +
566
+      "var fun for is in This throw return " +
567
+      "break continue object if else while do try when !in !is as? " +
568
+
569
+      /*soft keywords*/
570
+      "file import where by get set abstract enum open inner override private public internal " +
571
+      "protected catch finally out final vararg reified dynamic companion constructor init " +
572
+      "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
573
+      "external annotation crossinline const operator infix"
574
+    ),
575
+    types: words(
576
+      /* package java.lang */
577
+      "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
578
+      "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
579
+      "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
580
+      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
581
+    ),
582
+    intendSwitch: false,
583
+    indentStatements: false,
584
+    multiLineStrings: true,
585
+    blockKeywords: words("catch class do else finally for if where try while enum"),
586
+    defKeywords: words("class val var object package interface fun"),
587
+    atoms: words("true false null this"),
588
+    hooks: {
589
+      '"': function(stream, state) {
590
+        state.tokenize = tokenKotlinString(stream.match('""'));
591
+        return state.tokenize(stream, state);
592
+      }
593
+    },
594
+    modeProps: {closeBrackets: {triples: '"'}}
595
+  });
596
+
597
+  def(["x-shader/x-vertex", "x-shader/x-fragment"], {
598
+    name: "clike",
599
+    keywords: words("sampler1D sampler2D sampler3D samplerCube " +
600
+                    "sampler1DShadow sampler2DShadow " +
601
+                    "const attribute uniform varying " +
602
+                    "break continue discard return " +
603
+                    "for while do if else struct " +
604
+                    "in out inout"),
605
+    types: words("float int bool void " +
606
+                 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
607
+                 "mat2 mat3 mat4"),
608
+    blockKeywords: words("for while do if else struct"),
609
+    builtin: words("radians degrees sin cos tan asin acos atan " +
610
+                    "pow exp log exp2 sqrt inversesqrt " +
611
+                    "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
612
+                    "length distance dot cross normalize ftransform faceforward " +
613
+                    "reflect refract matrixCompMult " +
614
+                    "lessThan lessThanEqual greaterThan greaterThanEqual " +
615
+                    "equal notEqual any all not " +
616
+                    "texture1D texture1DProj texture1DLod texture1DProjLod " +
617
+                    "texture2D texture2DProj texture2DLod texture2DProjLod " +
618
+                    "texture3D texture3DProj texture3DLod texture3DProjLod " +
619
+                    "textureCube textureCubeLod " +
620
+                    "shadow1D shadow2D shadow1DProj shadow2DProj " +
621
+                    "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
622
+                    "dFdx dFdy fwidth " +
623
+                    "noise1 noise2 noise3 noise4"),
624
+    atoms: words("true false " +
625
+                "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
626
+                "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
627
+                "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
628
+                "gl_FogCoord gl_PointCoord " +
629
+                "gl_Position gl_PointSize gl_ClipVertex " +
630
+                "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
631
+                "gl_TexCoord gl_FogFragCoord " +
632
+                "gl_FragCoord gl_FrontFacing " +
633
+                "gl_FragData gl_FragDepth " +
634
+                "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
635
+                "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
636
+                "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
637
+                "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
638
+                "gl_ProjectionMatrixInverseTranspose " +
639
+                "gl_ModelViewProjectionMatrixInverseTranspose " +
640
+                "gl_TextureMatrixInverseTranspose " +
641
+                "gl_NormalScale gl_DepthRange gl_ClipPlane " +
642
+                "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
643
+                "gl_FrontLightModelProduct gl_BackLightModelProduct " +
644
+                "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
645
+                "gl_FogParameters " +
646
+                "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
647
+                "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
648
+                "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
649
+                "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
650
+                "gl_MaxDrawBuffers"),
651
+    indentSwitch: false,
652
+    hooks: {"#": cppHook},
653
+    modeProps: {fold: ["brace", "include"]}
654
+  });
655
+
656
+  def("text/x-nesc", {
657
+    name: "clike",
658
+    keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
659
+                    "implementation includes interface module new norace nx_struct nx_union post provides " +
660
+                    "signal task uses abstract extends"),
661
+    types: words(cTypes),
662
+    blockKeywords: words("case do else for if switch while struct"),
663
+    atoms: words("null true false"),
664
+    hooks: {"#": cppHook},
665
+    modeProps: {fold: ["brace", "include"]}
666
+  });
667
+
668
+  def("text/x-objectivec", {
669
+    name: "clike",
670
+    keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
671
+                    "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
672
+    types: words(cTypes),
673
+    atoms: words("YES NO NULL NILL ON OFF true false"),
674
+    hooks: {
675
+      "@": function(stream) {
676
+        stream.eatWhile(/[\w\$]/);
677
+        return "keyword";
678
+      },
679
+      "#": cppHook,
680
+      indent: function(_state, ctx, textAfter) {
681
+        if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
682
+      }
683
+    },
684
+    modeProps: {fold: "brace"}
685
+  });
686
+
687
+  def("text/x-squirrel", {
688
+    name: "clike",
689
+    keywords: words("base break clone continue const default delete enum extends function in class" +
690
+                    " foreach local resume return this throw typeof yield constructor instanceof static"),
691
+    types: words(cTypes),
692
+    blockKeywords: words("case catch class else for foreach if switch try while"),
693
+    defKeywords: words("function local class"),
694
+    typeFirstDefinitions: true,
695
+    atoms: words("true false null"),
696
+    hooks: {"#": cppHook},
697
+    modeProps: {fold: ["brace", "include"]}
698
+  });
699
+
700
+  // Ceylon Strings need to deal with interpolation
701
+  var stringTokenizer = null;
702
+  function tokenCeylonString(type) {
703
+    return function(stream, state) {
704
+      var escaped = false, next, end = false;
705
+      while (!stream.eol()) {
706
+        if (!escaped && stream.match('"') &&
707
+              (type == "single" || stream.match('""'))) {
708
+          end = true;
709
+          break;
710
+        }
711
+        if (!escaped && stream.match('``')) {
712
+          stringTokenizer = tokenCeylonString(type);
713
+          end = true;
714
+          break;
715
+        }
716
+        next = stream.next();
717
+        escaped = type == "single" && !escaped && next == "\\";
718
+      }
719
+      if (end)
720
+          state.tokenize = null;
721
+      return "string";
722
+    }
723
+  }
724
+
725
+  def("text/x-ceylon", {
726
+    name: "clike",
727
+    keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
728
+                    " exists extends finally for function given if import in interface is let module new" +
729
+                    " nonempty object of out outer package return satisfies super switch then this throw" +
730
+                    " try value void while"),
731
+    types: function(word) {
732
+        // In Ceylon all identifiers that start with an uppercase are types
733
+        var first = word.charAt(0);
734
+        return (first === first.toUpperCase() && first !== first.toLowerCase());
735
+    },
736
+    blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
737
+    defKeywords: words("class dynamic function interface module object package value"),
738
+    builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
739
+                   " native optional sealed see serializable shared suppressWarnings tagged throws variable"),
740
+    isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
741
+    isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
742
+    numberStart: /[\d#$]/,
743
+    number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
744
+    multiLineStrings: true,
745
+    typeFirstDefinitions: true,
746
+    atoms: words("true false null larger smaller equal empty finished"),
747
+    indentSwitch: false,
748
+    styleDefs: false,
749
+    hooks: {
750
+      "@": function(stream) {
751
+        stream.eatWhile(/[\w\$_]/);
752
+        return "meta";
753
+      },
754
+      '"': function(stream, state) {
755
+          state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
756
+          return state.tokenize(stream, state);
757
+        },
758
+      '`': function(stream, state) {
759
+          if (!stringTokenizer || !stream.match('`')) return false;
760
+          state.tokenize = stringTokenizer;
761
+          stringTokenizer = null;
762
+          return state.tokenize(stream, state);
763
+        },
764
+      "'": function(stream) {
765
+        stream.eatWhile(/[\w\$_\xa1-\uffff]/);
766
+        return "atom";
767
+      },
768
+      token: function(_stream, state, style) {
769
+          if ((style == "variable" || style == "variable-3") &&
770
+              state.prevToken == ".") {
771
+            return "variable-2";
772
+          }
773
+        }
774
+    },
775
+    modeProps: {
776
+        fold: ["brace", "import"],
777
+        closeBrackets: {triples: '"'}
778
+    }
779
+  });
780
+
781
+});

+ 51 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/clike/test.js Ver fichero

@@ -0,0 +1,51 @@
1
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+// Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+(function() {
5
+  var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c");
6
+  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7
+
8
+  MT("indent",
9
+     "[variable-3 void] [def foo]([variable-3 void*] [variable a], [variable-3 int] [variable b]) {",
10
+     "  [variable-3 int] [variable c] [operator =] [variable b] [operator +]",
11
+     "    [number 1];",
12
+     "  [keyword return] [operator *][variable a];",
13
+     "}");
14
+
15
+  MT("indent_switch",
16
+     "[keyword switch] ([variable x]) {",
17
+     "  [keyword case] [number 10]:",
18
+     "    [keyword return] [number 20];",
19
+     "  [keyword default]:",
20
+     "    [variable printf]([string \"foo %c\"], [variable x]);",
21
+     "}");
22
+
23
+  MT("def",
24
+     "[variable-3 void] [def foo]() {}",
25
+     "[keyword struct] [def bar]{}",
26
+     "[variable-3 int] [variable-3 *][def baz]() {}");
27
+
28
+  MT("double_block",
29
+     "[keyword for] (;;)",
30
+     "  [keyword for] (;;)",
31
+     "    [variable x][operator ++];",
32
+     "[keyword return];");
33
+
34
+  MT("preprocessor",
35
+     "[meta #define FOO 3]",
36
+     "[variable-3 int] [variable foo];",
37
+     "[meta #define BAR\\]",
38
+     "[meta 4]",
39
+     "[variable-3 unsigned] [variable-3 int] [variable bar] [operator =] [number 8];",
40
+     "[meta #include <baz> ][comment // comment]")
41
+
42
+
43
+  var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src");
44
+  function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); }
45
+
46
+  MTCPP("cpp14_literal",
47
+    "[number 10'000];",
48
+    "[number 0b10'000];",
49
+    "[number 0x10'000];",
50
+    "[string '100000'];");
51
+})();

+ 230 - 0
xxl-job-admin/src/main/webapp/static/plugins/codemirror/mode/groovy/groovy.js Ver fichero

@@ -0,0 +1,230 @@
1
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+// Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+(function(mod) {
5
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+    mod(require("../../lib/codemirror"));
7
+  else if (typeof define == "function" && define.amd) // AMD
8
+    define(["../../lib/codemirror"], mod);
9
+  else // Plain browser env
10
+    mod(CodeMirror);
11
+})(function(CodeMirror) {
12
+"use strict";
13
+
14
+CodeMirror.defineMode("groovy", function(config) {
15
+  function words(str) {
16
+    var obj = {}, words = str.split(" ");
17
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18
+    return obj;
19
+  }
20
+  var keywords = words(
21
+    "abstract as assert boolean break byte case catch char class const continue def default " +
22
+    "do double else enum extends final finally float for goto if implements import in " +
23
+    "instanceof int interface long native new package private protected public return " +
24
+    "short static strictfp super switch synchronized threadsafe throw throws transient " +
25
+    "try void volatile while");
26
+  var blockKeywords = words("catch class do else finally for if switch try while enum interface def");
27
+  var standaloneKeywords = words("return break continue");
28
+  var atoms = words("null true false this");
29
+
30
+  var curPunc;
31
+  function tokenBase(stream, state) {
32
+    var ch = stream.next();
33
+    if (ch == '"' || ch == "'") {
34
+      return startString(ch, stream, state);
35
+    }
36
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
37
+      curPunc = ch;
38
+      return null;
39
+    }
40
+    if (/\d/.test(ch)) {
41
+      stream.eatWhile(/[\w\.]/);
42
+      if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
43
+      return "number";
44
+    }
45
+    if (ch == "/") {
46
+      if (stream.eat("*")) {
47
+        state.tokenize.push(tokenComment);
48
+        return tokenComment(stream, state);
49
+      }
50
+      if (stream.eat("/")) {
51
+        stream.skipToEnd();
52
+        return "comment";
53
+      }
54
+      if (expectExpression(state.lastToken, false)) {
55
+        return startString(ch, stream, state);
56
+      }
57
+    }
58
+    if (ch == "-" && stream.eat(">")) {
59
+      curPunc = "->";
60
+      return null;
61
+    }
62
+    if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
63
+      stream.eatWhile(/[+\-*&%=<>|~]/);
64
+      return "operator";
65
+    }
66
+    stream.eatWhile(/[\w\$_]/);
67
+    if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
68
+    if (state.lastToken == ".") return "property";
69
+    if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
70
+    var cur = stream.current();
71
+    if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
72
+    if (keywords.propertyIsEnumerable(cur)) {
73
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
74
+      else if (standaloneKeywords.propertyIsEnumerable(cur)) curPunc = "standalone";
75
+      return "keyword";
76
+    }
77
+    return "variable";
78
+  }
79
+  tokenBase.isBase = true;
80
+
81
+  function startString(quote, stream, state) {
82
+    var tripleQuoted = false;
83
+    if (quote != "/" && stream.eat(quote)) {
84
+      if (stream.eat(quote)) tripleQuoted = true;
85
+      else return "string";
86
+    }
87
+    function t(stream, state) {
88
+      var escaped = false, next, end = !tripleQuoted;
89
+      while ((next = stream.next()) != null) {
90
+        if (next == quote && !escaped) {
91
+          if (!tripleQuoted) { break; }
92
+          if (stream.match(quote + quote)) { end = true; break; }
93
+        }
94
+        if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
95
+          state.tokenize.push(tokenBaseUntilBrace());
96
+          return "string";
97
+        }
98
+        escaped = !escaped && next == "\\";
99
+      }
100
+      if (end) state.tokenize.pop();
101
+      return "string";
102
+    }
103
+    state.tokenize.push(t);
104
+    return t(stream, state);
105
+  }
106
+
107
+  function tokenBaseUntilBrace() {
108
+    var depth = 1;
109
+    function t(stream, state) {
110
+      if (stream.peek() == "}") {
111
+        depth--;
112
+        if (depth == 0) {
113
+          state.tokenize.pop();
114
+          return state.tokenize[state.tokenize.length-1](stream, state);
115
+        }
116
+      } else if (stream.peek() == "{") {
117
+        depth++;
118
+      }
119
+      return tokenBase(stream, state);
120
+    }
121
+    t.isBase = true;
122
+    return t;
123
+  }
124
+
125
+  function tokenComment(stream, state) {
126
+    var maybeEnd = false, ch;
127
+    while (ch = stream.next()) {
128
+      if (ch == "/" && maybeEnd) {
129
+        state.tokenize.pop();
130
+        break;
131
+      }
132
+      maybeEnd = (ch == "*");
133
+    }
134
+    return "comment";
135
+  }
136
+
137
+  function expectExpression(last, newline) {
138
+    return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
139
+      last == "newstatement" || last == "keyword" || last == "proplabel" ||
140
+      (last == "standalone" && !newline);
141
+  }
142
+
143
+  function Context(indented, column, type, align, prev) {
144
+    this.indented = indented;
145
+    this.column = column;
146
+    this.type = type;
147
+    this.align = align;
148
+    this.prev = prev;
149
+  }
150
+  function pushContext(state, col, type) {
151
+    return state.context = new Context(state.indented, col, type, null, state.context);
152
+  }
153
+  function popContext(state) {
154
+    var t = state.context.type;
155
+    if (t == ")" || t == "]" || t == "}")
156
+      state.indented = state.context.indented;
157
+    return state.context = state.context.prev;
158
+  }
159
+
160
+  // Interface
161
+
162
+  return {
163
+    startState: function(basecolumn) {
164
+      return {
165
+        tokenize: [tokenBase],
166
+        context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
167
+        indented: 0,
168
+        startOfLine: true,
169
+        lastToken: null
170
+      };
171
+    },
172
+
173
+    token: function(stream, state) {
174
+      var ctx = state.context;
175
+      if (stream.sol()) {
176
+        if (ctx.align == null) ctx.align = false;
177
+        state.indented = stream.indentation();
178
+        state.startOfLine = true;
179
+        // Automatic semicolon insertion
180
+        if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) {
181
+          popContext(state); ctx = state.context;
182
+        }
183
+      }
184
+      if (stream.eatSpace()) return null;
185
+      curPunc = null;
186
+      var style = state.tokenize[state.tokenize.length-1](stream, state);
187
+      if (style == "comment") return style;
188
+      if (ctx.align == null) ctx.align = true;
189
+
190
+      if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
191
+      // Handle indentation for {x -> \n ... }
192
+      else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
193
+        popContext(state);
194
+        state.context.align = false;
195
+      }
196
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
197
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
198
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
199
+      else if (curPunc == "}") {
200
+        while (ctx.type == "statement") ctx = popContext(state);
201
+        if (ctx.type == "}") ctx = popContext(state);
202
+        while (ctx.type == "statement") ctx = popContext(state);
203
+      }
204
+      else if (curPunc == ctx.type) popContext(state);
205
+      else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
206
+        pushContext(state, stream.column(), "statement");
207
+      state.startOfLine = false;
208
+      state.lastToken = curPunc || style;
209
+      return style;
210
+    },
211
+
212
+    indent: function(state, textAfter) {
213
+      if (!state.tokenize[state.tokenize.length-1].isBase) return 0;
214
+      var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
215
+      if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) ctx = ctx.prev;
216
+      var closing = firstChar == ctx.type;
217
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
218
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
219
+      else return ctx.indented + (closing ? 0 : config.indentUnit);
220
+    },
221
+
222
+    electricChars: "{}",
223
+    closeBrackets: {triples: "'\""},
224
+    fold: "brace"
225
+  };
226
+});
227
+
228
+CodeMirror.defineMIME("text/x-groovy", "groovy");
229
+
230
+});

+ 10 - 6
xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerThread.java Ver fichero

@@ -78,6 +78,7 @@ public class HandlerThread extends Thread{
78 78
 					String _msg = null;
79 79
 					try {
80 80
 						XxlJobFileAppender.contextHolder.set(trigger_log_id);
81
+						logger.info(">>>>>>>>>>> xxl-job handle start.");
81 82
 						_status = handler.handle(handlerParams);
82 83
 					} catch (Exception e) {
83 84
 						logger.info("HandlerThread Exception:", e);
@@ -85,20 +86,23 @@ public class HandlerThread extends Thread{
85 86
 						e.printStackTrace(new PrintWriter(out));
86 87
 						_msg = out.toString();
87 88
 					}
89
+					logger.info(">>>>>>>>>>> xxl-job handle end, handlerParams:{}, _status:{}, _msg:{}", 
90
+							new Object[]{handlerParams, _status, _msg});
88 91
 
89 92
 					// callback handler info
93
+					HashMap<String, String> params = new HashMap<String, String>();
94
+					params.put("trigger_log_id", trigger_log_id);
95
+					params.put("status", _status.name());
96
+					params.put("msg", _msg);
90 97
 					RemoteCallBack callback = null;
98
+					logger.info(">>>>>>>>>>> xxl-job callback start.");
91 99
 					try {
92
-						HashMap<String, String> params = new HashMap<String, String>();
93
-						params.put("trigger_log_id", trigger_log_id);
94
-						params.put("status", _status.name());
95
-						params.put("msg", _msg);
96 100
 						callback = HttpUtil.post(trigger_log_url, params);
97 101
 					} catch (Exception e) {
98 102
 						logger.info("HandlerThread Exception:", e);
99 103
 					}
100
-					logger.info(">>>>>>>>>>> xxl-job thread handle, handlerData:{}, callback_status:{}, callback_msg:{}, callback:{}, thread:{}", 
101
-							new Object[]{handlerData, _status, _msg, callback, this});
104
+					logger.info(">>>>>>>>>>> xxl-job callback end, params:{}, result:{}", new Object[]{params, callback.toString()});
105
+					
102 106
 				} else {
103 107
 					i++;
104 108
 					logIdSet.clear();

+ 6 - 0
xxl-job-client/src/main/java/com/xxl/job/client/util/HttpUtil.java Ver fichero

@@ -46,6 +46,12 @@ public class HttpUtil {
46 46
 		public String getMsg() {
47 47
 			return msg;
48 48
 		}
49
+		
50
+		@Override
51
+		public String toString() {
52
+			return "RemoteCallBack [status=" + status + ", msg=" + msg + "]";
53
+		}
54
+		
49 55
 	}
50 56
 	
51 57
 	/**