001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.common.util.execute; 017 018import java.io.File; 019import java.util.Properties; 020 021import org.kuali.common.util.LocationUtils; 022import org.kuali.common.util.PropertyUtils; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025import org.springframework.util.Assert; 026 027/** 028 * @deprecated 029 */ 030@Deprecated 031public class RunOnceExecutable implements Executable { 032 033 private static final Logger logger = LoggerFactory.getLogger(RunOnceExecutable.class); 034 035 Executable executable; 036 File propertiesFile; 037 String property; 038 String encoding; 039 boolean skip; 040 041 @Override 042 public void execute() { 043 if (skip) { 044 logger.info("Skipping execution"); 045 return; 046 } 047 Assert.notNull(propertiesFile); 048 Assert.notNull(property); 049 Assert.notNull(executable); 050 051 if (!propertiesFile.exists()) { 052 logger.info("Skipping execution. File does not exist - [{}]", LocationUtils.getCanonicalPath(propertiesFile)); 053 return; 054 } 055 056 logger.info("Examining run once property [{}] in [{}]", property, LocationUtils.getCanonicalPath(propertiesFile)); 057 058 // Load the properties 059 Properties properties = PropertyUtils.load(propertiesFile, encoding); 060 061 // Translate the property value into an execution mode 062 ExecutionMode mode = getExecutionMode(properties, property); 063 064 // Are we going to run once? 065 if (!isRunOnce(mode)) { 066 logger.info("Skipping execution - [{}={}]", property, mode); 067 return; 068 } 069 070 // Show the execution mode we are in 071 logger.info("{}={}", property, mode); 072 073 // Make sure we have the ability to successfully store updated properties back to the file 074 if (!isAlways(mode)) { 075 setState(properties, property, ExecutionMode.INPROGRESS); 076 } 077 078 try { 079 // Invoke execute now that we have successfully transitioned things to INPROGRESS 080 executable.execute(); 081 // There is always a chance that the executable finishes correctly and we encounter some kind of 082 // issue just storing the properties back to the file. This should be pretty rare considering 083 // we were able to successfully store the properties just prior to the executable commencing. 084 // In any event, the executable won't run again in the normal use case because we can only get to this point 085 // if the original execution mode was "TRUE" and we were able to successfully change it to "INPROGRESS" 086 if (!isAlways(mode)) { 087 setState(properties, property, ExecutionMode.COMPLETED); 088 } 089 } catch (Exception e) { 090 if (!isAlways(mode)) { 091 setState(properties, property, ExecutionMode.FAILED); 092 } 093 throw new IllegalStateException("Unexpected execution error", e); 094 } 095 } 096 097 protected boolean isAlways(ExecutionMode mode) { 098 return ExecutionMode.ALWAYS.equals(mode); 099 } 100 101 protected boolean isRunOnce(ExecutionMode mode) { 102 if (ExecutionMode.RUNONCE.equals(mode)) { 103 return true; 104 } 105 if (isAlways(mode)) { 106 return true; 107 } 108 return ExecutionMode.TRUE.equals(mode); 109 } 110 111 protected ExecutionMode getExecutionMode(Properties properties, String key) { 112 String value = properties.getProperty(property); 113 if (value == null) { 114 return ExecutionMode.NULL; 115 } else { 116 return ExecutionMode.valueOf(value.toUpperCase()); 117 } 118 119 } 120 121 protected void setState(Properties properties, String key, ExecutionMode mode) { 122 logger.info("{}={}", key, mode); 123 properties.setProperty(property, mode.name()); 124 PropertyUtils.store(properties, propertiesFile, encoding); 125 } 126 127 public Executable getExecutable() { 128 return executable; 129 } 130 131 public void setExecutable(Executable executable) { 132 this.executable = executable; 133 } 134 135 public File getPropertiesFile() { 136 return propertiesFile; 137 } 138 139 public void setPropertiesFile(File propertiesFile) { 140 this.propertiesFile = propertiesFile; 141 } 142 143 public String getProperty() { 144 return property; 145 } 146 147 public void setProperty(String property) { 148 this.property = property; 149 } 150 151 public String getEncoding() { 152 return encoding; 153 } 154 155 public void setEncoding(String encoding) { 156 this.encoding = encoding; 157 } 158 159 public boolean isSkip() { 160 return skip; 161 } 162 163 public void setSkip(boolean skip) { 164 this.skip = skip; 165 } 166}