| 1 4 package org.oddjob.framework; 5 6 import java.io.IOException ; 7 import java.io.ObjectInputStream ; 8 import java.io.ObjectOutputStream ; 9 import java.io.Serializable ; 10 import java.lang.reflect.InvocationHandler ; 11 import java.lang.reflect.Method ; 12 import java.lang.reflect.Proxy ; 13 import java.util.Arrays ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Map ; 17 import java.util.Set ; 18 19 import org.apache.commons.beanutils.DynaBean; 20 import org.apache.log4j.MDC; 21 import org.oddjob.Iconic; 22 import org.oddjob.Resetable; 23 import org.oddjob.Stateful; 24 import org.oddjob.Stoppable; 25 import org.oddjob.images.IconHelper; 26 import org.oddjob.logging.Log4jArchiver; 27 import org.oddjob.logging.LogEnabled; 28 import org.oddjob.state.JobStateHandler; 29 30 40 public class ServiceWrapper extends BaseWrapper 41 implements InvocationHandler { 42 43 private Service service; 44 45 private Object wrapped; 46 private transient DynaBean dynaBean; 47 48 private transient Map methods; 49 50 private Object proxy; 51 52 protected ServiceWrapper() { } 53 54 private ServiceWrapper(Service service) { 55 setWrapped(service); 56 } 57 58 public static Runnable wrapperFor(Service service) { 59 ServiceWrapper wrapper = new ServiceWrapper(service); 60 Set interfaces = new HashSet (); 61 interfaces.addAll(Arrays.asList(interfacesFor(service.getComponent()))); 62 interfaces.add(Runnable .class); 63 interfaces.add(Stateful.class); 64 interfaces.add(Resetable.class); 65 interfaces.add(DynaBean.class); 66 interfaces.add(Stoppable.class); 67 interfaces.add(Iconic.class); 68 interfaces.add(LogEnabled.class); 69 interfaces.add(ContextAware.class); 70 interfaces.add(Initializable.class); 71 interfaces.add(Destroyable.class); 72 if (!(service instanceof Serializable )) { 73 interfaces.add(Transient.class); 74 } 75 wrapper.proxy = 76 Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 77 (Class []) interfaces.toArray(new Class [0]), 78 wrapper); 79 80 wrapper.stateHandler = new JobStateHandler(wrapper.proxy); 81 wrapper.iconHelper = new IconHelper(wrapper.proxy); 82 83 return (Runnable ) wrapper.proxy; 84 } 85 86 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 87 Object destination = methods.get(method); 88 if (destination == null) { 89 destination = this; 91 } 92 return method.invoke(destination, args); 93 } 94 95 protected Object getWrapped() { 96 return wrapped; 97 } 98 99 protected DynaBean getDynaBean() { 100 return dynaBean; 101 } 102 103 protected Object getProxy() { 104 return proxy; 105 } 106 107 protected void setWrapped(Service service) { 108 this.service = service; 109 this.wrapped = service.getComponent(); 110 this.dynaBean = new WrapDynaBean(wrapped); 111 this.methods = new HashMap (); 112 113 Class [] interfaces = interfacesFor(wrapped); 114 for (int i = 0; i < interfaces.length; ++i) { 115 addMethods(interfaces[i], wrapped); 116 } 117 addMethods(Stateful.class, this); 118 addMethods(Resetable.class, this); 119 addMethods(DynaBean.class, this); 120 addMethods(Stoppable.class, this); 121 addMethods(Iconic.class, this); 122 addMethods(Runnable .class, this); 123 addMethods(LogEnabled.class, this); 124 addMethods(ContextAware.class, this); 125 addMethods(Initializable.class, this); 126 addMethods(Destroyable.class, this); 127 } 128 129 private void addMethods(Class from, Object destination) { 130 Method [] ms = from.getDeclaredMethods(); 131 for (int i = 0; i < ms.length; ++i) { 132 methods.put(ms[i], destination); 133 } 134 } 135 136 public void run() { 137 lock.accquire("Job executing."); 138 String oldMDC = (String )MDC.get(Log4jArchiver.MDC); 139 try { 140 MDC.put(Log4jArchiver.MDC, getLogger()); 141 if (!stateHandler.requestJobStateExecuting()) { 142 logger().debug("Can't execute job [" + this + "] because state is [" 143 + stateHandler.getJobState() + "]"); 144 return; 145 } 146 iconHelper.changeIcon(IconHelper.EXECUTING); 147 148 if (!configure()) { 150 return; 151 } 152 logger().info("Starting service[" + wrapped + "]"); 153 154 service.start(); 155 156 logger().info("Started service [" + wrapped + "]"); 157 } catch (Throwable t) { 158 logger().warn("Exception starting [" + wrapped + "]", t); 159 setJobStateException(t); 160 } 161 finally { 162 if (oldMDC != null) { 163 MDC.put(Log4jArchiver.MDC, oldMDC); 164 } 165 else { 166 MDC.remove(Log4jArchiver.MDC); 167 } 168 lock.release(); 169 } 170 } 171 172 public void onStop() throws RuntimeException { 173 lock.accquire("Job executing."); 174 String oldMDC = (String )MDC.get(Log4jArchiver.MDC); 175 try { 176 MDC.put(Log4jArchiver.MDC, getLogger()); 177 service.stop(); 178 int result = getResult(); 179 if (result == 0) { 180 setJobStateComplete(); 181 } else { 182 setJobStateNotComplete(); 183 } 184 } catch (Exception e) { 185 throw new RuntimeException (e); 186 } 187 finally { 188 if (oldMDC != null) { 189 MDC.put(Log4jArchiver.MDC, oldMDC); 190 } 191 else { 192 MDC.remove(Log4jArchiver.MDC); 193 } 194 lock.release(); 195 } 196 } 197 198 201 private void writeObject(ObjectOutputStream s) 202 throws IOException { 203 if (destroyed) { 204 throw new IllegalStateException ("[" + this + "] destroyed"); 205 } 206 s.defaultWriteObject(); 207 s.writeObject((Serializable ) getWrapped()); 208 s.writeObject(stateHandler); 209 s.writeObject(iconHelper); 210 } 211 212 215 private void readObject(ObjectInputStream s) 216 throws IOException , ClassNotFoundException { 217 s.defaultReadObject(); 218 Object wrapped = s.readObject(); 219 Service service = Service.serviceFor(wrapped); 220 setWrapped(service); 221 stateHandler = (JobStateHandler) s.readObject(); 222 stateHandler.setSource(proxy); 223 iconHelper = (IconHelper) s.readObject(); 224 iconHelper.setSource(proxy); 225 } 226 227 } 228 | Popular Tags |