KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > PropertyAccessorUtils


1 /*
2  * Copyright 2002-2006 the original author or authors.
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
17 package org.springframework.beans;
18
19 /**
20  * Utility methods for classes that perform bean property access
21  * according to the PropertyAccessor interface.
22  *
23  * @author Juergen Hoeller
24  * @since 1.2.6
25  * @see PropertyAccessor
26  */

27 public abstract class PropertyAccessorUtils {
28
29     /**
30      * Return the actual property name for the given property path.
31      * @param propertyPath the property path to determine the property name
32      * for (can include property keys, for example for specifying a map entry)
33      * @return the actual property name, without any key elements
34      */

35     public static String JavaDoc getPropertyName(String JavaDoc propertyPath) {
36         int separatorIndex = propertyPath.indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR);
37         return (separatorIndex != -1 ? propertyPath.substring(0, separatorIndex) : propertyPath);
38     }
39
40     /**
41      * Determine the first nested property separator in the
42      * given property path, ignoring dots in keys (like "map[my.key]").
43      * @param propertyPath the property path to check
44      * @return the index of the nested property separator, or -1 if none
45      */

46     public static int getFirstNestedPropertySeparatorIndex(String JavaDoc propertyPath) {
47         return getNestedPropertySeparatorIndex(propertyPath, false);
48     }
49
50     /**
51      * Determine the first nested property separator in the
52      * given property path, ignoring dots in keys (like "map[my.key]").
53      * @param propertyPath the property path to check
54      * @return the index of the nested property separator, or -1 if none
55      */

56     public static int getLastNestedPropertySeparatorIndex(String JavaDoc propertyPath) {
57         return getNestedPropertySeparatorIndex(propertyPath, true);
58     }
59
60     /**
61      * Determine the first (or last) nested property separator in the
62      * given property path, ignoring dots in keys (like "map[my.key]").
63      * @param propertyPath the property path to check
64      * @param last whether to return the last separator rather than the first
65      * @return the index of the nested property separator, or -1 if none
66      */

67     private static int getNestedPropertySeparatorIndex(String JavaDoc propertyPath, boolean last) {
68         boolean inKey = false;
69         final int length = propertyPath.length();
70         int i = (last ? length - 1 : 0);
71         while (last ? i >= 0 : i < length) {
72             switch (propertyPath.charAt(i)) {
73                 case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR:
74                 case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR:
75                     inKey = !inKey;
76                     break;
77                 case PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR:
78                     if (!inKey) {
79                         return i;
80                     }
81             }
82             if (last)
83                 i--;
84             else
85                 i++;
86         }
87         return -1;
88     }
89
90     /**
91      * Determine whether the given registered path matches the given property path,
92      * either indicating the property itself or an indexed element of the property.
93      * @param propertyPath the property path (typically without index)
94      * @param registeredPath the registered path (potentially with index)
95      * @return whether the paths match
96      */

97     public static boolean matchesProperty(String JavaDoc registeredPath, String JavaDoc propertyPath) {
98         if (!registeredPath.startsWith(propertyPath)) {
99             return false;
100         }
101         if (registeredPath.length() == propertyPath.length()) {
102             return true;
103         }
104         if (registeredPath.charAt(propertyPath.length()) != PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR) {
105             return false;
106         }
107         return (registeredPath.indexOf(PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR, propertyPath.length() + 1) ==
108                 registeredPath.length() - 1);
109     }
110
111     /**
112      * Determine the canonical name for the given property path.
113      * Removes surrounding quotes from map keys:<br>
114      * <code>map['key']</code> -> <code>map[key]</code><br>
115      * <code>map["key"]</code> -> <code>map[key]</code>
116      * @param propertyName the bean property path
117      * @return the canonical representation of the property path
118      */

119     public static String JavaDoc canonicalPropertyName(String JavaDoc propertyName) {
120         if (propertyName == null) {
121             return "";
122         }
123
124         // The following code does not use JDK 1.4's StringBuffer.indexOf(String)
125
// method to retain JDK 1.3 compatibility. The slight loss in performance
126
// is not really relevant, as this code will typically just run on startup.
127

128         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(propertyName);
129         int searchIndex = 0;
130         while (searchIndex != -1) {
131             int keyStart = buf.toString().indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX, searchIndex);
132             searchIndex = -1;
133             if (keyStart != -1) {
134                 int keyEnd = buf.toString().indexOf(
135                         PropertyAccessor.PROPERTY_KEY_SUFFIX, keyStart + PropertyAccessor.PROPERTY_KEY_PREFIX.length());
136                 if (keyEnd != -1) {
137                     String JavaDoc key = buf.substring(keyStart + PropertyAccessor.PROPERTY_KEY_PREFIX.length(), keyEnd);
138                     if ((key.startsWith("'") && key.endsWith("'")) || (key.startsWith("\"") && key.endsWith("\""))) {
139                         buf.delete(keyStart + 1, keyStart + 2);
140                         buf.delete(keyEnd - 2, keyEnd - 1);
141                         keyEnd = keyEnd - 2;
142                     }
143                     searchIndex = keyEnd + PropertyAccessor.PROPERTY_KEY_SUFFIX.length();
144                 }
145             }
146         }
147         return buf.toString();
148     }
149
150     /**
151      * Determine the canonical names for the given property paths.
152      * @param propertyNames the bean property paths (as array)
153      * @return the canonical representation of the property paths
154      * (as array of the same size)
155      * @see #canonicalPropertyName(String)
156      */

157     public static String JavaDoc[] canonicalPropertyNames(String JavaDoc[] propertyNames) {
158         if (propertyNames == null) {
159             return null;
160         }
161         String JavaDoc[] result = new String JavaDoc[propertyNames.length];
162         for (int i = 0; i < propertyNames.length; i++) {
163             result[i] = canonicalPropertyName(propertyNames[i]);
164         }
165         return result;
166     }
167
168 }
169
Popular Tags