View Javadoc
1 /*
2 * XmlBeanHelper.java
3 * Created on September 18, 2003
4 *
5 * The Blues Framework - A lightweight application framework
6 * Copyright (C) 2003 Lonnie Pryor
7 * http://blues.lonniepryor.com
8 *
9 * This library is free software; you can redistribute it and/or modify it under the
10 * terms of the GNU Lesser General Public License as published by the Free Software
11 * Foundation; either version 2.1 of the License, or (at your option) any later
12 * version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along
19 * with this library; if not, write to:
20 *
21 * The Free Software Foundation, Inc.
22 * 59 Temple Place, Suite 330
23 * Boston, MA 02111-1307 USA
24 *
25 */
26 package com.lonniepryor.blues.xml;
27
28 import java.beans.Introspector;
29
30 import java.lang.reflect.Method;
31
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.Map;
36 import java.util.Set;
37
38 import com.lonniepryor.blues.util.BeanHelper;
39 import com.lonniepryor.blues.util.Characters;
40 import com.lonniepryor.blues.util.Methods;
41 import com.lonniepryor.blues.util.Parameters;
42 import com.lonniepryor.blues.util.Strings;
43 import com.lonniepryor.blues.util.Types;
44
45 /***
46 * Helper class that extends normal JavaBean semantics with the Blues Xml XmlParser
47 * patterns.
48 *
49 * @author Lonnie Pryor
50 * @version $Revision: 1.1 $
51 */
52 public class XmlBeanHelper extends BeanHelper {
53 /*** A specification satisfied by valid local element declaration methods. */
54 private static final Methods localDeclarationMethods = Methods.named(
55 Strings.startingWith("declare")
56 .followedBy(
57 Characters.letters().and(Characters.upperCase()).or(
58 Characters.equalTo('_'))).endingWithAny())
59 .and(
60 Methods.taking(Parameters.withElement(Types.javaBeans())))
61 .and(
62 Methods.declaredPublic()).and(Methods.declaredStatic().not()).and(
63 Methods.returningVoid());
64 /*** A specification satisfied by valid prefixed element declaration methods. */
65 private static final Methods prefixedDeclarationMethods = Methods.named(
66 "declare")
67 .and(
68 Methods.taking(
69 Parameters.withElement(Types.interfaces().or(Types.classes()))))
70 .and(
71 Methods.declaredPublic()).and(Methods.declaredStatic().not()).and(
72 Methods.returningVoid());
73 /*** Mapping of element names to local declatation mutators. */
74 private final Map localDeclarations;
75 /*** Mapping of child element types to prefixed declatation mutators. */
76 private final Map prefixedDeclarations;
77
78 /***
79 * Creates a new XmlBeanHelper object.
80 *
81 * @param beanType The type of the xml bean.
82 */
83 public XmlBeanHelper (Class beanType) {
84 super(beanType);
85 Method[] localDeclMethods = localDeclarationMethods.selectAll(
86 beanType.getMethods());
87 Map tmpLocalDecls = new HashMap(localDeclMethods.length);
88 for (int i = 0; i < localDeclMethods.length; ++i) {
89 String name = Introspector.decapitalize(
90 localDeclMethods[i].getName().substring(7));
91 if (!tmpLocalDecls.containsKey(name))
92 tmpLocalDecls.put(name, localDeclMethods[i]);
93 }
94 localDeclarations = Collections.unmodifiableMap(tmpLocalDecls);
95 Method[] prefixedDeclMethods = prefixedDeclarationMethods.selectAll(
96 beanType.getMethods());
97 Map tmpPrefixedDecls = new HashMap(prefixedDeclMethods.length);
98 for (int i = 0; i < prefixedDeclMethods.length; ++i)
99 tmpPrefixedDecls.put(
100 prefixedDeclMethods[i].getParameterTypes()[0], prefixedDeclMethods[i]);
101 prefixedDeclarations = Collections.unmodifiableMap(tmpPrefixedDecls);
102 }
103
104 /***
105 * Returns the names of all of the local declarations the bean type exposes.
106 *
107 * @return The names of all of the local declarations the bean type exposes.
108 */
109 public Set getLocalDeclarationNames () {
110 return localDeclarations.keySet();
111 }
112
113 /***
114 * Returns the types of all of the prefixed declarations the bean type exposes.
115 *
116 * @return The types of all of the prefixed declarations the bean type exposes.
117 */
118 public Set getPrefixedDeclarationTypes () {
119 return prefixedDeclarations.keySet();
120 }
121
122 /***
123 * Returns the mutator method for the named local declaration, or null if one is
124 * not found.
125 *
126 * @param localDeclarationName The name of the local declaration.
127 *
128 * @return The mutator method for the named local declaration, or null if one is
129 * not found.
130 */
131 public Method getLocalDeclarationMutator (String localDeclarationName) {
132 if (localDeclarationName == null)
133 throw new NullPointerException("localDeclarationName");
134 return (Method)localDeclarations.get(localDeclarationName);
135 }
136
137 /***
138 * Returns the mutator method for the prefixed declaration registered for the
139 * specified child element type, or null if one is not found.
140 *
141 * @param childElementType The type of child element to find a mutator for.
142 *
143 * @return The mutator method for the prefixed declaration registered for the
144 * specified child element type, or null if one is not found.
145 */
146 public Method getPrefixedDeclarationMutator (Class childElementType) {
147 if (childElementType == null)
148 throw new NullPointerException("childElementType");
149 for (Iterator iter = getPrefixedDeclarationTypes().iterator(); iter.hasNext();) {
150 Class type = (Class)iter.next();
151 if (type.isAssignableFrom(childElementType))
152 return (Method)prefixedDeclarations.get(type);
153 }
154 return null;
155 }
156
157 /***
158 * Returns the type of the named local declaration, or null if one is not found.
159 *
160 * @param localDeclarationName The name of the local declaration.
161 *
162 * @return The type of the named local declaration, or null if one is not found.
163 */
164 public Class getLocalDeclarationType (String localDeclarationName) {
165 if (localDeclarationName == null)
166 throw new NullPointerException("localDeclarationName");
167 Method method = getLocalDeclarationMutator(localDeclarationName);
168 if (method == null)
169 return null;
170 return method.getParameterTypes()[0];
171 }
172
173 /***
174 * Declares a local element with the supplied name on the specified instance.
175 *
176 * @param instance The instance to declare the child element on.
177 * @param localDeclarationName The name of the local declaration to invoke.
178 * @param childElement The child element to declare.
179 *
180 * @return True if the child element was successfully declared.
181 */
182 public boolean declareLocalElement (
183 Object instance, String localDeclarationName, Object childElement) {
184 if (instance == null)
185 throw new NullPointerException("instance");
186 if (localDeclarationName == null)
187 throw new NullPointerException("localDeclarationName");
188 Method method = getLocalDeclarationMutator(localDeclarationName);
189 if (method == null)
190 return false;
191 invoke(instance, method, new Object[] { childElement });
192 return true;
193 }
194
195 /***
196 * Declares a prefixed element on the specified instance.
197 *
198 * @param instance The instance to declare the child element on.
199 * @param childElement The child element to declare.
200 *
201 * @return True if the child element was successfully declared.
202 */
203 public boolean declarePrefixedElement (Object instance, Object childElement) {
204 if (instance == null)
205 throw new NullPointerException("instance");
206 Method method = getPrefixedDeclarationMutator(childElement.getClass());
207 if (method == null)
208 return false;
209 invoke(instance, method, new Object[] { childElement });
210 return true;
211 }
212 }
This page was automatically generated by Maven