1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util.execute;
17
18 import java.io.File;
19 import java.util.Properties;
20
21 import org.kuali.common.util.LocationUtils;
22 import org.kuali.common.util.PropertyUtils;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.springframework.util.Assert;
26
27 public class RunOnceExecutable implements Executable {
28
29 private static final Logger logger = LoggerFactory.getLogger(RunOnceExecutable.class);
30
31 Executable executable;
32 File propertiesFile;
33 String property;
34 String encoding;
35 boolean skip;
36
37 @Override
38 public void execute() {
39 if (skip) {
40 logger.info("Skipping execution");
41 return;
42 }
43 Assert.notNull(propertiesFile);
44 Assert.notNull(property);
45 Assert.notNull(executable);
46
47 if (!propertiesFile.exists()) {
48 logger.info("Skipping execution. File does not exist - [{}]", LocationUtils.getCanonicalPath(propertiesFile));
49 return;
50 }
51
52 logger.info("Examining run once property [{}] in [{}]", property, LocationUtils.getCanonicalPath(propertiesFile));
53
54
55 Properties properties = PropertyUtils.load(propertiesFile, encoding);
56
57
58 ExecutionMode mode = getExecutionMode(properties, property);
59
60
61 if (!isRunOnce(mode)) {
62 logger.info("Skipping execution - [{}={}]", property, mode);
63 return;
64 }
65
66
67 logger.info("{}={}", property, mode);
68
69
70 if (!isAlways(mode)) {
71 setState(properties, property, ExecutionMode.INPROGRESS);
72 }
73
74 try {
75
76 executable.execute();
77
78
79
80
81
82 if (!isAlways(mode)) {
83 setState(properties, property, ExecutionMode.COMPLETED);
84 }
85 } catch (Exception e) {
86 if (!isAlways(mode)) {
87 setState(properties, property, ExecutionMode.FAILED);
88 }
89 throw new IllegalStateException("Unexpected execution error", e);
90 }
91 }
92
93 protected boolean isAlways(ExecutionMode mode) {
94 return ExecutionMode.ALWAYS.equals(mode);
95 }
96
97 protected boolean isRunOnce(ExecutionMode mode) {
98 if (ExecutionMode.RUNONCE.equals(mode)) {
99 return true;
100 }
101 if (isAlways(mode)) {
102 return true;
103 }
104 return ExecutionMode.TRUE.equals(mode);
105 }
106
107 protected ExecutionMode getExecutionMode(Properties properties, String key) {
108 String value = properties.getProperty(property);
109 if (value == null) {
110 return ExecutionMode.NULL;
111 } else {
112 return ExecutionMode.valueOf(value.toUpperCase());
113 }
114
115 }
116
117 protected void setState(Properties properties, String key, ExecutionMode mode) {
118 logger.info("{}={}", key, mode);
119 properties.setProperty(property, mode.name());
120 PropertyUtils.store(properties, propertiesFile, encoding);
121 }
122
123 public Executable getExecutable() {
124 return executable;
125 }
126
127 public void setExecutable(Executable executable) {
128 this.executable = executable;
129 }
130
131 public File getPropertiesFile() {
132 return propertiesFile;
133 }
134
135 public void setPropertiesFile(File propertiesFile) {
136 this.propertiesFile = propertiesFile;
137 }
138
139 public String getProperty() {
140 return property;
141 }
142
143 public void setProperty(String property) {
144 this.property = property;
145 }
146
147 public String getEncoding() {
148 return encoding;
149 }
150
151 public void setEncoding(String encoding) {
152 this.encoding = encoding;
153 }
154
155 public boolean isSkip() {
156 return skip;
157 }
158
159 public void setSkip(boolean skip) {
160 this.skip = skip;
161 }
162 }