1 | // |
2 | // (c) Copyright, Moebius Solutions, 2002 |
3 | // |
4 | // All Rights Reserved |
5 | // |
6 | // This material may be reproduced by or for the U. S. Government |
7 | // pursuant to the copyright license under the clause at |
8 | // DFARS 252.227-7013 (OCT 1988). |
9 | // |
10 | /* |
11 | * $Id: JavaClassGenerator.java,v 1.2 2004/05/25 00:25:46 adamp Exp $ |
12 | */ |
13 | package com.moesol.generator; |
14 | |
15 | import java.io.*; |
16 | import java.lang.reflect.*; |
17 | import java.util.*; |
18 | import com.moesol.generator.core.*; |
19 | import com.moesol.generator.printer.CniBeginNamespaceTypePrinter; |
20 | import com.moesol.generator.printer.CniNameTypePrinter; |
21 | import com.moesol.generator.printer.CniTypePrinter; |
22 | import com.moesol.generator.visitor.*; |
23 | |
24 | /** |
25 | * Abstract base class for code generators |
26 | */ |
27 | public class JavaClassGenerator extends ClassGenerator { |
28 | public JavaClassGenerator(Class clazz, boolean quiet, TranslationContext ctx) { |
29 | super(clazz, quiet, ctx); |
30 | } |
31 | |
32 | /** Template method */ |
33 | protected void extendClassProperties(Properties p) throws ApplyException{ |
34 | p.setProperty("extends", getExtends()); |
35 | p.setProperty(",", p.getProperty("extends").length() > 0 ? ", " : "extends"); |
36 | p.setProperty("peer_parameters", getPeerParameters()); |
37 | p.setProperty("cni_package_begin", getCniPackageBegin()); |
38 | p.setProperty("cni_package_end", getCniPackageEnd()); |
39 | p.setProperty("cni_include_protect", getCniIncludeProtect()); |
40 | p.setProperty("cni_include", getCniInclude()); |
41 | p.setProperty("cni_base", getCniBase()); |
42 | p.setProperty("cni_name", getCniName()); |
43 | if(getC2pcCoclass(m_class) != null){ |
44 | p.setProperty("coclass", getC2pcCoclass(m_class)); |
45 | } |
46 | } |
47 | |
48 | protected String getCniName() throws ApplyException { |
49 | return CniNameTypePrinter.getInstance().toString(m_class); |
50 | } |
51 | |
52 | /** Template method */ |
53 | protected String getTemplateName() throws ApplyException { |
54 | return findClassTemplate("java", "class"); |
55 | } |
56 | /** Template method */ |
57 | protected ClassGeneratorVisitor createClassVisitor(Writer out) throws ApplyException { |
58 | return new JavaClassGeneratorVisitor(out, getTranslationContext()); |
59 | } |
60 | /** Template method */ |
61 | protected String getFileSuffix(){ |
62 | return ".java"; |
63 | } |
64 | |
65 | private String getExtends() { |
66 | final StringBuffer sb = new StringBuffer(); |
67 | BaseVisitor v = new BaseVisitor() { |
68 | public void visitSuperClass(Class clazz, Class super_class) { |
69 | if (!Modifier.isPublic(super_class.getModifiers())) { |
70 | return; // we skip non-public supers. |
71 | } |
72 | sb.append("extends "); |
73 | sb.append(super_class.getName()); |
74 | } |
75 | public void visitInterface(Class clazz, Class iface, int iface_number) { |
76 | if (!Modifier.isPublic(iface.getModifiers())) { |
77 | return; // we skip non-public super ifaces. |
78 | } |
79 | if (m_generated_iface_count == 0) { |
80 | if (clazz.isInterface()) { |
81 | sb.append(" extends "); |
82 | } else { |
83 | sb.append(" implements "); |
84 | } |
85 | } else { |
86 | sb.append(", "); |
87 | } |
88 | sb.append(iface.getName()); |
89 | m_generated_iface_count++; |
90 | } |
91 | /** |
92 | * Since we skip non-public superinterface we need our own count |
93 | */ |
94 | private int m_generated_iface_count = 0; |
95 | }; |
96 | VisitClass.visitBases(m_class, v); |
97 | return sb.toString(); |
98 | } |
99 | private String getPeerParameters() { |
100 | // TODO Translation.findPeerParameters("java", m_class); |
101 | return "todo"; |
102 | } |
103 | private String getCniPackageBegin() throws ApplyException { |
104 | StringWriter sw = new StringWriter(); |
105 | try { |
106 | CniBeginNamespaceTypePrinter.getInstance().print(m_class, sw); |
107 | } catch (IOException e) { |
108 | throw new ApplyException(e); |
109 | } |
110 | return sw.toString(); |
111 | } |
112 | private static class BuildPackageEnd implements ClassNameVisitor { |
113 | public void visitPartName(String name) { |
114 | m_result.append("} "); |
115 | } |
116 | public void visitClassName(String name) { |
117 | } |
118 | public String getResult() { |
119 | return m_result.toString(); |
120 | } |
121 | private StringBuffer m_result = new StringBuffer(); |
122 | } |
123 | private String getCniPackageEnd() { |
124 | BuildPackageEnd v = new BuildPackageEnd(); |
125 | VisitClassName.visit(m_class, v); |
126 | return v.getResult(); |
127 | } |
128 | |
129 | private String getCniIncludeProtect() { |
130 | BuildFullName v = new BuildFullName("_"); |
131 | VisitClassName.visit(m_class, v); |
132 | return "_" + v.getResult() + "_h_included"; |
133 | } |
134 | private String getCniInclude() { |
135 | if (m_class.getSuperclass() == null) { |
136 | return ""; |
137 | } |
138 | return "\\#include \"" + getClassDirectory(m_class.getSuperclass()) + ".h\""; |
139 | } |
140 | private String getCniBase() throws ApplyException { |
141 | // TODO below is yacky, see jni.h |
142 | if (m_class.getSuperclass() == null) { |
143 | return "public _jobject"; |
144 | } |
145 | // if (m_class == Class.class) { |
146 | // return "public _jclass"; |
147 | // } |
148 | // if (m_class == Throwable.class) { |
149 | // return "public _jthrowable"; |
150 | // } |
151 | // if (m_class == String.class) { |
152 | // return "public _jstring"; |
153 | // } |
154 | // if (m_class.isArray()) { |
155 | // return "public _jarray"; |
156 | // } |
157 | try { |
158 | StringWriter sw = new StringWriter(); |
159 | CniTypePrinter.getInstance().print(m_class.getSuperclass(), sw); |
160 | return "public " + sw.toString(); |
161 | } catch (IOException e) { |
162 | throw new ApplyException(e); |
163 | } |
164 | } |
165 | |
166 | private static class BuildFullName implements ClassNameVisitor { |
167 | public BuildFullName(String sep) { |
168 | m_sep = sep; |
169 | } |
170 | public void visitPartName(String name) { |
171 | m_result.append(name); |
172 | m_result.append(m_sep); |
173 | } |
174 | public void visitClassName(String name) { |
175 | m_result.append(name); |
176 | } |
177 | public String getResult() { |
178 | return m_result.toString(); |
179 | } |
180 | private String m_sep; |
181 | private StringBuffer m_result = new StringBuffer(); |
182 | } |
183 | |
184 | protected String getC2pcCoclass(Class cls) throws ApplyException { |
185 | String mapped = getTransProperty("coclass." + cls.getName()); |
186 | if (mapped == null) { |
187 | return getTransProperty("coclass.*"); |
188 | } else { |
189 | return mapped; |
190 | } |
191 | } |
192 | |
193 | // additional method for each #{method} in the template... |
194 | } |