/* * AdminRequestProcessor.java * * This work is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This work is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Copyright (c) 2004 Per Cederberg. All rights reserved. */ package org.liquidsite.app.admin; import java.io.File; import java.util.ArrayList; import org.liquidsite.app.admin.view.AdminView; import org.liquidsite.app.servlet.Application; import org.liquidsite.app.servlet.RequestException; import org.liquidsite.app.servlet.RequestProcessor; import org.liquidsite.app.template.TemplateException; import org.liquidsite.core.content.Content; import org.liquidsite.core.content.ContentDocument; import org.liquidsite.core.content.ContentException; import org.liquidsite.core.content.ContentFile; import org.liquidsite.core.content.ContentManager; import org.liquidsite.core.content.ContentSection; import org.liquidsite.core.content.ContentSecurityException; import org.liquidsite.core.content.ContentSite; import org.liquidsite.core.content.ContentTemplate; import org.liquidsite.core.content.Domain; import org.liquidsite.core.content.PersistentObject; import org.liquidsite.core.content.User; import org.liquidsite.core.web.Request; import org.liquidsite.util.log.Log; /** * The request processor for the administration site(s). * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public class AdminRequestProcessor extends RequestProcessor { /** * The class logger. */ private static final Log LOG = new Log(AdminRequestProcessor.class); /** * The system view request processor. */ private SystemRequestProcessor system = new SystemRequestProcessor(); /** * The admin form handlers (workflows). */ private ArrayList workflows = new ArrayList(); /** * Creates a new administration request processor. * * @param app the application context */ public AdminRequestProcessor(Application app) { super(new ContentManager(app.getContentManager(), true), app.getBaseDir()); AdminUtils.setApplication(app); AdminUtils.setContentManager(getContentManager()); workflows.add(new HomeEditFormHandler()); workflows.add(new SiteAddFormHandler()); workflows.add(new SiteEditFormHandler()); workflows.add(new ContentAddFormHandler()); workflows.add(new ContentEditFormHandler()); workflows.add(new PublishDialogHandler()); workflows.add(new UnpublishDialogHandler()); workflows.add(new RevertDialogHandler()); workflows.add(new DeleteDialogHandler()); workflows.add(new PermissionsDialogHandler()); workflows.add(new UnlockDialogHandler()); workflows.add(new UsersAddFormHandler()); workflows.add(new UsersEditFormHandler()); workflows.add(new UsersDeleteDialogHandler()); } /** * Destroys this request processor. This method frees all * internal resources used by this processor. */ public void destroy() { // Nothing to be done } /** * Processes a request. * * @param request the request object */ public void process(Request request) { // Requests must be either authorized or unauthorized, // which is decided in the default request processor. } /** * Processes an authorized request. This is a request from a user * with permissions to access the admin site. * * @param request the request object * @param path the request path * * @throws RequestException if the request couldn't be processed * correctly */ public void processAuthorized(Request request, String path) throws RequestException { if (path.equals("style.css")) { request.sendFile(getFile(path), false); } else if (path.startsWith("images/")) { request.sendFile(getFile(path), false); } else if (path.startsWith("script/")) { request.sendFile(getFile(path), false); } else if (path.equals("") || path.equals("index.html")) { AdminView.HOME.viewHome(request); } else if (path.equals("home.html")) { AdminView.HOME.viewHome(request); } else if (path.equals("site.html")) { processViewSite(request); } else if (path.equals("content.html")) { processViewContent(request); } else if (path.equals("users.html")) { processViewUsers(request); } else if (path.equals("view-users.html")) { processViewUserDetails(request); } else if (path.equals("system.html")) { system.process(request, path); } else if (path.equals("statistics.html")) { processViewStatistics(request); } else if (path.equals("logout.html")) { processLogout(request); } else if (path.equals("loadsite.js")) { processLoadSite(request); } else if (path.equals("loadcontent.js")) { processLoadContent(request); } else if (path.equals("opensite.js")) { processOpenSite(request); } else if (path.equals("opencontent.js")) { processOpenContent(request); } else if (path.equals("opentemplate.js")) { processOpenTemplate(request); } else if (path.equals("sessionping.js")) { processSessionPing(request); } else if (path.startsWith("preview/")) { processPreview(request, path.substring(8)); } else if (path.startsWith("sessionpreview/")) { processSessionPreview(request, path.substring(15)); } else if (path.startsWith("stats/")) { processStats(request, path.substring(6)); } else { processWorkflow(request, path); } if (!request.hasResponse()) { throw RequestException.RESOURCE_NOT_FOUND; } } /** * Processes an unauthorized request. This is a request from a * user without permissions to access the admin site. * * @param request the request object * @param path the request path */ public void processUnauthorized(Request request, String path) { String str; if (path.equals("style.css")) { request.sendFile(getFile(path), false); } else if (path.startsWith("images/")) { request.sendFile(getFile(path), false); } else if (path.endsWith(".js")) { AdminView.SCRIPT.viewReload(request); } else if (path.equals("") || path.equals("index.html") || path.equals("home.html") || path.equals("site.html") || path.equals("content.html") || path.equals("users.html") || path.equals("system.html")) { if (request.getUser() != null) { request.setAttribute("error", "Access denied for your current user."); } AdminUtils.sendTemplate(request, "admin/login.ftl"); } else { str = request.getEnvironment().getSite().getDirectory(); request.sendRedirect(str); } } /** * Processes a logout request. * * @param request the request object */ private void processLogout(Request request) { request.setUser(null); request.sendRedirect("index.html"); } /** * Processes a form workflow request. This method will check the * specified page for a matching workflow. If no workflow is * found, no processing takes place. * * @param request the request object * @param page the request page */ private void processWorkflow(Request request, String page) { AdminFormHandler formHandler; for (int i = 0; i < workflows.size(); i++) { formHandler = (AdminFormHandler) workflows.get(i); if (formHandler.getFormPage().equals(page)) { formHandler.process(request); return; } } } /** * Processes a view site request. * * @param request the request object */ private void processViewSite(Request request) { try { AdminView.SITE.viewSite(request); } catch (ContentException e) { LOG.error(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } } /** * Processes a view content request. * * @param request the request object */ private void processViewContent(Request request) { try { AdminView.CONTENT.viewContent(request); } catch (ContentException e) { LOG.error(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } } /** * Processes a view users request. * * @param request the request object */ private void processViewUsers(Request request) { try { AdminView.USER.viewUsers(request); } catch (ContentException e) { LOG.error(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } } /** * Processes a view user or group detail request. * * @param request the request object */ private void processViewUserDetails(Request request) { try { AdminView.USER.viewGroup(request); } catch (ContentException e) { LOG.error(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } } /** * Processes a view statistics request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processViewStatistics(Request request) throws RequestException { PersistentObject obj; try { obj = AdminUtils.getReference(request); if (!obj.hasPublishAccess(request.getUser())) { throw RequestException.FORBIDDEN; } if (obj instanceof Domain) { AdminView.DIALOG.viewStatistics(request, (Domain) obj); } else { AdminView.BASE.viewError(request, "Cannot display statistics for object", "index.html"); } } catch (ContentException e) { LOG.error(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); AdminView.BASE.viewError(request, e.getMessage(), "index.html"); } } /** * Processes a JavaScript load site tree item request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processLoadSite(Request request) throws RequestException { PersistentObject obj; boolean open; try { obj = AdminUtils.getReference(request); open = request.getParameter("open", "").equals("true"); AdminView.SITE.viewLoadSiteScript(request, obj, open); } catch (ContentException e) { LOG.error(e.getMessage()); throw RequestException.INTERNAL_ERROR; } catch (ContentSecurityException e) { throw RequestException.FORBIDDEN; } } /** * Processes a JavaScript load content tree item request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processLoadContent(Request request) throws RequestException { PersistentObject obj; boolean open; try { obj = AdminUtils.getReference(request); open = request.getParameter("open", "").equals("true"); AdminView.CONTENT.viewLoadContentScript(request, obj, open); } catch (ContentException e) { LOG.error(e.getMessage()); throw RequestException.INTERNAL_ERROR; } catch (ContentSecurityException e) { throw RequestException.FORBIDDEN; } } /** * Processes a JavaScript open site tree item request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processOpenSite(Request request) throws RequestException { PersistentObject obj; try { obj = AdminUtils.getReference(request); AdminView.SITE.viewOpenSiteScript(request, obj); } catch (ContentException e) { LOG.error(e.getMessage()); throw RequestException.INTERNAL_ERROR; } catch (ContentSecurityException e) { throw RequestException.FORBIDDEN; } } /** * Processes a JavaScript open content tree item request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processOpenContent(Request request) throws RequestException { PersistentObject obj; try { obj = AdminUtils.getReference(request); AdminView.CONTENT.viewOpenContentScript(request, obj); } catch (ContentException e) { LOG.error(e.getMessage()); throw RequestException.INTERNAL_ERROR; } catch (ContentSecurityException e) { throw RequestException.FORBIDDEN; } } /** * Processes a JavaScript open template request. * * @param request the request object * * @throws RequestException if the request couldn't be processed * correctly */ private void processOpenTemplate(Request request) throws RequestException { int id; Content content; ContentTemplate template; try { id = Integer.parseInt(request.getParameter("id", "0")); content = getContentManager().getContent(request.getUser(), id); if (content instanceof ContentTemplate) { template = (ContentTemplate) content; AdminView.SITE.viewOpenTemplateScript(request, template); } else { AdminView.SITE.viewOpenTemplateScript(request, null); } } catch (NumberFormatException e) { throw RequestException.FORBIDDEN; } catch (ContentException e) { LOG.error(e.getMessage()); throw RequestException.INTERNAL_ERROR; } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); throw RequestException.FORBIDDEN; } } /** * Processes a sesssion keep-alive ping request. * * @param request the request object */ private void processSessionPing(Request request) { request.sendData("text/javascript", "/* Pong, session active. */"); } /** * Processes the preview requests. * * @param request the request object * @param path the preview path * * @throws RequestException if the request couldn't be processed * correctly */ private void processPreview(Request request, String path) throws RequestException { Content content; int id; int pos; try { pos = path.indexOf("/"); id = Integer.parseInt(path.substring(0, pos)); path = path.substring(pos + 1); content = getContentManager().getContent(request.getUser(), id); if (content instanceof ContentSite) { processPreview(request, (ContentSite) content, path); } else if (content instanceof ContentTemplate) { processPreview(request, (ContentTemplate) content); } else if (content instanceof ContentDocument) { processPreview(request, (ContentDocument) content, path); } else if (content instanceof ContentSection) { processPreview(request, (ContentSection) content); } else if (content instanceof ContentFile) { processPreview(request, (ContentFile) content); } else { throw RequestException.FORBIDDEN; } } catch (ContentException e) { LOG.error(e.getMessage()); request.sendData("text/plain", e.getMessage()); } catch (ContentSecurityException e) { request.sendData("text/plain", e.getMessage()); } catch (TemplateException e) { LOG.error(e.getMessage()); request.sendData("text/plain", e.getMessage()); } catch (RuntimeException e) { request.sendData("text/plain", "Cannot preview this object"); } } /** * Processes a preview request for a specific site. * * @param request the request object * @param site the content site object * @param path the preview path (within the site) * * @throws RequestException if the request couldn't be processed * correctly * @throws ContentException if the database couldn't be accessed * properly * @throws ContentSecurityException if the request referred to an * object that wasn't readable by the user * @throws TemplateException if the page template couldn't be * processed correctly */ private void processPreview(Request request, ContentSite site, String path) throws RequestException, ContentException, ContentSecurityException, TemplateException { String dir; // Adjust the request environment request.getEnvironment().setDomain(site.getDomain()); dir = request.getEnvironment().getSite().getDirectory() + "preview/" + site.getId() + "/"; site.setDirectory(dir); request.getEnvironment().setSite(site); // Process preview request if (path.startsWith("liquidsite/")) { processLiquidSite(request, path.substring(11)); } else { processNormal(request, site, path, true); } } /** * Processes a preview request for a specific file. * * @param request the request object * @param file the content file object * * @throws RequestException if the request couldn't be processed * correctly * @throws ContentException if the database couldn't be accessed * properly * @throws ContentSecurityException if the request referred to an * object that wasn't readable by the user * @throws TemplateException if the page template couldn't be * processed correctly */ private void processPreview(Request request, ContentFile file) throws RequestException, ContentException, ContentSecurityException, TemplateException { String revision; revision = request.getParameter("revision"); if (revision != null) { file = (ContentFile) file.getRevision(Integer.parseInt(revision)); } sendContent(request, file); } /** * Processes a preview request for a content template. * * @param request the request object * @param template the content template object * * @throws RequestException if the request couldn't be processed * correctly * @throws ContentException if the database couldn't be accessed * properly */ private void processPreview(Request request, ContentTemplate template) throws RequestException, ContentException { Content content; String revision; content = template; revision = request.getParameter("revision"); if (content != null && revision != null) { content = content.getRevision(Integer.parseInt(revision)); } if (content instanceof ContentTemplate) { AdminView.SITE.viewTemplatePreview(request, (ContentTemplate) content); } else { throw RequestException.RESOURCE_NOT_FOUND; } } /** * Processes a preview request for a specific document. * * @param request the request object * @param doc the content document object * @param path the preview path (within the document) * * @throws RequestException if the request couldn't be processed * correctly * @throws ContentException if the database couldn't be accessed * properly * @throws ContentSecurityException if the request referred to an * object that wasn't readable by the user */ private void processPreview(Request request, ContentDocument doc, String path) throws RequestException, ContentException, ContentSecurityException { ContentManager manager = getContentManager(); Content content = null; String revision; if (path.equals("")) { content = doc; } else { content = manager.getContentChild(request.getUser(), doc, path); } revision = request.getParameter("revision"); if (content != null && revision != null) { content = content.getRevision(Integer.parseInt(revision)); } if (content instanceof ContentDocument) { AdminView.CONTENT.viewDocumentPreview(request, (ContentDocument) content); } else if (content instanceof ContentFile) { request.sendFile(((ContentFile) content).getFile(), !content.hasReadAccess(null)); } else { throw RequestException.RESOURCE_NOT_FOUND; } } /** * Processes a preview request for a content section. * * @param request the request object * @param section the content section object * * @throws RequestException if the request couldn't be processed * correctly * @throws ContentException if the database couldn't be accessed * properly */ private void processPreview(Request request, ContentSection section) throws RequestException, ContentException { Content content; String revision; content = section; revision = request.getParameter("revision"); if (content != null && revision != null) { content = content.getRevision(Integer.parseInt(revision)); } if (content instanceof ContentSection) { AdminView.CONTENT.viewSectionPreview(request, (ContentSection) content); } else { throw RequestException.RESOURCE_NOT_FOUND; } } /** * Processes the session preview requests. * * @param request the request object * @param path the preview path * * @throws RequestException if the request couldn't be processed * correctly */ private void processSessionPreview(Request request, String path) throws RequestException { File file = request.getSession().getFile(path); if (file == null) { throw RequestException.RESOURCE_NOT_FOUND; } else { request.sendFile(file, true); } } /** * Processes the statistics requests. * * @param request the request object * @param path the statistics path * * @throws RequestException if the request couldn't be processed * correctly */ private void processStats(Request request, String path) throws RequestException { User user = request.getUser(); Domain domain; File file; String str; int pos; try { pos = path.indexOf("/"); str = path.substring(0, pos); path = path.substring(pos + 1); domain = getContentManager().getDomain(user, str); if (!domain.hasPublishAccess(user)) { throw RequestException.FORBIDDEN; } file = AdminUtils.getStatisticsDir(domain); if (file == null) { throw RequestException.RESOURCE_NOT_FOUND; } file = new File(file, path); if (file.canRead()) { request.sendFile(file, true); } else { throw RequestException.RESOURCE_NOT_FOUND; } } catch (ContentException e) { LOG.error(e.getMessage()); request.sendData("text/plain", e.getMessage()); } catch (ContentSecurityException e) { request.sendData("text/plain", e.getMessage()); } } }