001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.cache;
029
030import org.opencms.db.CmsDriverManager;
031import org.opencms.file.CmsResource;
032import org.opencms.main.CmsEvent;
033import org.opencms.main.I_CmsEventListener;
034import org.opencms.main.OpenCms;
035import org.opencms.util.CmsCollectionsGenericWrapper;
036
037import java.util.List;
038
039/**
040 * Configurable VFS based cache, for caching objects related to offline/online resources.<p>
041 *
042 * @since 7.6
043 */
044public abstract class CmsVfsCache implements I_CmsEventListener {
045
046    /**
047     * Initializes the cache. Only intended to be called during startup.<p>
048     */
049    protected CmsVfsCache() {
050
051        // empty
052    }
053
054    /**
055     * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent)
056     */
057    public void cmsEvent(CmsEvent event) {
058
059        CmsResource resource = null;
060        List<CmsResource> resources = null;
061
062        switch (event.getType()) {
063            case I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED:
064            case I_CmsEventListener.EVENT_RESOURCE_MODIFIED:
065                Object change = event.getData().get(I_CmsEventListener.KEY_CHANGE);
066                if ((change != null) && change.equals(Integer.valueOf(CmsDriverManager.NOTHING_CHANGED))) {
067                    // skip lock & unlock
068                    return;
069                }
070                // a resource has been modified in a way that it *IS NOT* necessary also to clear
071                // lists of cached sub-resources where the specified resource might be contained inside.
072                resource = (CmsResource)event.getData().get(I_CmsEventListener.KEY_RESOURCE);
073                uncacheResource(resource);
074                break;
075
076            case I_CmsEventListener.EVENT_RESOURCES_AND_PROPERTIES_MODIFIED:
077                // a list of resources and all of their properties have been modified
078                resources = CmsCollectionsGenericWrapper.list(event.getData().get(I_CmsEventListener.KEY_RESOURCES));
079                uncacheResources(resources);
080                break;
081
082            case I_CmsEventListener.EVENT_RESOURCE_MOVED:
083            case I_CmsEventListener.EVENT_RESOURCE_DELETED:
084            case I_CmsEventListener.EVENT_RESOURCES_MODIFIED:
085                // a list of resources has been modified
086                resources = CmsCollectionsGenericWrapper.list(event.getData().get(I_CmsEventListener.KEY_RESOURCES));
087                uncacheResources(resources);
088                break;
089
090            case I_CmsEventListener.EVENT_CLEAR_ONLINE_CACHES:
091            case I_CmsEventListener.EVENT_PUBLISH_PROJECT:
092                flush(true);
093                break;
094
095            case I_CmsEventListener.EVENT_CLEAR_CACHES:
096                flush(true);
097                flush(false);
098                break;
099
100            case I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES:
101                flush(false);
102                break;
103
104            default:
105                // noop
106                break;
107        }
108    }
109
110    /**
111     * Clean up at shutdown time. Only intended to be called at system shutdown.<p>
112     *
113     * @see org.opencms.main.OpenCmsCore#shutDown
114     */
115    public void shutdown() {
116
117        if (OpenCms.getMemoryMonitor() != null) {
118            // prevent accidental calls
119            return;
120
121        }
122        flush(true);
123        flush(false);
124    }
125
126    /**
127     * Flushes the caches.<p>
128     *
129     * @param online if to flush the online or offline caches
130     */
131    protected abstract void flush(boolean online);
132
133    /**
134     * Adds this instance as an event listener to the CMS event manager.<p>
135     */
136    protected void registerEventListener() {
137
138        OpenCms.addCmsEventListener(
139            this,
140            new int[] {
141                I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED,
142                I_CmsEventListener.EVENT_RESOURCES_AND_PROPERTIES_MODIFIED,
143                I_CmsEventListener.EVENT_RESOURCE_MODIFIED,
144                I_CmsEventListener.EVENT_RESOURCES_MODIFIED,
145                I_CmsEventListener.EVENT_RESOURCE_MOVED,
146                I_CmsEventListener.EVENT_RESOURCE_DELETED,
147                I_CmsEventListener.EVENT_PUBLISH_PROJECT,
148                I_CmsEventListener.EVENT_CLEAR_CACHES,
149                I_CmsEventListener.EVENT_CLEAR_ONLINE_CACHES,
150                I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES});
151    }
152
153    /**
154     * Removes a cached resource from the cache.<p>
155     *
156     * @param resource the resource
157     */
158    protected abstract void uncacheResource(CmsResource resource);
159
160    /**
161     * Removes a bunch of cached resources from the cache.<p>
162     *
163     * @param resources a list of resources
164     *
165     * @see #uncacheResource(CmsResource)
166     */
167    protected void uncacheResources(List<CmsResource> resources) {
168
169        if (resources == null) {
170            return;
171        }
172        for (int i = 0, n = resources.size(); i < n; i++) {
173            // remove the resource
174            uncacheResource(resources.get(i));
175        }
176    }
177}