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 GmbH & Co. KG, 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.flex;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsRequestContext;
032import org.opencms.file.CmsResource;
033import org.opencms.jsp.util.CmsJspStandardContextBean;
034import org.opencms.jsp.util.CmsJspStandardContextBean.CmsContainerElementWrapper;
035import org.opencms.jsp.util.CmsJspStandardContextBean.TemplateBean;
036import org.opencms.loader.CmsTemplateContextManager;
037import org.opencms.loader.I_CmsResourceLoader;
038import org.opencms.main.CmsLog;
039import org.opencms.main.OpenCms;
040import org.opencms.util.CmsCollectionsGenericWrapper;
041import org.opencms.util.CmsRequestUtil;
042import org.opencms.util.CmsUUID;
043
044import java.util.Map;
045
046import javax.servlet.http.HttpServletRequest;
047import javax.servlet.http.HttpSession;
048
049import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
050import org.apache.commons.logging.Log;
051
052/**
053 * Describes the caching behaviour (or caching options) for a Flex request.<p>
054 *
055 * @since 6.0.0
056 */
057public class CmsFlexRequestKey {
058
059    /**
060     * Contains the root paths to be used for determining the buckets of a flex cache entry.<p>
061     */
062    public static class PathsBean {
063
064        /** The container element path. */
065        private String m_containerElement;
066
067        /** The detail element path. */
068        private String m_detailElement;
069
070        /** The site root. */
071        private String m_site;
072
073        /** The URI. */
074        private String m_uri;
075
076        /**
077         * Returns the container element.<p>
078         *
079         * @return the container element
080         */
081        public String getContainerElement() {
082
083            return m_containerElement;
084        }
085
086        /**
087         * Returns the detail element.<p>
088         *
089         * @return the detail element
090         */
091        public String getDetailElement() {
092
093            return m_detailElement;
094        }
095
096        /**
097         * Returns the site.<p>
098         *
099         * @return the site
100         */
101        public String getSite() {
102
103            return m_site;
104        }
105
106        /**
107         * Returns the uri.<p>
108         *
109         * @return the uri
110         */
111        public String getUri() {
112
113            return m_uri;
114        }
115
116        /**
117         * Sets the container element.<p>
118         *
119         * @param containerElement the container element to set
120         */
121        public void setContainerElement(String containerElement) {
122
123            m_containerElement = containerElement;
124        }
125
126        /**
127         * Sets the detail element.<p>
128         *
129         * @param detailElement the detail element to set
130         */
131        public void setDetailElement(String detailElement) {
132
133            m_detailElement = detailElement;
134        }
135
136        /**
137         * Sets the site.<p>
138         *
139         * @param site the site to set
140         */
141        public void setSite(String site) {
142
143            m_site = site;
144        }
145
146        /**
147         * Sets the uri.<p>
148         *
149         * @param uri the uri to set
150         */
151        public void setUri(String uri) {
152
153            m_uri = uri;
154        }
155
156        /**
157         * @see java.lang.Object#toString()
158         */
159        @Override
160        public String toString() {
161
162            return ReflectionToStringBuilder.toString(this);
163        }
164    }
165
166    /** The log object for this class. */
167    private static final Log LOG = CmsLog.getLog(CmsFlexRequestKey.class);
168
169    /** The current container element. */
170    private String m_containerElement;
171
172    /** The request context this request was made in. */
173    private CmsRequestContext m_context;
174
175    /** The current detail view id. */
176    private CmsUUID m_detailViewId;
177
178    /** Stores the device this request was made with. */
179    private String m_device;
180
181    /** The bean storing the paths which should be used to determine the flex cache buckets for this entry. */
182    private PathsBean m_paths = new PathsBean();
183
184    /** The (Flex) Http request this key was constructed for. */
185    private HttpServletRequest m_request;
186
187    /** The OpenCms resource that this key is used for. */
188    private String m_resource;
189
190    /**
191     * This constructor is used when building a cache key from a request.<p>
192     *
193     * The request contains several data items that are neccessary to construct
194     * the output. These items are e.g. the Query-String, the requested resource,
195     * the current time etc. etc.
196     * All required items are saved in the constructed cache - key.<p>
197     *
198     * @param req the request to construct the key for
199     * @param target the requested resource in the OpenCms VFS
200     * @param online must be true for an online resource, false for offline resources
201     */
202    public CmsFlexRequestKey(HttpServletRequest req, String target, boolean online) {
203
204        // store the request
205        m_request = req;
206
207        // fetch the cms from the request
208        CmsObject cms = CmsFlexController.getCmsObject(req);
209
210        // store the request context
211        m_context = cms.getRequestContext();
212
213        // calculate the resource name
214        m_resource = CmsFlexCacheKey.getKeyName(m_context.addSiteRoot(target), online);
215
216        // calculate the device
217        m_device = OpenCms.getSystemInfo().getDeviceSelector().getDeviceType(req);
218
219        CmsJspStandardContextBean standardContext = CmsJspStandardContextBean.getInstance(req);
220        // get the current container element
221        String templateContextKey = "";
222        TemplateBean templateBean = (TemplateBean)(req.getAttribute(CmsTemplateContextManager.ATTR_TEMPLATE_BEAN));
223        if (templateBean != null) {
224            templateContextKey = templateBean.getName();
225        }
226        m_containerElement = standardContext.elementCachingHash() + "_tc_" + templateContextKey;
227
228        // get the current detail view id
229        m_detailViewId = standardContext.getDetailContentId();
230        CmsResource detailContent = standardContext.getDetailContent();
231        if (detailContent != null) {
232            m_paths.setDetailElement(detailContent.getRootPath());
233        }
234        m_paths.setSite(m_context.getSiteRoot());
235        CmsContainerElementWrapper wrapper = standardContext.getElement();
236        if (wrapper != null) {
237            CmsResource containerElementResource = wrapper.getResource();
238            if (containerElementResource != null) {
239                m_paths.setContainerElement(containerElementResource.getRootPath());
240            }
241        }
242        m_paths.setUri(m_context.addSiteRoot(m_context.getUri()));
243        if (LOG.isDebugEnabled()) {
244            LOG.debug(Messages.get().getBundle().key(Messages.LOG_FLEXREQUESTKEY_CREATED_NEW_KEY_1, m_resource));
245        }
246    }
247
248    /**
249     * Returns the request attributes.<p>
250     *
251     * @return the request attributes
252     */
253    public Map<String, Object> getAttributes() {
254
255        Map<String, Object> attrs = CmsRequestUtil.getAtrributeMap(m_request);
256
257        if (attrs.size() == 0) {
258            return null;
259        }
260        return attrs;
261    }
262
263    /**
264     * Returns the current container element.<p>
265     *
266     * @return the current container element
267     */
268    public String getContainerElement() {
269
270        return m_containerElement;
271    }
272
273    /**
274     * Returns the device.<p>
275     *
276     * @return the device
277     */
278    public String getDevice() {
279
280        return m_device;
281    }
282
283    /**
284     * Returns the element.<p>
285     *
286     * @return the element
287     */
288    public String getElement() {
289
290        return m_request.getParameter(I_CmsResourceLoader.PARAMETER_ELEMENT);
291    }
292
293    /**
294     * Returns the encoding.<p>
295     *
296     * @return the encoding
297     */
298    public String getEncoding() {
299
300        return m_context.getEncoding();
301    }
302
303    /**
304     * Returns the ip.<p>
305     *
306     * @return the ip
307     */
308    public String getIp() {
309
310        return m_context.getRemoteAddress();
311    }
312
313    /**
314     * Returns the locale.<p>
315     *
316     * @return the locale
317     */
318    public String getLocale() {
319
320        return m_context.getLocale().toString();
321    }
322
323    /**
324     * Returns the parameters.<p>
325     *
326     * @return the parameters
327     */
328    public Map<String, String[]> getParams() {
329
330        // get the params
331        Map<String, String[]> params = CmsCollectionsGenericWrapper.map(m_request.getParameterMap());
332        if (params.size() == 0) {
333            return null;
334        }
335        return params;
336    }
337
338    /**
339     * Gets the bean containing the paths which should be used to determine the flex cache buckets for this entry.<p>
340     *
341     * @return the bean with the paths for this entry
342     */
343    public PathsBean getPaths() {
344
345        return m_paths;
346    }
347
348    /**
349     * Returns the port.<p>
350     *
351     * @return the port
352     */
353    public Integer getPort() {
354
355        return new Integer(m_request.getServerPort());
356    }
357
358    /**
359     * Returns the resource.<p>
360     *
361     * @return the resource
362     */
363    public String getResource() {
364
365        return m_resource;
366    }
367
368    /**
369     * Returns the schemes.<p>
370     *
371     * @return the schemes
372     */
373    public String getScheme() {
374
375        return m_request.getScheme().toLowerCase();
376    }
377
378    /**
379     * Returns the the current users session, or <code>null</code> if the current user
380     * has no session.<p>
381     *
382     * @return the current users session, or <code>null</code> if the current user has no session
383     */
384    public HttpSession getSession() {
385
386        return m_request.getSession(false);
387    }
388
389    /**
390     * Returns the site root.<p>
391     *
392     * @return the site root
393     */
394    public String getSite() {
395
396        return m_context.getSiteRoot();
397    }
398
399    /**
400     * Returns the uri.<p>
401     *
402     * @return the uri
403     */
404    public String getUri() {
405
406        String uri = m_context.addSiteRoot(m_context.getUri());
407        if (m_detailViewId != null) {
408            uri += m_detailViewId.toString() + "/";
409        }
410        return uri;
411    }
412
413    /**
414     * Returns the user.<p>
415     *
416     * @return the user
417     */
418    public String getUser() {
419
420        return m_context.getCurrentUser().getName();
421    }
422
423    /**
424     * Returns true if the 'force absolute links' flag is set in the request context.
425     *
426     * @return the 'force absolute links' flag from the request context
427     */
428    public boolean isForceAbsoluteLinks() {
429
430        return m_context.isForceAbsoluteLinks();
431    }
432}