1 package com.icesoft.faces.webapp.http.servlet; 2 3 import com.icesoft.faces.context.BridgeFacesContext; 4 import com.icesoft.faces.context.ViewListener; 5 import com.icesoft.faces.env.ServletEnvironmentRequest; 6 import com.icesoft.faces.webapp.command.Command; 7 import com.icesoft.faces.webapp.command.CommandQueue; 8 import com.icesoft.faces.webapp.command.NOOP; 9 import com.icesoft.faces.webapp.http.common.Configuration; 10 import com.icesoft.faces.webapp.http.core.ViewQueue; 11 import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState; 12 import com.icesoft.util.SeamUtilities; 13 import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock; 14 import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock; 15 import org.apache.commons.logging.Log; 16 import org.apache.commons.logging.LogFactory; 17 18 import javax.servlet.http.HttpServletRequest ; 19 import javax.servlet.http.HttpServletResponse ; 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.Collections ; 23 import java.util.Iterator ; 24 import java.util.Map ; 25 26 public class ServletView implements CommandQueue { 27 private static final Log Log = LogFactory.getLog(ServletView.class); 28 private static final NOOP NOOP = new NOOP(); 29 private Lock lock = new ReentrantLock(); 30 private ServletExternalContext externalContext; 31 private BridgeFacesContext facesContext; 32 private PersistentFacesState persistentFacesState; 33 private Map bundles = Collections.EMPTY_MAP; 34 private ServletEnvironmentRequest wrappedRequest; 35 private Command currentCommand = NOOP; 36 private String viewIdentifier; 37 private ArrayList onPutListeners = new ArrayList (); 38 private ArrayList onTakeListeners = new ArrayList (); 39 private Collection viewListeners = new ArrayList (); 40 private String sessionID; 41 private Configuration configuration; 42 43 public ServletView(final String viewIdentifier, String sessionID, HttpServletRequest request, HttpServletResponse response, final ViewQueue allServedViews, Configuration configuration) { 44 this.wrappedRequest = new ServletEnvironmentRequest(request); 45 this.sessionID = sessionID; 46 this.configuration = configuration; 47 this.viewIdentifier = viewIdentifier; 48 this.externalContext = new ServletExternalContext(viewIdentifier, wrappedRequest, response, this, configuration); 49 this.facesContext = new BridgeFacesContext(externalContext, viewIdentifier, sessionID, this, configuration); 50 this.persistentFacesState = new PersistentFacesState(facesContext, viewListeners, configuration); 51 this.onPut(new Runnable () { 52 public void run() { 53 try { 54 allServedViews.put(viewIdentifier); 55 } catch (InterruptedException e) { 56 Log.warn("Failed to queue updated view", e); 57 } 58 } 59 }); 60 this.notifyViewCreation(); 61 } 62 63 public void updateOnXMLHttpRequest(HttpServletRequest request, HttpServletResponse response) { 64 externalContext.update(request, response); 65 makeCurrent(); 66 } 67 68 public void updateOnRequest(HttpServletRequest request, HttpServletResponse response) { 69 if (differentURI(request)) { 70 redirectPage(request, response); 71 } else { 72 reloadPage(request, response); 73 } 74 makeCurrent(); 75 } 76 77 public void switchToNormalMode() { 78 facesContext.switchToNormalMode(); 79 externalContext.switchToNormalMode(); 80 } 81 82 public void switchToPushMode() { 83 bundles = externalContext.collectBundles(); 85 facesContext.switchToPushMode(); 86 externalContext.switchToPushMode(); 87 } 88 89 95 public boolean differentURI(HttpServletRequest request) { 96 return (SeamUtilities.isSeamEnvironment()) || 99 !request.getRequestURI().equals(wrappedRequest.getRequestURI()); 100 } 101 102 public void put(Command command) { 103 lock.lock(); 104 currentCommand = currentCommand.coalesceWith(command); 105 lock.unlock(); 106 broadcastTo(onPutListeners); 107 } 108 109 public Command take() { 110 lock.lock(); 111 Command command = currentCommand; 112 currentCommand = NOOP; 113 lock.unlock(); 114 broadcastTo(onTakeListeners); 115 return command; 116 } 117 118 public void onPut(Runnable listener) { 119 onPutListeners.add(listener); 120 } 121 122 public void onTake(Runnable listener) { 123 onTakeListeners.add(listener); 124 } 125 126 private void broadcastTo(Collection listeners) { 127 Iterator i = listeners.iterator(); 128 while (i.hasNext()) { 129 Runnable listener = (Runnable ) i.next(); 130 try { 131 listener.run(); 132 } catch (Exception e) { 133 Log.error("Failed to notify listener: " + listener, e); 134 } 135 } 136 } 137 138 public void release() { 139 facesContext.release(); 140 persistentFacesState.release(); 141 externalContext.resetRequestMap(); 142 } 143 144 public BridgeFacesContext getFacesContext() { 145 return facesContext; 146 } 147 148 public void dispose() { 149 this.notifyViewDisposal(); 150 this.release(); 151 this.facesContext.dispose(); 152 this.externalContext.dispose(); 153 } 154 155 private void redirectPage(HttpServletRequest request, HttpServletResponse response) { 157 this.wrappedRequest = new ServletEnvironmentRequest(request); 158 this.externalContext = new ServletExternalContext(viewIdentifier, wrappedRequest, response, this, configuration); 159 this.facesContext = new BridgeFacesContext(externalContext, viewIdentifier, sessionID, this, configuration); 160 this.persistentFacesState.setFacesContext(this.facesContext); 161 } 162 163 private void reloadPage(HttpServletRequest request, HttpServletResponse response) { 164 wrappedRequest = new ServletEnvironmentRequest(request); 165 externalContext.updateOnReload(wrappedRequest, response); 166 } 167 168 public void makeCurrent() { 169 externalContext.injectBundles(bundles); 170 persistentFacesState.setCurrentInstance(); 171 facesContext.setCurrentInstance(); 172 facesContext.applyBrowserDOMChanges(); 173 } 174 175 private void notifyViewCreation() { 176 Iterator i = viewListeners.iterator(); 177 while (i.hasNext()) { 178 try { 179 ViewListener listener = (ViewListener) i.next(); 180 listener.viewCreated(); 181 } catch (Throwable t) { 182 Log.warn("Failed to invoke view listener", t); 183 } 184 } 185 } 186 187 private void notifyViewDisposal() { 188 Iterator i = viewListeners.iterator(); 189 while (i.hasNext()) { 190 try { 191 ViewListener listener = (ViewListener) i.next(); 192 listener.viewDisposed(); 193 } catch (Throwable t) { 194 Log.warn("Failed to invoke view listener", t); 195 } 196 } 197 } 198 } | Popular Tags |