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 org.w3c.dom.Document;
22  import org.w3c.dom.DocumentFragment;
23  import org.w3c.dom.Element;
24  import org.w3c.dom.Node;
25  import org.apache.myfaces.trinidad.logging.TrinidadLogger;
26  
27  /**
28   * Change specialization for adding a child component to a facet using document
29   * mark up. While applying this Change, the child component is created and added to
30   * the document.  If the facet doesn't exist, it will be created.  If the facet
31   * does exist, all of its content will be removed and the new content added.
32   */
33  public class SetFacetChildDocumentChange extends AddComponentDocumentChange 
34  {  
35    /**
36     * Constructs an AddFacetDocumentChange with the specified child component mark up and
37     *  the name of the facet.
38     * @param facetName Name of facet to create the child component in
39     * @param fragment DOM mark up for child component to be inserted.
40     * @throws IllegalArgumentException if facetName or componentFragment is
41     *         <code>null</code>
42     */
43    public SetFacetChildDocumentChange(
44      String facetName,
45      DocumentFragment fragment)
46    {
47      super(fragment);
48      
49      if ((facetName == null) || (facetName.length() == 0))
50        throw new IllegalArgumentException(_LOG.getMessage(
51          "FACET_NAME_MUST_SPECIFIED"));
52        
53      _facetName = facetName;
54    }
55    
56    /**
57     * Returns the identifier of the sibling before which this new child needs to
58     *  be inserted.
59     */
60    public String getFacetName()
61    {
62      return _facetName;
63    }
64    
65    /**
66     * Given the DOM Node representing a Component, apply any necessary
67     * DOM changes.
68     * While applying this Change, the child component is created and added to
69     * the document.  If the facet doesn't exist, it will be created.  If the facet
70     * does exist, all of its content will be removed and the new content added.
71     */
72    public void changeDocument(Node componentNode)
73    {
74      if (componentNode == null)
75        throw new IllegalArgumentException(_LOG.getMessage(
76          "NO_NODE_SPECIFIED"));
77      
78      // get the fragement, imported into the target document
79      DocumentFragment targetFragment = getImportedComponentFragment(componentNode);
80      
81      Element facetElement = ChangeUtils.__getFacetElement(componentNode, _facetName);
82      
83      if (facetElement != null)
84      {
85        // remove any current children
86        ChangeUtils.__removeAllChildren(facetElement);
87      }
88      else
89      {
90        Document targetDocument = componentNode.getOwnerDocument();
91        
92        facetElement = targetDocument.createElementNS(_JSF_CORE_NAMESPACE, "f:facet");
93        
94        // set the xmlns for the prefix to make sure that "f:" is the
95        // prefix for faces
96        // =-= bts TODO In theory, this could cause problems if the
97        // added component used the prefix "f:" for something other than
98        // the JSF core
99        facetElement.setAttributeNS(_XMLNS_NAMESPACE, "xmlns:f",
100                                   _JSF_CORE_NAMESPACE);
101       
102       facetElement.setAttribute(_FACET_ATTRIBUTE_NAME, _facetName);
103 
104       componentNode.appendChild(facetElement);
105     }
106     
107     // add our new facet content
108     facetElement.appendChild(targetFragment);
109   }
110 
111   /** 
112    * Returns true if adding the DocumentChange should force the JSP Document
113    * to reload
114    */
115   @Override
116   public boolean getForcesDocumentReload()
117   {
118     return false;
119   }
120 
121   private static final String _JSF_CORE_NAMESPACE = "http://java.sun.com/jsf/core";
122   private static final String _XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/";
123   private static final String _FACET_ATTRIBUTE_NAME = "name";
124 
125   private final String _facetName;
126   private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
127     SetFacetChildDocumentChange.class);
128 }