📄 eventproviderimpl.java
字号:
/*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.
*/
package org.apache.pluto.driver.services.container;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.portlet.Event;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pluto.Constants;
import org.apache.pluto.EventContainer;
import org.apache.pluto.PortletContainer;
import org.apache.pluto.PortletContainerException;
import org.apache.pluto.PortletWindow;
import org.apache.pluto.driver.AttributeKeys;
import org.apache.pluto.driver.config.DriverConfiguration;
import org.apache.pluto.driver.core.PortalRequestContext;
import org.apache.pluto.driver.core.PortletWindowImpl;
import org.apache.pluto.driver.services.portal.PageConfig;
import org.apache.pluto.driver.services.portal.PortletWindowConfig;
import org.apache.pluto.driver.url.PortalURL;
import org.apache.pluto.driver.url.impl.PortalURLParserImpl;
import org.apache.pluto.internal.impl.EventImpl;
import org.apache.pluto.om.portlet.EventDefinition;
import org.apache.pluto.om.portlet.EventDefinitionReference;
import org.apache.pluto.om.portlet.PortletDefinition;
import org.apache.pluto.om.portlet.PortletApplicationDefinition;
import org.apache.pluto.spi.optional.PortletContextService;
import org.apache.pluto.spi.EventProvider;
import org.apache.pluto.spi.optional.PortletRegistryService;
public class EventProviderImpl implements org.apache.pluto.spi.EventProvider,
Cloneable {
private static final int DEFAULT_MAPSIZE = 10;
/** Logger. */
private static final Log LOG = LogFactory.getLog(EventProviderImpl.class);
private static final long WAITING_CYCLE = 100;
private HttpServletRequest request;
private HttpServletResponse response;
private PortletContainer container;
private PortletWindow portletWindow;
ThreadGroup threadGroup = new ThreadGroup("FireEventThreads");
private EventList savedEvents = new EventList();
private Map<String, PortletWindowThread> portletWindowThreads = new HashMap<String, PortletWindowThread>();
/** PortletRegistryService used to obtain PortletApplicationConfig objects */
private PortletRegistryService portletRegistry;
/** PortletContextService used to obtain PortletContext objects */
private PortletContextService portletContextService;
/**
* factory method gets the EventProvider out of the Request, or sets a new
* one
*
* @param request
* The {@link HttpServletRequest} of the EventProvider
* @param response
* The {@link HttpServletResponse} of the EventProvider
* @return The corresponding EventProvierImpl instance
*/
public static EventProviderImpl getEventProviderImpl(
HttpServletRequest request, PortletWindow portletWindow) {
EventProviderImpl eventProvider = (EventProviderImpl) request
.getAttribute(Constants.PROVIDER);
if (eventProvider == null) {
eventProvider = new EventProviderImpl();
eventProvider.request = request;
PortalRequestContext context = PortalRequestContext
.getContext(request);
eventProvider.response = context.getResponse();
ServletContext servletContext = context.getServletContext();
eventProvider.container = (PortletContainer) servletContext
.getAttribute(AttributeKeys.PORTLET_CONTAINER);
request.setAttribute(Constants.PROVIDER, eventProvider);
}
try {
eventProvider = (EventProviderImpl) eventProvider.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
}
eventProvider.portletWindow = portletWindow;
return eventProvider;
}
/**
* factory method, for accessing the static elements without a request /
* response FIXME: bad idea
*
* @return The EventProvider for accessing the static elements
*/
public static EventProvider getEventProviderImpl() {
return new EventProviderImpl();
}
/**
* c'tor
*/
private EventProviderImpl() {
}
/**
* Register an event, which should be fired within that request
*
* @param qname
* @param value
* @throws {@link IllegalArgumentException}
*/
public void registerToFireEvent(QName qname, Serializable value)
throws IllegalArgumentException {
if (isDeclaredAsPublishingEvent(qname)) {
if (value != null && !isValueInstanceOfDefinedClass(qname, value))
throw new IllegalArgumentException(
"Payload has not the right class");
try {
if (value == null) {
savedEvents.addEvent(new EventImpl(qname, value));
} else if (!(value instanceof Serializable)) {
throw new IllegalArgumentException(
"Object payload must implement Serializable");
} else {
Writer out = new StringWriter();
Class clazz = value.getClass();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try
{
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
JAXBContext jc = JAXBContext.newInstance(clazz);
Marshaller marshaller = jc.createMarshaller();
JAXBElement<Serializable> element = new JAXBElement<Serializable>(
qname, clazz, value);
marshaller.marshal(element, out);
// marshaller.marshal(value, out);
}
finally
{
Thread.currentThread().setContextClassLoader(cl);
}
if (out != null) {
savedEvents.addEvent(new EventImpl(qname,
(Serializable) out.toString()));
} else {
savedEvents.addEvent(new EventImpl(qname, value));
}
}
} catch (JAXBException e) {
// maybe there is no valid jaxb binding
// TODO wsrp:eventHandlingFailed
LOG.error("Event handling failed", e);
} catch (FactoryConfigurationError e) {
LOG.warn(e);
}
}
}
/**
* Fire all saved events Note, that the order isn't important
*
* @see PLT14.3.2
* @param eventContainer
* The {@link PortletContainerImpl} to fire the events
*/
public void fireEvents(EventContainer eventContainer) {
ServletContext containerServletContext = PortalRequestContext.getContext(request).getServletContext();
DriverConfiguration driverConfig = (DriverConfiguration) containerServletContext
.getAttribute(AttributeKeys.DRIVER_CONFIG);
PortalURL portalURL = PortalURLParserImpl.getParser().parse(request);
while (savedEvents.hasMoreEvents()
&& savedEvents.getSize() < Constants.MAX_EVENTS_SIZE) {
Event eActual = getArbitraryEvent();
this.savedEvents.setProcessed(eActual);
List<String> portletNames = getAllPortletsRegisteredForEvent(
eActual, driverConfig, containerServletContext);
Collection<PortletWindowConfig> portlets = getAllPortlets(driverConfig);
// iterate all portlets in the portal
for (PortletWindowConfig config : portlets) {
PortletWindow window = new PortletWindowImpl(container, config, portalURL);
if (portletNames != null) {
for (String portlet : portletNames) {
if (portlet.equals(config.getId())) {
// the thread now is a new one, with possible
// waiting,
// for the old to exit
PortletWindowThread portletWindowThread = getPortletWindowThread(
eventContainer, config, window, containerServletContext);
// is this event
portletWindowThread.addEvent(eActual);
portletWindowThread.start();
}
}
}
}
waitForEventExecution();
try {
Thread.sleep(WAITING_CYCLE);
} catch (InterruptedException e) {
LOG.warn(e);
}
}
waitForEventExecution();
}
private List<String> getAllPortletsRegisteredForEvent(Event event,
DriverConfiguration driverConfig, ServletContext containerServletContext) {
Set<String> resultSet = new HashSet<String>();
List<String> resultList = new ArrayList<String>();
QName eventName = event.getQName();
Collection<PortletWindowConfig> portlets = getAllPortlets(driverConfig);
if (portletRegistry == null) {
portletRegistry = ((PortletContainer) containerServletContext
.getAttribute(AttributeKeys.PORTLET_CONTAINER))
.getOptionalContainerServices().getPortletRegistryService();
}
for (PortletWindowConfig portlet : portlets) {
String contextPath = portlet.getContextPath();
String applicationName = contextPath;
if (applicationName.length() >0 )
{
applicationName = applicationName.substring(1);
}
PortletApplicationDefinition portletAppDD = null;
try {
portletAppDD = portletRegistry.getPortletApplication(applicationName);
List<? extends PortletDefinition> portletDDs = portletAppDD.getPortlets();
List<QName> aliases = getAllAliases(eventName, portletAppDD);
for (PortletDefinition portletDD : portletDDs) {
List<? extends EventDefinitionReference> processingEvents = portletDD.getSupportedProcessingEvents();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -