From 7c279747beb43c7e88633a6228a155a30e6834f7 Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Mon, 27 May 2024 11:38:33 -0400 Subject: Initial import --- .../dynamic/DynamicallyAccessibleObject.java | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 israfil-foundation-dynamic/src/main/java/net/israfil/foundation/dynamic/DynamicallyAccessibleObject.java (limited to 'israfil-foundation-dynamic/src/main/java/net/israfil/foundation/dynamic/DynamicallyAccessibleObject.java') diff --git a/israfil-foundation-dynamic/src/main/java/net/israfil/foundation/dynamic/DynamicallyAccessibleObject.java b/israfil-foundation-dynamic/src/main/java/net/israfil/foundation/dynamic/DynamicallyAccessibleObject.java new file mode 100644 index 0000000..fd376a7 --- /dev/null +++ b/israfil-foundation-dynamic/src/main/java/net/israfil/foundation/dynamic/DynamicallyAccessibleObject.java @@ -0,0 +1,144 @@ +/* + * Copyright © 2003-2009 Israfil Consulting Services Corporation + * Copyright © 2003-2009 Christian Edward Gruber + * All Rights Reserved + * + * This software is licensed under the Berkeley Standard Distribution license, + * (BSD license), as defined below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Israfil Consulting Services nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * $Id: DynamicallyAccessibleObject.java 76 2006-08-03 15:37:05Z cgruber $ + */ +package net.israfil.foundation.dynamic; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.israfil.foundation.core.Strings; + +/** + * An implementation of the DynamicallyAccessible interface with the + * appropriate infrastructure for retrieving field data, via accessors if + * such are implemented, or directly from the field where not. + * + * @author Christian Edward Gruber + * @author Latest: $Author: cgruber $ + * @version $Revision: 76 $ + */ +public abstract class DynamicallyAccessibleObject extends DynamicObject implements DynamicallyAccessible { + private static Logger logger = Logger.getLogger(DynamicallyAccessibleObject.class.getName()); + + public Object get(String attributeName) { + return get(this,attributeName); + } + + public static Object get(Object receiver, String attributeName) { + try { + return _get(receiver, attributeName); + } catch (NoSuchFieldException e) { + logger.log(Level.FINE,"Object attempted to dynamically access a non-existant or unreadable field.",e); + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + logger.log(Level.FINE,"Object attempted to dynamically access a inaccessible field.",e); + throw new RuntimeException(e); + } + } + + /** @deprecated This method is deprecated in favour of the static _get(receiver, attributeName) */ + Object _get(String attributeName) throws NoSuchFieldException, IllegalAccessException { + return _get(this,attributeName); + } + + /** + * Internal _get method that throws all the exceptions, to be wrapped by public methods + * so that the various exceptions can be given meaning in different contexts (such + * as fetching data, vs. testing for the existance of something. + * + * @param attributeName + * @return + * @throws NoSuchFieldException + * @throws IllegalAccessException + */ + static Object _get(Object receiver, String attributeName) throws NoSuchFieldException, IllegalAccessException { + if (hasAccessor(receiver,attributeName)) return DynamicUtil.performOn(receiver,_getAccessorSelector(receiver,attributeName), new Object[]{}); + return receiver.getClass().getField(attributeName).get(receiver); + } + + /** + * Determines whether an attribute of the given name exists on this object's + * definition, or if not, if there is a javabeans-style accessor named + * appropriately for that attribute. Put another way, determines whether + * a get() call would work against this attribute name. + * + * The existing implementation is inefficient, but simple to maintain. + */ + public boolean hasAttribute(String attributeName) { + return hasAttribute(this,attributeName); + } + + public static boolean hasAttribute(Object receiver, String attributeName) { + try { + _get(receiver,attributeName); + return true; + } catch (NoSuchFieldException e) { + logger.log(Level.FINEST,"Object attempted to dynamically access a non-existant or unreadable field.",e); + return false; + } catch (IllegalAccessException e) { + logger.log(Level.FINEST,"Object attempted to dynamically access a inaccessible field.",e); + return false; + } + } + + protected static final String[] accessPrefixes = new String[] { "get","is" }; + + /** @deprecated This method is deprecated in favour of the static _getAccessorSelector(receiver,attribute) */ + protected String getAccessorSelector(String attributeName) { return _getAccessorSelector(this,attributeName); } + + protected static String _getAccessorSelector(Object receiver, String attributeName) { + if (attributeName == null || attributeName.equals("")) return null; + String camelAttr = camel(attributeName); + for (String prefix : accessPrefixes) { + String selector = prefix+camelAttr; + if (DynamicUtil.respondsTo(receiver,selector)) return selector; + } + // No accessor, try a NeXTSTEP-style accessor, named the same as the property. + if (DynamicUtil.respondsTo(receiver,attributeName)) return attributeName; + return null; + } + + public boolean hasAccessor(String attributeName) { + return hasAccessor(this,attributeName); + } + + public static boolean hasAccessor(Object receiver, String attributeName) { + return _getAccessorSelector(receiver,attributeName) != null; + } + + /** @deprecated This method has been moved to net.israfil.foundation.core.Strings.camel(String) */ + public static String camel(String string) { + return Strings.camel(string); + } + +} -- cgit v1.2.3