001: package org.purl.sword.server;
002:
003: import java.io.IOException;
004: import java.io.PrintWriter;
005: import java.util.StringTokenizer;
006:
007: import javax.servlet.ServletException;
008: import javax.servlet.http.HttpServlet;
009: import javax.servlet.http.HttpServletRequest;
010: import javax.servlet.http.HttpServletResponse;
011:
012: import org.apache.commons.codec.binary.Base64;
013: import org.apache.log4j.Logger;
014: import org.purl.sword.base.HttpHeaders;
015: import org.purl.sword.base.SWORDAuthenticationException;
016: import org.purl.sword.base.SWORDException;
017: import org.purl.sword.server.SWORDServer;
018: import org.purl.sword.base.ServiceDocument;
019: import org.purl.sword.base.ServiceDocumentRequest;
020:
021: public class ServiceDocumentServlet extends HttpServlet {
022:
023: private SWORDServer myRepository;
024:
025: private String authN;
026:
027: private static Logger log = Logger
028: .getLogger(ServiceDocumentServlet.class);
029:
030: public void init() {
031: // Instantiate the correct SWORD Server class
032: String className = getServletContext().getInitParameter(
033: "server-class");
034: if (className == null) {
035: log
036: .fatal("Unable to read value of 'sword-server-class' from Servlet context");
037: } else {
038: try {
039: myRepository = (SWORDServer) Class.forName(className)
040: .newInstance();
041: log.info("Using " + className + " as the SWORDServer");
042: } catch (Exception e) {
043: log
044: .fatal("Unable to instantiate class from 'sword-server-class': "
045: + className);
046: }
047: }
048:
049: // Set the authentication method
050: authN = getServletContext().getInitParameter(
051: "authentication-method");
052: if ((authN == null) || (authN == "")) {
053: authN = "None";
054: }
055: log.info("Authentication type set to: " + authN);
056: }
057:
058: protected void doGet(HttpServletRequest request,
059: HttpServletResponse response) throws ServletException,
060: IOException {
061: // Create the ServiceDocumentRequest
062: ServiceDocumentRequest sdr = new ServiceDocumentRequest();
063:
064: // Are there any authentication details?
065: String usernamePassword = getUsernamePassword(request);
066: if ((usernamePassword != null)
067: && (!usernamePassword.equals(""))) {
068: int p = usernamePassword.indexOf(":");
069: if (p != -1) {
070: sdr.setUsername(usernamePassword.substring(0, p));
071: sdr.setPassword(usernamePassword.substring(p + 1));
072: }
073: } else if (authenticateWithBasic()) {
074: String s = "Basic realm=\"SWORD\"";
075: response.setHeader("WWW-Authenticate", s);
076: response.setStatus(401);
077: return;
078: }
079:
080: // Set the x-on-behalf-of header
081: sdr.setOnBehalfOf(request.getHeader(HttpHeaders.X_ON_BEHALF_OF
082: .toString()));
083:
084: // Set the IP address
085: sdr.setIPAddress(request.getRemoteAddr());
086:
087: // Get the ServiceDocument
088: try {
089: ServiceDocument sd = myRepository.doServiceDocument(sdr);
090:
091: // Print out the Service Document
092: // response.setContentType("application/atomserv+xml");
093: response.setContentType("application/xml");
094: PrintWriter out = response.getWriter();
095: out.write(sd.marshall());
096: out.flush();
097: } catch (SWORDAuthenticationException sae) {
098: if (authN.equals("Basic")) {
099: String s = "Basic realm=\"SWORD\"";
100: response.setHeader("WWW-Authenticate", s);
101: response.setStatus(401);
102: }
103: } catch (SWORDException se) {
104: // Throw a HTTP 500
105: response
106: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
107: }
108: }
109:
110: protected void doPost(HttpServletRequest request,
111: HttpServletResponse response) throws ServletException,
112: IOException {
113: // Send a '501 Not Implemented'
114: response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
115: }
116:
117: /**
118: * Utiliy method to return the username and password (separated by a colon ':')
119: *
120: * @param request
121: * @return The username and password combination
122: */
123: private String getUsernamePassword(HttpServletRequest request) {
124: try {
125: String authHeader = request.getHeader("Authorization");
126: if (authHeader != null) {
127: StringTokenizer st = new StringTokenizer(authHeader);
128: if (st.hasMoreTokens()) {
129: String basic = st.nextToken();
130: if (basic.equalsIgnoreCase("Basic")) {
131: String credentials = st.nextToken();
132: String userPass = new String(Base64
133: .decodeBase64(credentials.getBytes()));
134: return userPass;
135: }
136: }
137: }
138: } catch (Exception e) {
139: log.debug(e.toString());
140: }
141: return null;
142: }
143:
144: /**
145: * Utility method to deicde if we are using HTTP Basic authentication
146: *
147: * @return if HTTP Basic authentication is in use or not
148: */
149: private boolean authenticateWithBasic() {
150: if (authN.equalsIgnoreCase("Basic")) {
151: return true;
152: } else {
153: return false;
154: }
155: }
156: }
|