001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/CmsFrameset.java,v $
003: * Date : $Date: 2008-02-27 12:05:45 $
004: * Version: $Revision: 1.92 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.workplace;
033:
034: import org.opencms.configuration.CmsDefaultUserSettings;
035: import org.opencms.db.CmsUserSettings;
036: import org.opencms.file.CmsProject;
037: import org.opencms.file.CmsResourceFilter;
038: import org.opencms.i18n.CmsEncoder;
039: import org.opencms.jsp.CmsJspActionElement;
040: import org.opencms.main.CmsException;
041: import org.opencms.main.CmsLog;
042: import org.opencms.main.OpenCms;
043: import org.opencms.security.CmsOrganizationalUnit;
044: import org.opencms.site.CmsSite;
045: import org.opencms.synchronize.CmsSynchronizeSettings;
046: import org.opencms.util.CmsRequestUtil;
047: import org.opencms.util.CmsStringUtil;
048:
049: import java.util.ArrayList;
050: import java.util.Arrays;
051: import java.util.Collections;
052: import java.util.Iterator;
053: import java.util.List;
054: import java.util.Map;
055: import java.util.Set;
056:
057: import javax.servlet.http.HttpServletRequest;
058: import javax.servlet.http.HttpSession;
059:
060: import org.apache.commons.logging.Log;
061:
062: /**
063: * Provides methods for building the main framesets of the OpenCms Workplace.<p>
064: *
065: * The following files use this class:
066: * <ul>
067: * <li>/views/top.html
068: * <li>/views/top_foot.html
069: * <li>/views/top_head.html
070: * </ul>
071: * <p>
072: *
073: * @author Alexander Kandzior
074: *
075: * @version $Revision: 1.92 $
076: *
077: * @since 6.0.0
078: */
079: public class CmsFrameset extends CmsWorkplace {
080:
081: /** Path to the JSP workplace frame loader file. */
082: public static final String JSP_WORKPLACE_URI = CmsWorkplace.VFS_PATH_VIEWS
083: + "workplace.jsp";
084:
085: /** The request parameter for the selection of the frame. */
086: public static final String PARAM_WP_FRAME = "wpFrame";
087:
088: /** The request parameter for the workplace start selection. */
089: public static final String PARAM_WP_START = "wpStart";
090:
091: /** The request parameter for the workplace view selection. */
092: public static final String PARAM_WP_VIEW = "wpView";
093:
094: /** The names of the supported frames. */
095: private static final String[] FRAMES = { "top", "head", "body",
096: "foot" };
097:
098: /** The names of the supported frames in a list. */
099: public static final List FRAMES_LIST = Collections
100: .unmodifiableList(Arrays.asList(FRAMES));
101:
102: /** The log object for this class. */
103: private static final Log LOG = CmsLog.getLog(CmsFrameset.class);
104:
105: /** Indicates if a reload of the main body frame is required. */
106: private boolean m_reloadRequired;
107:
108: /**
109: * Public constructor.<p>
110: *
111: * @param jsp an initialized JSP action element
112: */
113: public CmsFrameset(CmsJspActionElement jsp) {
114:
115: super (jsp);
116: }
117:
118: /**
119: * Returns the javascript code for the broadcast message alert in the foot of the workplace.<p>
120: *
121: * @return javascript code showing an alert box when the foot load
122: */
123: public String getBroadcastMessage() {
124:
125: StringBuffer result = new StringBuffer(512);
126: String message = getBroadcastMessageString();
127:
128: if (CmsStringUtil.isNotEmpty(message)) {
129: // create a javascript alert for the message
130: result
131: .append("\n<script type=\"text/javascript\">\n<!--\n");
132: // the timeout gives the frameset enough time to load before the alert is shown
133: result.append("function showMessage() {\n");
134: result.append("\talert(decodeURIComponent(\"");
135: // the user has pending messages, display them all
136: result.append(CmsEncoder.escapeWBlanks(message,
137: CmsEncoder.ENCODING_UTF_8));
138: result.append("\"));\n}\n");
139: result.append("setTimeout('showMessage();', 2000);");
140: result.append("\n//-->\n</script>");
141: }
142: return result.toString();
143: }
144:
145: /**
146: * Returns the remote ip address of the current user.<p>
147: *
148: * @return the remote ip address of the current user
149: */
150: public String getLoginAddress() {
151:
152: return getCms().getRequestContext().getRemoteAddress();
153: }
154:
155: /**
156: * Returns the last login time of the current user in localized format.<p>
157: *
158: * @return the last login time of the current user in localized format
159: */
160: public String getLoginTime() {
161:
162: return getMessages().getDateTime(
163: getSettings().getUser().getLastlogin());
164: }
165:
166: /**
167: * Returns the html for the "preferences" button depending on the current users permissions and
168: * the default workplace settings.<p>
169: *
170: * @return the html for the "preferences" button
171: */
172: public String getPreferencesButton() {
173:
174: int buttonStyle = getSettings().getUserSettings()
175: .getWorkplaceButtonStyle();
176: if (!getCms().getRequestContext().currentUser().isManaged()) {
177: return button("../commons/preferences.jsp", "body",
178: "preferences.png",
179: Messages.GUI_BUTTON_PREFERENCES_0, buttonStyle);
180: } else {
181: return button(null, null, "preferences_in.png",
182: Messages.GUI_BUTTON_PREFERENCES_0, buttonStyle);
183: }
184: }
185:
186: /**
187: * Returns a html select box filled with the current users accessible projects.<p>
188: *
189: * @param htmlAttributes attributes that will be inserted into the generated html
190: * @param htmlWidth additional style attributes containing width information
191: * @return a html select box filled with the current users accessible projects
192: */
193: public String getProjectSelect(String htmlAttributes,
194: String htmlWidth) {
195:
196: // get all project information
197: List allProjects;
198: try {
199: allProjects = getCms().getAllAccessibleProjects();
200: } catch (CmsException e) {
201: // should usually never happen
202: if (LOG.isInfoEnabled()) {
203: LOG.info(e.getLocalizedMessage());
204: }
205: allProjects = Collections.EMPTY_LIST;
206: }
207:
208: boolean singleOu = true;
209: String ouFqn = null;
210: Iterator itProjects = allProjects.iterator();
211: while (itProjects.hasNext()) {
212: CmsProject prj = (CmsProject) itProjects.next();
213: if (prj.isOnlineProject()) {
214: // skip the online project
215: continue;
216: }
217: if (ouFqn == null) {
218: // set the first ou
219: ouFqn = prj.getOuFqn();
220: }
221: if (!ouFqn.equals(prj.getOuFqn())) {
222: // break if one different ou is found
223: singleOu = false;
224: break;
225: }
226: }
227:
228: List options = new ArrayList();
229: List values = new ArrayList();
230: int selectedIndex = -1;
231: int ouDefaultProjIndex = -1;
232:
233: CmsOrganizationalUnit ou = null;
234: try {
235: ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(
236: getCms(), getCms().getRequestContext().getOuFqn());
237: } catch (CmsException e) {
238: // should never happen, ignore
239: }
240:
241: // now loop through all projects and fill the result vectors
242: for (int i = 0, n = allProjects.size(); i < n; i++) {
243: CmsProject project = (CmsProject) allProjects.get(i);
244: String projectId = project.getUuid().toString();
245: String projectName = project.getSimpleName();
246: if (!singleOu && !project.isOnlineProject()) {
247: try {
248: projectName = projectName
249: + " - "
250: + OpenCms.getOrgUnitManager()
251: .readOrganizationalUnit(getCms(),
252: project.getOuFqn())
253: .getDisplayName(getLocale());
254: } catch (CmsException e) {
255: projectName = projectName + " - "
256: + project.getOuFqn();
257: }
258: }
259:
260: values.add(projectId);
261: options.add(projectName);
262:
263: if (project.getUuid().equals(getSettings().getProject())) {
264: // this is the user's current project
265: selectedIndex = i;
266: }
267: if ((ou != null)
268: && project.getUuid().equals(ou.getProjectId())) {
269: ouDefaultProjIndex = i;
270: }
271: }
272: if (selectedIndex == -1) {
273: if (ouDefaultProjIndex == -1) {
274: selectedIndex = 0;
275: } else {
276: selectedIndex = ouDefaultProjIndex;
277: }
278: }
279: if (CmsStringUtil.isNotEmpty(htmlWidth)) {
280: StringBuffer buf = new StringBuffer(htmlAttributes.length()
281: + htmlWidth.length() + 2);
282: buf.append(htmlAttributes);
283: buf.append(" ");
284: buf.append(htmlWidth);
285: htmlAttributes = buf.toString();
286: }
287:
288: return buildSelect(htmlAttributes, options, values,
289: selectedIndex);
290: }
291:
292: /**
293: * Returns the html for the "publish project" button depending on the current users permissions and the default
294: * workplace settings.<p>
295: *
296: * @return the html for the "publish project" button
297: */
298: public String getPublishButton() {
299:
300: String publishButton = OpenCms.getWorkplaceManager()
301: .getDefaultUserSettings().getPublishButtonAppearance();
302: if (CmsDefaultUserSettings.PUBLISHBUTTON_SHOW_NEVER
303: .equals(publishButton)) {
304: return "";
305: }
306:
307: int buttonStyle = getSettings().getUserSettings()
308: .getWorkplaceButtonStyle();
309:
310: if (CmsDefaultUserSettings.PUBLISHBUTTON_SHOW_AUTO
311: .equals(publishButton)) {
312: if (getCms().isManagerOfProject()) {
313: return button("../commons/publishproject.jsp", "body",
314: "publish.png", Messages.GUI_BUTTON_PUBLISH_0,
315: buttonStyle);
316: } else {
317: return "";
318: }
319: }
320:
321: if (getCms().isManagerOfProject()) {
322: return (button("../commons/publishproject.jsp", "body",
323: "publish.png", Messages.GUI_BUTTON_PUBLISH_0,
324: buttonStyle));
325: } else {
326: return (button(null, null, "publish_in.png",
327: Messages.GUI_BUTTON_PUBLISH_0, buttonStyle));
328: }
329: }
330:
331: /**
332: * Returns the html for the "publish queue" button.<p>
333: *
334: * @return the html for the "publish queue" button
335: */
336: public String getPublishQueueButton() {
337:
338: int buttonStyle = getSettings().getUserSettings()
339: .getWorkplaceButtonStyle();
340: StringBuffer js = new StringBuffer(128);
341: js
342: .append("javascript:if (parent.body.admin_content && parent.body.admin_menu) {");
343: js.append("parent.body.location.href = '");
344: js
345: .append(getJsp()
346: .link(
347: "/system/workplace/views/admin/admin-fs.jsp?root=admin&path=/publishqueue"));
348: js.append("';");
349: js.append("} else {");
350: js
351: .append("parent.body.explorer_body.explorer_files.location.href = '");
352: js
353: .append(getJsp()
354: .link(
355: "/system/workplace/views/admin/admin-fs.jsp?root=explorer&path=/publishqueue&menu=no"));
356: js.append("';");
357: js.append("};");
358: return button(js.toString(), null, "publish_queue.png",
359: Messages.GUI_BUTTON_PUBLISHQUEUE_0, buttonStyle);
360: }
361:
362: /**
363: * Returns a html select box filled with the current users accessible sites.<p>
364: *
365: * @param htmlAttributes attributes that will be inserted into the generated html
366: * @return a html select box filled with the current users accessible sites
367: */
368: public String getSiteSelect(String htmlAttributes) {
369:
370: List options = new ArrayList();
371: List values = new ArrayList();
372: int selectedIndex = 0;
373:
374: List sites = OpenCms.getSiteManager().getAvailableSites(
375: getCms(), true);
376:
377: Iterator i = sites.iterator();
378: int pos = 0;
379: while (i.hasNext()) {
380: CmsSite site = (CmsSite) i.next();
381: values.add(site.getSiteRoot());
382: options.add(site.getTitle());
383: if (site.getSiteRoot().equals(getSettings().getSite())) {
384: // this is the user's current site
385: selectedIndex = pos;
386: }
387: pos++;
388: }
389:
390: return buildSelect(htmlAttributes, options, values,
391: selectedIndex);
392: }
393:
394: /**
395: * Returns the startup URI for display in the main body frame, this can
396: * either be the user default view, or (if set) a specific startup resource.<p>
397: *
398: * @return the startup URI for display in the main body frame
399: */
400: public String getStartupUri() {
401:
402: String result = getSettings().getViewStartup();
403: if (result == null) {
404: // no specific startup URI is set, use view from user settings
405: result = getSettings().getViewUri();
406: } else {
407: // reset the startup URI, so that it is not displayed again on reload of the frameset
408: getSettings().setViewStartup(null);
409: }
410: // add eventual request parameters to startup uri
411: if (getJsp().getRequest().getParameterMap().size() > 0) {
412: Set params = getJsp().getRequest().getParameterMap()
413: .entrySet();
414: Iterator i = params.iterator();
415: while (i.hasNext()) {
416: Map.Entry entry = (Map.Entry) i.next();
417: result = CmsRequestUtil.appendParameter(result,
418: (String) entry.getKey(), ((String[]) entry
419: .getValue())[0]);
420: }
421: }
422: // append the frame name to the startup uri
423: return CmsRequestUtil.appendParameter(result,
424: CmsFrameset.PARAM_WP_FRAME, FRAMES[2]);
425: }
426:
427: /**
428: * Returns a html select box filled with the views accessible by the current user.<p>
429: *
430: * @param htmlAttributes attributes that will be inserted into the generated html
431: * @return a html select box filled with the views accessible by the current user
432: */
433: public String getViewSelect(String htmlAttributes) {
434:
435: List options = new ArrayList();
436: List values = new ArrayList();
437: int selectedIndex = 0;
438:
439: // loop through the vectors and fill the result vectors
440: Iterator i = OpenCms.getWorkplaceManager().getViews()
441: .iterator();
442: int count = -1;
443: String currentView = getSettings().getViewUri();
444: if (CmsStringUtil.isNotEmpty(currentView)) {
445: // remove possible parameters from current view
446: int pos = currentView.indexOf('?');
447: if (pos >= 0) {
448: currentView = currentView.substring(0, pos);
449: }
450: }
451: while (i.hasNext()) {
452: CmsWorkplaceView view = (CmsWorkplaceView) i.next();
453: if (getCms().existsResource(view.getUri(),
454: CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) {
455: count++;
456: // ensure the current user has +v+r permissions on the view
457: String loopLink = getJsp().link(view.getUri());
458: String localizedKey = resolveMacros(view.getKey());
459: options.add(localizedKey);
460: values.add(loopLink);
461:
462: if (loopLink.equals(currentView)) {
463: selectedIndex = count;
464: }
465: }
466: }
467:
468: return buildSelect(htmlAttributes, options, values,
469: selectedIndex);
470: }
471:
472: /**
473: * Returns the reload URI for the OpenCms workplace.<p>
474: *
475: * @return the reload URI for the OpenCms workplace
476: */
477: public String getWorkplaceReloadUri() {
478:
479: return getJsp().link(CmsFrameset.JSP_WORKPLACE_URI);
480: }
481:
482: /**
483: * Returns <code>true</code> if a reload of the main body frame is required.<p>
484: *
485: * This value is modified with the select options (project, site or view) in the head frame of
486: * the Workplace. If a user changes one of these select values, the head frame is posted
487: * "against itself". The posted values will be processed by this class, causing
488: * the internal Workplace settings to change. After these settings have been changed,
489: * a reload of the main body frame is required in order to update it with the new values.
490: * A JavaScript in the Workplace head frame will be executed in this case.<p>
491: *
492: * @return <code>true</code> if a reload of the main body frame is required
493: */
494: public boolean isReloadRequired() {
495:
496: return m_reloadRequired;
497: }
498:
499: /**
500: * Returns true if the user has enabled synchronization.<p>
501: *
502: * @return true if the user has enabled synchronization
503: */
504: public boolean isSyncEnabled() {
505:
506: CmsSynchronizeSettings syncSettings = getSettings()
507: .getUserSettings().getSynchronizeSettings();
508: return (syncSettings != null) && syncSettings.isSyncEnabled();
509: }
510:
511: /**
512: * Indicates if the site selector should be shown in the top frame depending on the count of accessible sites.<p>
513: *
514: * @return true if site selector should be shown, otherwise false
515: */
516: public boolean showSiteSelector() {
517:
518: if (getSettings().getUserSettings().getRestrictExplorerView()) {
519: // restricted explorer view to site and folder, do not show site selector
520: return false;
521: }
522: // count available sites
523: int siteCount = OpenCms.getSiteManager().getAvailableSites(
524: getCms(), true).size();
525: return (siteCount > 1);
526: }
527:
528: /**
529: * @see org.opencms.workplace.CmsWorkplace#initTimeWarp(org.opencms.db.CmsUserSettings, javax.servlet.http.HttpSession)
530: */
531: protected void initTimeWarp(CmsUserSettings settings,
532: HttpSession session) {
533:
534: // overriden to avoid deletion of the configured time warp:
535: // this is triggered by editors and in auto time warping a direct edit
536: // must not delete a potential auto warped request time
537: }
538:
539: /**
540: * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
541: */
542: protected void initWorkplaceRequestValues(
543: CmsWorkplaceSettings settings, HttpServletRequest request) {
544:
545: // check if a startup page has been set
546: String frame = CmsRequestUtil.getNotEmptyDecodedParameter(
547: request, CmsFrameset.PARAM_WP_FRAME);
548: if ((frame == null) || (FRAMES_LIST.indexOf(frame) < 0)) {
549: // illegal or no frame selected, assume the "top" frame
550: frame = FRAMES[0];
551: }
552:
553: if (FRAMES[0].equals(frame)) {
554: // top frame requested - execute special reload actions
555: topFrameReload(settings);
556: }
557:
558: // check if a startup page has been set
559: String startup = CmsRequestUtil.getNotEmptyDecodedParameter(
560: request, CmsFrameset.PARAM_WP_START);
561: if (startup != null) {
562: m_reloadRequired = true;
563: settings.setViewStartup(startup);
564: }
565:
566: // check if the user requested a view change
567: String view = request.getParameter(CmsFrameset.PARAM_WP_VIEW);
568: if (view != null) {
569: m_reloadRequired = true;
570: settings.setViewUri(view);
571: settings.getFrameUris().put("body", view);
572: }
573:
574: m_reloadRequired = initSettings(settings, request)
575: || m_reloadRequired;
576: }
577:
578: /**
579: * Performs certain clear cache actions if the top frame is reloaded.<p>
580: *
581: * @param settings the current users workplace settings
582: */
583: protected void topFrameReload(CmsWorkplaceSettings settings) {
584:
585: // ensure to read the settings from the database
586: initUserSettings(getCms(), settings, true);
587:
588: // reset the HTML list in order to force a full reload
589: settings.setListObject(null);
590: }
591: }
|