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 javax.faces.component.UIComponent;
22  import javax.faces.context.FacesContext;
23  
24  import org.apache.myfaces.trinidad.component.UIXIterator;
25  import org.apache.myfaces.trinidad.logging.TrinidadLogger;
26  
27  import org.apache.myfaces.trinidad.util.ComponentUtils;
28  
29  import org.w3c.dom.Document;
30  
31  
32  /**
33   * Base ChangeManager implementation that manages the bookkeeping for
34   * supporting both ComponentChanges and DocumentChanges.
35   * subclasses must implement addComponentChangeImpl() to implement
36   * the ComponentChange support.  To support DocumentChanges,
37   * <code>getDocument</code> must be implemented.
38   *
39   * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/change/BaseChangeManager.java#1 $) $Date: 11-nov-2005.14:59:41 $
40   */
41  abstract class BaseChangeManager extends ChangeManager
42  {
43    /**
44     * {@inheritDoc}
45     */
46    @Override
47    public void addComponentChange(
48      FacesContext facesContext,
49      UIComponent uiComponent,
50      ComponentChange change)
51    {
52      // if our component is a stamped component by UIXIterator, we 
53      // don't want to persist the changes 
54      UIComponent parent = uiComponent.getParent();
55      UIComponent root = facesContext.getViewRoot();
56      while (parent != null && parent != root) 
57      {
58        if (parent.getClass() == UIXIterator.class) 
59        {
60          _LOG.info("DONT_PERSIST_STAMPED_COMPONENT_INSIDE_ITERATOR");      
61          return;
62        }
63        parent = parent.getParent();      
64      }
65          
66      if (facesContext == null || uiComponent == null || change == null)
67        throw new IllegalArgumentException(_LOG.getMessage(
68          "CANNOT_ADD_CHANGE_WITH_FACECONTEXT_OR_UICOMPONENT_OR_NULL"));
69  
70      // add the change to the component
71      addComponentChangeImpl(facesContext, uiComponent, change);
72  
73      if (supportsDocumentPersistence(facesContext))
74      {
75        DocumentChange docChange = null;
76  
77        if (change instanceof DocumentChange)
78        {
79          docChange = (DocumentChange)change;
80        }
81        else
82        {
83          // try to get equivalent DocumentChange from ComponentChange
84          docChange = createDocumentChange(change);
85        }
86  
87        if (docChange != null)
88        {
89          addDocumentChange(facesContext, uiComponent, docChange);
90        }
91      }
92    }
93  
94    /**
95     * A no-op implementation of adding a ComponentChange. Sub-classers should
96     * override and provide an implementation if they support component changes.
97     * @param facesContext The FacesContext for this request.
98     * @param targetComponent The target component against which this change needs
99     * to be registered and applied later on.
100    * @param componentChange The ComponentChange to add
101    */
102    protected void addComponentChangeImpl(
103     FacesContext facesContext,
104     UIComponent targetComponent,
105     ComponentChange componentChange)
106   {
107     //no-op
108   }
109 
110   // =-= bts Testing hack hook
111   protected void persistDocumentChanges(
112     FacesContext facesContext)
113   {
114     // noop
115   }
116 
117   /**
118    * Override to return the Document to modify as part of document-based
119    * persistence.
120    * Subclassers adding Document-based Persistence
121    * must override this method and should override
122    * <code>supportsDocumentPersistence</code>
123    * in order to enable  Document-based Persistence
124    */
125   protected abstract Document getDocument(FacesContext context);
126 
127   /**
128    *  Returns true if we can support Document-based Persistence
129    *  in this ChangeManager.  Subclassers adding Document-based Persistence
130    *  should override this method and must override <code>getDocument</code>
131    *  in order to enable  Document-based Persistence.
132    * @param context
133    * @return true if we can support Document-based Persistence
134    */
135   protected boolean supportsDocumentPersistence(FacesContext context)
136   {
137     // correct, but potentially slow implementation
138     return getDocument(context) != null;
139   }
140   private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
141     BaseChangeManager.class);
142 }