⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genericportlet.java

📁 portal越来越流行了
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache 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.apache.org/licenses/LICENSE-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.
 */
/*
 * NOTE: this source code is based on an early draft version of JSR 286 and not intended for product
 * implementations. This file may change or vanish in the final version of the JSR 286 specification.
 */
/*
 * This source code implements specifications defined by the Java
 * Community Process. In order to remain compliant with the specification
 * DO NOT add / change / or delete method signatures!
 */
/**
 * Copyright 2006 IBM Corporation.
 */

package javax.portlet;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.namespace.QName;

/**
 * The <CODE>GenericPortlet</CODE> class provides a default implementation for
 * the <CODE>Portlet</CODE> interface.
 * <p>
 * It provides an abstract class to be subclassed to create portlets. A subclass
 * of <CODE>GenericPortlet</CODE> should either use one of the following annotations:
 * <ul>
 * <li><code>@ProcessAction</code></li>
 * <li><code>@ProcessEvent</code></li>
 * <li><code>@RenderMode</code></li>
 * </ul>
 * or override at least one method, usually
 * one of the following:
 * <ul>
 * <li>processAction, to handle action requests</li>
 * <li>doView, to handle render requests when in VIEW mode</li>
 * <li>doEdit, to handle render requests when in EDIT mode</li>
 * <li>doHelp, to handle render request when in HELP mode</li>
 * <li>init and destroy, to manage resources that are held for the life of the
 * servlet</li>
 * </ul>
 * <p>
 * Normally there is no need to override the render or the doDispatch methods.
 * Render handles render requests setting the title of the portlet in the
 * response and invoking doDispatch. doDispatch dispatches the request to one of
 * the doView, doEdit or doHelp method depending on the portlet mode indicated
 * in the request.
 * <p>
 * Portlets typically run on multithreaded servers, so please note that a
 * portlet must handle concurrent requests and be careful to synchronize access
 * to shared resources. Shared resources include in-memory data such as instance
 * or class variables and external objects such as files, database connections,
 * and network connections.
 */
public abstract class GenericPortlet implements Portlet, PortletConfig, EventPortlet, ResourceServingPortlet {

	private transient PortletConfig config;

	private transient Map<String, Method> processActionHandlingMethodsMap = new HashMap<String, Method>();
	private transient Map<String, Method> processEventHandlingMethodsMap = new HashMap<String, Method>();
	private transient Map<String, Method> renderModeHandlingMethodsMap = new HashMap<String, Method>();

	/**
	 * Does nothing.
	 */

	public GenericPortlet() {
	}

	/**
	 * Called by the portlet container to indicate to a portlet that the portlet
	 * is being placed into service.
	 * <p>
	 * The default implementation stores the <code>PortletConfig</code> object
	 * and checks for annotated methods with the annotations
	 * <ul>
	 * <li>@ProcessAction</li>
	 * <li>@ProcessEvent</li>
	 * <li>@RenderMode</li>
	 * </ul>
	 * and stores these in a hashmap for later dispatching.
	 * <p>
	 * The portlet container calls the <code>init</code> method exactly once
	 * after instantiating the portlet. The <code>init</code> method must
	 * complete successfully before the portlet can receive any requests.
	 * 
	 * <p>
	 * The portlet container cannot place the portlet into service if the
	 * <code>init</code> method does one of the following:
	 * <ol>
	 * <li>it throws a <code>PortletException</code>
	 * <li>it does not return within a time period defined by the Web server
	 * </ol>
	 * 
	 * 
	 * @param config
	 *            a <code>PortletConfig</code> object containing the portlet
	 *            configuration and initialization parameters
	 * 
	 * @exception PortletException
	 *                if an exception has occurred that interferes with the
	 *                portlet normal operation.
	 * @exception UnavailableException
	 *                if the portlet cannot perform the initialization at this
	 *                time.
	 */
	public void init(PortletConfig config) throws PortletException {
		this.config = config;
		cacheAnnotatedMethods();
		this.init();
	}


	/**
	 * 
	 * A convenience method which can be overridden so that there's no need to
	 * call <code>super.init(config)</code>.
	 * 
	 * <p>
	 * Instead of overriding {@link #init(PortletConfig)}, simply override this
	 * method and it will be called by
	 * <code>GenericPortlet.init(PortletConfig config)</code>. The
	 * <code>PortletConfig</code> object can still be retrieved via {@link
	 * #getPortletConfig}.
	 * 
	 * @exception PortletException
	 *                if an exception has occurred that interferes with the
	 *                portlet normal operation.
	 * @exception UnavailableException
	 *                if the portlet is unavailable to perform init
	 */
	public void init() throws PortletException {
	}

	/**
	 * Called by the portlet container to allow the portlet to process an action
	 * request. This method is called if the client request was originated by a
	 * URL created (by the portlet) with the
	 * <code>RenderResponse.createActionURL()</code> method.
	 * <p>
	 * The default implementation tries to dispatch to a method
	 * annotated with <code>@ProcessAction</name> that matches the action parameter 
	 * value <code>ActionRequest.ACTION_NAME</code> or, if no
	 * such method is found throws a <code>PortletException</code>.<br>
 	 * Note that the annotated methods needs to be public in order
	 * to be allowed to be called by <code>GenericPortlet</code>.

	 * 
	 * @param request
	 *            the action request
	 * @param response
	 *            the action response
	 * @exception PortletException
	 *                if the portlet cannot fulfilling the request
	 * @exception UnavailableException
	 *                if the portlet is unavailable to process the action at
	 *                this time
	 * @exception PortletSecurityException
	 *                if the portlet cannot fullfill this request because of
	 *                security reasons
	 * @exception java.io.IOException
	 *                if the streaming causes an I/O problem
	 */
	public void processAction(ActionRequest request, ActionResponse response) throws PortletException,
			java.io.IOException {
		String action = request.getParameter(ActionRequest.ACTION_NAME);

		try {
			// check if action is cached
			Method actionMethod = processActionHandlingMethodsMap.get(action);
			if (actionMethod != null) {
				actionMethod.invoke(this, request, response);
				return;
			}
		} catch (Exception e) {
			throw new PortletException(e);
		}

		// if no action processing method was found throw exc
		throw new PortletException("processAction method not implemented");
	}

	/**
	 * The default implementation of this method sets the headers using the
	 * <code>doHeaders</code> method, sets the title using the
	 * <code>getTitle</code> method and invokes the <code>doDispatch</code>
	 * method.
	 * <p>
	 * It also evaluates the <code>RENDER_PART</code> request attribute and if
	 * set calls the <code>doHeaders, getNextPossiblePortletModes</code> and
	 * <code>getTitle</code> methods for the <code>RENDER_HEADERS</code>
	 * part and the <code>doDispatch</code> method for the
	 * <code>RENDER_MARKUP</code> part.<br>
	 * If the <code>RENDER_PART</code> request attribute is not set all of the
	 * above methods will be called.
	 * 
	 * @param request
	 *            the render request
	 * @param response
	 *            the render response
	 * 
	 * @exception PortletException
	 *                if the portlet cannot fulfilling the request
	 * @exception UnavailableException
	 *                if the portlet is unavailable to perform render at this
	 *                time
	 * @exception PortletSecurityException
	 *                if the portlet cannot fullfill this request because of
	 *                security reasons
	 * @exception java.io.IOException
	 *                if the streaming causes an I/O problem
	 * 
	 */
	public void render(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
		Object renderPartAttrValue = request.getAttribute(RenderRequest.RENDER_PART);
		if (renderPartAttrValue != null) {
			// streaming portal calling
			if (renderPartAttrValue.equals(RenderRequest.RENDER_HEADERS)) {
				doHeaders(request, response);
				Collection<PortletMode> nextModes = getNextPossiblePortletModes(request);
				if (nextModes != null)
					response.setNextPossiblePortletModes(nextModes);
				response.setTitle(getTitle(request));
			} else if (renderPartAttrValue.equals(RenderRequest.RENDER_MARKUP)) {
				doDispatch(request, response);
			} else {
				throw new PortletException("Unknown value of the 'javax.portlet.render_part' request attribute");
			}
		} else {
			// buffered portal calling
			doHeaders(request, response);
			Collection<PortletMode> nextModes = getNextPossiblePortletModes(request);
			if (nextModes != null)
				response.setNextPossiblePortletModes(nextModes);
			response.setTitle(getTitle(request));
			doDispatch(request, response);
		}
	}

	/**
	 * Used by the render method to get the title.
	 * <p>
	 * The default implementation gets the title from the ResourceBundle of the
	 * PortletConfig of the portlet. The title is retrieved using the
	 * 'javax.portlet.title' resource name.
	 * <p>
	 * Portlets can overwrite this method to provide dynamic titles (e.g. based
	 * on locale, client, and session information). Examples are:
	 * <UL>
	 * <LI>language-dependent titles for multi-lingual portals</li>
	 * <LI>shorter titles for WAP phones</li>
	 * <LI>the number of messages in a mailbox portlet</li>
	 * </UL>
	 * 
	 * @return the portlet title for this window
	 * @throws java.lang.IllegalStateException
	 *             if no portlet config object is available
	 */
	protected java.lang.String getTitle(RenderRequest request) {
		if (config == null)
			throw new java.lang.IllegalStateException(
					"Config is null, please ensure that your init(config) method calls super.init(config)");

		return config.getResourceBundle(request.getLocale()).getString("javax.portlet.title");
	}

	/**
	 * The default implementation of this method routes the render request to:
	 * <ol>
	 * <li>method annotated with <code>@RenderMode</name> and the name of the
	 *       portlet mode</li>
	 *   <li>a set of helper methods depending on the current portlet mode the portlet
	 * 		 is currently in. These methods are:
	 * 		<ul>
	 * 			<li><code>doView</code> for handling <code>view</code> requests</li>
	 * 			<li><code>doEdit</code> for handling <code>edit</code> requests</li>
	 * 			<li><code>doHelp</code> for handling <code>help</code> requests</li>
	 * 		</ul>
	 *	</li>
	 * </ul> 
	 * <P>
	 * If the window state of this portlet is <code>minimized</code>, this
	 * method does not invoke any of the portlet mode rendering methods.
	 * <p>
	 * For handling custom portlet modes the portlet should either use the
	 * <code>@RenderMode</code> annotation or override this
	 * method. Note that the annotated methods needs to be public in order
	 * to be allowed to be called by <code>GenericPortlet</code>.
	 * 
	 * @param request
	 *            the render request
	 * @param response
	 *            the render response
	 * 
	 * @exception PortletException
	 *                if the portlet cannot fulfilling the request
	 * @exception UnavailableException
	 *                if the portlet is unavailable to perform render at this
	 *                time
	 * @exception PortletSecurityException
	 *                if the portlet cannot fullfill this request because of
	 *                security reasons
	 * @exception java.io.IOException
	 *                if the streaming causes an I/O problem
	 * 
	 * @see #doView(RenderRequest, RenderResponse)
	 * @see #doEdit(RenderRequest, RenderResponse)
	 * @see #doHelp(RenderRequest, RenderResponse)
	 */
	protected void doDispatch(RenderRequest request, RenderResponse response) throws PortletException,
			java.io.IOException {
		WindowState state = request.getWindowState();

		if (!state.equals(WindowState.MINIMIZED)) {
			PortletMode mode = request.getPortletMode();
			// first look if there are methods annotated for
			// handling the rendering of this mode
			try {
				// check if mode is cached
				Method renderMethod = renderModeHandlingMethodsMap.get(mode.toString());
				if (renderMethod != null) {
					renderMethod.invoke(this, request, response);
					return;
				}
			} catch (Exception e) {
				throw new PortletException(e);
			}

			// if not, try the default doXYZ methods
			if (mode.equals(PortletMode.VIEW)) {
				doView(request, response);
			} else if (mode.equals(PortletMode.EDIT)) {
				doEdit(request, response);
			} else if (mode.equals(PortletMode.HELP)) {
				doHelp(request, response);
			} else {
				throw new PortletException("unknown portlet mode: " + mode);
			}
		}
	}

	/**
	 * Helper method to serve up the mandatory <code>view</code> mode.
	 * <p>
	 * The default implementation throws an exception.
	 * 
	 * @param request
	 *            the portlet request
	 * @param response
	 *            the render response
	 * 
	 * @exception PortletException
	 *                if the portlet cannot fulfilling the request
	 * @exception UnavailableException
	 *                if the portlet is unavailable to perform render at this
	 *                time
	 * @exception PortletSecurityException
	 *                if the portlet cannot fullfill this request because of
	 *                security reasons
	 * @exception java.io.IOException
	 *                if the streaming causes an I/O problem
	 * 
	 */
	protected void doView(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
		throw new PortletException("doView method not implemented");
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -