xlawrence    2005/08/05 15:50:38 CEST

  Added files:
    core/src/java/org/jahia/ajax AjaxServlet.java 
  Log:
  Added AJAX servlet to process requests and build the action menus
  
  Revision  Changes    Path
  1.1       +408 -0    jahia/core/src/java/org/jahia/ajax/AjaxServlet.java (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/ajax/AjaxServlet.java?rev=1.1&content-type=text/plain
  
  
  
  Index: AjaxServlet.java
  ====================================================================
  /*
   *                                   ____.
   *                       __/\ ______|    |__/\.     _______
   *            __   .____|    |       \   |    +----+       \
   *    _______|  /--|    |    |    -   \  _    |    :    -   \_________
   *   \\______: :---|    :    :           |    :    |         \________>
   *           |__\---\_____________:______:    :____|____:_____\
   *                                      /_____|
   *
   *              . . . i n   j a h i a   w e   t r u s t . . .
   *
   *
   *
   * ----- BEGIN LICENSE BLOCK -----
   * Version: JCSL 1.0
   *
   * The contents of this file are subject to the Jahia Community Source License
   * 1.0 or later (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.jahia.org/license
   *
   * Software distributed under the License is distributed on an "AS IS" basis,
   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   * for the rights, obligations and limitations governing use of the contents
   * of the file. The Original and Upgraded Code is the Jahia CMS and Portal
   * Server. The developer of the Original and Upgraded Code is JAHIA Ltd. JAHIA
   * Ltd. owns the copyrights in the portions it created. All Rights Reserved.
   *
   * The Shared Modifications are Jahia View Helper.
   *
   * The Developer of the Shared Modifications is Jahia Solution Sàrl.
   * Portions created by the Initial Developer are Copyright (C) 2002 by the
   * Initial Developer. All Rights Reserved.
   *
   * ----- END LICENSE BLOCK -----
   */
  
  package org.jahia.ajax;
  
  import java.io.IOException;
  import java.io.OutputStream;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import org.jahia.bin.Jahia;
  import org.jahia.content.ContentPageKey;
  import org.jahia.data.beans.ActionURIBean;
  import org.jahia.data.beans.ContainerBean;
  import org.jahia.data.beans.ContainerListBean;
  import org.jahia.data.beans.ContentBean;
  import org.jahia.data.beans.FieldBean;
  import org.jahia.data.beans.PageBean;
  import org.jahia.data.containers.JahiaContainer;
  import org.jahia.data.containers.JahiaContainerList;
  import org.jahia.data.fields.JahiaField;
  import org.jahia.data.fields.LoadFlags;
  import org.jahia.exceptions.JahiaException;
  import org.jahia.gui.GuiBean;
  import org.jahia.gui.HTMLToolBox;
  import org.jahia.params.ProcessingContext;
  import org.jahia.params.ProcessingContextFactory;
  import org.jahia.registries.ServicesRegistry;
  import org.jahia.resourcebundle.JahiaResourceBundle;
  import org.jahia.services.pages.ContentPage;
  import org.jahia.services.pages.JahiaPage;
  import org.jahia.services.version.EntryLoadRequest;
  import org.springframework.beans.factory.BeanFactory;
  
  /**
   * AJAX Servlet implementation to handle asynchronous calls to retreive the
   * body of the Action Menus.
   *
   * @author Xavier Lawrence
   * @version 1.0
   */
  public class AjaxServlet extends HttpServlet {
      
      private static final String AJAX_FIELDSET = "fieldset";
      private static final String AJAX_LAUNCHER = "launcher";
      private static final String AJAX_IMAGE = "image";
      private static final String AJAX_METHOD = "method";
      
      private static final String KEY = "key";
      private static final String TYPE = "type";
      private static final String DEF = "def";
      private static final String PARENT = "parent";
      private static final String PAGE = "page";
      
      private static final String DELIMITER = ";;";
      
      private static final String CHARSET = "UTF-8";
      private static final String XML_HEADER =
              "<?xml version=\"1.0\" encoding=\"" + CHARSET + "\"?>\n";
      
      private static final String CACHE_CONTROL = "Cache-Control" ;
      private static final String NO_CACHE = "no-cache" ;
      private static final String XML_CONTENT = "text/xml" ;
      
      private static final String DEFAULT_LOCK_IMAGE = "lock_grey.gif";
      
      private static final org.apache.log4j.Logger logger =
              org.apache.log4j.Logger.getLogger(AjaxServlet.class);
      
      private static final ServicesRegistry servicesRegistry = 
ServicesRegistry.getInstance();
      
      // Used to store information that will be used once the action is built, 
but which is 
      // provided when drawing the menu in the template.
      private static final HashMap objectKeyToInfo = new HashMap();
      
      public void doGet(final HttpServletRequest request, final 
HttpServletResponse response)
      throws IOException, ServletException {
          processMenuRequest(request, response);
      }
      
      public void doPost(final HttpServletRequest request, final 
HttpServletResponse response)
      throws IOException, ServletException {
          processMenuRequest(request, response);
      }
      
      /**
       * Process the request and get all the actions for the action menu. The
       * information will be returned in an XML document.
       * @param request The current request
       * @param response The current response
       *
       * @throws ServletException
       * @throws IOException
       */
      private void processMenuRequest( final HttpServletRequest request, 
              final HttpServletResponse response )
      throws IOException, ServletException {
          try {
              final String objectType = getParameter(request, response, TYPE);
              if (objectType == null) return;
              
              final String objectID = getParameter(request, response, KEY);
              if (objectID == null) return;
              
              final String definitionID = getParameter(request, response, DEF);
              if (definitionID == null) return;
              
              final String parentID = getParameter(request, response, PARENT);
              if (parentID == null) return;
              
              final String pageID = getParameter(request, response, PAGE);
              if (pageID == null) return;
              final int pid = Integer.parseInt(pageID);
              
              logger.debug("processRequest: objectType=" + objectType + ", 
objectID="+
                      objectID + ", definitionID=" + definitionID + ", 
parentID=" +
                      parentID + ", pageID=" + pageID);
              
              // Create the ProcessingContext
              final BeanFactory bf = Jahia.getConfigBeanFactory();
              final ProcessingContextFactory pcf = (ProcessingContextFactory) 
bf.
                      getBean(ProcessingContextFactory.class.getName());
              final ProcessingContext jParams = pcf.getContext(request, 
response, 
                      super.getServletContext());
              
              jParams.setOpMode(jParams.EDIT);
              
              logger.debug("jParams: pid = " + jParams.getPageID() + ", user = 
" +
                      jParams.getUser().getName() + ", mode = " + 
                      jParams.getOperationMode () + ", SessionID = " + 
                      jParams.getSessionID());
              
              // The unique contentObject ID
              final int objID = Integer.parseInt(objectID);
              
              final EntryLoadRequest elr = new 
EntryLoadRequest(EntryLoadRequest.
                      STAGING_WORKFLOW_STATE,
                      0,
                      jParams.getEntryLoadRequest().getLocales());
              jParams.setSubstituteEntryLoadRequest(elr);
              
              final ContentBean bean;
              
              // Action Menu for a page
              if (PageBean.TYPE.equals(objectType)) {
                  bean = new PageBean(jParams.getPage(), jParams);
                  logger.debug("PageID: " + bean.getID());
                  
              // Action Menu for a ContainerList
              } else if (ContainerListBean.TYPE.equals(objectType)) {     
                  final JahiaContainerList list;
                  if (objID > 0) {
                      list = servicesRegistry.getJahiaContainersService().
                              loadContainerListInfo(objID, elr);
                  } else {
                      final int parentid = Integer.parseInt(parentID);
                      if (parentid == pid) {
                          list = new JahiaContainerList(0, 0,
                                  pid, Integer.parseInt(definitionID), 0);
                      } else {
                          list = new JahiaContainerList(0, parentid,
                                  pid, Integer.parseInt(definitionID), 0);
                      }
                  }
                  logger.debug("ContainerListID: " + list.getID() + ", def: " + 
                          list.getDefinition().getID());
                  bean = new ContainerListBean(list, jParams);
                 
              // Action Menu for a Container
              } else if (ContainerBean.TYPE.equals(objectType)) {
                  final JahiaContainer container = 
servicesRegistry.getJahiaContainersService().
                          loadContainerInfo(objID, elr);
                  logger.debug("ContainerID: " + container.getID());
                  bean = new ContainerBean(container, jParams);
                  
              // Action Menu for a Field
              } else if (FieldBean.TYPE.equals(objectType)) {
                  final JahiaField field = 
servicesRegistry.getJahiaFieldService().
                          loadField(objID, LoadFlags.ALL, jParams, elr);
                  logger.debug("FieldID: " + field.getID());
                  bean = new FieldBean(field, jParams);
                  
              } else {
                  bean = null;
                  response.setStatus(response.SC_BAD_REQUEST);
                  response.sendError(response.SC_BAD_REQUEST,
                          "Unknown 'ObjectType' value ! 'ObjectType' value 
should be '"+ 
                          PageBean.TYPE + "', '" + ContainerListBean.TYPE + "', 
'" + 
                          ContainerBean.TYPE + "' or '" + FieldBean.TYPE + 
"'.");
                  return;
              }
              
              // Get all the information regarding the Action entries
              final Map info = getActionsInfo(bean, jParams);
              logger.debug("ActionsInfo:\n" + info);
              
              // Build the response message...
              response.setContentType(XML_CONTENT);    // mandatory, do not 
remove !
              response.setHeader(CACHE_CONTROL, NO_CACHE);    // mandatory, do 
not remove !
              
              // This buffer contains the response document
              final StringBuffer buff = new StringBuffer();
              buff.append(XML_HEADER);
              buildNode(buff, KEY, objectID);
              buildNode(buff, TYPE, objectType);
              buildNode(buff, DEF, definitionID);
              buildNode(buff, PARENT, parentID);
              buildNode(buff, PAGE, pageID);
              
              if (info.containsKey(AJAX_FIELDSET)) {
                  buildNode(buff, AJAX_FIELDSET,
                          (String)info.get(AJAX_FIELDSET));
              }
              
              buildNode(buff, AJAX_LAUNCHER,
                      (String)info.get(AJAX_LAUNCHER));
              
              buildNode(buff, AJAX_IMAGE,
                      (String)info.get(AJAX_IMAGE));
              
              buildNode(buff, AJAX_METHOD,
                      (String)info.get(AJAX_METHOD));
             
              logger.debug("Response:\n" + buff);
              final byte[] bytes = buff.toString().getBytes(CHARSET);
              
              response.setContentLength(bytes.length);
              response.setStatus(response.SC_OK);
  
              final OutputStream out = response.getOutputStream ();
              out.write(bytes);
              out.flush();
              
          } catch (Exception e) {
              logger.fatal("Unable to process the request !", e);
              response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
              response.sendError(response.SC_INTERNAL_SERVER_ERROR,
                      "Unable to process the request ! Msg: "+ e.getMessage());
          }
      }
      
      /** 
       * Simple utility method to retreive a parameter from a request and send
       * an error message (status 400) in case the parameter is not found.
       *
       * @param request the HttpServletRequest
       * @param response the HttpServletResponse
       * @param name The required parameter name
       *
       * @throws ServletException
       * @throws IOException
       */
      protected String getParameter(final HttpServletRequest request,
              final HttpServletResponse response, final String name)
              throws ServletException, IOException {
          final String value = request.getParameter(name);
          if (value == null) {
              logger.fatal("Missing required '" + name + "' parameter in 
request.");
              response.setStatus(response.SC_BAD_REQUEST);
              response.sendError(response.SC_BAD_REQUEST,
                      "Missing required '" + name + "' parameter in request.");
          }
          return value;
      }
      
      /**
       * Simple utility method to build a String representing an XML node and 
its 
       * value.
       * @param buff The StringBuffer that will be used to store the result
       * @param tagName The XML tag name
       * @param tagValue The XML tag value.
       */
      protected void buildNode(final StringBuffer buff, final String tagName, 
              final String tagValue) {
          if (tagValue == null || tagValue.length() == 0) { return; }
          buff.append("<").append(tagName).append(">");
          buff.append(tagValue);
          buff.append("</").append(tagName).append(">\n");
      }
      
      /**
       * Retrieves all the information required to build the actual action menu.
       * @param bean The ContentBean for which the menu will be built
       * @param jParams ProcessingContext
       *
       * @throws JahiaException
       */
      protected Map getActionsInfo(final ContentBean bean,
              final ProcessingContext jParams) throws JahiaException {
          final GuiBean gui = new GuiBean(jParams);
          final HTMLToolBox box = new HTMLToolBox(gui, jParams);
          final HashMap result = new HashMap();
          
          final Map objectInfo = (Map)objectKeyToInfo.get(
                  box.buildUniqueContentID(bean));
          
          logger.debug("objectInfo for ContentBean " + bean.getID() + ": " +
                  objectInfo);
          
          if (objectInfo.get("useFieldSet").equals(Boolean.TRUE)) {   
              final String param;
              if (bean.isCompletelyLocked()) {
                  param = "complete";
                  
              } else if (bean.isPartiallyLocked()) {
                  param = "partial";
                                  
              } else {
                  param = null;
              }
              
              result.put(AJAX_FIELDSET, param);
          }
          
          final Iterator actionURIIter = 
bean.getActionURIBeans().entrySet().iterator();
          
          final StringBuffer launchers = new StringBuffer();
          final StringBuffer methods = new StringBuffer();
          final StringBuffer images = new StringBuffer();
          
          while (actionURIIter.hasNext()) {
              final Map.Entry curEntry = (Map.Entry) actionURIIter.next();
              final ActionURIBean curActionURIBean = (ActionURIBean) 
curEntry.getValue();
              
              if (curActionURIBean.isAuthorized()) {
                  
launchers.append(curActionURIBean.getLauncherUri()).append(DELIMITER);
                  
                  final String resourceBundle = 
(String)objectInfo.get("resourceBundle");
                  methods.append(box.getResource(resourceBundle,
                          curActionURIBean.getName())).append(DELIMITER);
                  
                  images.append(box.getURLImageContext());
                  
                  if (curActionURIBean.isLocked()) {
                      final String lockIcon = 
(String)objectInfo.get("lockIcon");
                      if (lockIcon == null) {
                          images.append("/").append(DEFAULT_LOCK_IMAGE);
                      } else {
                          images.append("/").append(lockIcon);
                      }
                      
                  } else {
                      images.append("/").append(curActionURIBean.getName()).
                              append(".gif");
                  }
                  
                  images.append(DELIMITER);
              }
          }
          
          if (methods.length() > 0) {
              result.put(AJAX_LAUNCHER, launchers.toString());
              result.put(AJAX_METHOD, methods.toString());
              result.put(AJAX_IMAGE, images.toString());
          }
          
          return result;
      }
      
      /**
       * Method used to store information about the ActionMenu that will only 
be needed
       * when the user loads the menu.
       * @param menuID The key associated with the menu
       * @param props The information of the menu
       */
      public static void setObjectInfo(final String menuID, final Map props) {
          objectKeyToInfo.put(menuID, props);
          logger.debug("setObjectInfo: "+menuID+ ", " + props);
      }
  }
  

Reply via email to