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