001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package org.apache.myfaces.tobago.application; 021 022 import org.apache.commons.logging.Log; 023 import org.apache.commons.logging.LogFactory; 024 import org.apache.myfaces.tobago.component.ComponentUtil; 025 import org.apache.myfaces.tobago.context.ClientProperties; 026 import org.apache.myfaces.tobago.util.RequestUtils; 027 028 import javax.faces.FacesException; 029 import javax.faces.application.ViewHandler; 030 import javax.faces.component.UIViewRoot; 031 import javax.faces.context.FacesContext; 032 import java.io.IOException; 033 import java.util.Locale; 034 035 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_CLIENT_PROPERTIES; 036 037 public class ViewHandlerImpl extends ViewHandler { 038 039 private static final Log LOG = LogFactory.getLog(ViewHandlerImpl.class); 040 041 public static final String PAGE_ID = "tobago::page-id"; 042 043 private ViewHandler base; 044 045 public ViewHandlerImpl(ViewHandler base) { 046 if (LOG.isInfoEnabled()) { 047 LOG.info("Hiding RI base implementation: " + base); 048 } 049 this.base = base; 050 } 051 052 public Locale calculateLocale(FacesContext facesContext) { 053 return base.calculateLocale(facesContext); 054 } 055 056 public String calculateRenderKitId(FacesContext facesContext) { 057 return base.calculateRenderKitId(facesContext); 058 } 059 060 public UIViewRoot createView(FacesContext facesContext, String viewId) { 061 if (LOG.isDebugEnabled()) { 062 LOG.debug("creating new view with viewId: '" + viewId + "'"); 063 } 064 UIViewRoot viewRoot = base.createView(facesContext, viewId); 065 // ensure tobago UIViewRoot RI don't create the component via application 066 if (!(viewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot)) { 067 UIViewRoot tobagoViewRoot = (UIViewRoot) 068 facesContext.getApplication().createComponent(UIViewRoot.COMPONENT_TYPE); 069 if (!(tobagoViewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot)) { 070 LOG.warn("Application creating wrong UIViewRoot, forcing Tobago"); 071 tobagoViewRoot = new org.apache.myfaces.tobago.component.UIViewRoot(); 072 } 073 tobagoViewRoot.setLocale(viewRoot.getLocale()); 074 tobagoViewRoot.setViewId(viewId); 075 tobagoViewRoot.setRenderKitId(viewRoot.getRenderKitId()); 076 viewRoot = tobagoViewRoot; 077 } 078 ensureClientProperties(facesContext, viewRoot); 079 080 return viewRoot; 081 } 082 083 private void ensureClientProperties(FacesContext facesContext, 084 UIViewRoot viewRoot) { 085 if (viewRoot != null) { 086 ClientProperties clientProperties 087 = ClientProperties.getInstance(facesContext); 088 viewRoot.getAttributes().put(ATTR_CLIENT_PROPERTIES, clientProperties); 089 } 090 } 091 092 public String getActionURL(FacesContext facesContext, String viewId) { 093 return base.getActionURL(facesContext, viewId); 094 } 095 096 public String getResourceURL(FacesContext facesContext, String path) { 097 return base.getResourceURL(facesContext, path); 098 } 099 100 public void renderView(FacesContext facesContext, UIViewRoot viewRoot) 101 throws IOException, FacesException { 102 // standard 103 if (LOG.isDebugEnabled()) { 104 LOG.debug("renderView - view id '" 105 + (viewRoot != null ? viewRoot.getViewId() : "N/A") 106 + "'; view root: '" + viewRoot + "'"); 107 } 108 base.renderView(facesContext, viewRoot); 109 110 if (LOG.isDebugEnabled()) { 111 LOG.debug("VIEW"); 112 LOG.debug(ComponentUtil.toString(facesContext.getViewRoot(), 0)); 113 } 114 } 115 116 public UIViewRoot restoreView(FacesContext facesContext, String viewId) { 117 if (LOG.isDebugEnabled()) { 118 LOG.debug("restore view with viewId: '" + viewId + "'"); 119 } 120 // this is only needed in the first request, the later will be handled by faces 121 // TODO: maybe find a way to make this unneeded 122 RequestUtils.ensureEncoding(facesContext); 123 UIViewRoot viewRoot = base.restoreView(facesContext, viewId); 124 ensureClientProperties(facesContext, viewRoot); 125 return viewRoot; 126 } 127 128 public void writeState(FacesContext facesContext) throws IOException { 129 base.writeState(facesContext); 130 } 131 132 } 133