org.opencms.gwt.CmsGwtServiceContext.java Source code

Java tutorial

Introduction

Here is the source code for org.opencms.gwt.CmsGwtServiceContext.java

Source

/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.gwt;

import org.opencms.db.CmsDriverManager;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.main.CmsEvent;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.I_CmsEventListener;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsCollectionsGenericWrapper;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.List;

import org.apache.commons.logging.Log;

import com.google.gwt.user.server.rpc.SerializationPolicy;
import com.google.gwt.user.server.rpc.SerializationPolicyLoader;

/**
 * This class contains the data that should be cached for a specific service class.<p>
 * 
 * We cache instances of this class rather than caching instances of {@link CmsGwtService} directly because
 * its superclass, {@link com.google.gwt.user.server.rpc.RemoteServiceServlet}, does some caching which we can't use because it doesn't
 * take the distinction between online and offline requests into account. 
 * 
 * @since 8.0.0
 * 
 */
public class CmsGwtServiceContext implements I_CmsEventListener {

    /** The static log object for this class. */
    private static final Log LOG = CmsLog.getLog(CmsGwtServiceContext.class);

    /** The name, which is used for debugging. */
    private String m_name;

    /** The serialization policy path. */
    private String m_serializationPolicyPath;

    /** The offline serialization policy. */
    private SerializationPolicy m_serPolicyOffline;

    /** The online serialization policy. */
    private SerializationPolicy m_serPolicyOnline;

    /**
     * Creates a new service context object.<p>
     * 
     * @param name an identifier which is used for debugging
     */
    public CmsGwtServiceContext(String name) {

        m_name = name;

        // listen on VFS changes for serialization policies 
        OpenCms.addCmsEventListener(this,
                new int[] { I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED,
                        I_CmsEventListener.EVENT_RESOURCES_AND_PROPERTIES_MODIFIED,
                        I_CmsEventListener.EVENT_RESOURCE_MODIFIED, I_CmsEventListener.EVENT_RESOURCES_MODIFIED,
                        I_CmsEventListener.EVENT_RESOURCE_DELETED, I_CmsEventListener.EVENT_PUBLISH_PROJECT,
                        I_CmsEventListener.EVENT_CLEAR_CACHES, I_CmsEventListener.EVENT_CLEAR_ONLINE_CACHES,
                        I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES });

    }

    /**
     * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent)
     */
    public void cmsEvent(CmsEvent event) {

        CmsResource resource = null;
        List<CmsResource> resources = null;

        switch (event.getType()) {
        case I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED:
        case I_CmsEventListener.EVENT_RESOURCE_MODIFIED:
            Object change = event.getData().get(I_CmsEventListener.KEY_CHANGE);
            if ((change != null) && change.equals(new Integer(CmsDriverManager.NOTHING_CHANGED))) {
                // skip lock & unlock
                return;
            }
            // a resource has been modified in a way that it *IS NOT* necessary also to clear 
            // lists of cached sub-resources where the specified resource might be contained inside.
            resource = (CmsResource) event.getData().get(I_CmsEventListener.KEY_RESOURCE);
            uncacheResource(resource);
            break;

        case I_CmsEventListener.EVENT_RESOURCES_AND_PROPERTIES_MODIFIED:
            // a list of resources and all of their properties have been modified
            resources = CmsCollectionsGenericWrapper.list(event.getData().get(I_CmsEventListener.KEY_RESOURCES));
            uncacheResources(resources);
            break;

        case I_CmsEventListener.EVENT_RESOURCE_MOVED:
        case I_CmsEventListener.EVENT_RESOURCE_DELETED:
        case I_CmsEventListener.EVENT_RESOURCES_MODIFIED:
            // a list of resources has been modified
            resources = CmsCollectionsGenericWrapper.list(event.getData().get(I_CmsEventListener.KEY_RESOURCES));
            uncacheResources(resources);
            break;

        case I_CmsEventListener.EVENT_CLEAR_ONLINE_CACHES:
        case I_CmsEventListener.EVENT_PUBLISH_PROJECT:
            m_serPolicyOnline = null;
            break;

        case I_CmsEventListener.EVENT_CLEAR_CACHES:
            m_serPolicyOnline = null;
            m_serPolicyOffline = null;
            break;

        case I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES:
            m_serPolicyOffline = null;
            break;

        default:
            // noop
            break;
        }
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {

        return super.toString() + "(" + m_name + ")";
    }

    /**
     * Returns the serialization policy for the service.<p>
     * 
     * @param cms the current CMS context 
     * @param moduleBaseURL the module's base URL 
     * @param strongName the strong name of the service 
     * 
     * @return the serialization policy for the given service  
     */
    protected SerializationPolicy getSerializationPolicy(CmsObject cms, String moduleBaseURL, String strongName) {

        if (m_serializationPolicyPath == null) {
            m_serializationPolicyPath = getSerializationPolicyPath(cms, moduleBaseURL, strongName);
        }
        return getSerializationPolicy(cms);
    }

    /**
     * Finds the path of the serialization policy file.<p>
     * 
     * @param cms the current CMS context 
     * @param moduleBaseURL the GWT module's base url
     * @param strongName the strong name of the service 
     * 
     * @return the serialization policy path
     */
    protected String getSerializationPolicyPath(CmsObject cms, String moduleBaseURL, String strongName) {

        // locate the serialization policy file in OpenCms
        String modulePath = null;
        try {
            modulePath = new URL(moduleBaseURL).getPath();
        } catch (MalformedURLException ex) {
            // moduleBaseUrl is bad
            LOG.error(ex.getLocalizedMessage(), ex);
            return null;
        } catch (NullPointerException ex) {
            // moduleBaseUrl is null
            LOG.error(ex.getLocalizedMessage(), ex);
            return null;
        }
        String serializationPolicyUrl = SerializationPolicyLoader
                .getSerializationPolicyFileName(modulePath + strongName);
        return OpenCms.getLinkManager().getRootPath(cms, serializationPolicyUrl);

    }

    /**
     * Returns the serialization policy, using lazy initialization.<p>
     * 
     * @param cms the current cms context 
     * 
     * @return the serialization policy 
     */
    private SerializationPolicy getSerializationPolicy(CmsObject cms) {

        boolean online = cms.getRequestContext().getCurrentProject().isOnlineProject();
        if (online && (m_serPolicyOnline != null)) {
            return m_serPolicyOnline;
        } else if (!online && (m_serPolicyOffline != null)) {
            return m_serPolicyOffline;
        }

        SerializationPolicy serializationPolicy = null;

        // Open the RPC resource file and read its contents
        InputStream is;
        try {
            is = new ByteArrayInputStream(cms.readFile(m_serializationPolicyPath).getContents());
        } catch (CmsException ex) {
            // most likely file not found
            String message = "ERROR: The serialization policy file '" + m_serializationPolicyPath
                    + "' was not found; did you forget to include it in this deployment?";
            LOG.warn(message);
            LOG.warn(ex.getLocalizedMessage(), ex);
            return new CmsDummySerializationPolicy();
        }

        // read the policy
        try {
            serializationPolicy = SerializationPolicyLoader.loadFromStream(is, null);
        } catch (ParseException e) {
            LOG.error("ERROR: Failed to parse the policy file '" + m_serializationPolicyPath + "'", e);
        } catch (IOException e) {
            LOG.error("ERROR: Could not read the policy file '" + m_serializationPolicyPath + "'", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                // Ignore this error
            }
        }

        if (online) {
            m_serPolicyOnline = serializationPolicy;
        } else {
            m_serPolicyOffline = serializationPolicy;
        }
        return serializationPolicy;
    }

    /**
     * Removes a cached resource from the cache.<p>
     * 
     * @param resource the resource
     */
    private void uncacheResource(CmsResource resource) {

        if (resource == null) {
            return;
        }
        if ((m_serializationPolicyPath != null) && resource.getRootPath().equals(m_serializationPolicyPath)) {
            m_serPolicyOffline = null;
        }
    }

    /**
     * Removes a bunch of cached resources from the cache.<p>
     * 
     * @param resources a list of resources
     * 
     * @see #uncacheResource(CmsResource)
     */
    private void uncacheResources(List<CmsResource> resources) {

        if (resources == null) {
            return;
        }
        for (int i = 0, n = resources.size(); i < n; i++) {
            // remove the resource
            uncacheResource(resources.get(i));
        }
    }

}