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.xml.xml2json.handler;
029
030import org.opencms.configuration.CmsParameterConfiguration;
031import org.opencms.file.CmsFile;
032import org.opencms.file.CmsObject;
033import org.opencms.file.CmsResource;
034import org.opencms.main.CmsException;
035import org.opencms.main.CmsLog;
036import org.opencms.xml.content.CmsXmlContent;
037import org.opencms.xml.content.CmsXmlContentFactory;
038import org.opencms.xml.xml2json.CmsJsonAccessPolicy;
039
040import java.lang.ref.WeakReference;
041import java.util.Collections;
042import java.util.LinkedHashMap;
043import java.util.Map;
044
045import org.apache.commons.logging.Log;
046
047/**
048 * Provides context information to JSON handlers.<p>
049 *
050 * Also lazily loads the resource or content to be rendered as JSON.
051 */
052public class CmsJsonHandlerContext {
053
054    /**
055     * Cache key for JSON handler contexts.
056     *
057     * <p>Contains a weak reference to the context, for use in LoadingCache.
058     *
059     */
060    public static class Key {
061
062        /** The reference to the context from which this key was created. */
063        WeakReference<CmsJsonHandlerContext> m_contextRef;
064
065        /** The key string. */
066        private String m_keyString;
067
068        /**
069         * Creates a new cache key for a context.
070         *
071         * @param context the context
072         */
073        public Key(CmsJsonHandlerContext context) {
074
075            StringBuilder buffer = new StringBuilder();
076            buffer.append(context.getCms().getRequestContext().getCurrentProject().getId());
077            buffer.append("|");
078            buffer.append(context.getCms().getRequestContext().getSiteRoot());
079            buffer.append("|");
080            buffer.append(context.getCms().getRequestContext().getCurrentUser().getId());
081            buffer.append("|");
082            buffer.append(context.getPath());
083            buffer.append("|");
084            buffer.append(context.getParameters());
085            m_keyString = buffer.toString();
086            m_contextRef = new WeakReference<>(context);
087        }
088
089        /**
090         * @see java.lang.Object#equals(java.lang.Object)
091         */
092        @Override
093        public boolean equals(Object obj) {
094
095            return (obj instanceof Key) && ((Key)obj).m_keyString.equals(m_keyString);
096        }
097
098        /**
099         * @see java.lang.Object#hashCode()
100         */
101        @Override
102        public int hashCode() {
103
104            return m_keyString.hashCode();
105        }
106
107        /**
108         * Gets the original context, if it hasn't been garbage collected yet.
109         *
110         * @return the original context or null if it has already been collected
111         */
112        CmsJsonHandlerContext getContext() {
113
114            return m_contextRef.get();
115        }
116    }
117
118    /** The logger instance for this class. */
119    @SuppressWarnings("unused")
120    private static final Log LOG = CmsLog.getLog(CmsJsonHandlerContext.class);
121
122    /** Gets the access policy. */
123    private CmsJsonAccessPolicy m_accessPolicy;
124
125    /** The CMS context with the original site root. */
126    private CmsObject m_cms;
127
128    /** The XML content (initially null). */
129    private CmsXmlContent m_content;
130
131    /** The file for the path (initially null). */
132    private CmsFile m_file;
133
134    /** The handler parameters from opencms-system.xml. */
135    private CmsParameterConfiguration m_handlerConfig;
136
137    /** The request parameters from the resource init handler call. */
138    private Map<String, String> m_parameters;
139
140    /** The path below the JSON handler prefix. */
141    private String m_path;
142
143    /** The resource for the path. */
144    private CmsResource m_resource;
145
146    /** The CMS context initialized with the root site. */
147    private CmsObject m_rootCms;
148
149    /** Temporary data storage to be used by individual handlers. */
150    private Map<String, Object> m_tempData = new LinkedHashMap<>();
151
152    /**
153     * Creates a new instance.
154     *
155     * @param cms the CMS context
156     * @param rootCms the CMS context initialized for the root site
157     * @param path the path below the JSON handler
158     * @param resource the resource (may be null)
159     * @param params the request parameters
160     * @param handlerConfig the handler parameters from opencms-system.xml
161     * @param policy the access policy
162     */
163    public CmsJsonHandlerContext(
164        CmsObject cms,
165        CmsObject rootCms,
166        String path,
167        CmsResource resource,
168        Map<String, String> params,
169        CmsParameterConfiguration handlerConfig,
170        CmsJsonAccessPolicy policy) {
171
172        m_cms = cms;
173        m_resource = resource;
174        m_rootCms = rootCms;
175        m_path = path;
176        m_parameters = params;
177        m_handlerConfig = handlerConfig;
178        if (m_parameters == null) {
179            m_parameters = Collections.emptyMap();
180        }
181        if (m_handlerConfig == null) {
182            m_handlerConfig = new CmsParameterConfiguration();
183        }
184        m_accessPolicy = policy;
185    }
186
187    /**
188     * Gets the access policy.
189     *
190     * @return the access policy
191     */
192    public CmsJsonAccessPolicy getAccessPolicy() {
193
194        return m_accessPolicy;
195    }
196
197    /**
198     * Gets the CMS context.
199     *
200     * @return the CMS context
201     */
202    public CmsObject getCms() {
203
204        return m_cms;
205    }
206
207    /**
208     * Loads the XML content.<p>
209     *
210     * This only works if the resource for the given path is actually an  XML content.
211     *
212     * @return the XML content for the path
213     *
214     * @throws CmsException if something goes wrong
215     */
216    public CmsXmlContent getContent() throws CmsException {
217
218        if (m_content == null) {
219            m_content = CmsXmlContentFactory.unmarshal(m_cms, getFile());
220        }
221        return m_content;
222    }
223
224    /**
225     * Gets the file for the path.
226     *
227     * This will only work if the resource for the path is actually a file.
228     *
229     * @return the file for the path
230     *
231     * @throws CmsException if something goes wrong
232     */
233    public CmsFile getFile() throws CmsException {
234
235        if (m_file == null) {
236            m_file = m_cms.readFile(getResource());
237        }
238        return m_file;
239    }
240
241    /**
242     * Gets the configured handler parameters.
243     *
244     * @return the configured handler parameters
245     */
246    public CmsParameterConfiguration getHandlerConfig() {
247
248        return m_handlerConfig;
249    }
250
251    /**
252     * Creates a cache key for this context.
253     *
254     * @return the cache key
255     */
256    public Key getKey() {
257
258        return new Key(this);
259    }
260
261    /**
262     * Gets the request parameters.
263     *
264     * @return the request parameters
265     */
266    public Map<String, String> getParameters() {
267
268        return Collections.unmodifiableMap(m_parameters);
269    }
270
271    /**
272     * Returns the path.
273     *
274     * @return the path
275     */
276    public String getPath() {
277
278        return m_path;
279    }
280
281    /**
282     * Gets the resource (may be null if there is no resource).
283     *
284     * @return the resource
285     */
286    public CmsResource getResource() {
287
288        return m_resource;
289    }
290
291    /**
292     * Gets the CMS context initialized to the root site.
293     *
294     * @return the CMS context initialized to the root site
295     */
296    public CmsObject getRootCms() {
297
298        return m_rootCms;
299    }
300
301    /**
302     * Gets the temporary storage to be used by individual handlers.
303     *
304     * @return the temporary storage
305     */
306    public Map<String, Object> getTempStorage() {
307
308        return m_tempData;
309    }
310
311}