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.db;
029
030import org.opencms.file.CmsProject;
031import org.opencms.file.CmsRequestContext;
032import org.opencms.file.CmsUser;
033import org.opencms.file.CmsVfsException;
034import org.opencms.flex.CmsFlexRequestContextInfo;
035import org.opencms.i18n.CmsMessageContainer;
036import org.opencms.main.CmsException;
037import org.opencms.main.CmsRuntimeException;
038import org.opencms.report.I_CmsReport;
039import org.opencms.util.CmsRequestUtil;
040import org.opencms.util.CmsUUID;
041
042import java.util.HashMap;
043import java.util.Map;
044
045/**
046 * Wraps context information to access the OpenCms database.<p>
047 *
048 * @since 6.0.0
049 */
050public class CmsDbContext {
051
052    /** Context attributes. */
053    protected Map<String, Object> m_attributes;
054
055    /** The current Flex request context info (if available). */
056    protected CmsFlexRequestContextInfo m_flexRequestContextInfo;
057
058    /** The id of the project for the context. */
059    protected CmsUUID m_projectId;
060
061    /** The wrapped user request context. */
062    protected CmsRequestContext m_requestContext;
063
064    /**
065     * Creates a new, empty database context.<p>
066     */
067    public CmsDbContext() {
068
069        this(null);
070    }
071
072    /**
073     * Creates a new database context initialized with the given user request context.<p>
074     *
075     * @param context the current users request context
076     */
077    public CmsDbContext(CmsRequestContext context) {
078
079        m_requestContext = context;
080        m_projectId = CmsUUID.getNullUUID();
081
082        if (m_requestContext != null) {
083            m_flexRequestContextInfo = (CmsFlexRequestContextInfo)m_requestContext.getAttribute(
084                CmsRequestUtil.HEADER_LAST_MODIFIED);
085        }
086    }
087
088    /**
089     * Clears this database context.<p>
090     */
091    public void clear() {
092
093        m_requestContext = null;
094        m_flexRequestContextInfo = null;
095    }
096
097    /**
098     * Returns the current users project.<p>
099     *
100     * @return the current users project
101     */
102    public CmsProject currentProject() {
103
104        return m_requestContext.getCurrentProject();
105    }
106
107    /**
108     * Returns the current user.<p>
109     *
110     * @return the current user
111     */
112    public CmsUser currentUser() {
113
114        return m_requestContext.getCurrentUser();
115    }
116
117    /**
118     * Get an attribute from the DB context.<p>
119     *
120     * @param key the attribute key
121     *
122     * @return the attribute value or null if the attribute does not exist
123     */
124    public Object getAttribute(String key) {
125
126        if (m_attributes == null) {
127            return null;
128        }
129        return m_attributes.get(key);
130    }
131
132    /**
133     * Returns the current Flex request context info.<p>
134     *
135     * @return the current Flex request context info
136     */
137    public CmsFlexRequestContextInfo getFlexRequestContextInfo() {
138
139        return m_flexRequestContextInfo;
140    }
141
142    /**
143     * Gets the history driver associated with this database context.<p>
144     *
145     * @param projectId the project id for which the history driver should be retrieved
146     *
147     * @return the history driver
148     */
149    public I_CmsHistoryDriver getHistoryDriver(CmsUUID projectId) {
150
151        return null;
152    }
153
154    /**
155     * Gets the project driver associated with this database context.<p>
156     *
157     * @param projectId the project id for which the project driver should be retrieved
158     *
159     * @return the project driver
160     */
161    public I_CmsProjectDriver getProjectDriver(CmsUUID projectId) {
162
163        return null;
164    }
165
166    /**
167     * Returns the project id of the context.<p>
168     *
169     * @return the project
170     */
171    public CmsUUID getProjectId() {
172
173        return m_projectId;
174    }
175
176    /**
177     * Returns the request context.<p>
178     *
179     * @return the request context
180     */
181    public CmsRequestContext getRequestContext() {
182
183        return m_requestContext;
184    }
185
186    /**
187     * Gets the user driver associated with this database context.<p>
188     *
189     * @param projectId the project id for which the user driver should be retrieved
190     *
191     * @return the user driver
192     */
193    public I_CmsUserDriver getUserDriver(CmsUUID projectId) {
194
195        return null;
196    }
197
198    /**
199     * Gets the VFS driver associated with this database context.<p>
200     *
201     * @param projectId the project id for which the VFS driver should be retrieved
202     *
203     * @return the VFS driver
204     */
205    public I_CmsVfsDriver getVfsDriver(CmsUUID projectId) {
206
207        return null;
208    }
209
210    /**
211     * Checks if the database context uses the default implementation.<p>
212     *
213     * @return <code>true</code> if the database context uses the default implementation
214     */
215    public boolean isDefaultDbContext() {
216
217        return true;
218    }
219
220    /**
221     * Processes the current database context.<p>
222     *
223     * @throws CmsException if something goes wrong
224     */
225    public void pop() throws CmsException {
226
227        if (!isDefaultDbContext()) {
228            throw new CmsException(Messages.get().container(Messages.ERR_PROCESS_DB_CONTEXT_0));
229        }
230    }
231
232    /**
233     * Removes the given attribute from the DB context.<p>
234     *
235     * @param key the attribute key
236     */
237    public void removeAttribute(String key) {
238
239        if (m_attributes == null) {
240            return;
241        }
242        m_attributes.remove(key);
243    }
244
245    /**
246     * Removes the current site root prefix from the absolute path in the resource name,
247     * that is adjusts the resource name for the current site root.<p>
248     *
249     * If no user request context is available, the given resource name is
250     * returned unchanged.<p>
251     *
252     * @param resourcename the resource name
253     *
254     * @return the resource name adjusted for the current site root
255     */
256    public String removeSiteRoot(String resourcename) {
257
258        if ((m_requestContext != null) && (resourcename != null)) {
259            return m_requestContext.removeSiteRoot(resourcename);
260        }
261
262        return resourcename;
263    }
264
265    /**
266     * Reports an error to the given report (if available) and to the OpenCms log file.<p>
267     *
268     * @param report the report to write the error to
269     * @param message the message to write to the report / log
270     * @param throwable the exception to write to the report / log
271     *
272     * @throws CmsException if the <code>throwable</code> parameter is not <code>null</code> and a {@link CmsException}
273     * @throws CmsVfsException if the <code>throwable</code> parameter is not <code>null</code> and no {@link CmsException}
274     */
275    public void report(I_CmsReport report, CmsMessageContainer message, Throwable throwable)
276    throws CmsVfsException, CmsException {
277
278        if (report != null) {
279            if (message != null) {
280                report.println(message, I_CmsReport.FORMAT_ERROR);
281            }
282            if (throwable != null) {
283                report.println(throwable);
284            }
285        }
286
287        throwException(message, throwable);
288    }
289
290    /**
291     * Rolls back current transaction.<p>
292     */
293    public void rollback() {
294
295        // This method is only implemented org.opencms.db.jpa.CmsDbContext
296    }
297
298    /**
299     * Sets an attribute in the DB context.<p>
300     *
301     * @param key the attribute key
302     * @param value the attribute value
303     */
304    public void setAttribute(String key, Object value) {
305
306        if (m_attributes == null) {
307            m_attributes = new HashMap<String, Object>(4);
308        }
309        m_attributes.put(key, value);
310    }
311
312    /**
313     * Sets the project id of the context.<p>
314     *
315     * @param projectId the id of the project to set
316     */
317    public void setProjectId(CmsUUID projectId) {
318
319        m_projectId = projectId;
320    }
321
322    /**
323     * Returns an exception of the same type as <code>throwable</code>, if <code>throwable</code> is an OpenCms Exception
324     * with the message as a {@link CmsMessageContainer} and the <code>throwable</code> as a cause.<p>
325     *
326     * @param message the message container for the exception to create
327     * @param throwable the cause of the exception
328     *
329     * @throws CmsException if the <code>throwable</code> parameter is not <code>null</code> and a {@link CmsException}
330     * @throws CmsVfsException if the <code>throwable</code> parameter is not <code>null</code> and no {@link CmsException}
331     */
332    public void throwException(CmsMessageContainer message, Throwable throwable) throws CmsVfsException, CmsException {
333
334        if (throwable instanceof CmsException) {
335            throw ((CmsException)throwable).createException(message, throwable);
336        } else if (throwable instanceof CmsRuntimeException) {
337            throw ((CmsRuntimeException)throwable).createException(message, throwable);
338        } else {
339            throw new CmsVfsException(message, throwable);
340        }
341    }
342}