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.main;
029
030import org.opencms.file.CmsProject;
031import org.opencms.file.CmsRequestContext;
032import org.opencms.file.CmsResource;
033import org.opencms.file.CmsUser;
034import org.opencms.i18n.CmsEncoder;
035import org.opencms.i18n.CmsLocaleManager;
036import org.opencms.security.CmsOrganizationalUnit;
037import org.opencms.site.CmsSiteMatcher;
038
039import java.io.Serializable;
040import java.util.Locale;
041
042/**
043 * Contains user information for automated creation of a
044 * {@link org.opencms.file.CmsRequestContext} during system runtime.<p>
045 *
046 * @since 6.0.0
047 */
048public class CmsContextInfo implements Serializable {
049
050    /** Name of the http session attribute the request time is stored in. */
051    public static final String ATTRIBUTE_REQUEST_TIME = "__org.opencms.main.CmsContextInfo#m_requestTime";
052
053    /** Indicates the request time should always be the current time. */
054    public static final long CURRENT_TIME = -1L;
055
056    /** Localhost ip used in fallback cases. */
057    public static final String LOCALHOST = "127.0.0.1";
058
059    /** The serial version id. */
060    private static final long serialVersionUID = -2906001878274166112L;
061
062    /** The detail content resource, if available. */
063    private CmsResource m_detailResource;
064
065    /** The encoding to create the context with. */
066    private String m_encoding;
067
068    /** Indicates if the configuration if this context info can still be changed or not. */
069    private boolean m_frozen;
070
071    /** True if this was determined to be a request to a secure site. */
072    private boolean m_isSecureRequest;
073
074    /** The locale to create the context with. */
075    private Locale m_locale;
076
077    /** The locale name to create the context with. */
078    private String m_localeName;
079
080    /** The organizational unit to create the context with. */
081    private String m_ouFqn;
082
083    /** The project to create the context with. */
084    private CmsProject m_project;
085
086    /** The user name to create the context with. */
087    private String m_projectName;
088
089    /** The remote ip address to create the context with. */
090    private String m_remoteAddr;
091
092    /** The request URI to create the context with. */
093    private String m_requestedUri;
094
095    /** the matcher for the current request, that is the host part of the URI from the original http request. */
096    private CmsSiteMatcher m_requestMatcher;
097
098    /** The time for the request, used for resource publication and expiration dates. */
099    private long m_requestTime;
100
101    /** The site root to create the context with. */
102    private String m_siteRoot;
103
104    /** The user to create the context with. */
105    private CmsUser m_user;
106
107    /** The user name to create the context with. */
108    private String m_userName;
109
110    /**
111     * Creates a new instance, initializing the variables with some reasonable default values.<p>
112     *
113     * The default values are:<dl>
114     * <dt>User name</dt><dd>(configured default guest user)</dd>
115     * <dt>Project name</dt><dd>Online</dd>
116     * <dt>Requested URI</dt><dd>/</dd>
117     * <dt>Site root</dt><dd>/</dd>
118     * <dt>Locale name</dt><dd>(configured default locale name)</dd>
119     * <dt>Encoding</dt><dd>(configured default system encoding)</dd>
120     * <dt>Remote address</dt><dd>127.0.0.1</dd>
121     * <dt>Organizational unit</dt><dd>/</dd>
122     * </dl><p>
123     */
124    public CmsContextInfo() {
125
126        setUserName(OpenCms.getDefaultUsers().getUserGuest());
127        setProjectName(CmsProject.ONLINE_PROJECT_NAME);
128        setRequestedUri("/");
129        setSiteRoot("/");
130        setRequestMatcher(
131            OpenCms.getSiteManager() != null
132            ? OpenCms.getSiteManager().getWorkplaceSiteMatcher()
133            : CmsSiteMatcher.DEFAULT_MATCHER);
134        setLocaleName(CmsLocaleManager.getDefaultLocale().toString());
135        setEncoding(OpenCms.getSystemInfo().getDefaultEncoding());
136        setRemoteAddr(CmsContextInfo.LOCALHOST);
137        setRequestTime(CURRENT_TIME);
138        setOuFqn("");
139    }
140
141    /**
142     * Creates a new instance with all context variables initialized from the given request context.<p>
143     *
144     * @param requestContext the request context to initialize this context info with
145     */
146    public CmsContextInfo(CmsRequestContext requestContext) {
147
148        setUserName(requestContext.getCurrentUser().getName());
149        setProjectName(requestContext.getCurrentProject().getName());
150        setRequestedUri(requestContext.getUri());
151        setSiteRoot(requestContext.getSiteRoot());
152        setRequestMatcher(requestContext.getRequestMatcher());
153        setLocale(requestContext.getLocale());
154        setEncoding(requestContext.getEncoding());
155        setRemoteAddr(requestContext.getRemoteAddress());
156        setRequestTime(requestContext.getRequestTime());
157        setIsSecureRequest(requestContext.isSecureRequest());
158        setOuFqn(requestContext.getOuFqn());
159        setDetailResource(requestContext.getDetailResource());
160    }
161
162    /**
163     * Creates a new instance with all context variables initialized.<p>
164     *
165     * @param user the user to create the context with
166     * @param project the project to create the context with
167     * @param requestedUri the request URI to create the context with
168     * @param requestMatcher the matcher for the current request, that is the host part of the URI from the original http request
169     * @param siteRoot the site root to create the context with
170     * @param isSecureRequest if this a secure request
171     * @param locale the locale to create the context with
172     * @param encoding the encoding to create the context with
173     * @param remoteAddr the remote ip address to create the context with
174     * @param requestTime the time of the request (used for resource publication / expiration date)
175     * @param ouFqn the fully qualified name of the organizational unit to create the context with
176     */
177    public CmsContextInfo(
178        CmsUser user,
179        CmsProject project,
180        String requestedUri,
181        CmsSiteMatcher requestMatcher,
182        String siteRoot,
183        boolean isSecureRequest,
184        Locale locale,
185        String encoding,
186        String remoteAddr,
187        long requestTime,
188        String ouFqn) {
189
190        m_user = user;
191        setUserName(m_user.getName());
192        m_project = project;
193        setProjectName(m_project.getName());
194        setRequestedUri(requestedUri);
195        setRequestMatcher(requestMatcher);
196        setSiteRoot(siteRoot);
197        setIsSecureRequest(isSecureRequest);
198        setLocale(locale);
199        setEncoding(encoding);
200        setRemoteAddr(remoteAddr);
201        setRequestTime(requestTime);
202        setOuFqn(ouFqn);
203    }
204
205    /**
206     * Creates a new instance, initializing the user name as provided and
207     * all other vaiables with the same default values as in {@link #CmsContextInfo()}.<p>
208     *
209     * @param userName the user name to create the context with
210     *
211     * @see #CmsContextInfo()
212     */
213    public CmsContextInfo(String userName) {
214
215        this();
216        setUserName(userName);
217    }
218
219    /**
220     * Creates a clone of this context info object.<p>
221     *
222     * @see java.lang.Object#clone()
223     */
224    @Override
225    public Object clone() {
226
227        CmsContextInfo result = new CmsContextInfo();
228        result.m_encoding = m_encoding;
229        result.m_frozen = false;
230        result.m_locale = m_locale;
231        result.m_localeName = m_localeName;
232        result.m_project = m_project;
233        result.m_projectName = m_projectName;
234        result.m_isSecureRequest = m_isSecureRequest;
235        result.m_remoteAddr = m_remoteAddr;
236        result.m_requestedUri = m_requestedUri;
237        result.m_requestTime = m_requestTime;
238        result.m_siteRoot = m_siteRoot;
239        result.m_user = m_user;
240        result.m_userName = m_userName;
241        return result;
242    }
243
244    /**
245     * Finalizes (freezes) the configuration of this context information.<p>
246     *
247     * After this entry has been frozen, any attempt to change the
248     * configuration of this context info with one of the "set..." methods
249     * will lead to a <code>RuntimeException</code>.<p>
250     */
251    public void freeze() {
252
253        m_frozen = true;
254    }
255
256    /**
257     * Gets the detail content resource.<p>
258     *
259     * @return the detail content resource
260     */
261    public CmsResource getDetailResource() {
262
263        return m_detailResource;
264    }
265
266    /**
267     * Returns the encoding.<p>
268     *
269     * @return the encoding
270     *
271     * @see CmsRequestContext#getEncoding()
272     */
273    public String getEncoding() {
274
275        return m_encoding;
276    }
277
278    /**
279     * Returns the locale.<p>
280     *
281     * @return the locale
282     *
283     * @see CmsRequestContext#getLocale()
284     */
285    public Locale getLocale() {
286
287        return m_locale;
288    }
289
290    /**
291     * Returns the locale name.<p>
292     *
293     * @return the locale name
294     *
295     * @see CmsRequestContext#getLocale()
296     */
297    public String getLocaleName() {
298
299        return m_localeName;
300    }
301
302    /**
303     * Returns the fully qualified name of the organizational unit.<p>
304     *
305     * @return the fully qualified name of the organizational unit
306     */
307    public String getOuFqn() {
308
309        return m_ouFqn;
310    }
311
312    /**
313     * Returns the project, or <code>null</code> if the project
314     * has not been configured.<p>
315     *
316     * If the project has not been configured, at last the
317     * project name will be available.<p>
318     *
319     * @return the project
320     *
321     * @see #getProjectName()
322     * @see CmsRequestContext#getCurrentProject()
323     */
324    public CmsProject getProject() {
325
326        return m_project;
327    }
328
329    /**
330     * Returns the project name.<p>
331     *
332     * @return the project name
333     *
334     * @see #getProject()
335     * @see CmsRequestContext#getCurrentProject()
336     */
337    public String getProjectName() {
338
339        return m_projectName;
340    }
341
342    /**
343     * Returns the remote ip address.<p>
344     *
345     * @return the remote ip address
346     *
347     * @see CmsRequestContext#getRemoteAddress()
348     */
349    public String getRemoteAddr() {
350
351        return m_remoteAddr;
352    }
353
354    /**
355     * Returns the requested uri.<p>
356     *
357     * @return the requested uri
358     *
359     * @see CmsRequestContext#getUri()
360     */
361    public String getRequestedUri() {
362
363        return m_requestedUri;
364    }
365
366    /**
367     * Returns the matcher for the current request, that is the host part of the URI from the original http request.<p>
368     *
369     * @return the matcher for the current request, that is the host part of the URI from the original http request
370     */
371    public CmsSiteMatcher getRequestMatcher() {
372
373        return m_requestMatcher;
374    }
375
376    /**
377     * Returns the request time used for validation of resource publication and expiration dates.<p>
378     *
379     * @return the request time used for validation of resource publication and expiration dates
380     *
381     * @see CmsRequestContext#getRequestTime()
382     */
383    public long getRequestTime() {
384
385        return m_requestTime;
386    }
387
388    /**
389     * Returns the siteroot.<p>
390     *
391     * @return the siteroot
392     *
393     * @see CmsRequestContext#getSiteRoot()
394     */
395    public String getSiteRoot() {
396
397        return m_siteRoot;
398    }
399
400    /**
401     * Returns the user, or <code>null</code> if the user
402     * has not been configured.<p>
403     *
404     * If the user has not been configured, at last the
405     * user name will be available.<p>
406     *
407     * @return the user
408     *
409     * @see #getUserName()
410     * @see CmsRequestContext#getCurrentUser()
411     */
412    public CmsUser getUser() {
413
414        return m_user;
415    }
416
417    /**
418     * Returns the username.<p>
419     *
420     * @return the username
421     *
422     * @see #getUser()
423     * @see CmsRequestContext#getCurrentUser()
424     */
425    public String getUserName() {
426
427        return m_userName;
428    }
429
430    /**
431     * Returns true if this a secure request.<p>
432     *
433     * @return true if this is a secure request
434     */
435    public boolean isSecureRequest() {
436
437        return m_isSecureRequest;
438    }
439
440    /**
441     * Sets the detail content resource.<p>
442     *
443     * @param detailResource the detail content resource to set
444     */
445    public void setDetailResource(CmsResource detailResource) {
446
447        m_detailResource = detailResource;
448    }
449
450    /**
451     * Sets the encoding.<p>
452     *
453     * @param encoding the encoding to set
454     *
455     * @see CmsRequestContext#setEncoding(String)
456     */
457    public void setEncoding(String encoding) {
458
459        checkFrozen();
460        m_encoding = CmsEncoder.lookupEncoding(encoding, OpenCms.getSystemInfo().getDefaultEncoding());
461    }
462
463    /**
464     * Sets the 'isSecureRequest' attribute.<p>
465     *
466     * @param isSecureRequest  true if this a secure request
467     */
468    public void setIsSecureRequest(boolean isSecureRequest) {
469
470        m_isSecureRequest = isSecureRequest;
471    }
472
473    /**
474     * Sets the locale.<p>
475     *
476     * Setting the locale name will override the currently selected locale
477     * and vice-versa. The locale name and the locale will always match.<p>
478     *
479     * @param locale the locale to set
480     *
481     * @see #setLocaleName(String)
482     * @see CmsRequestContext#getLocale()
483     */
484    public void setLocale(Locale locale) {
485
486        checkFrozen();
487        m_locale = locale;
488        m_localeName = m_locale.toString();
489    }
490
491    /**
492     * Sets the locale name.<p>
493     *
494     * Setting the locale name will override the currently selected locale
495     * and vice-versa. The locale name and the locale will always match.<p>
496     *
497     * @param localeName the locale name to set
498     *
499     * @see #setLocale(Locale)
500     * @see CmsRequestContext#getLocale()
501     */
502    public void setLocaleName(String localeName) {
503
504        checkFrozen();
505        m_localeName = localeName;
506        m_locale = CmsLocaleManager.getLocale(localeName);
507    }
508
509    /**
510     * Sets the fully qualified name of the organizational unit.<p>
511     *
512     * @param ouFqn the fully qualified name of the organizational unit to set
513     */
514    public void setOuFqn(String ouFqn) {
515
516        checkFrozen();
517        m_ouFqn = ouFqn;
518    }
519
520    /**
521     * Sets the project name.<p>
522     *
523     * @param projectName the project name to set
524     *
525     * @see CmsRequestContext#getCurrentProject()
526     */
527    public void setProjectName(String projectName) {
528
529        checkFrozen();
530        m_projectName = projectName;
531    }
532
533    /**
534     * Sets the remote ip address.<p>
535     *
536     * @param remoteAddr the remote ip address
537     *
538     * @see CmsRequestContext#getRemoteAddress()
539     */
540    public void setRemoteAddr(String remoteAddr) {
541
542        checkFrozen();
543        m_remoteAddr = remoteAddr;
544    }
545
546    /**
547     * Sets the requested uri.<p>
548     *
549     * @param requestedUri the requested uri to set
550     *
551     * @see CmsRequestContext#setUri(String)
552     */
553    public void setRequestedUri(String requestedUri) {
554
555        checkFrozen();
556        m_requestedUri = requestedUri;
557    }
558
559    /**
560     * Sets the matcher for the current request, that is the host part of the URI from the original http request.<p>
561     *
562     * @param requestMatcher the matcher for the current request
563     */
564    public void setRequestMatcher(CmsSiteMatcher requestMatcher) {
565
566        m_requestMatcher = requestMatcher;
567    }
568
569    /**
570     * Sets the request time used for validation of resource publication and expiration dates.<p>
571     *
572     * @param requestTime the request time to set
573     *
574     * @see CmsRequestContext#getRequestTime()
575     */
576    public void setRequestTime(long requestTime) {
577
578        checkFrozen();
579        if (requestTime == CURRENT_TIME) {
580            m_requestTime = System.currentTimeMillis();
581        } else {
582            m_requestTime = requestTime;
583        }
584    }
585
586    /**
587     * Sets the siteroot.<p>
588     *
589     * @param siteRoot the siteroot to set
590     *
591     * @see CmsRequestContext#setSiteRoot(String)
592     */
593    public void setSiteRoot(String siteRoot) {
594
595        checkFrozen();
596        m_siteRoot = siteRoot;
597    }
598
599    /**
600     * Sets the username.<p>
601     *
602     * @param userName the username to set
603     *
604     * @see CmsRequestContext#getCurrentUser()
605     */
606    public void setUserName(String userName) {
607
608        checkFrozen();
609        m_userName = userName;
610        setOuFqn(CmsOrganizationalUnit.getParentFqn(userName));
611    }
612
613    /**
614     * Checks if this context info configuration is frozen.<p>
615     *
616     * @throws CmsRuntimeException in case the configuration is already frozen
617     */
618    protected void checkFrozen() throws CmsRuntimeException {
619
620        if (m_frozen) {
621            throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONTEXT_INFO_FROZEN_0));
622        }
623    }
624}