1 package com.opensymphony.webwork.interceptor; 2 3 import com.opensymphony.webwork.ServletActionContext; 4 import com.opensymphony.xwork.ActionContext; 5 import com.opensymphony.xwork.ActionInvocation; 6 import com.opensymphony.xwork.ActionProxy; 7 import com.opensymphony.xwork.interceptor.AroundInterceptor; 8 import com.opensymphony.xwork.interceptor.PreResultListener; 9 import com.opensymphony.xwork.util.OgnlValueStack; 10 import org.apache.commons.logging.Log; 11 import org.apache.commons.logging.LogFactory; 12 13 import javax.servlet.ServletContext ; 14 import javax.servlet.http.HttpServletRequest ; 15 import javax.servlet.http.HttpSession ; 16 import java.util.IdentityHashMap ; 17 import java.util.Map ; 18 19 22 public class ScopeInterceptor extends AroundInterceptor implements PreResultListener { 23 private static final Log LOG = LogFactory.getLog(ScopeInterceptor.class); 24 25 private static Map locks = new IdentityHashMap (); 26 27 String [] application = null; 28 String [] session = null; 29 String key; 30 String type = null; 31 32 public void setApplication(String s) { 34 if (s != null) { 35 application = s.split(" *, *"); 36 } 37 } 38 39 public void setSession(String s) { 41 if (s != null) { 42 session = s.split(" *, *"); 43 } 44 } 45 46 private String getKey(ActionInvocation invocation) { 47 ActionProxy proxy = invocation.getProxy(); 48 if (key == null || "CLASS".equals(key)) { 49 key = "webwork.ScopeInterceptor:" + proxy.getNamespace() + ":" + proxy.getAction().getClass(); 51 } else if ("ACTION".equals(key)) { 52 key = "webwork.ScopeInterceptor:" + proxy.getNamespace() + ":" + proxy.getActionName(); 53 } 54 return key; 55 } 56 57 public ScopeInterceptor() { 58 super(); 59 } 60 61 62 private static final Object NULL = new Object () { 63 public String toString() { 64 return "NULL"; 65 } 66 }; 67 68 private static Object nullConvert(Object o) { 69 if (o == null) { 70 return NULL; 71 } 72 73 if (o == NULL) { 74 return null; 75 } 76 77 return o; 78 } 79 80 static void lock(Object o, ActionInvocation invocation) throws Exception { 81 synchronized (o) { 82 int count = 3; 83 Object previous; 84 while ((previous = locks.get(o)) != null) { 85 if (previous == invocation) { 86 return; 87 } 88 89 if (count-- <= 0) { 90 throw new RuntimeException ("Deadlock in session lock"); 91 } 92 o.wait(60000); 93 } 94 locks.put(o, invocation); 95 } 96 } 97 98 static void unlock(Object o) { 99 synchronized (o) { 100 locks.remove(o); 101 o.notify(); 102 } 103 } 104 105 protected void after(ActionInvocation dispatcher, String result) throws Exception { 106 } 107 108 protected void before(ActionInvocation invocation) throws Exception { 109 invocation.addPreResultListener(this); 110 111 ActionContext ctx = invocation.getInvocationContext(); 112 HttpServletRequest req = (HttpServletRequest ) ctx.get(ServletActionContext.HTTP_REQUEST); 113 ServletContext app = (ServletContext ) ctx.get(ServletActionContext.SERVLET_CONTEXT); 114 OgnlValueStack stack = invocation.getStack(); 115 HttpSession ses = req.getSession(true); 116 117 lock(ses, invocation); 119 String key = getKey(invocation); 120 121 if (application != null) { 122 for (int i = 0; i < application.length; i++) { 123 String string = application[i]; 124 Object attribute = app.getAttribute(key + string); 125 if (attribute != null) { 126 if (LOG.isDebugEnabled()) { 127 log.debug("application scoped variable set " + string + " = " + String.valueOf(attribute)); 128 } 129 130 stack.setValue(string, nullConvert(attribute)); 131 } 132 } 133 } 134 135 if (session != null && (!"start".equals(type))) { 136 for (int i = 0; i < session.length; i++) { 137 String string = session[i]; 138 Object attribute = ses.getAttribute(key + string); 139 if (attribute != null) { 140 if (LOG.isDebugEnabled()) { 141 log.debug("application scoped variable set " + string + " = " + String.valueOf(attribute)); 142 } 143 144 stack.setValue(string, nullConvert(attribute)); 145 } 146 } 147 } 148 } 149 150 153 public void setKey(String key) { 154 this.key = key; 155 } 156 157 public void beforeResult(ActionInvocation invocation, String resultCode) { 158 HttpSession ses = ServletActionContext.getRequest().getSession(); 159 try { 160 String key = getKey(invocation); 161 ServletContext app = ServletActionContext.getServletContext(); 162 final OgnlValueStack stack = ActionContext.getContext().getValueStack(); 163 164 if (application != null) 165 for (int i = 0; i < application.length; i++) { 166 String string = application[i]; 167 Object value = stack.findValue(string); 168 if (LOG.isDebugEnabled()) { 169 log.debug("application scoped variable saved " + string + " = " + String.valueOf(value)); 170 } 171 172 app.setAttribute(key + string, nullConvert(value)); 174 } 175 176 boolean ends = "end".equals(type); 177 178 if (session != null) 179 for (int i = 0; i < session.length; i++) { 180 String string = session[i]; 181 if (ends) { 182 ses.removeAttribute(key + string); 183 } else { 184 Object value = stack.findValue(string); 185 186 if (LOG.isDebugEnabled()) { 187 log.debug("session scoped variable saved " + string + " = " + String.valueOf(value)); 188 } 189 190 ses.setAttribute(key + string, nullConvert(value)); 193 } 194 } 195 196 197 } finally { 198 unlock(ses); 199 } 200 } 201 202 205 public String getType() { 206 return type; 207 } 208 209 212 public void setType(String type) { 213 type = type.toLowerCase(); 214 if ("start".equals(type) || "end".equals(type)) { 215 this.type = type; 216 } else { 217 throw new IllegalArgumentException ("Only start or end are allowed arguments for type"); 218 } 219 } 220 } | Popular Tags |