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.
32   * @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 $
33   */
34  public class AddChildComponentChange extends AddComponentChange 
35  {
36    /**
37     * Constructs an AddChildChange that appends the specified child component.
38     * @param childComponent The child component that is to be appended.
39     * @throws IllegalArgumentException if specified childComponent is null.
40     */
41    public AddChildComponentChange(UIComponent childComponent)
42    {
43      this(null,childComponent);
44    }
45    
46    /**
47     * Constructs an AddChildChange with the specified child component and the
48     *  the identifier of the neighbour. If the neighbour is not found
49     *  when applying this Change, or is <code>null<code>< the child is
50     *  appended to the end of the list of children.
51    *  @param insertBeforeId The identifier of the sibling before which this new 
52    *         child is to be inserted.
53     * @param childComponent The child component that is to be added.
54     * @throws IllegalArgumentException if specified childComponent is null
55     */
56    public AddChildComponentChange(
57      String insertBeforeId,
58      UIComponent childComponent)
59    {
60      super(childComponent);
61     
62      _insertBeforeId = insertBeforeId;
63    }
64    
65    /**
66     * Returns the identifier of the sibling before which this new child needs to
67     *  be inserted.
68     */
69    public String getInsertBeforeId()
70    {
71      return _insertBeforeId;
72    }
73    
74    /**
75     * {@inheritDoc}
76     */
77    @SuppressWarnings("unchecked")
78    @Override
79    public void changeComponent(UIComponent uiComponent)
80    {
81      UIComponent child = getComponent();
82      
83      if (child == null)
84        return;
85        
86      String newChildId = child.getId();
87      List<UIComponent> children = uiComponent.getChildren();
88      
89      //pu: If there were to be a child already with the ID same as the
90      //  to-be-added child, remove it and get the new one added.
91      UIComponent removableChild = ChangeUtils.getChildForId(uiComponent, newChildId);
92    
93      // Users can add component themselves in addition to adding a ComponentChange
94      //  This could cause duplicates, which is fine. Handle this gracefully with 
95      //  a info log and replacement
96      if (removableChild != null)
97      {
98        _LOG.info("ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID", newChildId);
99        children.remove(removableChild);
100     }
101     
102     if (_insertBeforeId == null)
103     {
104       // append the child
105       children.add(child); 
106     }
107     else
108     {
109       int index = ChangeUtils.getChildIndexForId(uiComponent, _insertBeforeId);
110       if(index == -1)
111       {
112         children.add(child);
113       }
114       else
115       {
116         children.add(index, child);
117       }
118     }
119   }
120   
121   private final String _insertBeforeId;
122   static private final TrinidadLogger _LOG =
123     TrinidadLogger.createTrinidadLogger(AddChildComponentChange.class);
124   private static final long serialVersionUID = 1L;
125 }