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