package org.python.core.adapter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.python.core.PyObject; /** * A PyObjectAdapter attempts to adapt a Java Object with three user fillable * groups of adapters: preClass, class and postClass. * */ public class ExtensiblePyObjectAdapter implements PyObjectAdapter { /** * @return true if a preClass, postClass or class adapter can handle this */ public boolean canAdapt(Object o) { return findAdapter(preClassAdapters, o) != null || classAdapters.containsKey(o.getClass()) || findAdapter(postClassAdapters, o) != null; } /** * Attempts to adapt o using the preClass, class and postClass adapters. * * First each of the preClass adapters is asked in the order of addition if * they can adapt o. If so, they adapt it. Otherwise, if o.getClass() is * equal to one of the classes from the added ClassAdapters, that class * adapter is used. Finally, each of the post class adapters are asked in * turn if they can adapt o. If so, that adapter handles it. If none can, * null is returned. */ public PyObject adapt(Object o) { PyObjectAdapter adapter = findAdapter(preClassAdapters, o); if (adapter != null) { return adapter.adapt(o); } adapter = (PyObjectAdapter) classAdapters.get(o.getClass()); if (adapter != null) { return adapter.adapt(o); } adapter = findAdapter(postClassAdapters, o); if (adapter != null) { return adapter.adapt(o); } return null; } /** * Adds an adapter to the list of adapters to be tried before the * ClassAdapters. */ public void addPreClass(PyObjectAdapter adapter) { preClassAdapters.add(adapter); } /** * Adds a Class handling adapter that will adapt any objects of its Class if * that object hasn't already been handled by one of the pre class adapters. */ public void add(ClassAdapter adapter) { classAdapters.put(adapter.getAdaptedClass(), adapter); } /** * Adds an adapter to the list of adapters to be tried after the * ClassAdapters. */ public void addPostClass(PyObjectAdapter converter) { postClassAdapters.add(converter); } private static PyObjectAdapter findAdapter(List l, Object o) { for (Iterator iter = l.iterator(); iter.hasNext();) { PyObjectAdapter adapter = (PyObjectAdapter) iter.next(); if (adapter.canAdapt(o)) { return adapter; } } return null; } private List preClassAdapters = new ArrayList(); private List postClassAdapters = new ArrayList(); private Map classAdapters = new HashMap(); }