001: package org.python.core.adapter;
002:
003: import org.python.core.Py;
004: import org.python.core.PyArray;
005: import org.python.core.PyFloat;
006: import org.python.core.PyInteger;
007: import org.python.core.PyJavaClass;
008: import org.python.core.PyJavaInstance;
009: import org.python.core.PyLong;
010: import org.python.core.PyObject;
011: import org.python.core.PyProxy;
012: import org.python.core.PyString;
013: import org.python.core.PyType;
014:
015: /**
016: * Implements the algorithm originally used in {@link Py#java2py} to adapt objects.
017: *
018: * Pre-class adapters are added to handle instances of PyObject, PyProxy and
019: * null values. Class adapters are added to handle builtin Java classes: String,
020: * Integer, Float, Double, Byte, Long, Short, Character, Class and Boolean. An
021: * adapter is added to the post-class adapters to handle wrapping arrays
022: * properly. Finally, if all of the added adapters can handle an object, it's
023: * wrapped in a PyJavaInstance.
024: *
025: */
026: public class ClassicPyObjectAdapter extends ExtensiblePyObjectAdapter {
027:
028: public ClassicPyObjectAdapter() {
029: addPreClass(new PyObjectAdapter() {
030:
031: public PyObject adapt(Object o) {
032: return (PyObject) o;
033: }
034:
035: public boolean canAdapt(Object o) {
036: return o instanceof PyObject;
037: }
038: });
039: addPreClass(new PyObjectAdapter() {
040:
041: public PyObject adapt(Object o) {
042: return ((PyProxy) o)._getPyInstance();
043: }
044:
045: public boolean canAdapt(Object o) {
046: return o instanceof PyProxy;
047: }
048: });
049: addPreClass(new PyObjectAdapter() {
050:
051: public boolean canAdapt(Object o) {
052: return o == null;
053: }
054:
055: public PyObject adapt(Object o) {
056: return Py.None;
057: }
058: });
059:
060: add(new ClassAdapter(String.class) {
061:
062: public PyObject adapt(Object o) {
063: return new PyString((String) o);
064: }
065:
066: });
067: add(new ClassAdapter(Character.class) {
068:
069: public PyObject adapt(Object o) {
070: return Py.makeCharacter((Character) o);
071: }
072:
073: });
074: add(new ClassAdapter(Class.class) {
075:
076: public PyObject adapt(Object o) {
077: Class cls = (Class) o;
078: if (PyObject.class.isAssignableFrom(cls)) {
079: return PyType.fromClass(cls);
080: }
081: return PyJavaClass.lookup(cls);
082: }
083:
084: });
085: add(new NumberToPyFloat(Double.class));
086: add(new NumberToPyFloat(Float.class));
087: add(new NumberToPyInteger(Integer.class));
088: add(new NumberToPyInteger(Byte.class));
089: add(new NumberToPyInteger(Short.class));
090: add(new ClassAdapter(Long.class) {
091:
092: public PyObject adapt(Object o) {
093: return new PyLong(((Number) o).longValue());
094: }
095:
096: });
097: add(new ClassAdapter(Boolean.class) {
098:
099: public PyObject adapt(Object o) {
100: return ((Boolean) o).booleanValue() ? Py.One : Py.Zero;
101: }
102:
103: });
104: addPostClass(new PyObjectAdapter() {
105:
106: public PyObject adapt(Object o) {
107: return new PyArray(o.getClass().getComponentType(), o);
108: }
109:
110: public boolean canAdapt(Object o) {
111: return o.getClass().isArray();
112: }
113: });
114: }
115:
116: /**
117: * Always returns true as we just return new PyJavaInstance(o) if the
118: * adapters added to the superclass can't handle o.
119: */
120: public boolean canAdapt(Object o) {
121: return true;
122: }
123:
124: public PyObject adapt(Object o) {
125: PyObject result = super .adapt(o);
126: if (result != null) {
127: return result;
128: }
129: return new PyJavaInstance(o);
130: }
131:
132: private static class NumberToPyInteger extends ClassAdapter {
133:
134: public NumberToPyInteger(Class c) {
135: super (c);
136: }
137:
138: public PyObject adapt(Object o) {
139: return new PyInteger(((Number) o).intValue());
140: }
141:
142: }
143:
144: private static class NumberToPyFloat extends ClassAdapter {
145: public NumberToPyFloat(Class c) {
146: super (c);
147: }
148:
149: public PyObject adapt(Object o) {
150: return new PyFloat(((Number) o).doubleValue());
151: }
152:
153: }
154: }
|