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