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