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.internal.component;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.component.Visual;
24  import org.apache.myfaces.tobago.model.ExpandedState;
25  import org.apache.myfaces.tobago.model.ScrollPosition;
26  import org.apache.myfaces.tobago.model.SelectedState;
27  import org.apache.myfaces.tobago.model.TreeState;
28  
29  import javax.el.ELContext;
30  import javax.el.ValueExpression;
31  import javax.faces.component.NamingContainer;
32  import javax.faces.component.UIComponent;
33  import javax.faces.context.FacesContext;
34  
35  /**
36   * {@link org.apache.myfaces.tobago.internal.taglib.component.TreeTagDeclaration}
37   */
38  public abstract class AbstractUITree extends AbstractUIData implements NamingContainer, Visual {
39  
40    public static final String SUFFIX_PARENT = "parent";
41  
42    private TreeState state;
43  
44    @Override
45    public void processValidators(final FacesContext facesContext) {
46      final int last = isRowsUnlimited() ? Integer.MAX_VALUE : getFirst() + getRows();
47      for (int rowIndex = getFirst(); rowIndex < last; rowIndex++) {
48        setRowIndex(rowIndex);
49        if (!isRowAvailable()) {
50          break;
51        }
52        for (final UIComponent child : getChildren()) {
53          child.processValidators(facesContext);
54        }
55      }
56      setRowIndex(-1);
57    }
58  
59    @Override
60    public void processUpdates(final FacesContext facesContext) {
61      final int last = isRowsUnlimited() ? Integer.MAX_VALUE : getFirst() + getRows();
62      for (int rowIndex = getFirst(); rowIndex < last; rowIndex++) {
63        setRowIndex(rowIndex);
64        if (!isRowAvailable()) {
65          break;
66        }
67        for (final UIComponent child : getChildren()) {
68          child.processUpdates(facesContext);
69        }
70      }
71      setRowIndex(-1);
72    }
73  
74    @Override
75    public boolean getRendersChildren() {
76      return true;
77    }
78  
79    @Override
80    public void processDecodes(final FacesContext facesContext) {
81  
82      if (!isRendered()) {
83        return;
84      }
85  
86      final int last = isRowsUnlimited() ? Integer.MAX_VALUE : getFirst() + getRows();
87      for (int rowIndex = getFirst(); rowIndex < last; rowIndex++) {
88        setRowIndex(rowIndex);
89        if (!isRowAvailable()) {
90          break;
91        }
92        for (final UIComponent child : getChildren()) {
93          child.processDecodes(facesContext);
94        }
95      }
96      setRowIndex(-1);
97  
98      decode(facesContext);
99    }
100 
101 /* XXX
102   @Override
103   public void validate(FacesContext context) {
104 */
105 
106   // todo: validate must be written new, without TreeState
107 /*
108     if (isRequired() && getState().getSelection().size() == 0) {
109       setValid(false);
110       FacesMessage facesMessage = MessageUtils.createFacesMessage(context,
111           UISelectOne.MESSAGE_VALUE_REQUIRED, FacesMessage.SEVERITY_ERROR);
112       context.addMessage(getClientId(context), facesMessage);
113     }
114 
115     String selectable = ComponentUtils.getStringAttribute(this, selectable);
116     if (selectable != null && selectable.endsWith("LeafOnly")) {
117 
118       Set<DefaultMutableTreeNode> selection = getState().getSelection();
119 
120       for (DefaultMutableTreeNode node : selection) {
121         if (!node.isLeaf()) {
122           FacesMessage facesMessage = MessageUtils.createFacesMessage(
123               context, MESSAGE_NOT_LEAF, FacesMessage.SEVERITY_ERROR);
124           context.addMessage(getClientId(context), facesMessage);
125           break; // don't continue iteration, no dublicate messages needed
126         }
127       }
128     }
129 */
130 //  call all validators
131 /*
132     if (getValidators() != null) {
133       for (Validator validator : getValidators()) {
134         try {
135           validator.validate(context, this, null);
136         } catch (ValidatorException ve) {
137           // If the validator throws an exception, we're
138           // invalid, and we need to add a message
139           setValid(false);
140           FacesMessage message = ve.getFacesMessage();
141           if (message != null) {
142             message.setSeverity(FacesMessage.SEVERITY_ERROR);
143             context.addMessage(getClientId(context), message);
144           }
145         }
146       }
147     }
148   }
149 
150   @Override
151   public void updateModel(FacesContext facesContext) {
152     // nothing to update for tree's
153     // TODO: updating the model here and *NOT* in the decode phase
154   }
155 */
156   public void setState(final TreeState state) {
157     this.state = state;
158   }
159 
160   public TreeState getState() {
161     if (state != null) {
162       return state;
163     }
164 
165     final ELContext elContext = FacesContext.getCurrentInstance().getELContext();
166     final ValueExpression expression = getValueExpression(Attributes.state.getName());
167 
168     if (expression != null) {
169       TreeState treeState = (TreeState) expression.getValue(elContext);
170       if (treeState == null) {
171         treeState = new TreeState(new ExpandedState(2), new SelectedState(), new ScrollPosition());
172         expression.setValue(elContext, treeState);
173       }
174       return treeState;
175     }
176 
177     state = new TreeState(new ExpandedState(2), new SelectedState(), new ScrollPosition());
178     return state;
179   }
180 
181   @Override
182   public SelectedState getSelectedState() {
183     return getState().getSelectedState();
184   }
185 
186   @Override
187   public ExpandedState getExpandedState() {
188     return getState().getExpandedState();
189   }
190 
191   @Override
192   public void restoreState(final FacesContext context, final Object componentState) {
193     final Object[] values = (Object[]) componentState;
194     super.restoreState(context, values[0]);
195     state = (TreeState) values[1];
196   }
197 
198   @Override
199   public Object saveState(final FacesContext context) {
200     final Object[] values = new Object[2];
201     values[0] = super.saveState(context);
202     values[1] = state;
203     return values;
204   }
205 }