001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.client.tide.impl; 036 037import java.beans.PropertyChangeListener; 038import java.beans.PropertyChangeSupport; 039import java.lang.reflect.Method; 040import java.util.concurrent.ConcurrentHashMap; 041 042import org.granite.client.util.WeakIdentityHashMap; 043import org.granite.logging.Logger; 044 045/** 046 * @author William DRAI 047 */ 048public class BindingUtil { 049 050 private static final Logger log = Logger.getLogger(BindingUtil.class); 051 052 private static final ConcurrentHashMap<Class<?>, Method[]> changeListenerMethodsMap = new ConcurrentHashMap<Class<?>, Method[]>(); 053 private static final WeakIdentityHashMap<Object, PropertyChangeSupport> pcsMap = new WeakIdentityHashMap<Object, PropertyChangeSupport>(); 054 055 private static Method[] getPropertyChangeListeners(Class<?> clazz) throws NoSuchMethodException { 056 Method[] m = changeListenerMethodsMap.get(clazz); 057 if (m == null) { 058 try { 059 Method add1 = clazz.getMethod("addPropertyChangeListener", PropertyChangeListener.class); 060 Method rem1 = clazz.getMethod("removePropertyChangeListener", PropertyChangeListener.class); 061 try { 062 Method add2 = clazz.getMethod("addPropertyChangeListener", String.class, PropertyChangeListener.class); 063 Method rem2 = clazz.getMethod("removePropertyChangeListener", String.class, PropertyChangeListener.class); 064 m = new Method[] { add1, rem1, add2, rem2 }; 065 } 066 catch (NoSuchMethodException e) { 067 m = new Method[] { add1, rem1 }; 068 } 069 } 070 catch (NoSuchMethodException e) { 071 m = new Method[0]; 072 } 073 changeListenerMethodsMap.put(clazz, m); 074 } 075 return m; 076 } 077 078 private static PropertyChangeSupport getProperyChangeSupport(Object bean) { 079 PropertyChangeSupport pcs = pcsMap.get(bean); 080 if (pcs == null) { 081 pcs = new PropertyChangeSupport(bean); 082 pcsMap.put(bean, pcs); 083 } 084 return pcs; 085 } 086 087 public static void addPropertyChangeListener(Object bean, PropertyChangeListener listener) { 088 try { 089 Method[] m = getPropertyChangeListeners(bean.getClass()); 090 if (m.length > 0) 091 m[0].invoke(bean, listener); 092 else 093 getProperyChangeSupport(bean).addPropertyChangeListener(listener); 094 } 095 catch (Exception e) { 096 log.debug("Could not add property change listener on %s", bean); 097 } 098 } 099 100 public static void addPropertyChangeListener(Object bean, String propertyName, PropertyChangeListener listener) { 101 try { 102 Method[] m = getPropertyChangeListeners(bean.getClass()); 103 if (m.length > 2) 104 m[2].invoke(bean, listener); 105 else 106 getProperyChangeSupport(bean).addPropertyChangeListener(propertyName, listener); 107 } 108 catch (Exception e) { 109 log.debug("Could not add property change listener %s on %s", propertyName, bean); 110 } 111 } 112 113 public static void removePropertyChangeListener(Object bean, PropertyChangeListener listener) { 114 try { 115 Method[] m = getPropertyChangeListeners(bean.getClass()); 116 if (m.length > 0) 117 m[1].invoke(bean, listener); 118 else 119 getProperyChangeSupport(bean).removePropertyChangeListener(listener); 120 } 121 catch (Exception e) { 122 log.debug("Could not remove property change listener on %s", bean); 123 } 124 } 125 126 public static void removePropertyChangeListener(Object bean, String propertyName, PropertyChangeListener listener) { 127 try { 128 Method[] m = getPropertyChangeListeners(bean.getClass()); 129 if (m.length > 2) 130 m[3].invoke(bean, listener); 131 else 132 getProperyChangeSupport(bean).removePropertyChangeListener(propertyName, listener); 133 } 134 catch (Exception e) { 135 log.debug("Could not remove property change listener %s on %s", propertyName, bean); 136 } 137 } 138}