001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.ui.apps; 029 030import org.opencms.main.CmsLog; 031import org.opencms.ui.A_CmsUI; 032import org.opencms.ui.CmsVaadinUtils; 033import org.opencms.ui.I_CmsAppView; 034import org.opencms.ui.Messages; 035import org.opencms.ui.apps.CmsWorkplaceAppManager.NavigationState; 036import org.opencms.ui.components.CmsAppViewLayout; 037import org.opencms.ui.components.I_CmsWindowCloseListener; 038import org.opencms.ui.components.OpenCmsTheme; 039 040import java.util.HashMap; 041import java.util.HashSet; 042import java.util.Map; 043import java.util.Set; 044 045import org.apache.commons.logging.Log; 046 047import com.vaadin.event.Action; 048import com.vaadin.event.Action.Handler; 049import com.vaadin.event.ShortcutAction; 050import com.vaadin.navigator.ViewChangeListener; 051import com.vaadin.server.Page.BrowserWindowResizeEvent; 052import com.vaadin.server.Page.BrowserWindowResizeListener; 053import com.vaadin.ui.Label; 054import com.vaadin.ui.UI; 055import com.vaadin.ui.VerticalLayout; 056import com.vaadin.ui.themes.ValoTheme; 057 058/** 059 * Displays the selected app.<p> 060 */ 061public class CmsAppView 062implements ViewChangeListener, I_CmsWindowCloseListener, I_CmsAppView, Handler, BrowserWindowResizeListener { 063 064 /** 065 * Enum representing caching status of a view.<p> 066 */ 067 public static enum CacheStatus { 068 /** Cache view. */ 069 cache, 070 071 /** Cache view one time only. */ 072 cacheOnce, 073 074 /** Don't cache view. */ 075 noCache 076 } 077 078 /** 079 * Used in case the requested app can not be displayed to the current user.<p> 080 */ 081 protected class NotAvailableApp implements I_CmsWorkplaceApp { 082 083 /** 084 * @see org.opencms.ui.apps.I_CmsWorkplaceApp#initUI(org.opencms.ui.apps.I_CmsAppUIContext) 085 */ 086 public void initUI(I_CmsAppUIContext context) { 087 088 Label label = new Label(CmsVaadinUtils.getMessageText(Messages.GUI_APP_NOT_AVAILABLE_0)); 089 label.addStyleName(ValoTheme.LABEL_H2); 090 label.addStyleName(OpenCmsTheme.LABEL_ERROR); 091 VerticalLayout content = new VerticalLayout(); 092 content.setMargin(true); 093 content.addComponent(label); 094 context.setAppContent(content); 095 } 096 097 /** 098 * @see org.opencms.ui.apps.I_CmsWorkplaceApp#onStateChange(java.lang.String) 099 */ 100 public void onStateChange(String state) { 101 102 // nothing to do 103 } 104 105 } 106 107 /** The history back action. */ 108 private static final Action ACTION_HISTORY_BACK = new ShortcutAction( 109 "Alt+ArrowLeft", 110 ShortcutAction.KeyCode.ARROW_LEFT, 111 new int[] {ShortcutAction.ModifierKey.ALT}); 112 113 /** The history forward action. */ 114 private static final Action ACTION_HISTORY_FORWARD = new ShortcutAction( 115 "Alt+ArrowRight", 116 ShortcutAction.KeyCode.ARROW_RIGHT, 117 new int[] {ShortcutAction.ModifierKey.ALT}); 118 119 /** The serial version id. */ 120 private static final long serialVersionUID = -8128528863875050216L; 121 122 /** Logger instance for this class. */ 123 private static final Log LOG = CmsLog.getLog(CmsAppView.class); 124 125 /** The current app. */ 126 private I_CmsWorkplaceApp m_app; 127 128 /** The app shortcut actions. */ 129 private Map<Action, Runnable> m_appActions; 130 131 /** The app configuration. */ 132 private I_CmsWorkplaceAppConfiguration m_appConfig; 133 134 /** The app layout component. */ 135 private CmsAppViewLayout m_appLayout; 136 137 /** The cache status. */ 138 private CacheStatus m_cacheStatus = CacheStatus.noCache; 139 140 /** The default shortcut actions. */ 141 private Map<Action, Runnable> m_defaultActions; 142 143 /** The requires restore from cache flag. */ 144 private boolean m_requiresRestore; 145 146 /** 147 * Constructor.<p> 148 * 149 * @param appConfig the app configuration 150 */ 151 public CmsAppView(I_CmsWorkplaceAppConfiguration appConfig) { 152 153 m_appConfig = appConfig; 154 m_defaultActions = new HashMap<Action, Runnable>(); 155 m_defaultActions.put(ACTION_HISTORY_BACK, new Runnable() { 156 157 public void run() { 158 159 ((CmsAppWorkplaceUi)UI.getCurrent()).historyBack(); 160 } 161 }); 162 m_defaultActions.put(ACTION_HISTORY_FORWARD, new Runnable() { 163 164 public void run() { 165 166 ((CmsAppWorkplaceUi)UI.getCurrent()).historyForward(); 167 } 168 }); 169 } 170 171 /** 172 * @see com.vaadin.navigator.ViewChangeListener#afterViewChange(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) 173 */ 174 public void afterViewChange(ViewChangeEvent event) { 175 176 if (m_app instanceof ViewChangeListener) { 177 ((ViewChangeListener)m_app).afterViewChange(event); 178 } 179 } 180 181 /** 182 * @see com.vaadin.navigator.ViewChangeListener#beforeViewChange(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) 183 */ 184 public boolean beforeViewChange(ViewChangeEvent event) { 185 186 disableGlobalShortcuts(); 187 if (m_appLayout != null) { 188 m_appLayout.closePopupViews(); 189 } 190 if (m_app instanceof ViewChangeListener) { 191 return ((ViewChangeListener)m_app).beforeViewChange(event); 192 } 193 return true; 194 } 195 196 /** 197 * @see com.vaadin.server.Page.BrowserWindowResizeListener#browserWindowResized(com.vaadin.server.Page.BrowserWindowResizeEvent) 198 */ 199 public void browserWindowResized(BrowserWindowResizeEvent event) { 200 201 if (m_appLayout != null) { 202 m_appLayout.browserWindowResized(event); 203 } 204 } 205 206 /** 207 * @see org.opencms.ui.I_CmsAppView#disableGlobalShortcuts() 208 */ 209 public void disableGlobalShortcuts() { 210 211 UI.getCurrent().removeActionHandler(this); 212 } 213 214 /** 215 * @see org.opencms.ui.I_CmsAppView#enableGlobalShortcuts() 216 */ 217 public void enableGlobalShortcuts() { 218 219 // to avoid multiple action handler registration, remove this first 220 UI.getCurrent().removeActionHandler(this); 221 UI.getCurrent().addActionHandler(this); 222 } 223 224 /** 225 * @see org.opencms.ui.I_CmsAppView#enter(java.lang.String) 226 */ 227 public void enter(String newState) { 228 229 if (newState.startsWith(NavigationState.PARAM_SEPARATOR)) { 230 newState = newState.substring(1); 231 } 232 if ((m_appLayout != null) && (m_appConfig != null)) { 233 m_appLayout.setAppTitle(m_appConfig.getName(UI.getCurrent().getLocale())); 234 } 235 m_app.onStateChange(newState); 236 if (m_app instanceof I_CmsHasShortcutActions) { 237 m_appActions = ((I_CmsHasShortcutActions)m_app).getShortcutActions(); 238 } 239 UI.getCurrent().addActionHandler(this); 240 } 241 242 /** 243 * @see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) 244 */ 245 public void enter(ViewChangeEvent event) { 246 247 String newState = event.getParameters(); 248 enter(newState); 249 } 250 251 /** 252 * @see com.vaadin.event.Action.Handler#getActions(java.lang.Object, java.lang.Object) 253 */ 254 public Action[] getActions(Object target, Object sender) { 255 256 if (m_appActions != null) { 257 Set<Action> actions = new HashSet<Action>(m_defaultActions.keySet()); 258 actions.addAll(m_appActions.keySet()); 259 return actions.toArray(new Action[actions.size()]); 260 } 261 return m_defaultActions.keySet().toArray(new Action[m_defaultActions.size()]); 262 } 263 264 /** 265 * Gets the cache status of the view.<p> 266 * 267 * @return the cache status of the view 268 */ 269 public CacheStatus getCacheStatus() { 270 271 return m_cacheStatus; 272 } 273 274 /** 275 * @see org.opencms.ui.I_CmsAppView#getComponent() 276 */ 277 public CmsAppViewLayout getComponent() { 278 279 if (m_app == null) { 280 return reinitComponent(); 281 } 282 return m_appLayout; 283 } 284 285 /** 286 * @see org.opencms.ui.I_CmsAppView#getName() 287 */ 288 public String getName() { 289 290 return m_appConfig.getId(); 291 } 292 293 /** 294 * @see com.vaadin.event.Action.Handler#handleAction(com.vaadin.event.Action, java.lang.Object, java.lang.Object) 295 */ 296 public void handleAction(Action action, Object sender, Object target) { 297 298 if ((m_appActions != null) && m_appActions.containsKey(action)) { 299 m_appActions.get(action).run(); 300 } else if (m_defaultActions.containsKey(action)) { 301 m_defaultActions.get(action).run(); 302 } 303 } 304 305 /** 306 * @see org.opencms.ui.I_CmsAppView#isCachable() 307 */ 308 public boolean isCachable() { 309 310 return (m_app instanceof I_CmsCachableApp) && ((I_CmsCachableApp)m_app).isCachable(); 311 } 312 313 /** 314 * @see org.opencms.ui.components.I_CmsWindowCloseListener#onWindowClose() 315 */ 316 public void onWindowClose() { 317 318 if (m_app instanceof I_CmsWindowCloseListener) { 319 ((I_CmsWindowCloseListener)m_app).onWindowClose(); 320 } 321 disableGlobalShortcuts(); 322 } 323 324 /** 325 * @see org.opencms.ui.I_CmsAppView#reinitComponent() 326 */ 327 public CmsAppViewLayout reinitComponent() { 328 329 if (m_app != null) { 330 beforeViewChange( 331 new ViewChangeEvent(CmsAppWorkplaceUi.get().getNavigator(), this, this, m_appConfig.getId(), "")); 332 } 333 if (!m_appConfig.getVisibility(A_CmsUI.getCmsObject()).isActive()) { 334 m_app = new NotAvailableApp(); 335 } else { 336 m_app = m_appConfig.getAppInstance(); 337 } 338 m_appLayout = new CmsAppViewLayout(m_appConfig.getId()); 339 m_appLayout.setAppTitle(m_appConfig.getName(UI.getCurrent().getLocale())); 340 m_app.initUI(m_appLayout); 341 return m_appLayout; 342 } 343 344 /** 345 * @see org.opencms.ui.I_CmsAppView#requiresRestore() 346 */ 347 public boolean requiresRestore() { 348 349 return m_requiresRestore; 350 } 351 352 /** 353 * Restores the view from cache.<p> 354 */ 355 public void restoreFromCache() { 356 357 ((I_CmsCachableApp)m_app).onRestoreFromCache(); 358 m_requiresRestore = false; 359 } 360 361 /** 362 * Sets the cache status. 363 * 364 * @param status the new cache status 365 */ 366 public void setCacheStatus(CacheStatus status) { 367 368 m_cacheStatus = status; 369 } 370 371 /** 372 * @see org.opencms.ui.I_CmsAppView#setRequiresRestore(boolean) 373 */ 374 public void setRequiresRestore(boolean restored) { 375 376 m_requiresRestore = restored; 377 } 378 379 /** 380 * @see java.lang.Object#toString() 381 */ 382 @Override 383 public String toString() { 384 385 return "appView " + getName() + System.identityHashCode(this) + " (" + m_app + ")"; 386 } 387 388}