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.util;
21  
22  import javax.faces.component.NamingContainer;
23  import javax.faces.component.UIComponent;
24  import javax.faces.component.UINamingContainer;
25  import javax.faces.context.FacesContext;
26  
27  // Will be normally called via ComponentUtils.
28  public final class FindComponentUtils {
29  
30    private FindComponentUtils() {
31    }
32  
33    public static UIComponent findComponent(UIComponent from, String relativeId) {
34      int idLength = relativeId.length();
35      if (idLength > 0 && relativeId.charAt(0) == '@') {
36        if (relativeId.equals("@this")) {
37          return from;
38        }
39      }
40  
41      // Figure out how many colons
42      int colonCount = 0;
43      while (colonCount < idLength) {
44        if (relativeId.charAt(colonCount) != UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance())) {
45          break;
46        }
47        colonCount++;
48      }
49  
50      // colonCount == 0: fully relative
51      // colonCount == 1: absolute (still normal findComponent syntax)
52      // colonCount > 1: for each extra colon after 1, go up a naming container
53      // (to the view root, if naming containers run out)
54      if (colonCount > 1) {
55        relativeId = relativeId.substring(colonCount);
56        for (int j = 1; j < colonCount; j++) {
57          while (from.getParent() != null) {
58            from = from.getParent();
59            if (from instanceof NamingContainer) {
60              break;
61            }
62          }
63        }
64      }
65      return from.findComponent(relativeId);
66    }
67  }