001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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 GmbH & Co. KG, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://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.staticexport;
029
030import org.opencms.db.storage.I_CmsStorageDelivery;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.file.CmsStoredContentInfo;
034import org.opencms.loader.CmsStoredContentDeliveryHelper;
035import org.opencms.loader.I_CmsStaticExportDirectResponseLoader;
036import org.opencms.loader.I_CmsStaticExportStreamLoader;
037import org.opencms.loader.I_CmsStoredContentDirectDeliveryLoader;
038import org.opencms.main.CmsException;
039
040import java.io.IOException;
041
042import jakarta.servlet.http.HttpServletRequest;
043import jakarta.servlet.http.HttpServletResponse;
044
045/**
046 * Support class for direct delivery of stored content during static export.<p>
047 */
048public class CmsStoredContentDeliverySupport {
049
050    /**
051     * Handles a streamed static export through direct stored content delivery if possible.<p>
052     *
053     * @param manager the static export manager
054     * @param loader the resource loader
055     * @param cms the CMS context
056     * @param exportResource the resource to export
057     * @param req the current request
058     * @param res the current response
059     * @param exportFileName the target export file name
060     *
061     * @return <code>true</code> if the export has been handled without writing the local export file
062     *
063     * @throws CmsException if something goes wrong
064     */
065    public boolean handle(
066        CmsStaticExportManager manager,
067        CmsStoredContentDeliveryConfiguration configuration,
068        I_CmsStaticExportStreamLoader loader,
069        CmsObject cms,
070        CmsResource exportResource,
071        HttpServletRequest req,
072        HttpServletResponse res,
073        String exportFileName)
074    throws CmsException {
075
076        if (tryHandleStoredContentDelivery(
077            manager,
078            configuration,
079            loader,
080            cms,
081            exportResource,
082            req,
083            res,
084            exportFileName)) {
085            return true;
086        }
087        if (!configuration.isSuffixEnabled(exportFileName)) {
088            return false;
089        }
090        return tryHandleDirectResponse(manager, loader, cms, exportResource, req, res, exportFileName);
091    }
092
093    /**
094     * Handles an on-demand static export directly through the loader if possible.<p>
095     *
096     * @param manager the static export manager
097     * @param loader the resource loader
098     * @param cms the CMS context
099     * @param exportResource the resource to export
100     * @param req the current request
101     * @param res the current response
102     * @param exportFileName the target export file name
103     *
104     * @return <code>true</code> if the export has been handled without writing the local export file
105     *
106     * @throws CmsException if something goes wrong
107     */
108    protected boolean tryHandleDirectResponse(
109        CmsStaticExportManager manager,
110        I_CmsStaticExportStreamLoader loader,
111        CmsObject cms,
112        CmsResource exportResource,
113        HttpServletRequest req,
114        HttpServletResponse res,
115        String exportFileName)
116    throws CmsException {
117
118        if ((req == null) || !(loader instanceof I_CmsStaticExportDirectResponseLoader)) {
119            return false;
120        }
121        try {
122            if (((I_CmsStaticExportDirectResponseLoader)loader).tryExportDirectResponse(
123                cms,
124                exportResource,
125                req,
126                res)) {
127                manager.removeStoredContentExportFile(exportFileName);
128                return true;
129            }
130            return false;
131        } catch (IOException e) {
132            throw new CmsStaticExportException(
133                Messages.get().container(Messages.ERR_OUTPUT_STREAM_1, exportFileName),
134                e);
135        }
136    }
137
138    /**
139     * Handles a static export through direct stored content delivery if possible.<p>
140     *
141     * @param manager the static export manager
142     * @param configuration the stored content delivery configuration
143     * @param loader the resource loader
144     * @param cms the CMS context
145     * @param exportResource the resource to export
146     * @param req the current request
147     * @param res the current response
148     * @param exportFileName the target export file name
149     *
150     * @return <code>true</code> if the export has been handled without writing the local export file
151     *
152     * @throws CmsException if something goes wrong
153     */
154    protected boolean tryHandleStoredContentDelivery(
155        CmsStaticExportManager manager,
156        CmsStoredContentDeliveryConfiguration configuration,
157        I_CmsStaticExportStreamLoader loader,
158        CmsObject cms,
159        CmsResource exportResource,
160        HttpServletRequest req,
161        HttpServletResponse res,
162        String exportFileName)
163    throws CmsException {
164
165        if (!(loader instanceof I_CmsStoredContentDirectDeliveryLoader)) {
166            return false;
167        }
168        if (!configuration.isSuffixEnabled(exportResource.getRootPath())) {
169            return false;
170        }
171        I_CmsStoredContentDirectDeliveryLoader directDeliveryLoader = (I_CmsStoredContentDirectDeliveryLoader)loader;
172        if (!directDeliveryLoader.isStoredContentDirectDeliveryEnabled(cms, exportResource, req, res)) {
173            return false;
174        }
175        CmsStoredContentInfo info = cms.readStoredContentInfo(exportResource);
176        if ((info == null) || !info.isExternallyStored()) {
177            return false;
178        }
179        I_CmsStorageDelivery storage = cms.getStoredContentDelivery(info.getStorage());
180        if (!(new CmsStoredContentDeliveryHelper()).canDeliver(info, storage)) {
181            return false;
182        }
183        manager.removeStoredContentExportFile(exportFileName);
184        if ((req == null) || (res == null)) {
185            return true;
186        }
187        try {
188            return directDeliveryLoader.exportStoredContentTo(cms, exportResource, req, res);
189        } catch (IOException e) {
190            throw new CmsStaticExportException(
191                Messages.get().container(Messages.ERR_OUTPUT_STREAM_1, exportFileName),
192                e);
193        }
194    }
195}