/** * * Funf: Open Sensing Framework * Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland. * Acknowledgments: Alan Gardner * Contact: nadav@media.mit.edu * * Author(s): Pararth Shah (pararthshah717@gmail.com) * * This file is part of Funf. * * Funf is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Funf is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Funf. If not, see <http://www.gnu.org/licenses/>. * */ package edu.mit.media.funf.config; import static edu.mit.media.funf.util.LogUtil.TAG; import java.io.IOException; import java.lang.reflect.Field; import android.util.Log; import com.google.gson.Gson; import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapterFactory; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import edu.mit.media.funf.datasource.DataSource; import edu.mit.media.funf.probe.Probe.DataListener; import edu.mit.media.funf.util.AnnotationUtil; public class ListenerInjectorTypeAdapterFactory implements TypeAdapterFactory { private TypeAdapterFactory delegate; public ListenerInjectorTypeAdapterFactory(TypeAdapterFactory delegate) { this.delegate = delegate; } @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegateAdapter = delegate.create(gson, type); if (delegateAdapter == null) { return null; } else { return new TypeAdapter<T>() { @Override public void write(JsonWriter out, T value) throws IOException { delegateAdapter.write(out, value); } @Override public T read(JsonReader in) throws IOException { T value = delegateAdapter.read(in); if (value != null && value instanceof DataSource) { try { Field filtersField = AnnotationUtil.getField(ConfigRewriteUtil.FILTER_FIELD_NAME, value.getClass()); Field delegatorField = AnnotationUtil.getField(ConfigRewriteUtil.DELEGATOR_FIELD_NAME, value.getClass()); boolean isDelegatorAccessible = delegatorField.isAccessible(); delegatorField.setAccessible(true); DataListener delegator = (DataListener)delegatorField.get(value); if (filtersField != null && delegator != null) { boolean isAccessible = filtersField.isAccessible(); filtersField.setAccessible(true); Object existingFilter = filtersField.get(value); if (existingFilter == null) filtersField.set(value, delegator); else injectListener(existingFilter, delegator); filtersField.setAccessible(isAccessible); } delegatorField.setAccessible(isDelegatorAccessible); } catch (SecurityException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalArgumentException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalAccessException e) { // Swallow Log.v(TAG, e.getMessage()); } } return value; } private void injectListener(Object value, DataListener listener) { try { Field listenerField = AnnotationUtil.getField(ConfigRewriteUtil.LISTENER_FIELD_NAME, value.getClass()); if (listenerField != null && DataListener.class.isAssignableFrom(listenerField.getType())) { boolean isAccessible = listenerField.isAccessible(); listenerField.setAccessible(true); Object existingListener = listenerField.get(value); if (existingListener == null) listenerField.set(existingListener, listener); else injectListener(existingListener, listener); listenerField.setAccessible(isAccessible); return; } } catch (SecurityException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalArgumentException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalAccessException e) { // Swallow Log.v(TAG, e.getMessage()); } try { Field targetField = AnnotationUtil.getField(ConfigRewriteUtil.TARGET_FIELD_NAME, value.getClass()); if (targetField != null) { boolean isAccessible = targetField.isAccessible(); targetField.setAccessible(true); Object existingTarget = targetField.get(value); if (existingTarget != null) injectListener(existingTarget, listener); targetField.setAccessible(isAccessible); return; } } catch (SecurityException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalArgumentException e) { // Swallow Log.v(TAG, e.getMessage()); } catch (IllegalAccessException e) { // Swallow Log.v(TAG, e.getMessage()); } if (value instanceof DataSource) { ((DataSource)value).setListener(listener); return; } } }; } } }