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  package org.apache.myfaces.trinidad.change;
20  
21  import java.util.List;
22  
23  import javax.faces.component.UIComponent;
24  
25  import org.apache.myfaces.trinidad.logging.TrinidadLogger;
26  
27  
28  /**
29   * Change specialization for adding a child component.
30   * While applying this Change, the child component is re-created and added to
31   *  the list of children. If a child component with an id same as the new child being added is 
32   *  already present in the parent container, the new child is not added.
33   * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/change/AddChildComponentChange.java#0 $) $Date: 10-nov-2005.19:09:54 $
34   */
35  public class AddChildComponentChange extends AddComponentChange 
36  {
37    /**
38     * Constructs an AddChildChange that appends the specified child component.
39     * @param childComponent The child component that is to be appended.
40     * @throws IllegalArgumentException if specified childComponent is null.
41     */
42    public AddChildComponentChange(UIComponent childComponent)
43    {
44      this(null,childComponent);
45    }
46    
47    /**
48     * Constructs an AddChildChange with the specified child component and the
49     *  the identifier of the neighbour. If the neighbour is not found
50     *  when applying this Change, or is <code>null<code>< the child is
51     *  appended to the end of the list of children.
52    *  @param insertBeforeId The identifier of the sibling before which this new 
53    *         child is to be inserted.
54     * @param childComponent The child component that is to be added.
55     * @throws IllegalArgumentException if specified childComponent is null
56     */
57    public AddChildComponentChange(
58      String insertBeforeId,
59      UIComponent childComponent)
60    {
61      super(childComponent);
62     
63      _insertBeforeId = insertBeforeId;
64    }
65    
66    /**
67     * Returns the identifier of the sibling before which this new child needs to
68     *  be inserted.
69     */
70    public String getInsertBeforeId()
71    {
72      return _insertBeforeId;
73    }
74    
75    /**
76     * {@inheritDoc}
77     */
78    @SuppressWarnings("unchecked")
79    @Override
80    public void changeComponent(UIComponent uiComponent)
81    {
82      UIComponent child = getComponent();
83      
84      if (child == null)
85        return;
86        
87      String newChildId = child.getId();
88      List<UIComponent> children = uiComponent.getChildren();
89      
90      // If there were to be a child already with the ID same as the to-be-added child, it might have
91      //  been added from previous change application, and further customizations might have happened
92      //  on them. We just want to warn, abort the child addition, and not alter the component tree.
93      UIComponent duplicateChild = ChangeUtils.getChildForId(uiComponent, newChildId);
94    
95      if (duplicateChild != null)
96      {
97        _LOG.info("ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID", newChildId);
98        return;
99      }
100     
101     if (_insertBeforeId == null)
102     {
103       // append the child
104       children.add(child); 
105     }
106     else
107     {
108       int index = ChangeUtils.getChildIndexForId(uiComponent, _insertBeforeId);
109       if(index == -1)
110       {
111         children.add(child);
112       }
113       else
114       {
115         children.add(index, child);
116       }
117     }
118   }
119   
120   private final String _insertBeforeId;
121   static private final TrinidadLogger _LOG =
122     TrinidadLogger.createTrinidadLogger(AddChildComponentChange.class);
123   private static final long serialVersionUID = 1L;
124 }