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