KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > controls > api > properties > PropertySetProxy


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

19
20 import java.lang.annotation.Annotation JavaDoc;
21 import java.lang.reflect.InvocationHandler JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.Proxy JavaDoc;
24
25 import org.apache.beehive.controls.api.properties.PropertyKey;
26 import org.apache.beehive.controls.api.properties.PropertyMap;
27 import org.apache.beehive.controls.api.properties.PropertySet;
28
29 /**
30  * The PropertySetProxy class is a dynamic proxy InvocationHandler class that exposes the
31  * values held within a PropertyMap as an Object implementing an annotation type interface.
32  * <p>
33  * This enables properties resolved using the PropertyMap's hiearchical resolution mechanism to
34  * be exposed to the client of the proxy in the same way that JSR-175 annotations are
35  * exposed using raw Java reflection APIs. A proxy of this type should behave identically
36  * to the one returned from a call to <code>AnnotatedElement.getAnnotation()</code>, but backed
37  * by a richer, more dynamic resolution mechanism.
38  *
39  * @see java.lang.reflect.Proxy
40  * @see java.lang.reflect.InvocationHandler
41  * @see java.lang.reflect.AnnotatedElement#getAnnotation
42  * @see org.apache.beehive.controls.api.properties.PropertySet
43  * @see org.apache.beehive.controls.api.properties.PropertyMap
44  */

45 public class PropertySetProxy <T extends Annotation JavaDoc> implements InvocationHandler JavaDoc
46 {
47     /**
48      * Creates a new proxy instance implementing the PropertySet interface and backed
49      * by the data from the property map.
50      *
51      * @param propertySet an annotation type that has the PropertySet meta-annotation
52      * @param propertyMap the PropertyMap containing property values backing the proxy
53      * @return proxy that implements the PropertySet interface
54      */

55     public static <T extends Annotation JavaDoc> T getProxy(Class JavaDoc<T> propertySet, PropertyMap propertyMap)
56     {
57         assert propertySet != null && propertyMap != null;
58
59         if (!propertySet.isAnnotation())
60             throw new IllegalArgumentException JavaDoc(propertySet + " is not an annotation type");
61
62         return (T) Proxy.newProxyInstance(propertySet.getClassLoader(),
63                                           new Class JavaDoc [] {propertySet },
64                                           new PropertySetProxy(propertySet, propertyMap));
65     }
66
67     /**
68      * Private constructor, called only from the getProxy factory method
69      */

70     private PropertySetProxy(Class JavaDoc<T> propertySet, PropertyMap propertyMap)
71     {
72         _propertySet = propertySet;
73         _propertyMap = propertyMap;
74     }
75
76     //
77
// InvocationHandler.invoke
78
//
79
public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
80     {
81         // Handle cases where Object/Annotation methods are called on this
82
// proxy. We were getting null back from Annotation.annotationType.
83
Object JavaDoc value = null;
84         if (method.getDeclaringClass() == Object JavaDoc.class)
85         {
86             try {
87                 if (method.getName().equals("getClass"))
88                 {
89                     value = _propertySet;
90                 }
91                 else
92                 {
93                     value = method.invoke(_propertyMap, args);
94                 }
95             }
96             catch (Exception JavaDoc e)
97             {
98                 e.printStackTrace();
99             }
100         }
101         else if (method.getDeclaringClass() == Annotation JavaDoc.class &&
102                  method.getName().equals("annotationType"))
103         {
104             value = _propertySet;
105         }
106         else
107         {
108
109             // Query the nested value in the property map
110
PropertyKey key = new PropertyKey(_propertySet, method.getName());
111             value = _propertyMap.getProperty(key);
112
113             // If the returned value is itself a PropertyMap (i.e. a nested annotation type),
114
// then wrap it in a PropertySetProxy instance before returning.
115
if (value instanceof PropertyMap)
116             {
117                 PropertyMap propertyMap = (PropertyMap)value;
118                 value = getProxy(propertyMap.getMapClass(), propertyMap);
119             }
120         }
121
122         return value;
123     }
124
125     /**
126      * Returns the PropertySet annotation type associated with the proxy
127      */

128     public Class JavaDoc<T> getPropertySet() { return _propertySet; }
129
130     /**
131      * Returns the underlying PropertyMap containing the property values exposed by the
132      * proxy.
133      */

134     public PropertyMap getPropertyMap() { return _propertyMap; }
135
136     private Class JavaDoc<T> _propertySet;
137     private PropertyMap _propertyMap;
138 }
139
Popular Tags