All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.beehive.controls.api.properties.PropertySetProxy Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Header:$
 */
package org.apache.beehive.controls.api.properties;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * The PropertySetProxy class is a dynamic proxy {@link InvocationHandler} class that exposes the
 * values held within a PropertyMap as an Object implementing an annotation type interface.
 * 

* This enables properties resolved using the {@link PropertyMap}'s hiearchical resolution mechanism to * be exposed to the client of the proxy in the same way that Java 5 annotations are * exposed using raw Java reflection APIs. A proxy of this type should behave identically * to the one returned from a call to AnnotatedElement.getAnnotation(), but backed * by a richer, more dynamic resolution mechanism. * * @see java.lang.reflect.Proxy * @see java.lang.reflect.InvocationHandler * @see java.lang.reflect.AnnotatedElement#getAnnotation * @see org.apache.beehive.controls.api.properties.PropertySet * @see org.apache.beehive.controls.api.properties.PropertyMap */ public class PropertySetProxy implements InvocationHandler { /** * Creates a new proxy instance implementing the PropertySet interface and backed * by the data from the property map. * * @param propertySet an annotation type that has the PropertySet meta-annotation * @param propertyMap the PropertyMap containing property values backing the proxy * @return proxy that implements the PropertySet interface */ public static T getProxy(Class propertySet, PropertyMap propertyMap) { assert propertySet != null && propertyMap != null; if (!propertySet.isAnnotation()) throw new IllegalArgumentException(propertySet + " is not an annotation type"); return (T)Proxy.newProxyInstance(propertySet.getClassLoader(), new Class [] {propertySet }, new PropertySetProxy(propertySet, propertyMap)); } /** * Private constructor, called only from the getProxy factory method */ private PropertySetProxy(Class propertySet, PropertyMap propertyMap) { _propertySet = propertySet; _propertyMap = propertyMap; } // // InvocationHandler.invoke // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Handle cases where Object/Annotation methods are called on this // proxy. We were getting null back from Annotation.annotationType. Object value = null; if (method.getDeclaringClass() == Object.class) { try { if (method.getName().equals("getClass")) { value = _propertySet; } else { value = method.invoke(_propertyMap, args); } } catch (Exception e) { e.printStackTrace(); } } else if (method.getDeclaringClass() == Annotation.class && method.getName().equals("annotationType")) { value = _propertySet; } else { // Query the nested value in the property map PropertyKey key = new PropertyKey(_propertySet, method.getName()); value = _propertyMap.getProperty(key); // If the returned value is itself a PropertyMap (i.e. a nested annotation type), // then wrap it in a PropertySetProxy instance before returning. if (value instanceof PropertyMap) { PropertyMap propertyMap = (PropertyMap)value; value = getProxy(propertyMap.getMapClass(), propertyMap); } } return value; } /** * Returns the PropertySet annotation type associated with the proxy */ public Class getPropertySet() { return _propertySet; } /** * Returns the underlying PropertyMap containing the property values exposed by the * proxy. */ public PropertyMap getPropertyMap() { return _propertyMap; } private Class _propertySet; private PropertyMap _propertyMap; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy