001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.console; 018 019 import org.apache.commons.logging.Log; 020 import org.apache.commons.logging.LogFactory; 021 import org.apache.commons.fileupload.portlet.PortletFileUpload; 022 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 023 import org.apache.commons.fileupload.FileItem; 024 import org.apache.commons.fileupload.FileUploadException; 025 026 import javax.portlet.ActionRequest; 027 import javax.portlet.ActionResponse; 028 import javax.portlet.PortletException; 029 import javax.portlet.RenderRequest; 030 import javax.portlet.RenderResponse; 031 import javax.portlet.WindowState; 032 import javax.portlet.PortletConfig; 033 import javax.portlet.PortletRequest; 034 import java.util.Map; 035 import java.util.HashMap; 036 import java.util.Iterator; 037 import java.util.List; 038 import java.io.IOException; 039 040 /** 041 * A base class for porlets consisting on multiple JSPs with before and after 042 * actions (e.g. for load and validation/save) and the ability for an "after" 043 * action to set the next page to load. 044 * 045 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 046 */ 047 public abstract class MultiPagePortlet extends BasePortlet { 048 private final static Log log = LogFactory.getLog(MultiPagePortlet.class); 049 protected static final String MODE_KEY = "mode"; 050 protected final Map<String, MultiPageAbstractHandler> helpers = new HashMap<String, MultiPageAbstractHandler>(); 051 052 public void destroy() { 053 for (MultiPageAbstractHandler handler : helpers.values()) { 054 handler.destroy(); 055 } 056 helpers.clear(); 057 super.destroy(); 058 } 059 060 public void processAction(ActionRequest actionRequest, 061 ActionResponse actionResponse) throws PortletException, IOException { 062 String mode = null; 063 Map<String, FileItem> files = null; 064 Map<String, String> fields = null; 065 if(actionRequest.getContentType() != null && actionRequest.getContentType().startsWith("multipart/form-data")) { 066 files = new HashMap<String, FileItem>(); 067 fields = new HashMap<String, String>(); 068 PortletFileUpload request = new PortletFileUpload(new DiskFileItemFactory()); 069 try { 070 List<FileItem> items = request.parseRequest(actionRequest); 071 for (FileItem item : items) { 072 if (item.isFormField()) { 073 if (item.getFieldName().equals(MODE_KEY)) { 074 mode = item.getString(); 075 } 076 fields.put(item.getFieldName(), item.getString()); 077 } else { 078 files.put(item.getFieldName(), item); 079 } 080 } 081 } catch (FileUploadException e) { 082 log.error("Unable to process form including a file upload", e); 083 } 084 } else { 085 mode = actionRequest.getParameter(MODE_KEY); 086 } 087 MultiPageModel model = getModel(actionRequest); 088 while(true) { 089 if(mode == null) { 090 break; 091 } 092 int pos = mode.lastIndexOf('-'); 093 if(pos == -1) { // Assume it's a render request 094 break; 095 } else { 096 String type = mode.substring(pos+1); 097 mode = mode.substring(0, pos); 098 MultiPageAbstractHandler handler = helpers.get(mode); 099 if(handler == null) { 100 log.error("No handler for action mode '"+mode+"'"); 101 break; 102 } 103 if(files == null) { 104 handler.getUploadFields().clear(); 105 handler.getUploadFiles().clear(); 106 } else { 107 handler.getUploadFields().putAll(fields); 108 handler.getUploadFiles().putAll(files); 109 } 110 log.debug("Using action handler '"+handler.getClass().getName()+"'"); 111 if(type.equals("before")) { 112 mode = handler.actionBeforeView(actionRequest, actionResponse, model); 113 } else if(type.equals("after")) { 114 mode = handler.actionAfterView(actionRequest, actionResponse, model); 115 } else { 116 log.error("Unrecognized portlet action '"+mode+"'"); 117 mode = null; 118 } 119 } 120 } 121 if(mode != null) { 122 actionResponse.setRenderParameter(MODE_KEY, mode); 123 } 124 if(model != null) { 125 model.save(actionResponse, actionRequest.getPortletSession(true)); 126 } 127 } 128 129 protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { 130 if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) { 131 return; 132 } 133 String mode = renderRequest.getParameter(MODE_KEY); 134 MultiPageModel model = getModel(renderRequest); 135 if(mode == null || mode.equals("")) { 136 mode = getDefaultMode(); 137 } 138 MultiPageAbstractHandler handler = helpers.get(mode); 139 try { 140 if(handler == null) { 141 log.error("No handler for render mode '"+mode+"'"); 142 } else { 143 log.debug("Using render handler '"+handler.getClass().getName()+"'"); 144 handler.renderView(renderRequest, renderResponse, model); 145 } 146 } catch (Throwable e) { 147 log.error("Unable to render portlet", e); 148 } 149 renderRequest.setAttribute(getModelJSPVariableName(), model); 150 if(handler != null) { 151 handler.getView().include(renderRequest, renderResponse); 152 } 153 } 154 155 protected void addHelper(MultiPageAbstractHandler handler, PortletConfig config) throws PortletException { 156 handler.init(config); 157 helpers.put(handler.getMode(), handler); 158 } 159 160 protected String getDefaultMode() { 161 if(helpers.containsKey("index")) return "index"; 162 if(helpers.containsKey("list")) return "list"; 163 return null; 164 } 165 166 protected abstract String getModelJSPVariableName(); 167 168 protected abstract MultiPageModel getModel(PortletRequest request); 169 }