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.util;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.myfaces.tobago.component.Attributes;
24  import org.apache.myfaces.tobago.component.Facets;
25  import org.apache.myfaces.tobago.component.UIPopup;
26  import org.apache.myfaces.tobago.event.PopupFacetActionListener;
27  import org.apache.myfaces.tobago.internal.component.AbstractUICommandBase;
28  import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
29  import org.apache.myfaces.tobago.util.ComponentUtils;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  import javax.faces.component.UIComponent;
34  import javax.faces.component.ValueHolder;
35  import javax.faces.context.FacesContext;
36  import java.util.Arrays;
37  
38  public class CommandRendererHelper {
39  
40    private static final Logger LOG = LoggerFactory.getLogger(CommandRendererHelper.class);
41  
42    private String onclick;
43    private boolean disabled;
44    private String href;
45    private String target;
46  
47    public CommandRendererHelper(FacesContext facesContext, AbstractUICommandBase command) {
48      this(facesContext, command, null);
49    }
50  
51    public CommandRendererHelper(FacesContext facesContext, AbstractUICommandBase command, Tag tag) {
52  
53      disabled = ComponentUtils.getBooleanAttribute(command, Attributes.DISABLED);
54  
55      if (disabled) {
56        onclick = "";
57        href = "";
58      } else {
59        href = "#"; // this is to make the link "active", needed for focus, cursor, etc.
60        UIPopup popup = (UIPopup) command.getFacet(Facets.POPUP);
61        if (popup != null) {
62          if (!ComponentUtils.containsPopupActionListener(command)) {
63            command.addActionListener(new PopupFacetActionListener());
64          }
65        }
66  
67        boolean transition = ComponentUtils.getBooleanAttribute(command, Attributes.TRANSITION);
68  
69        if (StringUtils.isNotEmpty(command.getLink()) || StringUtils.isNotEmpty(command.getResource())) {
70          String url = RenderUtils.generateUrl(facesContext, command);
71          if (tag == Tag.ANCHOR) {
72            onclick = null;
73            href = url;
74            target = command.getTarget();
75          } else {
76            // TODO target
77            onclick = "Tobago.navigateToUrl('" + url + "');";
78          }
79        } else if (StringUtils.isNotEmpty(command.getOnclick())) {
80          onclick = prepareOnClick(facesContext, command);
81        } else if (command.getRenderedPartially().length > 0) {
82          String clientId = command.getClientId(facesContext);
83          String[] componentIds = command.getRenderedPartially();
84  
85          // TODO find a better way
86          boolean popupAction = ComponentUtils.containsPopupActionListener(command);
87          if (popupAction) {
88            if (componentIds.length != 1) {
89              LOG.warn("more than one partially rendered component is not supported for popup! using first one: "
90                  + Arrays.toString(componentIds));
91            }
92            onclick = "Tobago.Popup.openWithAction(this, '"
93                + HtmlRendererUtils.getComponentId(facesContext, command, componentIds[0]) + "', '" + clientId + "');";
94          } else {
95            onclick = "Tobago.reloadComponent(this, '"
96                + HtmlRendererUtils.getComponentIds(facesContext, command, componentIds) + "','" + clientId + "', {});";
97          }
98  
99        } else {
100         String clientId = command.getClientId(facesContext);
101         String target = ComponentUtils.getStringAttribute(command, Attributes.TARGET);
102         onclick = HtmlRendererUtils.createSubmitAction(clientId, transition, target, null);
103       }
104 
105       if (command.getAttributes().get(Attributes.POPUP_CLOSE) != null
106           && ComponentUtils.isInPopup(command)) {
107         String value = (String) command.getAttributes().get(Attributes.POPUP_CLOSE);
108         if (value.equals("immediate")) {
109           onclick = "Tobago.Popup.close(this);";
110         } else if (value.equals("afterSubmit")
111             && command instanceof org.apache.myfaces.tobago.component.UICommand
112             && ((org.apache.myfaces.tobago.component.UICommand) command).getRenderedPartially().length > 0) {
113           onclick = "Tobago.Popup.unlockBehind();" + onclick + "Tobago.Popup.close(this);";
114         }
115 
116       }
117       onclick = appendConfirmationScript(onclick, command);
118     }
119   }
120 
121   private String prepareOnClick(FacesContext facesContext, AbstractUICommandBase component) {
122     String onclick = component.getOnclick();
123     if (onclick.contains("@autoId")) {
124       onclick = StringUtils.replace(onclick, "@autoId", component.getClientId(facesContext));
125     }
126     return onclick;
127   }
128 
129   private String appendConfirmationScript(String onclick, UIComponent component) {
130     ValueHolder confirmation = (ValueHolder) component.getFacet(Facets.CONFIRMATION);
131     if (confirmation != null) {
132       StringBuilder script = new StringBuilder("return confirm('");
133       script.append(confirmation.getValue());
134       script.append("')");
135       if (onclick != null) {
136         script.append(" && ");
137         script.append(onclick);
138       }
139       onclick = script.toString();
140     }
141     return onclick;
142   }
143 
144   public String getOnclick() {
145     return onclick;
146   }
147 
148   public boolean isDisabled() {
149     return disabled;
150   }
151 
152   public String getHref() {
153     return href;
154   }
155 
156   public String getTarget() {
157     return target;
158   }
159 
160   public static enum Tag {
161     ANCHOR, BUTTON
162   }
163 }