source: java2python/src/main/java/tudelft/utilities/j2p/t/J2P.java@ 395

Last change on this file since 395 was 395, checked in by wouter, 2 years ago

#115 Stub get full name include the class name in the name.

File size: 5.1 KB
Line 
1package tudelft.utilities.j2p.t;
2
3import com.github.javaparser.ast.Node;
4import com.github.javaparser.ast.expr.AnnotationExpr;
5import com.github.javaparser.ast.expr.FieldAccessExpr;
6import com.github.javaparser.ast.expr.MethodCallExpr;
7import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
8
9import tudelft.utilities.j2p.formatting.Block;
10import tudelft.utilities.j2p.formatting.ExpressionLine;
11
12/**
13 * The interface to java-python translator. A translator helps to translate java
14 * Class access - function calls and field access. The result is a {@link Block}
15 * containing python code and imports. Translators for a class full.class.path
16 * are stored in the package
17 * <code>tudelft.utilities.j2p.t.full.class.path</code>. See also
18 * {@link #fetch(Object)}
19 * <p>
20 * Third party libraries should also put their packages in this same
21 * <code>tudelft.utilities.j2p.t.XXX</code> package. For instance a translator
22 * for "com.mycompany" could provide a jar with classes in
23 * <code>tudelft.utilities.j2p.t.com.mycompany</code>.
24 *
25 * @param <NodeType> the type of the java object that is translated into Python
26 * code.
27 */
28public interface J2P {
29 static final String BASE = "tudelft.utilities.j2p.t.";
30
31 /**
32 * Translates a MethodCall in java to python The impplementation may have to
33 * do further calls to translate scope and arguments. This is deliberately
34 * left to the translator so that it can manipulate function names, argument
35 * orders etc. Specific example : SCOPE.getClass() -> type(SCOPE). Here the
36 * scope SCOPE needs to be put as argument inside the call. This potential
37 * reversal requires us to pass the SCOPE into the call translator....
38 *
39 *
40 * @param callexp the {@link MethodCallExpr},
41 * @return a Block with the translation
42 */
43 public ExpressionLine call(MethodCallExpr callexp)
44 throws TranslationException;
45
46 /**
47 * @param fullname if true the full.class.path.to.FileName.ClassName is
48 * returned. If false, just the ClassName is returned.
49 * @return an {@link ExpressionLine} with the simple name, plus the required
50 * imports and installs to use this. eg when there is a Range object
51 * in the immutablelist package, this might return an ExpressionLine
52 * with text "Range", import "from tudelft.immutablelist.Range
53 * import Range" and install "utilities@http://.....".
54 */
55 public ExpressionLine getName(boolean fullname);
56
57 /**
58 * @param node a {@link FieldAccessExpr}
59 * @return code accessing the equivalent field in Python
60 */
61 public ExpressionLine field(FieldAccessExpr node)
62 throws TranslationException;
63
64 /**
65 * @param node the code that had an annotation (but this annotation is
66 * removed already)
67 * @param anno the annotation to be applied to the code. This is an
68 * annotation of the code.
69 * @return a translation of annotated code. Usually, annotate does just a
70 * normal translation of the code, with a few small modifications.
71 */
72 public <T extends Node & NodeWithAnnotations<?>> Block annotate(T node,
73 AnnotationExpr anno) throws TranslationException;
74
75 /************ FACTORY METHODS ************/
76 /**
77 *
78 * @param node the {@link Object} to be translated
79 * @return translator for that node type
80 * @throws ClassNotFoundException
81 */
82 public static J2P fetch(Object node) throws ClassNotFoundException {
83 return fetch(node.getClass().getName());
84 }
85
86 /**
87 *
88 * @param fully_qualified_name, as returned by {@link Class#getName()}. name
89 * can also be a primitive type, eg "int",
90 * referring to the java int.
91 * @return a J2P that can translate the given fully_qualified_name
92 * @throws IllegalArgumentException if the argument can not be handled, eg
93 * because there is no translator for the
94 * specified class
95 */
96 public static J2P fetch(String fully_qualified_name)
97 throws IllegalArgumentException {
98
99 if (StubPrimitive.isPrimitive(fully_qualified_name)) {
100 return new StubPrimitive(fully_qualified_name);
101 }
102
103 String trname = BASE + fully_qualified_name;
104 Class<?> clazz;
105 try {
106 clazz = Class.forName(trname);
107 } catch (ClassNotFoundException e) {
108 // it's not explicitly stubbed.
109 // If it's not a system class, try to stub it
110 if (!(fully_qualified_name.startsWith("java")))
111 try {
112 return new Stub(Class.forName(fully_qualified_name));
113 } catch (ClassNotFoundException e1) {
114 // we are going to throw anyway
115 }
116
117 throw new IllegalArgumentException("No translator found for "
118 + fully_qualified_name + ", missing class " + trname
119 + ". Please add translator or translator-modules to your project.");
120 }
121
122 // if we get here, we found explicit stub clazz
123 try {
124 if (!J2P.class.isAssignableFrom(clazz))
125 throw new ClassCastException(
126 "class " + trname + " is not implementing J2P");
127 return (J2P) clazz.getDeclaredConstructor().newInstance();
128 } catch (Exception e) {
129 throw new IllegalArgumentException("Found translator " + trname
130 + " but failed to create instance", e);
131 }
132 }
133
134}
Note: See TracBrowser for help on using the repository browser.