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 static org.apache.myfaces.tobago.TobagoConstants.ATTR_CLIENT_PROPERTIES; 025 import org.apache.myfaces.tobago.component.ComponentUtil; 026 import org.apache.myfaces.tobago.context.ClientProperties; 027 import org.apache.myfaces.tobago.util.RequestUtils; 028 029 import javax.faces.FacesException; 030 import javax.faces.application.ViewHandler; 031 import javax.faces.component.UIViewRoot; 032 import javax.faces.context.FacesContext; 033 import java.io.IOException; 034 import java.util.Locale; 035 036 public class ViewHandlerImpl extends ViewHandler { 037 038 private static final Log LOG = LogFactory.getLog(ViewHandlerImpl.class); 039 040 public static final String PAGE_ID = "tobago::page-id"; 041 042 private ViewHandler base; 043 044 public ViewHandlerImpl(ViewHandler base) { 045 if (LOG.isInfoEnabled()) { 046 LOG.info("Hiding RI base implemation: " + base); 047 } 048 this.base = base; 049 } 050 051 public Locale calculateLocale(FacesContext facesContext) { 052 return base.calculateLocale(facesContext); 053 } 054 055 public String calculateRenderKitId(FacesContext facesContext) { 056 return base.calculateRenderKitId(facesContext); 057 } 058 059 public UIViewRoot createView(FacesContext facesContext, String viewId) { 060 if (LOG.isDebugEnabled()) { 061 LOG.debug("creating new view with viewId: '" + viewId + "'"); 062 } 063 UIViewRoot viewRoot = base.createView(facesContext, viewId); 064 // ensure tobago UIViewRoot RI don't create the component via application 065 if (!(viewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot)) { 066 UIViewRoot tobagoViewRoot = (UIViewRoot) 067 facesContext.getApplication().createComponent(UIViewRoot.COMPONENT_TYPE); 068 if (!(tobagoViewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot)) { 069 LOG.warn("Application creating wrong UIViewRoot, forcing Tobago"); 070 tobagoViewRoot = new org.apache.myfaces.tobago.component.UIViewRoot(); 071 } 072 tobagoViewRoot.setLocale(viewRoot.getLocale()); 073 tobagoViewRoot.setViewId(viewId); 074 tobagoViewRoot.setRenderKitId(viewRoot.getRenderKitId()); 075 viewRoot = tobagoViewRoot; 076 } 077 ensureClientProperties(facesContext, viewRoot); 078 079 return viewRoot; 080 } 081 082 private void ensureClientProperties(FacesContext facesContext, 083 UIViewRoot viewRoot) { 084 if (viewRoot != null) { 085 ClientProperties clientProperties 086 = ClientProperties.getInstance(facesContext); 087 viewRoot.getAttributes().put(ATTR_CLIENT_PROPERTIES, clientProperties); 088 } 089 } 090 091 public String getActionURL(FacesContext facesContext, String viewId) { 092 return base.getActionURL(facesContext, viewId); 093 } 094 095 public String getResourceURL(FacesContext facesContext, String path) { 096 return base.getResourceURL(facesContext, path); 097 } 098 099 public void renderView(FacesContext facesContext, UIViewRoot viewRoot) 100 throws IOException, FacesException { 101 // standard 102 if (LOG.isDebugEnabled()) { 103 LOG.debug("renderView - view id '" 104 + (viewRoot != null ? viewRoot.getViewId() : "N/A") 105 + "'; view root: '" + viewRoot + "'"); 106 } 107 base.renderView(facesContext, viewRoot); 108 109 if (LOG.isDebugEnabled()) { 110 LOG.debug("VIEW"); 111 LOG.debug(ComponentUtil.toString(facesContext.getViewRoot(), 0)); 112 } 113 } 114 115 public UIViewRoot restoreView(FacesContext facesContext, String viewId) { 116 if (LOG.isDebugEnabled()) { 117 LOG.debug("restore view with viewId: '" + viewId + "'"); 118 } 119 // this is only needed in the first request, the later will be handled by faces 120 // TODO: maybe find a way to make this unneeded 121 RequestUtils.ensureEncoding(facesContext); 122 UIViewRoot viewRoot = base.restoreView(facesContext, viewId); 123 ensureClientProperties(facesContext, viewRoot); 124 return viewRoot; 125 } 126 127 public void writeState(FacesContext facesContext) throws IOException { 128 base.writeState(facesContext); 129 } 130 131 } 132