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}