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);
}
}