001/** 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 015package org.nuxeo.theme.jsf.facelets; 016 017import java.io.IOException; 018import java.net.URL; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Map; 024 025import javax.el.ELException; 026import javax.el.VariableMapper; 027import javax.faces.FacesException; 028import javax.faces.component.UIComponent; 029import javax.faces.context.ExternalContext; 030import javax.faces.context.FacesContext; 031import javax.faces.view.facelets.FaceletContext; 032import javax.faces.view.facelets.FaceletException; 033import javax.faces.view.facelets.TagAttribute; 034import javax.faces.view.facelets.TagConfig; 035import javax.servlet.http.HttpServletRequest; 036 037import org.apache.commons.logging.Log; 038import org.apache.commons.logging.LogFactory; 039import org.nuxeo.ecm.platform.ui.web.util.BaseURL; 040import org.nuxeo.theme.ApplicationType; 041import org.nuxeo.theme.Manager; 042import org.nuxeo.theme.NegotiationDef; 043import org.nuxeo.theme.jsf.negotiation.JSFNegotiator; 044import org.nuxeo.theme.negotiation.NegotiationException; 045import org.nuxeo.theme.types.TypeFamily; 046 047import com.sun.faces.facelets.FaceletContextImplBase; 048import com.sun.faces.facelets.TemplateClient; 049import com.sun.faces.facelets.el.VariableMapperWrapper; 050import com.sun.faces.facelets.tag.TagHandlerImpl; 051import com.sun.faces.facelets.tag.ui.DefineHandler; 052import com.sun.faces.facelets.tag.ui.ParamHandler; 053 054/** 055 * @author Jacob Hookom 056 * @version $Id: CompositionHandler.java,v 1.15 2009/02/02 22:58:59 driscoll Exp $ 057 */ 058public final class CompositionHandler extends TagHandlerImpl implements TemplateClient { 059 060 private static final Log log = LogFactory.getLog(CompositionHandler.class); 061 062 public static final String Name = "theme"; 063 064 protected final Map<String, DefineHandler> handlers; 065 066 protected final TagAttribute strategyAttribute; 067 068 protected final ParamHandler[] params; 069 070 static { 071 Manager.initializeProtocols(); 072 } 073 074 /** 075 * @param config 076 */ 077 public CompositionHandler(TagConfig config) { 078 super(config); 079 080 handlers = new HashMap<String, DefineHandler>(); 081 Iterator<DefineHandler> itr = this.findNextByType(DefineHandler.class); 082 DefineHandler d = null; 083 while (itr.hasNext()) { 084 d = itr.next(); 085 this.handlers.put(d.getName(), d); 086 log.debug(tag + " found Define[" + d.getName() + "]"); 087 } 088 final List paramC = new ArrayList(); 089 itr = this.findNextByType(ParamHandler.class); 090 while (itr.hasNext()) { 091 paramC.add(itr.next()); 092 } 093 if (paramC.size() > 0) { 094 this.params = new ParamHandler[paramC.size()]; 095 for (int i = 0; i < this.params.length; i++) { 096 this.params[i] = (ParamHandler) paramC.get(i); 097 } 098 } else { 099 this.params = null; 100 } 101 102 strategyAttribute = getAttribute("strategy"); 103 } 104 105 /* 106 * (non-Javadoc) 107 * @see com.sun.facelets.FaceletHandler#apply(com.sun.facelets.FaceletContext, javax.faces.component.UIComponent) 108 */ 109 @Override 110 public void apply(FaceletContext ctxObj, UIComponent parent) throws IOException, FacesException, FaceletException, 111 ELException { 112 FaceletContextImplBase ctx = (FaceletContextImplBase) ctxObj; 113 114 VariableMapper orig = ctx.getVariableMapper(); 115 if (this.params != null) { 116 VariableMapper vm = new VariableMapperWrapper(orig); 117 ctx.setVariableMapper(vm); 118 for (int i = 0; i < this.params.length; i++) { 119 this.params[i].apply(ctx, parent); 120 } 121 } 122 123 ctx.extendClient(this); 124 125 try { 126 final FacesContext facesContext = ctx.getFacesContext(); 127 128 // Get the negotiation strategy 129 final ExternalContext external = facesContext.getExternalContext(); 130 final Map<String, Object> requestMap = external.getRequestMap(); 131 final String root = external.getRequestContextPath(); 132 final ApplicationType application = (ApplicationType) Manager.getTypeRegistry().lookup( 133 TypeFamily.APPLICATION, root); 134 String strategy = null; 135 if (application != null) { 136 final NegotiationDef negotiation = application.getNegotiation(); 137 if (negotiation != null) { 138 requestMap.put("org.nuxeo.theme.default.theme", negotiation.getDefaultTheme()); 139 requestMap.put("org.nuxeo.theme.default.engine", negotiation.getDefaultEngine()); 140 requestMap.put("org.nuxeo.theme.default.perspective", negotiation.getDefaultPerspective()); 141 strategy = negotiation.getStrategy(); 142 } 143 } 144 // override startegy if defined 145 if (strategyAttribute != null) { 146 strategy = strategyAttribute.getValue(ctx); 147 } 148 String contextPath = BaseURL.getContextPath(); 149 if (strategy == null) { 150 log.error("Could not obtain the negotiation strategy for " + root); 151 external.redirect(contextPath + "/nxthemes/error/negotiationStrategyNotSet.faces"); 152 153 } else { 154 try { 155 final String spec = new JSFNegotiator(strategy, facesContext, 156 (HttpServletRequest) external.getRequest()).getSpec(); 157 final URL themeUrl = new URL(spec); 158 requestMap.put("org.nuxeo.theme.url", themeUrl); 159 ctx.includeFacelet(parent, themeUrl); 160 } catch (NegotiationException e) { 161 log.error("Could not get default negotiation settings.", e); 162 external.redirect(contextPath + "/nxthemes/error/negotiationDefaultValuesNotSet.faces"); 163 } 164 } 165 166 } finally { 167 ctx.popClient(this); 168 ctx.setVariableMapper(orig); 169 } 170 171 } 172 173 @Override 174 public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException, 175 FaceletException, ELException { 176 if (name != null) { 177 if (this.handlers == null) { 178 return false; 179 } 180 DefineHandler handler = this.handlers.get(name); 181 if (handler != null) { 182 handler.applyDefinition(ctx, parent); 183 return true; 184 } else { 185 return false; 186 } 187 } else { 188 this.nextHandler.apply(ctx, parent); 189 return true; 190 } 191 } 192 193}