source: pythonadapter/src/main/java/geniusweb/pythonadapter/PythonPartyAdapter.java

Last change on this file was 52, checked in by ruud, 13 months ago

Fixed small issues in domaineditor.

File size: 3.8 KB
Line 
1package geniusweb.pythonadapter;
2
3import org.python.core.Py;
4import org.python.core.PyObject;
5import org.python.core.PySystemState;
6import org.python.util.PythonInterpreter;
7
8import geniusweb.actions.Action;
9import geniusweb.connection.ConnectionEnd;
10import geniusweb.inform.Inform;
11import geniusweb.party.Capabilities;
12import geniusweb.party.DefaultParty;
13import geniusweb.party.Party;
14import tudelft.utilities.listener.Listener;
15
16/**
17 * An adapter that allows you to put a python-based Party into a jar file and
18 * use it with Genius2. This adapter supports the jython dialect. The reason
19 * this adapter is needed is that you can not directly use the .py file in java,
20 * we have to load a python interpreter and connect it to your file. *
21 * <h2>Usage</h2>
22 *
23 * <ul>
24 * <li>Place an implementation of this class (PythonPartyAdapter) inside your
25 * jar.
26 * <li>Implement {@link #getPythonClass()} so that it returns the proper name of
27 * your implementation.
28 * <li>Point to this implementation as the mainclass in the META-INF file. Check
29 * the RandomPyParty example on how to do this from Maven.
30 * <li>Ensure your Python file(s) get in the root of the jar. Eg, put them in
31 * resources/ or similar inside your maven project if you use maven.
32 * <li>Add more dependencies as needed, eg to access the Bid class or for
33 * deserializing.
34 * <li>Make sure you use the jar-with-dependencies in the parties server, as
35 * that includes jython.
36 * </ul>
37 *
38 * <h2>Working principle</h2>
39 *
40 * The created jar file contains a full python interpreter plus some glue code.
41 * The glue code runs your party inside the python interpreter and routes the
42 * calls through the Geniuseb java structures.
43 */
44public abstract class PythonPartyAdapter implements Party, Listener<Inform> {
45
46 private final PythonInterpreter interpreter = new PythonInterpreter();
47 private final DefaultParty pyparty;
48
49 public PythonPartyAdapter() {
50 /**
51 * Normally Party does not have a constructor. However this is a special
52 * case where we need to initialize Python and connect the python class.
53 */
54 interpreter.exec("import sys");
55 addPath("");
56 System.out.println("code is at " + getClass().getProtectionDomain()
57 .getCodeSource().getLocation().getPath());
58 // point to sources. Should include all dependencies.
59 // should work both in Eclipse and when using the compiled jar.
60 addPath(getClass().getProtectionDomain().getCodeSource().getLocation()
61 .getPath());
62 PySystemState state = new PySystemState();
63 PyObject importer = state.getBuiltins()
64 .__getitem__(Py.newString("__import__"));
65 PyObject module = importer.__call__(Py.newString(getPythonClass()));
66 PyObject klass = module.__getattr__(getPythonClass());
67 pyparty = (DefaultParty) klass.__call__()
68 .__tojava__(DefaultParty.class);
69 }
70
71 /**
72 * @return the class/modulename of both your python module filename (eg,
73 * X.py) and your python class (eg class X) inside that file that
74 * implements {@link DefaultParty}. This file must be in the root of
75 * the jar file/working directory. The name is without an extension.
76 */
77 abstract public String getPythonClass();
78
79 @Override
80 public Capabilities getCapabilities() {
81 return pyparty.getCapabilities();
82 }
83
84 @Override
85 public String getDescription() {
86 return pyparty.getDescription();
87 }
88
89 @Override
90 public void notifyChange(Inform data) {
91 pyparty.notifyChange(data);
92 }
93
94 @Override
95 public void disconnect() {
96 pyparty.disconnect();
97 }
98
99 @Override
100 public void terminate() {
101 pyparty.terminate();
102 }
103
104 @Override
105 public void connect(ConnectionEnd<Inform, Action> connection) {
106 pyparty.connect(connection);
107 }
108
109 private void addPath(String relpath) {
110 String path = System.getProperty("user.dir") + "/" + relpath + "/";
111
112 System.out.println("adding python path " + path);
113 interpreter.exec("sys.path.insert(0, '" + path + "')");
114
115 }
116
117}
Note: See TracBrowser for help on using the repository browser.