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 }