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.commons.lang.StringUtils;
23  import org.apache.myfaces.tobago.component.UITreeNode;
24  import org.apache.myfaces.tobago.context.Markup;
25  import org.apache.myfaces.tobago.event.TreeExpansionEvent;
26  import org.apache.myfaces.tobago.event.TreeMarkedEvent;
27  import org.apache.myfaces.tobago.internal.component.AbstractUITree;
28  import org.apache.myfaces.tobago.model.Selectable;
29  import org.apache.myfaces.tobago.renderkit.CommandRendererBase;
30  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
31  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
32  import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
33  import org.apache.myfaces.tobago.util.ComponentUtils;
34  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  import javax.faces.component.NamingContainer;
39  import javax.faces.component.UIComponent;
40  import javax.faces.context.FacesContext;
41  import java.io.IOException;
42  import java.util.Map;
43  
44  public class TreeListboxNodeRenderer extends CommandRendererBase {
45  
46    private static final Logger LOG = LoggerFactory.getLogger(TreeListboxNodeRenderer.class);
47  
48    // TODO cleanup: there might be some stuff to remove after tree refactoring
49  
50    @Override
51    public void decode(FacesContext facesContext, UIComponent component) {
52  
53      UITreeNode node = (UITreeNode) component;
54  
55      super.decode(facesContext, node);
56  
57      if (ComponentUtils.isOutputOnly(node)) {
58        return;
59      }
60  
61      final AbstractUITree tree = ComponentUtils.findAncestor(node, AbstractUITree.class);
62      final String treeId = tree.getClientId(facesContext);
63      final String nodeStateId = node.nodeStateId(facesContext);
64      final Map<String, String> requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
65      final String id = node.getClientId(facesContext);
66      final boolean folder = node.isFolder();
67  
68      // expand state
69      if (folder) {
70        boolean expanded = Boolean.parseBoolean((String) requestParameterMap.get(id + "-expanded"));
71        if (node.isExpanded() != expanded) {
72          new TreeExpansionEvent(node, node.isExpanded(), expanded).queue();
73        }
74      }
75  
76      // select
77      if (tree.getSelectableAsEnum() != Selectable.NONE) { // selection
78        String selected = (String) requestParameterMap.get(treeId + AbstractUITree.SELECT_STATE);
79        String searchString = ";" + nodeStateId + ";";
80        if (StringUtils.contains(selected, searchString)) {
81          // TODO: add selection to Component
82          //state.addSelection((DefaultMutableTreeNode) node.getValue());
83        }
84      }
85  
86      // marked
87      String marked
88          = (String) requestParameterMap.get(treeId + ComponentUtils.SUB_SEPARATOR + AbstractUITree.SUFFIX_MARKED);
89      if (marked != null) {
90        String searchString = treeId + NamingContainer.SEPARATOR_CHAR + nodeStateId;
91        boolean markedValue = marked.equals(searchString);
92        if (node.isMarked() != markedValue) {
93          new TreeMarkedEvent(node, node.isMarked(), markedValue).queue();
94        }
95      } else {
96        LOG.warn("This log message is help clarifying the occurrence of this else case.");
97      }
98    }
99  
100   @Override
101   public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
102     super.prepareRender(facesContext, component);
103 
104     final UITreeNode node = (UITreeNode) component;
105     if (node.isMarked()) {
106       node.setMarkup(Markup.MARKED.add(node.getMarkup()));
107     }
108   }
109 
110   @Override
111   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
112     final UITreeNode node = (UITreeNode) component;
113     final boolean folder = node.isFolder();
114     final String id = node.getClientId(facesContext);
115     final boolean expanded = folder && node.isExpanded();
116 
117     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
118 
119     writer.startElement(HtmlElements.OPTION, null);
120     // todo: define where to store the selection of a tree, node.getValue() seems not to be a god place.
121     //        writer.writeAttribute(HtmlAttributes.VALUE, node.getValue().toString(), true); // XXX converter?
122     writer.writeIdAttribute(id);
123     writer.writeAttribute(HtmlAttributes.SELECTED, expanded);
124   }
125 
126   @Override
127   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
128     final UITreeNode node = (UITreeNode) component;
129     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
130     final boolean folder = node.isFolder();
131 
132     if (folder) {
133       writer.writeText(" \u2192"); // this is an right arrow →
134     }
135     writer.endElement(HtmlElements.OPTION);
136   }
137 }