001/* 002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.platform.ui.web.component.document; 020 021import java.io.IOException; 022import java.net.URLEncoder; 023import java.util.logging.Level; 024 025import javax.faces.component.UIComponent; 026import javax.faces.context.FacesContext; 027import javax.faces.context.ResponseWriter; 028 029import org.apache.commons.lang.StringUtils; 030import org.nuxeo.ecm.platform.ui.web.rest.RestHelper; 031import org.nuxeo.ecm.platform.ui.web.tag.fn.Functions; 032 033import com.sun.faces.renderkit.Attribute; 034import com.sun.faces.renderkit.AttributeManager; 035import com.sun.faces.renderkit.RenderKitUtils; 036import com.sun.faces.renderkit.html_basic.OutputLinkRenderer; 037 038/** 039 * Overrides default output link renderer so that URL parameters passed through f:param tags are not added twice, since 040 * the component already takes them into account when building the URL. 041 * 042 * @see RestDocumentLink 043 * @since 5.4.2 044 */ 045public class RestDocumentLinkRenderer extends OutputLinkRenderer { 046 047 /** 048 * Returns an empty parameters list because parameters are already taken care of in the computed URL. 049 */ 050 @Override 051 protected Param[] getParamList(UIComponent command) { 052 return new Param[0]; 053 } 054 055 private static final Attribute[] PASSTHROUGHATTRIBUTES = AttributeManager.getAttributes(AttributeManager.Key.OUTPUTLINK); 056 057 @Override 058 protected void renderAsActive(FacesContext context, UIComponent component) throws IOException { 059 060 String hrefVal = getCurrentValue(context, component); 061 062 if (logger.isLoggable(Level.FINE)) { 063 logger.fine("Value to be rendered " + hrefVal); 064 } 065 066 // suppress rendering if "rendered" property on the output is 067 // false 068 if (!component.isRendered()) { 069 if (logger.isLoggable(Level.FINE)) { 070 logger.fine("End encoding component " + component.getId() + " since " 071 + "rendered attribute is set to false "); 072 } 073 return; 074 } 075 ResponseWriter writer = context.getResponseWriter(); 076 assert (writer != null); 077 writer.startElement("a", component); 078 String writtenId = writeIdAttributeIfNecessary(context, writer, component); 079 if (null != writtenId) { 080 writer.writeAttribute("name", writtenId, "name"); 081 } 082 // render an empty value for href if it is not specified 083 if (null == hrefVal || 0 == hrefVal.length()) { 084 hrefVal = ""; 085 } 086 087 // Write Anchor attributes 088 Param paramList[] = getParamList(component); 089 StringBuffer sb = new StringBuffer(); 090 sb.append(hrefVal); 091 boolean paramWritten = false; 092 for (int i = 0, len = paramList.length; i < len; i++) { 093 String pn = paramList[i].name; 094 if (pn != null && pn.length() != 0) { 095 String pv = paramList[i].value; 096 sb.append((paramWritten) ? '&' : '?'); 097 sb.append(URLEncoder.encode(pn, "UTF-8")); 098 sb.append('='); 099 if (pv != null && pv.length() != 0) { 100 sb.append(URLEncoder.encode(pv, "UTF-8")); 101 } 102 paramWritten = true; 103 } 104 } 105 106 String url; 107 Boolean isNewConversation = ((RestDocumentLink) component).getNewConversation(); 108 if (!Boolean.TRUE.equals(isNewConversation) && !StringUtils.isBlank(sb.toString())) { 109 url = sb.toString(); 110 String urlNewConversation = RestHelper.addCurrentConversationParameters(sb.toString()); 111 url += getFragment(component); 112 urlNewConversation += getFragment(component); 113 url = context.getExternalContext().encodeResourceURL(url); 114 urlNewConversation = context.getExternalContext().encodeResourceURL(urlNewConversation); 115 String onclickJS = "if(!(event.ctrlKey||event.shiftKey||event.metaKey||event.button==1)){this.href='" 116 + Functions.javaScriptEscape(urlNewConversation) + "'}"; 117 writer.writeAttribute("onclick", onclickJS, "onclick"); 118 } else { 119 sb.append(getFragment(component)); 120 url = context.getExternalContext().encodeResourceURL(sb.toString()); 121 } 122 123 writer.writeURIAttribute("href", url, "href"); 124 125 RenderKitUtils.renderPassThruAttributes(context, writer, component, PASSTHROUGHATTRIBUTES); 126 RenderKitUtils.renderXHTMLStyleBooleanAttributes(writer, component); 127 128 String target = (String) component.getAttributes().get("target"); 129 if (target != null && target.trim().length() != 0) { 130 writer.writeAttribute("target", target, "target"); 131 } 132 133 writeCommonLinkAttributes(writer, component); 134 135 writer.flush(); 136 } 137}