View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21  
22  import org.apache.myfaces.tobago.component.Facets;
23  import org.apache.myfaces.tobago.config.Configurable;
24  import org.apache.myfaces.tobago.context.ResourceManagerUtils;
25  import org.apache.myfaces.tobago.internal.component.AbstractUILink;
26  import org.apache.myfaces.tobago.internal.util.AccessKeyMap;
27  import org.apache.myfaces.tobago.layout.Measure;
28  import org.apache.myfaces.tobago.renderkit.CommandRendererBase;
29  import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
30  import org.apache.myfaces.tobago.renderkit.css.Classes;
31  import org.apache.myfaces.tobago.renderkit.css.Style;
32  import org.apache.myfaces.tobago.renderkit.html.Command;
33  import org.apache.myfaces.tobago.renderkit.html.CommandMap;
34  import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
35  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
36  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
37  import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
38  import org.apache.myfaces.tobago.renderkit.html.Popup;
39  import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
40  import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
41  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  import javax.faces.component.UIComponent;
46  import javax.faces.component.ValueHolder;
47  import javax.faces.context.FacesContext;
48  import javax.faces.context.ResponseWriter;
49  import java.io.IOException;
50  
51  public class LinkRenderer extends CommandRendererBase {
52  
53    private static final Logger LOG = LoggerFactory.getLogger(LinkRenderer.class);
54  
55    public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
56  
57      final AbstractUILink link = (AbstractUILink) component;
58      final String clientId = link.getClientId(facesContext);
59      final boolean disabled = link.isDisabled();
60  // final CommandRendererHelper helper = new CommandRendererHelper(facesContext, link, CommandRendererHelper.Tag.ANCHOR);
61  // final String href = helper.getHref();
62  
63      final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
64  
65      LabelWithAccessKey label = new LabelWithAccessKey(link);
66  
67      if (disabled) {
68        writer.startElement(HtmlElements.SPAN, link);
69      } else {
70        writer.startElement(HtmlElements.A, link);
71  //      writer.writeAttribute(HtmlAttributes.HREF, href, true); XXX
72  
73        final ValueHolder confirmationFacet = (ValueHolder) component.getFacet(Facets.CONFIRMATION);
74        final String confirmation = confirmationFacet != null ? "" + confirmationFacet.getValue() : null;
75  
76        final String url = RenderUtils.generateUrl(facesContext, link);
77        final CommandMap map = new CommandMap();
78        final String[] partialIds
79            = HtmlRendererUtils.getComponentIdsAsList(facesContext, link, link.getRenderedPartially());
80        final Popup popup = Popup.createPopup(link);
81        final Command click = new Command(
82            null, link.isTransition(), link.getTarget(), url, partialIds, null, confirmation, null, popup);
83        if (link.getOnclick() != null) {
84          click.setScript(link.getOnclick());
85        }
86        map.setClick(click);
87        writer.writeAttribute(DataAttributes.COMMANDS, JsonUtils.encode(map), true);
88  
89        writer.writeAttribute(HtmlAttributes.HREF, "#", false);
90  
91        if (label.getAccessKey() != null) {
92          writer.writeAttribute(HtmlAttributes.ACCESSKEY, Character.toString(label.getAccessKey()), false);
93        }
94  
95        final Integer tabIndex = link.getTabIndex();
96        if (tabIndex != null) {
97          writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
98        }
99      }
100     HtmlRendererUtils.writeDataAttributes(facesContext, writer, link);
101     Style style = new Style(facesContext, link);
102     writer.writeStyleAttribute(style);
103     HtmlRendererUtils.renderDojoDndItem(component, writer, true);
104     writer.writeClassAttribute(Classes.create(link));
105     writer.writeIdAttribute(clientId);
106     writer.writeNameAttribute(clientId);
107     HtmlRendererUtils.renderTip(link, writer);
108     writer.flush();
109 
110 //  image
111     String image = link.getImage();
112     if (image != null) {
113       if (ResourceManagerUtils.isAbsoluteResource(image)) {
114         // absolute Path to image : nothing to do
115       } else {
116         image = getImageWithPath(facesContext, image, disabled);
117       }
118       writer.startElement(HtmlElements.IMG, link);
119       writer.writeAttribute(HtmlAttributes.SRC, image, true);
120       writer.writeAttribute(HtmlAttributes.BORDER, 0); // TODO: is border=0 setting via style possible?
121       String tip = link.getTip();
122       writer.writeAttribute(HtmlAttributes.ALT, tip != null ? tip : "", true);
123       if (tip != null) {
124         writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
125       }
126       writer.endElement(HtmlElements.IMG);
127     }
128 
129 //  label
130     if (label.getText() != null) {
131       if (image != null) {
132         writer.write(" "); // separator: e.g.  
133       }
134       HtmlRendererUtils.writeLabelWithAccessKey(writer, label);
135     }
136 
137     if (label.getAccessKey() != null && !disabled) {
138       if (LOG.isInfoEnabled()
139           && !AccessKeyMap.addAccessKey(facesContext, label.getAccessKey())) {
140         LOG.info("duplicated accessKey : " + label.getAccessKey());
141       }
142 
143       //HtmlRendererUtils.addClickAcceleratorKey(facesContext, clientId, label.getAccessKey());
144     }
145   }
146 
147   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
148     AbstractUILink link = (AbstractUILink) component;
149     ResponseWriter writer = facesContext.getResponseWriter();
150     if (link.isDisabled()) {
151       writer.endElement(HtmlElements.SPAN);
152     } else {
153       writer.endElement(HtmlElements.A);
154     }
155   }
156 
157   @Override
158   public Measure getPreferredWidth(FacesContext facesContext, Configurable component) {
159     AbstractUILink link = (AbstractUILink) component;
160     LabelWithAccessKey label = new LabelWithAccessKey(link);
161     return RenderUtils.calculateStringWidth(facesContext, link, label.getText());
162   }
163 }