/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/citations/branches/sakai-2.8.1/citations-servlet/servlet/src/java/org/sakaiproject/citation/servlet/CitationServlet.java $ * $Id: CitationServlet.java 88776 2011-02-23 19:56:32Z arwhyte@umich.edu $ *********************************************************************************** * * Copyright (c) 2006, 2007, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.citation.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.cheftool.VmServlet; import org.sakaiproject.citation.api.Citation; import org.sakaiproject.citation.api.CitationCollection; import org.sakaiproject.citation.api.CitationHelper; import org.sakaiproject.citation.api.CitationService; import org.sakaiproject.citation.api.Schema; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.content.api.ContentHostingService; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.event.api.SessionState; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.exception.InUseException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.exception.ServerOverloadException; import org.sakaiproject.exception.TypeException; import org.sakaiproject.tool.api.ActiveTool; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.api.Tool; import org.sakaiproject.tool.api.ToolException; import org.sakaiproject.tool.cover.ActiveToolManager; import org.sakaiproject.tool.cover.SessionManager; import org.sakaiproject.util.BasicAuth; import org.sakaiproject.util.ParameterParser; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.util.Validator; import org.sakaiproject.util.Web; /** * * */ //public class CitationServlet extends VelocityPortletPaneledAction public class CitationServlet extends VmServlet { /** * */ public static final String SERVLET_TEMPLATE = "/vm/servlet.vm"; // private String collectionTitle = null; /** Our log (commons). */ private static Log M_log = LogFactory.getLog(CitationServlet.class); /** Resource bundle using current language locale */ protected static ResourceLoader rb = new ResourceLoader("citations"); /** set to true when init'ed. */ // protected boolean m_ready = false; protected BasicAuth basicAuth = null; protected enum Status { SUCCESS, ERROR; } // /** init thread - so we don't wait in the actual init() call */ // public class CitationServletInit extends Thread // { // protected CitationService m_citationService; // public void setCitationService(CitationService service) // { // this.m_citationService = service; // } // /** // * construct and start the init activity // */ // public CitationServletInit() // { // m_ready = false; // start(); // } // /** // * run the init // */ // public void run() // { // m_ready = true; // } // } /** * initialize the AccessServlet servlet * * @param config * the servlet config parameter * @exception ServletException * in case of difficulties */ public void init( ServletConfig config ) throws ServletException { super.init(config); // startInit(); basicAuth = new BasicAuth(); basicAuth.init(); } // /** // * Start the initialization process // */ // public void startInit() // { // new CitationServletInit(); // } /** * respond to an HTTP GET request * * @param req * HttpServletRequest object with the client request * @param res * HttpServletResponse object back to the client * @exception ServletException * in case of difficulties * @exception IOException * in case of difficulties */ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // process any login that might be present basicAuth.doLogin(req); // catch the login helper requests String option = req.getPathInfo(); String[] parts = option.split("/"); if ((parts.length == 2) && ((parts[1].equals("login")))) { doLogin( req, res, null ); } else { // try to add the Citation List citationCollectionTitleList = addCitation( ( ParameterParser )req.getAttribute( ATTR_PARAMS ), option, res ); Citation citation = (Citation) citationCollectionTitleList.get(0); String collectionTitle = (String) citationCollectionTitleList.get(1); if( citation != null ) { // return success M_log.debug( "doGet() [addCitation()] added Citation '" + citation.getDisplayName() + "'" ); respond( Status.SUCCESS, citation, collectionTitle, req, res ); } else { // return failure M_log.debug( "doGet() [addCitation()] failed to add citation" ); respond( Status.ERROR, null, collectionTitle, req, res ); } } } /** * respond to an HTTP POST request; only to handle the login process * * @param req * HttpServletRequest object with the client request * @param res * HttpServletResponse object back to the client * @exception ServletException * in case of difficulties * @exception IOException * in case of difficulties */ public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // process any login that might be present basicAuth.doLogin(req); // catch the login helper posts String option = req.getPathInfo(); String[] parts = option.split("/"); if ((parts.length == 2) && ((parts[1].equals("login")))) { doLogin(req, res, null); } else { // don't handle POSTs sendError(res, HttpServletResponse.SC_NOT_FOUND); } } /** * handle get and post communication from the user * * @param req HttpServletRequest object with the client request * @param res HttpServletResponse object back to the client */ public List addCitation( ParameterParser params, String option, HttpServletResponse res ) { // get the path info String path = params.getPath(); if (path == null) path = ""; // if (!m_ready) // { // sendError( res, HttpServletResponse.SC_SERVICE_UNAVAILABLE ); // } String collectionTitle = null; // parse the request path String[] parts = option.split("/"); String resourceUuid = parts[1]; // get services from ComponentManager ContentHostingService contentService = (ContentHostingService) ComponentManager.get("org.sakaiproject.content.api.ContentHostingService"); CitationService citationService = (CitationService) ComponentManager.get("org.sakaiproject.citation.api.CitationService"); CitationCollection collection = null; Citation citation = null; try { String resourceId = contentService.resolveUuid(resourceUuid); // check to see if user has revise permission if( !citationService.allowReviseCitationList( resourceId ) ) { // revise permission denied return null; } // revise permission granted ContentResource resource = contentService.getResource(resourceId); String collectionId = new String(resource.getContent()); collection = citationService.getCollection(collectionId); String genre = params.getString("genre"); String[] authors = params.getStrings("au"); String title = params.getString("title"); String atitle = params.getString("atitle"); String volume = params.getString("volume"); String issue = params.getString("issue"); String pages = params.getString("pages"); String publisher = params.getString("publisher"); String date = params.getString("date"); String id = params.getString("id"); // do we have enough info for a meaningful citation? if( ( title == null || title.trim().equals("") ) && ( atitle == null || atitle.trim().equals("") ) ) { // both title AND atitle are null return null; } // force a generic genre if we don't know any better if (genre == null || genre.trim().equals("")) { genre = CitationService.UNKNOWN_TYPE; } citation = citationService.addCitation(genre); StringBuilder info = new StringBuilder(); if(M_log.isDebugEnabled()) { info.append("New citation from Google Scholar:\n\t genre:\t\t"); info.append(genre); } // Generally, only books have a title that's the actual title of the piece. // We'll check to see if there's an atitle; if not, use the title as the // work's title. Otherwise, use the title as the source. if(title != null) { if (atitle != null) { if(M_log.isDebugEnabled()) { info.append("\n\t source title:\t\t"); } citation.addPropertyValue(Schema.SOURCE_TITLE, title); } else { if(M_log.isDebugEnabled()) { info.append("\n\t title:\t\t"); } citation.addPropertyValue(Schema.TITLE, title); } if(M_log.isDebugEnabled()) { info.append( title ); } } if(atitle != null) { if(M_log.isDebugEnabled()) { info.append("\n\t title:\t\t"); info.append( atitle ); } citation.addPropertyValue(Schema.TITLE, atitle); } if(authors != null && authors.length > 0) { for(int i = 0; i < authors.length; i++) { if(M_log.isDebugEnabled()) { info.append("\n\t au:\t\t"); info.append(authors[i]); } citation.addPropertyValue(Schema.CREATOR, authors[i]); } } if(volume != null) { if(M_log.isDebugEnabled()) { info.append("\n\t volume:\t\t"); info.append(volume); } citation.addPropertyValue(Schema.VOLUME, volume); } if(issue != null) { if(M_log.isDebugEnabled()) { info.append("\n\t issue:\t\t"); info.append(issue); } citation.addPropertyValue(Schema.ISSUE, issue); } if(pages != null) { if(M_log.isDebugEnabled()) { info.append("\n\t pages:\t\t"); info.append(pages); } citation.addPropertyValue(Schema.PAGES, pages); } if(publisher != null) { if(M_log.isDebugEnabled()) { info.append("\n\t publisher:\t\t"); info.append(publisher); } citation.addPropertyValue(Schema.PUBLISHER, publisher); } if(date != null) { if(M_log.isDebugEnabled()) { info.append("\n\t date:\t\t"); info.append(date); } citation.addPropertyValue(Schema.YEAR, date); } if(id != null) { if(M_log.isDebugEnabled()) { info.append("\n\t id:\t\t"); info.append(id); } citation.addPropertyValue(Schema.ISN, id); } if(M_log.isDebugEnabled()) { info.append("\n"); } collection.add(citation); citationService.save(collection); if(M_log.isDebugEnabled()) { M_log.debug(info.toString()); } // get the citation list title String refStr = contentService.getReference(resourceId); Reference ref = EntityManager.newReference(refStr); collectionTitle = ref.getProperties().getProperty(ResourceProperties.PROP_DISPLAY_NAME); } catch (PermissionException e) { // TODO Auto-generated catch block M_log.warn("PermissionException ", e); return null; } catch (IdUnusedException e) { // TODO Auto-generated catch block M_log.warn("IdUnusedException ", e); return null; } catch (TypeException e) { // TODO Auto-generated catch block M_log.warn("TypeException ", e); return null; } catch (ServerOverloadException e) { // TODO Auto-generated catch block M_log.warn("ServerOverloadException ", e); return null; } List citationCollectionTitleList = new ArrayList(); citationCollectionTitleList.add(citation); citationCollectionTitleList.add(collectionTitle); // return citation; return citationCollectionTitleList; } protected void respond( Status status, Citation citation, String collectionTitle, HttpServletRequest req, HttpServletResponse res ) throws ServletException { // the context wraps our real vm attribute set ResourceProperties props = new org.sakaiproject.util.BaseResourceProperties(); setVmReference("props", props, req); setVmReference("validator", new Validator(), req); setVmReference("tlang", rb, req); res.setContentType("text/html; charset=UTF-8"); Object success = null; if( status == Status.SUCCESS ) { success = new Object(); setVmReference( "citation", citation, req ); // schedule a refresh of the main toolframe // ToolSession toolSession = SessionManager.getCurrentToolSession(); // toolSession.setAttribute( "sakai.vppa.top.refresh", Boolean.TRUE ); setVmReference("topRefresh", Boolean.TRUE, req ); // TODO } // set the success flag setVmReference("success", success, req); // include object arrays for formatted messages if( collectionTitle == null || collectionTitle.trim().equals("") ) { collectionTitle = "your current citation list"; } Object[] titleArgs = { Validator.escapeHtml(collectionTitle) }; // TODO temporary placeholder setVmReference( "titleArgs", titleArgs, req ); // return the servlet template includeVm( SERVLET_TEMPLATE, req, res ); } /** * Make a redirect to the login url. * * @param req * HttpServletRequest object with the client request. * @param res * HttpServletResponse object back to the client. * @param path * The current request path, set ONLY if we want this to be where to redirect the user after successfull login * @throws IOException */ protected void doLogin(HttpServletRequest req, HttpServletResponse res, String path) throws ToolException, IOException { // if basic auth is valid do that if ( basicAuth.doAuth(req,res) ) { //System.err.println("BASIC Auth Request Sent to the Browser "); return; } // get the Sakai session Session session = SessionManager.getCurrentSession(); // set the return path for after login if needed (Note: in session, not tool session, special for Login helper) if (path != null) { // where to go after session.setAttribute(Tool.HELPER_DONE_URL, Web.returnUrl(req, path)); } // check that we have a return path set; might have been done earlier if (session.getAttribute(Tool.HELPER_DONE_URL) == null) { M_log.warn("doLogin - proceeding with null HELPER_DONE_URL"); } // map the request to the helper, leaving the path after ".../options" for the helper ActiveTool tool = ActiveToolManager.getActiveTool("sakai.login"); String context = req.getContextPath() + req.getServletPath() + "/login"; tool.help(req, res, context, "/login"); } /** * Utility method to return errors as the response * * @param res response associated with this request * @param code error code */ protected void sendError(HttpServletResponse res, int code) { try { res.sendError(code); } catch (Throwable t) { M_log.warn("sendError: " + t); } } }