KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > gargoylesoftware > htmlunit > javascript > configuration > ClassConfiguration


1 /*
2  * Copyright (c) 2002, 2005 Gargoyle Software Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. The end-user documentation included with the redistribution, if any, must
13  * include the following acknowledgment:
14  *
15  * "This product includes software developed by Gargoyle Software Inc.
16  * (http://www.GargoyleSoftware.com/)."
17  *
18  * Alternately, this acknowledgment may appear in the software itself, if
19  * and wherever such third-party acknowledgments normally appear.
20  * 4. The name "Gargoyle Software" must not be used to endorse or promote
21  * products derived from this software without prior written permission.
22  * For written permission, please contact info@GargoyleSoftware.com.
23  * 5. Products derived from this software may not be called "HtmlUnit", nor may
24  * "HtmlUnit" appear in their name, without prior written permission of
25  * Gargoyle Software Inc.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30  * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */

38 package com.gargoylesoftware.htmlunit.javascript.configuration;
39
40 import java.lang.reflect.Method JavaDoc;
41 import java.util.HashMap JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.Map JavaDoc;
44 import java.util.Set JavaDoc;
45
46 /**
47  * A container for all the javascript configuration information.
48  *
49  * @version $Revision: 100 $
50  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
51  * @author Chris Erskine
52  */

53 public final class ClassConfiguration {
54     private static final String JavaDoc GETTER_PREFIX = "jsxGet_";
55     private static final String JavaDoc SETTER_PREFIX = "jsxSet_";
56     private static final String JavaDoc FUNCTION_PREFIX = "jsxFunction_";
57     
58     private HashMap JavaDoc propertyMap_ = new HashMap JavaDoc();
59     private HashMap JavaDoc functionMap_ = new HashMap JavaDoc();
60     private String JavaDoc extendedClass_;
61     /**
62      * The fully qualified name of the class that implements this class.
63      */

64     private final String JavaDoc className_;
65     private final Class JavaDoc linkedClass_;
66     private final String JavaDoc htmlClassname_;
67     private final boolean jsObject_;
68     
69     /**
70      * Constructor
71      *
72      * @param classname the name of the configuration class this entry is for
73      * @param implementingClass - the fully qualified name of the class implimenting this functionality
74      * @param extendedClass - The name of the class that this class extends
75      * @param htmlClass The name of the html class that this object supports
76      * @param jsObject boolean flag for if this object is a JavaScript object
77      * @throws ClassNotFoundException - If the implementing class is not found
78      */

79     public ClassConfiguration(final String JavaDoc classname, final String JavaDoc implementingClass,
80         final String JavaDoc extendedClass, final String JavaDoc htmlClass, final boolean jsObject)
81         throws ClassNotFoundException JavaDoc {
82         className_ = classname;
83         extendedClass_ = extendedClass;
84         linkedClass_ = Class.forName(implementingClass);
85         jsObject_ = jsObject;
86         if (htmlClass != null && htmlClass.length() != 0) {
87             htmlClassname_ = htmlClass;
88         }
89         else {
90             htmlClassname_ = null;
91         }
92     }
93     
94     
95     /**
96      * @return Returns the className.
97      */

98     public String JavaDoc getClassName() {
99         return className_;
100     }
101
102
103     /**
104      * Add the property to the configuration
105      * @param name - Name of the property
106      * @param readable - Flag for if the property is readable
107      * @param writeable - Flag for if the property is writeable
108      */

109     public void addProperty(final String JavaDoc name, final boolean readable, final boolean writeable) {
110         final PropertyInfo info = new PropertyInfo();
111         info.setReadable(readable);
112         info.setWriteable(writeable);
113         try {
114             if (readable) {
115                 info.setReadMethod(linkedClass_.getMethod(GETTER_PREFIX + name, null));
116             }
117         }
118         catch (final NoSuchMethodException JavaDoc e) {
119             throw new IllegalStateException JavaDoc("Method '" + GETTER_PREFIX + name + "' was not found for "
120                 + name + " property in " + linkedClass_.getName());
121         }
122         // For the setters, we have to loop through the methods since we do not know what type of argument
123
// the method takes.
124
if (writeable) {
125             final Method JavaDoc[] methods = linkedClass_.getMethods();
126             final String JavaDoc setMethodName = SETTER_PREFIX + name;
127             for( int i=0; i<methods.length; i++ ) {
128                 if( methods[i].getName().equals(setMethodName) && methods[i].getParameterTypes().length == 1 ) {
129                     info.setWriteMethod(methods[i]);
130                     break;
131                 }
132             }
133             if(info.getWriteMethod() == null) {
134                 throw new IllegalStateException JavaDoc("Method '" + SETTER_PREFIX + name + "' was not found for " + name
135                     + " property in " + linkedClass_.getName());
136             }
137         }
138         propertyMap_.put(name, info);
139     }
140     
141     /**
142      * Return the set of keys for the defined properties.
143      * @return a set
144      */

145     public Set JavaDoc propertyKeys() {
146         return propertyMap_.keySet();
147     }
148     
149     /**
150      * Return the set of keys for the defined functions
151      * @return a set
152      */

153     public Set JavaDoc functionKeys() {
154         return functionMap_.keySet();
155     }
156     /**
157      * Add the function to the configuration
158      * @param name - Name of the function
159      */

160     public void addFunction(final String JavaDoc name) {
161         final FunctionInfo info = new FunctionInfo();
162         final Method JavaDoc[] methods = linkedClass_.getMethods();
163         final String JavaDoc setMethodName = FUNCTION_PREFIX + name;
164         for( int i=0; i<methods.length; i++ ) {
165             if( methods[i].getName().equals(setMethodName)) {
166                 info.setFunctionMethod(methods[i]);
167                 break;
168             }
169         }
170         if(info.getFunctionMethod() == null) {
171             throw new IllegalStateException JavaDoc("Method '" + FUNCTION_PREFIX + name + "' was not found for " + name
172                 + " function in " + linkedClass_.getName());
173         }
174         functionMap_.put(name, info);
175     }
176
177     
178     /**
179      * Set the browser information for this named property
180      * @param propertyName - Name of the property to set
181      * @param browserName - Browser name to set
182      * @throws IllegalStateException - Property does not exist
183      */

184     public void setBrowser(final String JavaDoc propertyName, final String JavaDoc browserName)
185         throws IllegalStateException JavaDoc {
186         final PropertyInfo property = getPropertyInfo(propertyName);
187         if (property == null) {
188             throw new IllegalStateException JavaDoc("Property does not exist to set browser");
189         }
190         property.setBrowser(new BrowserInfo(browserName));
191     }
192
193     /**
194      * @return Returns the extendedClass.
195      */

196     public String JavaDoc getExtendedClass() {
197         return extendedClass_;
198     }
199
200     /**
201      * @param extendedClass The extendedClass to set.
202      */

203     public void setExtendedClass(final String JavaDoc extendedClass) {
204         extendedClass_ = extendedClass;
205     }
206     
207     /**
208      * Return the PropertyInfo for the given property name
209      * @param propertyName Name of property
210      * @return ClassConfiguration.PropertyInfo
211      */

212     protected PropertyInfo getPropertyInfo(final String JavaDoc propertyName) {
213         return (PropertyInfo) propertyMap_.get(propertyName);
214     }
215     
216
217     private FunctionInfo getFunctionInfo(final String JavaDoc functionName) {
218         return (FunctionInfo) functionMap_.get(functionName);
219     }
220
221     /**
222      * Test for value equality of the 2 objects
223      *
224      * @param obj the reference object with which to compare.
225      * @return <code>true</code> if the value of this object is the same as the obj
226      * argument; <code>false</code> otherwise.
227      */

228     public boolean equals(final Object JavaDoc obj) {
229         if (! (obj instanceof ClassConfiguration)) {
230             return false;
231         }
232         final ClassConfiguration config = (ClassConfiguration) obj;
233         if (propertyMap_.size() != config.propertyMap_.size()) {
234             return false;
235         }
236         if (functionMap_.size() != config.functionMap_.size()) {
237             return false;
238         }
239         final Set JavaDoc keys = config.propertyMap_.keySet();
240         final Iterator JavaDoc it = keys.iterator();
241         while (it.hasNext()) {
242             final String JavaDoc key = (String JavaDoc) it.next();
243             if (!(((PropertyInfo)config.propertyMap_.get(key)).valueEquals(propertyMap_.get(key)))) {
244                 return false;
245             }
246         }
247         
248         final Set JavaDoc fkeys = config.functionMap_.keySet();
249         final Iterator JavaDoc fit = fkeys.iterator();
250         while (fit.hasNext()) {
251             final String JavaDoc fkey = (String JavaDoc) fit.next();
252             if (!(((FunctionInfo)config.functionMap_.get(fkey)).valueEquals(functionMap_.get(fkey)))) {
253                 return false;
254             }
255         }
256         return true;
257     }
258     
259     /**
260      * Generate a hashCode for this object. Currently, this is the hashcode for the name.
261      * @see java.lang.Object#hashCode()
262      */

263     public int hashCode() {
264         return className_.hashCode();
265     }
266     
267     /**
268      * Gets the method that implements the getter for the named property
269      *
270      * @param propertyName The name of the property
271      * @return Method
272      */

273     public Method JavaDoc getPropertyReadMethod(final String JavaDoc propertyName) {
274         final PropertyInfo info = getPropertyInfo(propertyName);
275         if (info == null) {
276             return null;
277         }
278         return info.getReadMethod();
279     }
280     
281     /**
282      * Gets the method that implements the setter for the named property
283      *
284      * @param propertyName The name of the property
285      * @return Method
286      */

287     public Method JavaDoc getPropertyWriteMethod(final String JavaDoc propertyName) {
288         final PropertyInfo info = getPropertyInfo(propertyName);
289         if (info == null) {
290             return null;
291         }
292         return info.getWriteMethod();
293     }
294     
295     /**
296      * Gets the method that implements the given function
297      *
298      * @param functionName The name of the property
299      * @return Method
300      */

301     public Method JavaDoc getFunctionMethod(final String JavaDoc functionName) {
302         final FunctionInfo info = getFunctionInfo(functionName);
303         if (info == null) {
304             return null;
305         }
306         return info.getFunctionMethod();
307     }
308     
309     /**
310      *
311      * @return Returns the linkedClass.
312      */

313     public Class JavaDoc getLinkedClass() {
314         return linkedClass_;
315     }
316     
317     /**
318      * @return Returns the htmlClassname.
319      */

320     public String JavaDoc getHtmlClassname() {
321         return htmlClassname_;
322     }
323
324     /**
325      * @return Returns the jsObject.
326      */

327     public boolean isJsObject() {
328         return jsObject_;
329     }
330     /**
331      * Class used to contain the property information if the property is readable, writeable and the
332      * methods that implement the get and set functions.
333      */

334     protected class PropertyInfo {
335         private boolean readable_ = false;
336         private boolean writeable_ = false;
337         private boolean hasBrowsers_ = false;
338         private Map JavaDoc browserMap_;
339         private Method JavaDoc readMethod_;
340         private Method JavaDoc writeMethod_;
341
342         /**
343          * @return Returns the readMethod.
344          */

345         public Method JavaDoc getReadMethod() {
346             return readMethod_;
347         }
348
349         /**
350          * @param readMethod The readMethod to set.
351          */

352         public void setReadMethod(final Method JavaDoc readMethod) {
353             readMethod_ = readMethod;
354         }
355
356         /**
357          * @return Returns the writeMethod.
358          */

359         public Method JavaDoc getWriteMethod() {
360             return writeMethod_;
361         }
362
363         /**
364          * @param writeMethod The writeMethod to set.
365          */

366         public void setWriteMethod(final Method JavaDoc writeMethod) {
367             writeMethod_ = writeMethod;
368         }
369         
370         private void setBrowser(final BrowserInfo browserInfo) {
371             if (browserMap_ == null) {
372                 hasBrowsers_ = true;
373                 browserMap_ = new HashMap JavaDoc();
374             }
375             
376             browserMap_.put(browserInfo.getBrowserName(), browserInfo);
377         }
378         
379         /**
380          * Test for value equality of the 2 objects
381          *
382          * @param obj the reference object with which to compare.
383          * @return <code>true</code> if the value of this object is the same as the obj
384          * argument; <code>false</code> otherwise.
385          */

386         private boolean valueEquals(final Object JavaDoc obj) {
387             if (!(obj instanceof PropertyInfo)) {
388                 return false;
389             }
390             final PropertyInfo info = (PropertyInfo) obj;
391             if (hasBrowsers_ != info.hasBrowsers_) {
392                 return false;
393             }
394             if (hasBrowsers_) {
395                 if (browserMap_.size() != info.browserMap_.size()) {
396                     return false;
397                 }
398                 final Set JavaDoc keys = browserMap_.keySet();
399                 final Iterator JavaDoc it = keys.iterator();
400                 while (it.hasNext()) {
401                     final String JavaDoc key = (String JavaDoc) it.next();
402                     if (!(((BrowserInfo)browserMap_.get(key)).valueEquals(info.browserMap_.get(key)))) {
403                         return false;
404                     }
405                 }
406
407             }
408             return (readable_ == info.readable_) &&
409                 (writeable_ == info.writeable_);
410         }
411     
412         /**
413          * @param readable The readable to set.
414          */

415         private void setReadable(final boolean readable) {
416             readable_ = readable;
417         }
418
419         /**
420          * @param writeable The writeable to set.
421          */

422         private void setWriteable(final boolean writeable) {
423             writeable_ = writeable;
424         }
425     }
426
427     private class FunctionInfo {
428         private boolean hasBrowsers_ = false;
429         private Map JavaDoc browserMap_;
430         private Method JavaDoc functionMethod_;
431         
432         /**
433          * Test for value equality of the 2 objects
434          *
435          * @param obj the reference object with which to compare.
436          * @return <code>true</code> if the value of this object is the same as the obj
437          * argument; <code>false</code> otherwise.
438          */

439         private boolean valueEquals(final Object JavaDoc obj) {
440             if (!(obj instanceof FunctionInfo)) {
441                 return false;
442             }
443             final FunctionInfo info = (FunctionInfo) obj;
444             if (hasBrowsers_ != info.hasBrowsers_) {
445                 return false;
446             }
447             if (hasBrowsers_) {
448                 if (browserMap_.size() != info.browserMap_.size()) {
449                     return false;
450                 }
451                 final Set JavaDoc keys = browserMap_.keySet();
452                 final Iterator JavaDoc it = keys.iterator();
453                 while (it.hasNext()) {
454                     final String JavaDoc key = (String JavaDoc) it.next();
455                     if (!(((BrowserInfo)browserMap_.get(key)).valueEquals(info.browserMap_.get(key)))) {
456                         return false;
457                     }
458                 }
459
460             }
461             return true;
462         }
463
464         /**
465          * @return Returns the functionMethod.
466          */

467         public Method JavaDoc getFunctionMethod() {
468             return functionMethod_;
469         }
470
471         /**
472          * @param functionMethod The functionMethod to set.
473          */

474         public void setFunctionMethod(final Method JavaDoc functionMethod) {
475             functionMethod_ = functionMethod;
476         }
477     }
478
479     private class BrowserInfo {
480         private String JavaDoc browserName_;
481         private String JavaDoc minVersion_;
482         private String JavaDoc maxVersion_;
483         private String JavaDoc lessThanVersion_;
484         
485         /**
486          * Test for value equality of the 2 objects
487          *
488          * @param obj the reference object with which to compare.
489          * @return <code>true</code> if the value of this object is the same as the obj
490          * argument; <code>false</code> otherwise.
491          */

492         private boolean valueEquals(final Object JavaDoc obj) {
493             if (!(obj instanceof BrowserInfo)) {
494                 return false;
495             }
496             final BrowserInfo info = (BrowserInfo) obj;
497             if (minVersion_ != null) {
498                 if (! minVersion_.equals(info.minVersion_)) {
499                     return false;
500                 }
501             }
502             if (maxVersion_ != null) {
503                 if (! maxVersion_.equals(info.maxVersion_)) {
504                     return false;
505                 }
506             }
507             if (lessThanVersion_ != null) {
508                 if (! lessThanVersion_.equals(info.lessThanVersion_)) {
509                     return false;
510                 }
511             }
512             return (browserName_ == info.browserName_);
513         }
514
515         /**
516          * @param browserName - Name of the browser
517          */

518         public BrowserInfo(final String JavaDoc browserName) {
519             browserName_ = browserName;
520         }
521
522         /**
523          * @return Returns the browserName.
524          */

525         private String JavaDoc getBrowserName() {
526             return browserName_;
527         }
528     }
529
530 }
531
Popular Tags