org.apereo.portal.portlet.container.EventProviderImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.apereo.portal.portlet.container.EventProviderImpl.java

Source

/**
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo 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 the following location:
 *
 *   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.apereo.portal.portlet.container;

import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;

import javax.portlet.Event;
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.container.EventProvider;
import org.apache.pluto.container.PortletContainerException;
import org.apache.pluto.container.driver.PortletContextService;
import org.apache.pluto.container.om.portlet.EventDefinition;
import org.apache.pluto.container.om.portlet.EventDefinitionReference;
import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
import org.apache.pluto.container.om.portlet.PortletDefinition;
import org.apereo.portal.portlet.om.IPortletWindow;

/**
 * @author Eric Dalquist
 * @version $Revision$
 */
public class EventProviderImpl implements EventProvider {
    protected final Log logger = LogFactory.getLog(this.getClass());

    private final IPortletWindow portletWindow;
    private final ClassLoader portletClassLoader;

    public EventProviderImpl(IPortletWindow portletWindow, PortletContextService portletContextService) {
        this.portletWindow = portletWindow;

        final PortletDefinition portletDefinition = portletWindow.getPlutoPortletWindow().getPortletDefinition();
        final PortletApplicationDefinition application = portletDefinition.getApplication();
        final String portletApplicationName = application.getName();
        try {
            this.portletClassLoader = portletContextService.getClassLoader(portletApplicationName);
        } catch (PortletContainerException e) {
            throw new IllegalStateException(
                    "Failed to find ClassLoader for portlet applicaiton: " + portletApplicationName, e);
        }
    }

    @Override
    public Event createEvent(QName qname, Serializable value) throws IllegalArgumentException {
        if (this.isDeclaredAsPublishingEvent(qname)) {
            if (value != null && !this.isValueInstanceOfDefinedClass(qname, value)) {
                throw new IllegalArgumentException("Payload class (" + value.getClass().getCanonicalName()
                        + ") does not have the right class, check your defined event types in portlet.xml.");
            }

            if (value == null) {
                return new EventImpl(qname);
            }

            try {
                final Thread currentThread = Thread.currentThread();
                final ClassLoader cl = currentThread.getContextClassLoader();
                final Writer out = new StringWriter();
                final Class clazz = value.getClass();
                try {
                    currentThread.setContextClassLoader(this.portletClassLoader);
                    final JAXBContext jc = JAXBContext.newInstance(clazz);
                    final Marshaller marshaller = jc.createMarshaller();
                    final JAXBElement<Serializable> element = new JAXBElement<Serializable>(qname, clazz, value);
                    marshaller.marshal(element, out);
                } finally {
                    currentThread.setContextClassLoader(cl);
                }
                return new EventImpl(qname, out.toString());
            } catch (JAXBException e) {
                // maybe there is no valid jaxb binding
                // TODO throw exception?
                logger.error("Event handling failed", e);
            } catch (FactoryConfigurationError e) {
                // TODO throw exception?
                logger.warn(e.getMessage(), e);
            }
        }
        return null;
    }

    private boolean isDeclaredAsPublishingEvent(QName qname) {
        final PortletDefinition portletDescriptor = this.portletWindow.getPlutoPortletWindow()
                .getPortletDefinition();
        final List<? extends EventDefinitionReference> events = portletDescriptor.getSupportedPublishingEvents();

        if (events == null) {
            return false;
        }

        final PortletApplicationDefinition application = portletDescriptor.getApplication();
        final String defaultNamespace = application.getDefaultNamespace();
        for (final EventDefinitionReference ref : events) {
            final QName name = ref.getQualifiedName(defaultNamespace);
            if (name == null) {
                continue;
            }
            if (qname.equals(name)) {
                return true;
            }
        }
        return false;
    }

    private boolean isValueInstanceOfDefinedClass(QName qname, Serializable value) {
        final PortletDefinition portletDefinition = this.portletWindow.getPlutoPortletWindow()
                .getPortletDefinition();
        final PortletApplicationDefinition app = portletDefinition.getApplication();
        final List<? extends EventDefinition> events = app.getEventDefinitions();
        if (events == null) {
            return true;
        }

        final String defaultNamespace = app.getDefaultNamespace();

        for (final EventDefinition eventDefinition : events) {
            if (eventDefinition.getQName() != null) {
                if (eventDefinition.getQName().equals(qname)) {
                    final Class<? extends Serializable> valueClass = value.getClass();
                    return valueClass.getName().equals(eventDefinition.getValueType());
                }
            } else {
                final QName tmp = new QName(defaultNamespace, eventDefinition.getName());
                if (tmp.equals(qname)) {
                    final Class<? extends Serializable> valueClass = value.getClass();
                    return valueClass.getName().equals(eventDefinition.getValueType());
                }
            }
        }

        // event not declared
        return true;
    }

}