001: /*
002: * Copyright Javelin Software, All rights reserved.
003: */
004:
005: package com.javelin.swinglets;
006:
007: import java.awt.event.*;
008: import java.io.*;
009: import java.util.*;
010: import java.net.*;
011:
012: import javax.servlet.*;
013: import javax.servlet.http.*;
014:
015: import com.javelin.swinglets.event.*;
016:
017: /**
018: * Defines an object that manages the Swinglets.
019: * <p>
020: * This class is an implementation of the SwingletManager class that implements
021: * servlets.
022: * <p>
023: * This manager adds itself listens to the Session to see when it is being unbound.
024: *
025: * @author Robin Sharp
026: */
027:
028: public class ServletManager extends SwingletManager implements
029: HttpSessionBindingListener {
030: /**
031: * Bind an value to the Swinglet Manager.
032: * @param name the key of the value.
033: * @param value the value. If this is null it is removed.
034: */
035: public void putValue(String name, Object value) {
036: if (value == null) {
037: hashMap.remove(name);
038: } else {
039: hashMap.put(name, value);
040: }
041: }
042:
043: /**
044: * Get a value by name.
045: */
046: public Object getValue(String name) {
047: return hashMap.get(name);
048: }
049:
050: /**
051: * Get an Enumeration of keys.
052: */
053: public Enumeration getKeys() {
054: return new IteratorEnumeration(hashMap.keySet().iterator());
055: }
056:
057: /**
058: * Get an Enumeration of keys.
059: */
060: public Enumeration getValues() {
061: return new IteratorEnumeration(hashMap.values().iterator());
062: }
063:
064: /**
065: * Called when this is added to the session.
066: */
067: public void valueBound(HttpSessionBindingEvent event) {
068: }
069:
070: /**
071: * Called when this is removed from the session. By default
072: * unbinding will clear all the hashmap and the local variables.
073: */
074: public void valueUnbound(HttpSessionBindingEvent event) {
075: hashMap.clear();
076: hashMap = null;
077: session = null;
078: request = null;
079: response = null;
080: }
081:
082: /**
083: * Initialise and return the instance of the SwingletManager for the session.
084: * <P>
085: * If the SwingletManager does not already exist add it to the session.
086: * <P>
087: * This will bind the SwingletManager to the current thread on the basis
088: * of the URL file name.
089: */
090: public static synchronized ServletManager getManager(
091: HttpServletRequest request) {
092: System.out
093: .println("Warning : resources will not load unless the config is set.");
094: return getManager(request, null);
095: }
096:
097: /**
098: * Initialise and return the instance of the SwingletManager for the session.
099: * <P>
100: * If the SwingletManager does not already exist add it to the session.
101: * <P>
102: * This will bind the SwingletManager to the current thread on the basis
103: * of the URL file name.
104: */
105: public static synchronized ServletManager getManager(
106: HttpServletRequest request, ServletConfig config) {
107: //Get (create) the session
108: HttpSession session = request.getSession(false);
109: if (session == null)
110: session = request.getSession(true);
111:
112: String servletPath = request.getServletPath();
113: //System.out.println( servletPath );
114:
115: //Get the servlet manager for the session && servlet
116: ServletManager servletManager = (ServletManager) session
117: .getValue(servletPath);
118:
119: //Create the servlet manager if it does not exist and put it in the session.
120: if (servletManager == null) {
121: servletManager = new ServletManager(session);
122:
123: try {
124: servletManager.setUrl(new URL(request.getScheme(),
125: request.getServerName(), request
126: .getServerPort(), request
127: .getRequestURI()));
128:
129: ImageManager
130: .getManager()
131: .setUrl(
132: new URL(request.getScheme(), request
133: .getServerName(), request
134: .getServerPort(),
135: "/servlet/com.javelin.swinglets.ImageServlet"));
136: } catch (Exception e) {
137: }
138:
139: //Keep track of the user in the servlet manager
140: servletManager.setRemoteUser(request.getRemoteUser());
141:
142: //Put the manager in the session so we can get it later
143: //The manager will also be informed when it is unbound
144: session.putValue(servletPath, servletManager);
145:
146: //initiate the browser profile.
147: servletManager.setBrowserProfile(BrowserProfile.getProfile(
148: request.getHeader("USER-AGENT"), request
149: .getHeader("accept")));
150: }
151:
152: //System.out.println( servletPath + " " + servletManager.hashCode() );
153:
154: if (servletManager != null) {
155: //Set the current SwingletManager by Thread
156: setSwingletManager(servletManager);
157:
158: // when we handle a request make sure we store it away
159: servletManager.request = request;
160: servletManager.config = config;
161: }
162:
163: return servletManager;
164: }
165:
166: /**
167: * Construct a ServletManager with a HttpSession.
168: */
169: protected ServletManager(HttpSession session) {
170: this .session = session;
171: }
172:
173: /**
174: * Handle any events arriving from the browser for a component.
175: * <P>
176: * Firstly, IF the SConstants.SOURCE_CONTAINER is NOT set on the request OR the
177: * SConstants.SOURCE_CONTAINER has NOT been put as a Value in the SwingletManager
178: * then dispatch a new FormEvent to the SOURCE_COMPONENT.
179: * <P>
180: * Secondly, If the SConstants.SOURCE_CONTAINER is set on the request, AND the
181: * SConstants.SOURCE_CONTAINER has been put as a Value in the SwingletManager
182: * then the SConstants.SOURCE_COMPONENT is looked up below that container and a
183: * new FormEvent is dispatched to that component.
184: * <P>
185: * If neither of these is found continue.
186: * <P>
187: * After the Event has been dispatched, then the target component is found.
188: * <P>
189: * If the SConstants.TARGET_COMPONENT is set and put as a Value in the
190: * SwingletManager is it returned.
191: * <P>
192: * If the SConstants.SOURCE_CONTAINER is set then return that, otherwise return the
193: * SConstants.SOURCE_COMPONENT.
194: * <P>
195: * Finally, If the SConstants.TARGET_COMPONENT is NOT set and the defaultTargetComponent has
196: * been put as a Value in the SwingletManager is it returned.
197: * <P>
198: * @param defaultTargetComponent. The default target component if one is not set.
199: * This is usually a Frame, but may be a component, for JSP/ASP
200: * @return the SComponent that is a reposnse to the event. This Component
201: * should be painted.
202: */
203: public synchronized SComponent handle(HttpServletRequest request,
204: HttpServletResponse response, String defaultTargetComponent)
205: throws ServletException, IOException {
206: // when we handle a request make sure we store it away
207: this .request = request;
208: this .response = response;
209:
210: // GET THE SOURCE COMPONENT //////////////////////////////////////////////////////
211:
212: //Get the Name of the Sources
213: String sourceComponent = request
214: .getParameter(SConstants.SOURCE_COMPONENT);
215:
216: //System.out.println( "handle.SOURCE_COMPONENT=" + sourceComponent );
217:
218: //Try looking up the component directly
219: SComponent component = null;
220: SComponent container = null;
221: if (sourceComponent != null && sourceComponent.length() > 0) {
222: //Get the component (SComponent) that fired the event
223: component = (SComponent) getValue(sourceComponent);
224:
225: //Couldnt find the component directly so look inside the container
226: if (component == null) {
227: String sourceContainer = request
228: .getParameter(SConstants.SOURCE_CONTAINER);
229: if (sourceContainer != null
230: && sourceContainer.length() > 0) {
231: //Get the container (SComponent) that fired the event
232: container = (SComponent) getValue(sourceContainer);
233:
234: if (container != null
235: && container instanceof SContainer) {
236: //Get the SComponent that fired the event
237: component = (SComponent) ((SContainer) container)
238: .getComponent(sourceComponent);
239:
240: if (component == null) {
241: throw new ServletException(
242: "Container="
243: + request
244: .getParameter(SConstants.SOURCE_CONTAINER)
245: + " Component="
246: + request
247: .getParameter(SConstants.SOURCE_COMPONENT)
248: + " Target="
249: + request
250: .getParameter(SConstants.TARGET_COMPONENT)
251: + " not found in the session.");
252: }
253: }
254: }
255: }
256: }
257:
258: // DISPATCH THE EVENT /////////////////////////////////////////////////////////
259:
260: if (component != null) {
261: component.dispatchEvent(new ServletFormEvent(component,
262: "GET", request));
263: }
264:
265: // RETURN THE TARGET COMPONENT ////////////////////////////////////////////////
266:
267: SComponent returnComponent = null;
268:
269: //Get the Name of the Target Component
270: String targetComponent = request
271: .getParameter(SConstants.TARGET_COMPONENT);
272:
273: //Get the Target Component
274: if (targetComponent != null) {
275: //System.out.println( "return Component " + targetComponent );
276: returnComponent = (SComponent) getValue(targetComponent);
277:
278: if (returnComponent != null) {
279: //System.out.println( "return Component " + returnComponent.getName() );
280: return returnComponent;
281: }
282: }
283:
284: //Return the source frame if the target frame has not been set
285: if (container != null) {
286: //System.out.println( "Source Container " + container.getName() );
287: return container;
288: }
289:
290: //Return the source component if the target frame or source frame has not been set
291: if (component != null) {
292: //System.out.println( "Component " + component.getName() );
293: return component;
294: }
295:
296: //Use the defaultTargetComponent is nothing else can be retrieved.
297: if (defaultTargetComponent != null) {
298: return (SComponent) getValue(defaultTargetComponent);
299: }
300:
301: return null;
302: }
303:
304: /**
305: * Get the output object for a Component. If the LookAndFeel is a Writer
306: * get the writer other wise get the OutputStream
307: */
308: public synchronized static Object getOutput(SComponent component,
309: HttpServletResponse response) throws IOException {
310: if (component.getLookAndFeel().isWriter()) {
311: return response.getWriter();
312: } else {
313: return response.getOutputStream();
314: }
315: }
316:
317: public ServletConfig getConfig() {
318: return config;
319: }
320:
321: public HttpServletRequest getRequest() {
322: return request;
323: }
324:
325: public HttpServletResponse getResponse() {
326: return response;
327: }
328:
329: public HttpSession getSession() {
330: return session;
331: }
332:
333: public URL getResource(String resourceName)
334: throws MalformedURLException {
335: if (config == null) {
336: throw new IllegalStateException(
337: "Config is not set on the ServletManager.");
338: }
339:
340: return getConfig().getServletContext()
341: .getResource(resourceName);
342: }
343:
344: public URL getImageResource(String imageName)
345: throws MalformedURLException {
346: return getResource(getImagePath() + imageName);
347: }
348:
349: // PRIVATE ///////////////////////////////////////////////////////
350:
351: private HashMap hashMap = new HashMap();
352:
353: private HttpSession session;
354: private HttpServletRequest request;
355: private HttpServletResponse response;
356: private ServletConfig config;
357: }
358:
359: class IteratorEnumeration implements Enumeration {
360: Iterator i = null;
361:
362: public IteratorEnumeration(Iterator i) {
363: this .i = i;
364: }
365:
366: public boolean hasMoreElements() {
367: return i.hasNext();
368: }
369:
370: public Object nextElement() {
371: return i.next();
372: }
373: }
|