001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/courier/tags/sakai_2-4-1/courier-tool/tool/src/java/org/sakaiproject/courier/tool/CourierTool.java $
003: * $Id: CourierTool.java 21893 2007-02-23 23:28:40Z andersjb@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.courier.tool;
021:
022: import java.io.IOException;
023: import java.io.PrintWriter;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Vector;
027:
028: import javax.servlet.ServletConfig;
029: import javax.servlet.ServletException;
030: import javax.servlet.http.HttpServlet;
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033:
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036: import org.sakaiproject.component.cover.ServerConfigurationService;
037: import org.sakaiproject.courier.api.Delivery;
038: import org.sakaiproject.courier.cover.CourierService;
039: import org.sakaiproject.presence.cover.PresenceService;
040: import org.sakaiproject.thread_local.cover.ThreadLocalManager;
041: import org.sakaiproject.tool.api.Session;
042: import org.sakaiproject.tool.cover.SessionManager;
043:
044: /**
045: * <p>
046: * CourierTool is a "tool" which handles courier requests and delivers courier deliveries.
047: * </p>
048: */
049: public class CourierTool extends HttpServlet {
050: /** Our log (commons). */
051: private static Log M_log = LogFactory.getLog(CourierTool.class);
052:
053: /**
054: * Shutdown the servlet.
055: */
056: public void destroy() {
057: M_log.info("destroy()");
058:
059: super .destroy();
060: }
061:
062: /**
063: * Respond to access requests.
064: *
065: * @param req
066: * The servlet request.
067: * @param res
068: * The servlet response.
069: * @throws ServletException.
070: * @throws IOException.
071: */
072: protected void doGet(HttpServletRequest req, HttpServletResponse res)
073: throws ServletException, IOException {
074: // lets see what we have ([0] will be "", [1] is the placement id, the rest is to make it unique to disable browser caching)
075: String[] parts = req.getPathInfo().split("/");
076: if (parts.length >= 2) {
077: String placementId = parts[1];
078:
079: // get the Sakai session
080: Session session = SessionManager.getCurrentSession();
081:
082: // if we are in a newly created session where we had an invalid (presumed timed out) session in the request,
083: // send script to cause a sakai top level redirect
084: if (ThreadLocalManager
085: .get(SessionManager.CURRENT_INVALID_SESSION) != null) {
086: String loggedOutUrl = ServerConfigurationService
087: .getLoggedOutUrl();
088: if (M_log.isDebugEnabled())
089: M_log.debug("sending top redirect: " + placementId
090: + " : " + loggedOutUrl);
091: sendTopRedirect(res, loggedOutUrl);
092: }
093:
094: else {
095: // compute our courier delivery address: this placement in this session
096: String deliveryId = session.getId() + placementId;
097:
098: // find all deliveries for the requested deivery address
099: List deliveries = CourierService
100: .getDeliveries(deliveryId);
101:
102: // form the reply
103: sendDeliveries(res, deliveries);
104:
105: // refresh our presence at the location (placement)
106: if (M_log.isDebugEnabled())
107: M_log.debug("setting presence: " + placementId);
108: PresenceService.setPresence(placementId);
109:
110: // the 3rd part. if it has one dash then it's the add on from \/ the head script:
111: // updateReq.open("GET", url + "/" + new Date().getTime() + "-" + Math.random() + "?auto=true", true);
112: if (parts.length >= 3
113: && parts[2].split("-").length != 1) {
114: String subContextId = parts[2];
115: // refresh our presence at the location (placement)
116: if (M_log.isDebugEnabled())
117: M_log.debug("setting presence subcontext: "
118: + subContextId);
119: PresenceService.setPresence(subContextId);
120: }
121: }
122: }
123:
124: // otherwise this is a bad request!
125: else {
126: M_log.warn("bad courier request: " + req.getPathInfo());
127: sendDeliveries(res, new Vector());
128: }
129: }
130:
131: /**
132: * Access the Servlet's information display.
133: *
134: * @return servlet information.
135: */
136: public String getServletInfo() {
137: return "Sakai Courier Tool";
138: }
139:
140: /**
141: * Initialize the servlet.
142: *
143: * @param config
144: * The servlet config.
145: * @throws ServletException
146: */
147: public void init(ServletConfig config) throws ServletException {
148: super .init(config);
149:
150: M_log.info("init()");
151: }
152:
153: /**
154: * Send any deliveries, or at least something javascrip eval()'able.
155: *
156: * @param res
157: * @param deliveries
158: * The list (possibly empty) of deliveries
159: * @throws IOException
160: */
161: protected void sendDeliveries(HttpServletResponse res,
162: List deliveries) throws IOException {
163: res.setContentType("text/plain; charset=UTF-8");
164: res.addDateHeader("Expires", System.currentTimeMillis()
165: - (1000L * 60L * 60L * 24L * 365L));
166: res.addDateHeader("Last-Modified", System.currentTimeMillis());
167: res
168: .addHeader("Cache-Control",
169: "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
170: res.addHeader("Pragma", "no-cache");
171:
172: // get the writer
173: PrintWriter out = res.getWriter();
174:
175: for (Iterator i = deliveries.iterator(); i.hasNext();) {
176: Delivery d = (Delivery) i.next();
177: String s = d.compose();
178: if (M_log.isDebugEnabled())
179: M_log.debug("sending delivery: " + s);
180: out.println(s);
181: }
182:
183: // make sure we send something
184: if (deliveries.isEmpty()) {
185: String s = "//";
186: if (M_log.isDebugEnabled())
187: M_log.debug("sending delivery: " + s);
188: out.println(s);
189: }
190: }
191:
192: /**
193: * Send a redirect so our "top" ends up at the url, via javascript.
194: *
195: * @param url
196: * The redirect url
197: */
198: protected void sendTopRedirect(HttpServletResponse res, String url)
199: throws IOException {
200: res.setContentType("text/plain; charset=UTF-8");
201: res.addDateHeader("Expires", System.currentTimeMillis()
202: - (1000L * 60L * 60L * 24L * 365L));
203: res.addDateHeader("Last-Modified", System.currentTimeMillis());
204: res
205: .addHeader("Cache-Control",
206: "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
207: res.addHeader("Pragma", "no-cache");
208:
209: // get the writer
210: PrintWriter out = res.getWriter();
211:
212: // we are on deep under the main portal window
213: out.println("parent.location.replace('" + url + "');");
214: }
215: }
|