1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.xml.ingest;
17  
18  import static com.google.common.base.Preconditions.checkArgument;
19  import static com.google.common.base.Preconditions.checkNotNull;
20  import static com.google.common.base.Preconditions.checkState;
21  
22  import org.apache.commons.lang3.StringUtils;
23  import org.kuali.common.util.log.LoggerUtils;
24  import org.kuali.common.util.runonce.smart.RunOnce;
25  import org.kuali.common.util.runonce.smart.RunOnceState;
26  import org.kuali.rice.core.api.util.Truth;
27  import org.kuali.rice.coreservice.api.parameter.Parameter;
28  import org.kuali.rice.coreservice.api.parameter.ParameterType;
29  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
30  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
31  import org.slf4j.Logger;
32  
33  import com.google.common.base.Optional;
34  
35  
36  
37  
38  
39  
40  public final class ParameterServiceRunOnce implements RunOnce {
41  
42  	private static final Logger logger = LoggerUtils.make();
43  
44      private static final String CONFIGURATION_PARAMETER_TYPE = "CONFG";
45      private static final String YES = "Y";
46  
47      private ParameterService parameterService;
48  	private final String applicationId;
49  	private final String namespace;
50  	private final String component;
51  	private final String name;
52  	private final Optional<String> description;
53  
54      private final boolean runOnMissingParameter;
55  
56  	private boolean initialized;
57  	private boolean runonce;
58  
59      
60  
61  
62  	@Override
63  	public synchronized void initialize() {
64  		checkState(!initialized, "Already initialized");
65  
66  		parameterService = CoreFrameworkServiceLocator.getParameterService();
67  
68  		Optional<Parameter> parameter = Optional.fromNullable(parameterService.getParameter(namespace, component, name));
69  		if (!parameter.isPresent() && runOnMissingParameter) {
70  			parameter = Optional.of(createParameter());
71  		}
72  		runonce = isRunOnce(parameter);
73  		showConfig(parameter);
74  
75  		initialized = true;
76  	}
77  
78      
79  
80  
81  	@Override
82  	public synchronized boolean isTrue() {
83  		checkState(initialized, "Not initialized");
84  
85          return runonce;
86  	}
87  
88      
89  
90  
91  	@Override
92  	public synchronized void changeState(RunOnceState state) {
93  		
94  		checkState(initialized, "Not initialized");
95  		checkNotNull(state, "'state' cannot be null");
96  
97  		
98  		Parameter existingParameter = parameterService.getParameter(namespace, component, name);
99  
100 		
101 		
102 		checkNotNull(existingParameter, "'existingParameter' cannot be null");
103 
104 		
105 		logger.info("Updating parameter: [{}]", name);
106 		Parameter.Builder builder = Parameter.Builder.create(existingParameter);
107 		builder.setValue(state.name());
108 		Parameter updatedParameter = parameterService.updateParameter(builder.build());
109 
110 		
111 		runonce = isRunOnce(updatedParameter);
112 		checkState(!isTrue(), "isTrue() must return false");
113 
114 		
115 		logger.info("Transitioned RunOnce to - [{}]", updatedParameter.getValue());
116 	}
117 
118 	private boolean isRunOnce(Optional<Parameter> parameter) {
119 		return parameter.isPresent() && isRunOnce(parameter.get());
120 	}
121 
122 	private boolean isRunOnce(Parameter parameter) {
123 		return Truth.strToBooleanIgnoreCase(parameter.getValue(), Boolean.FALSE).booleanValue();
124 	}
125 
126 	private Parameter createParameter() {
127 		logger.info("Creating parameter: [{}]=[{}]", name, YES);
128         ParameterType.Builder parameterTypeBuilder = ParameterType.Builder.create(CONFIGURATION_PARAMETER_TYPE);
129 		Parameter.Builder parameterBuilder = Parameter.Builder.create(applicationId, namespace, component, name, parameterTypeBuilder);
130         parameterBuilder.setValue(YES);
131 		if (description.isPresent()) {
132             parameterBuilder.setDescription(description.get());
133 		}
134 
135 		return parameterService.createParameter(parameterBuilder.build());
136 	}
137 
138 	private void showConfig(Optional<Parameter> optional) {
139 		logger.info(String.format("Parameter Metadata: [%s:%s:%s]", applicationId, namespace, component));
140 		if (optional.isPresent()) {
141 			Parameter parameter = optional.get();
142 			logger.info("Parameter: [{}]=[{}]", name, parameter.getValue());
143 		} else {
144 			logger.info("Parameter [{}] does not exist", name);
145 		}
146 		logger.info("RunOnce: [{}]", Boolean.valueOf(runonce));
147 	}
148 
149     
150 
151 
152 
153 
154     public String getApplicationId() {
155         return applicationId;
156     }
157 
158     
159 
160 
161 
162 
163     public String getNamespace() {
164         return namespace;
165     }
166 
167     
168 
169 
170 
171 
172     public String getComponent() {
173         return component;
174     }
175 
176     
177 
178 
179 
180 
181     public String getName() {
182         return name;
183     }
184 
185     
186 
187 
188 
189 
190     public Optional<String> getDescription() {
191         return description;
192     }
193 
194 	private ParameterServiceRunOnce(Builder builder) {
195 		this.applicationId = builder.applicationId;
196 		this.namespace = builder.namespace;
197 		this.component = builder.component;
198 		this.name = builder.name;
199 		this.description = builder.description;
200 		this.runOnMissingParameter = builder.runOnMissingParameter;
201 	}
202 
203     
204 
205 
206 
207 
208 
209 
210 
211 
212 
213     public static Builder builder(String applicationId, String namespace, String component, String name) {
214         return new Builder(applicationId, namespace, component, name);
215     }
216 
217     
218 
219 
220 	public static class Builder {
221 
222         
223 		private String applicationId;
224 		private String namespace;
225 		private String component;
226 		private String name;
227 
228         
229 		private Optional<String> description = Optional.absent();
230 		private boolean runOnMissingParameter;
231 
232         
233 
234 
235 
236 
237 
238 
239 
240         public Builder(String applicationId, String namespace, String component, String name) {
241             this.applicationId = applicationId;
242             this.namespace = namespace;
243             this.component = component;
244             this.name = name;
245         }
246 
247         
248 
249 
250 
251 
252 
253 
254 		public Builder description(String description) {
255 			this.description = Optional.fromNullable(description);
256 			return this;
257 		}
258 
259         
260 
261 
262 
263 
264 
265 
266         public Builder runOnMissingParameter(boolean runOnMissingParameter) {
267             this.runOnMissingParameter = runOnMissingParameter;
268             return this;
269         }
270 
271         
272 
273 
274 
275 
276 		public ParameterServiceRunOnce build() {
277 			ParameterServiceRunOnce instance = new ParameterServiceRunOnce(this);
278 			validate(instance);
279 			return instance;
280 		}
281 
282 		private static void validate(ParameterServiceRunOnce instance) {
283 			checkArgument(!StringUtils.isBlank(instance.getApplicationId()), "'application' id cannot be null");
284 			checkArgument(!StringUtils.isBlank(instance.getNamespace()), "'namespace' cannot be null");
285 			checkArgument(!StringUtils.isBlank(instance.getComponent()), "'component' cannot be null");
286 			checkArgument(!StringUtils.isBlank(instance.getName()), "'name' cannot be null");
287 			checkNotNull(instance.getDescription(), "'description' cannot be null");
288 		}
289 
290 	}
291 
292 }