KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > binding > JXPathBindingBuilderBase


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.binding;
17
18 import java.util.Map JavaDoc;
19
20 import org.apache.avalon.framework.logger.LogEnabled;
21 import org.apache.avalon.framework.logger.Logger;
22 import org.apache.cocoon.forms.util.DomHelper;
23 import org.apache.commons.lang.BooleanUtils;
24 import org.w3c.dom.Element JavaDoc;
25
26 /**
27  * Abstract base class enabling logging and supporting the intrepretation of
28  * common configuration settings on all specific implementations of
29  * {@link org.apache.cocoon.forms.binding.JXPathBindingBase}.
30  *
31  * Common supported configurations: {@link #getCommonAttributes(Element)}
32  * <ul>
33  * <li>Attribute direction="load|save|both": defaults to 'both'</li>
34  * <li>Attribute lenient="true|false|[undefined]": defaults to [undefined]
35  * which means: "continue in same leniency-mode as parent" </li>
36  * </ul>
37  *
38  * @version $Id: JXPathBindingBuilderBase.java 289538 2005-09-16 13:46:22Z sylvain $
39  */

40 public abstract class JXPathBindingBuilderBase implements LogEnabled {
41
42     private Logger logger;
43
44     /**
45      * Receives the Avalon logger to use.
46      */

47     public void enableLogging(Logger logger) {
48         this.logger = logger;
49         if (logger.isDebugEnabled()) {
50             logger.debug("JXPathBindingBuilderBase got logger...");
51         }
52     }
53     
54
55     /**
56      * Makes the logger available to the subclasses.
57      * @return Logger
58      */

59     protected Logger getLogger() {
60         return this.logger;
61     }
62
63     /**
64      * Builds a configured binding object based on the configuration as
65      * described in the bindingElement. The BuilderMap can be used to
66      * find appropriate builders for possible subBinders.
67      *
68      * @param bindingElm
69      * @param assistant
70      * @return JXPathBindingBase
71      */

72     public abstract JXPathBindingBase buildBinding(
73         Element JavaDoc bindingElm,
74         JXPathBindingManager.Assistant assistant) throws BindingException;
75
76     /**
77      * Helper method for interpreting the common attributes which are supported
78      * on each of the Bindings. These are
79      * <br>
80      * <code>@direction</code> can hold one of the following values:
81      * <ol><li><code>'load'</code>: This binding will only load.</li>
82      * <li><code>'save'</code>: This binding will only save.</li>
83      * <li><code>'both'</code>: This binding will perform both operations.</li>
84      * </ol>
85      * <br>
86      * <code>@lenient</code> can either be:
87      * <ol><li><code>'true'</code>: This binding will set the jxpath context to
88      * be lenient towards the usage of inexisting paths on the back-end model.</li>
89      * <li><code>'false'</code>: This binding will set the jxpath context to be
90      * strict and throwing exceptions for the usage of inexisting paths on the
91      * back-end model.</li>
92      * <li><code>(unset)</code>: This binding will not change the leniency behaviour
93      * on the jxpath this binding receives from his parent binding.</li>
94      * </ol>
95      * @param bindingElm
96      * @return an instance of CommonAttributes
97      * @throws BindingException
98      */

99     protected static CommonAttributes getCommonAttributes(Element JavaDoc bindingElm) throws BindingException {
100         try {
101             String JavaDoc location = DomHelper.getLocation(bindingElm);
102             //TODO: should we eventually remove this?
103
//throw an error if people are still using the old-style @read-only or @readonly
104
if (DomHelper.getAttributeAsBoolean(bindingElm, "readonly", false)) {
105                 throw new BindingException("Error in binding file " + location
106                         + "\nThe usage of the attribute @readonly has been deprecated in favour of @direction.");
107             }
108             if (DomHelper.getAttributeAsBoolean(bindingElm, "read-only", false)) {
109                 throw new BindingException("Error in binding file " + location
110                         + "\nThe usage of the attribute @read-only has been deprecated in favour of @direction.");
111             }
112
113             String JavaDoc direction = DomHelper.getAttribute(bindingElm, "direction", "both");
114
115             String JavaDoc leniency = DomHelper.getAttribute(bindingElm, "lenient", null);
116
117             //TODO: current jxpath is not inheriting registered namespaces over to
118
// child-relative jxpath contexts --> because of that we can't just
119
// remember the getLocalNSDeclarations but need the full set from
120
// getInheritedNSDeclarations
121
// IMPORTANT NOTE: if jxpath would change this behaviour we would however
122
// still need to be able to unregister namespace-declarations
123
// (in a smart way: unhide what is possably available from your parent.
124
// So both changes to jxpath need to be available before changing the below.
125
Map JavaDoc nsDeclarationMap = DomHelper.getInheritedNSDeclarations(bindingElm);
126             // we (actually jxpath) doesn't support un-prefixed namespace-declarations:
127
// so we decide to break on those above silently ignoring them
128
if (nsDeclarationMap != null && nsDeclarationMap.values().contains(null))
129                 throw new BindingException("Error in binding file " + location
130                                 + "\nBinding doesn't support having namespace-declarations without explicit prefixes.");
131             
132             return new CommonAttributes(location, direction, leniency, nsDeclarationMap);
133         } catch (BindingException e) {
134             throw e;
135         } catch (Exception JavaDoc e) {
136             throw new BindingException("Error building binding defined at " + DomHelper.getLocation(bindingElm), e);
137         }
138      }
139     
140     public static CommonAttributes mergeCommonAttributes(CommonAttributes existing, CommonAttributes extra) {
141         
142         if (extra == null)
143             return existing;
144         
145         Boolean JavaDoc leniency = null;
146         if(existing.leniency==null)
147             leniency = extra.leniency;
148         else
149             leniency = existing.leniency;
150         
151         String JavaDoc strLeniency = null;
152         if(leniency != null)
153             strLeniency = leniency.toString();
154         
155         String JavaDoc direction = existing.direction;
156         if(extra.direction!=null) // was defined
157
direction = extra.direction;
158         
159         
160         return new CommonAttributes(extra.location,direction,strLeniency,extra.nsDeclarations);
161     }
162
163      /**
164       * CommonAttributes is a simple helper class for holding the distinct data
165       * member fields indicating the activity of the sepearate load and save
166       * actions of a given binding.
167       */

168      protected static class CommonAttributes{
169
170         /**
171          * store direction (load/save enabledness) too for easier merging
172          */

173         String JavaDoc direction;
174         /**
175          * Source location of this binding.
176          */

177         final String JavaDoc location;
178         /**
179          * Flag which controls whether a binding is active during loading.
180          */

181         final boolean loadEnabled;
182         /**
183          * Flag which controls whether a binding is active during saving.
184          */

185         final boolean saveEnabled;
186         /**
187          * Flag which controls whether the jxpath context used by this binding
188          * should be operating in lenient mode or not
189          */

190         final Boolean JavaDoc leniency;
191         /**
192          * Array of namespace-declarations (prefix-uri pairs) that need to be set on the jxpath
193          */

194         final Map JavaDoc nsDeclarations;
195
196         final static CommonAttributes DEFAULT = new CommonAttributes("location unknown", true, true, null, null);
197
198         CommonAttributes(String JavaDoc location, String JavaDoc direction, String JavaDoc leniency, Map JavaDoc nsDeclarations){
199             this(location, isLoadEnabled(direction), isSaveEnabled(direction), decideLeniency(leniency), nsDeclarations);
200             this.direction = direction;
201         }
202
203         CommonAttributes(String JavaDoc location, boolean loadEnabled, boolean saveEnabled, Boolean JavaDoc leniency, Map JavaDoc nsDeclarations){
204             this.direction = null;
205             this.location = location;
206             this.loadEnabled = loadEnabled;
207             this.saveEnabled = saveEnabled;
208             this.leniency = leniency;
209             this.nsDeclarations = nsDeclarations;
210         }
211
212         /**
213          * Interpretes the value of the direction attribute into activity of the load action.
214          * @param direction
215          * @return true if direction is either set to "both" or "load"
216          */

217         private static boolean isLoadEnabled(String JavaDoc direction) {
218             return "both".equals(direction) || "load".equals(direction);
219         }
220
221         /**
222          * Interpretes the value of the direction attribute into activity of the save action.
223          * @param direction value of the @direction attribute
224          * @return true if direction is either set to "both" or "save"
225          */

226         private static boolean isSaveEnabled(String JavaDoc direction) {
227             return "both".equals(direction) || "save".equals(direction);
228         }
229
230
231         /**
232          * Interpretes the value of the lenient attribute into a Boolean object
233          * allowing three-state logic (true/false/unset)
234          * @param leniency value of the @lenient attribute
235          * @return null if the leniency parameter is null or a String otherwise the allowed values
236          */

237         private static Boolean JavaDoc decideLeniency(String JavaDoc leniency) {
238             return BooleanUtils.toBooleanObject(leniency);
239         }
240         
241     }
242 }
243
Popular Tags