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