View Javadoc

1   /**
2    * Copyright 2005 Steve Molloy
3    * 
4    * This file is part of OV4J.
5    * 
6    * OV4J is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
7    * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
8    * 
9    * OV4J is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
10   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11   * 
12   * You should have received a copy of the GNU General Public License along with OV4J; if not, write to the Free Software
13   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14   * 
15   */
16  package org.ov4j.retry;
17  
18  import java.io.Serializable;
19  import java.lang.reflect.Method;
20  import java.util.logging.Level;
21  import java.util.logging.Logger;
22  
23  /**
24   * This class holds information about a call which can be retried.
25   * 
26   * @author smolloy
27   * 
28   */
29  public class RetryableCall implements Comparable<RetryableCall>, Serializable {
30  	/**
31  	 * Logger for this class
32  	 */
33  	private static final Logger	logger				= Logger.getLogger(RetryableCall.class.getName());
34  
35  	/** Serial UID */
36  	private static final long	serialVersionUID	= 3307958120152660595L;
37  
38  	/** Name of the class to use. */
39  	private String				className;
40  
41  	/** Name of the method to call. */
42  	private String				methodName;
43  
44  	/** Array of names of classes to use as arguments for the call. */
45  	private String[]			argClassNames;
46  
47  	/** Unique ID to the stored arguments. */
48  	private Long				args;
49  
50  	/** Number of times to retry the call. */
51  	private int					numRetries			= 0;
52  
53  	/**
54  	 * Constructor.
55  	 * 
56  	 */
57  	public RetryableCall() {
58  	}
59  
60  	/**
61  	 * @see java.lang.Comparable#compareTo(T)
62  	 */
63  	public int compareTo(final RetryableCall o) {
64  		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
65  			RetryableCall.logger.entering("RetryableCall", "compareTo(RetryableCall=" + o + ")", "start");
66  		}
67  
68  		if (o == null) {
69  			if (RetryableCall.logger.isLoggable(Level.FINEST)) {
70  				RetryableCall.logger.exiting("RetryableCall", "compareTo(RetryableCall=null)",
71  					"end - return value=" + 1);
72  			}
73  			return 1;
74  		}
75  
76  		int res = ((className == null) ? "" : className).compareTo((o.getClassName() == null) ? "" : o.getClassName());
77  		if (res == 0) {
78  			res =
79  				((methodName == null) ? "" : methodName).compareTo((o.getMethod() == null) ? "" : o.getMethod()
80  					.getName());
81  			if (res == 0) {
82  				if (args == null) {
83  					res = (o.getArgs() == null) ? 0 : -1;
84  				} else {
85  					res = args.compareTo(o.getArgs());
86  				}
87  			}
88  		}
89  
90  		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
91  			RetryableCall.logger.exiting("RetryableCall", "compareTo(RetryableCall=" + o + ")", "end - return value="
92  				+ res);
93  		}
94  		return res;
95  	}
96  
97  	/**
98  	 * @see java.lang.Object#equals(java.lang.Object)
99  	 */
100 	@Override
101 	public boolean equals(final Object obj) {
102 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
103 			RetryableCall.logger.entering("RetryableCall", "equals(Object=" + obj + ")", "start");
104 		}
105 
106 		final boolean returnboolean = (obj instanceof RetryableCall && compareTo((RetryableCall) obj) == 0);
107 
108 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
109 			RetryableCall.logger.exiting("RetryableCall", "equals(Object=" + obj + ")", "end - return value="
110 				+ returnboolean);
111 		}
112 		return returnboolean;
113 	}
114 
115 	/**
116 	 * @return Returns the args.
117 	 */
118 	public Long getArgs() {
119 		return args;
120 	}
121 
122 	/**
123 	 * @return Returns the className.
124 	 */
125 	public String getClassName() {
126 		return className;
127 	}
128 
129 	/**
130 	 * @return Returns the methodName.
131 	 */
132 	public Method getMethod() {
133 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
134 			RetryableCall.logger.entering("RetryableCall", "getMethod()", "start");
135 		}
136 
137 		Method method = null;
138 		try {
139 			final Class<?>[] argClasses = new Class<?>[argClassNames.length];
140 			for (int i = 0; i < argClasses.length; i++) {
141 				if (argClassNames[i].equals("boolean")) {
142 					argClasses[i] = Boolean.TYPE;
143 				} else if (argClassNames[i].equals("char")) {
144 					argClasses[i] = Character.TYPE;
145 				} else if (argClassNames[i].equals("byte")) {
146 					argClasses[i] = Byte.TYPE;
147 				} else if (argClassNames[i].equals("short")) {
148 					argClasses[i] = Short.TYPE;
149 				} else if (argClassNames[i].equals("int")) {
150 					argClasses[i] = Integer.TYPE;
151 				} else if (argClassNames[i].equals("long")) {
152 					argClasses[i] = Long.TYPE;
153 				} else if (argClassNames[i].equals("float")) {
154 					argClasses[i] = Float.TYPE;
155 				} else if (argClassNames[i].equals("double")) {
156 					argClasses[i] = Double.TYPE;
157 				} else if (argClassNames[i].equals("void")) {
158 					argClasses[i] = Void.TYPE;
159 				} else {
160 					argClasses[i] = Class.forName(argClassNames[i]);
161 				}
162 			}
163 			method = Class.forName(className).getMethod(methodName, argClasses);
164 		} catch (final ClassNotFoundException e) {
165 			if (RetryableCall.logger.isLoggable(Level.FINE)) {
166 				RetryableCall.logger.logp(Level.FINE, "RetryableCall", "getMethod()", "exception ignored", e);
167 			}
168 		} catch (final SecurityException e) {
169 			if (RetryableCall.logger.isLoggable(Level.FINE)) {
170 				RetryableCall.logger.logp(Level.FINE, "RetryableCall", "getMethod()", "exception ignored", e);
171 			}
172 		} catch (final NoSuchMethodException e) {
173 			if (RetryableCall.logger.isLoggable(Level.FINE)) {
174 				RetryableCall.logger.logp(Level.FINE, "RetryableCall", "getMethod()", "exception ignored", e);
175 			}
176 		}
177 
178 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
179 			RetryableCall.logger.exiting("RetryableCall", "getMethod()", "end - return value=" + method);
180 		}
181 		return method;
182 	}
183 
184 	/**
185 	 * @return Returns the numRetries.
186 	 */
187 	public int getNumRetries() {
188 		return numRetries;
189 	}
190 
191 	/**
192 	 * @see java.lang.Object#hashCode()
193 	 */
194 	@Override
195 	public int hashCode() {
196 		return (className == null ? 0 : className.hashCode()) + (methodName == null ? 0 : methodName.hashCode())
197 			+ (args == null ? 0 : args.hashCode());
198 	}
199 
200 	/**
201 	 * @param args
202 	 *            The args to set.
203 	 */
204 	public void setArgs(final Long args) {
205 		this.args = args;
206 	}
207 
208 	/**
209 	 * @param className
210 	 *            The className to set.
211 	 */
212 	public void setClassName(final String className) {
213 		this.className = className;
214 	}
215 
216 	/**
217 	 * @param methodName
218 	 *            The methodName to set.
219 	 */
220 	public void setMethod(final Method method) {
221 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
222 			RetryableCall.logger.entering("RetryableCall", "setMethod(Method=" + method + ")", "start");
223 		}
224 
225 		methodName = method.getName();
226 		final Class<?>[] args = method.getParameterTypes();
227 		argClassNames = new String[args.length];
228 		for (int i = 0; i < argClassNames.length; i++) {
229 			argClassNames[i] = args[i].getName();
230 		}
231 
232 		if (RetryableCall.logger.isLoggable(Level.FINEST)) {
233 			RetryableCall.logger.exiting("RetryableCall", "setMethod(Method=" + method + ")", "end");
234 		}
235 	}
236 
237 	/**
238 	 * @param numRetries
239 	 *            The numRetries to set.
240 	 */
241 	public void setNumRetries(final int numRetries) {
242 		this.numRetries = numRetries;
243 	}
244 
245 	/**
246 	 * @see java.lang.Object#toString()
247 	 */
248 	@Override
249 	public String toString() {
250 		return "RetryableCall(Class: " + className + ", Method: " + methodName + ", Args: " + args + ")";
251 	}
252 }