1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.tentackle.persist.wurblet;
20
21 import freemarker.template.TemplateException;
22 import org.wurbelizer.misc.Constants;
23 import org.wurbelizer.wurbel.HeapStream;
24 import org.wurbelizer.wurbel.WurbelException;
25 import org.wurbelizer.wurbel.WurbelTerminationException;
26 import org.wurbelizer.wurbel.Wurbler;
27
28 import org.tentackle.buildsupport.codegen.AbstractGenerator;
29 import org.tentackle.buildsupport.codegen.GeneratedFile;
30 import org.tentackle.buildsupport.codegen.TemplateModel;
31 import org.tentackle.common.NamingRules;
32 import org.tentackle.common.StringHelper;
33 import org.tentackle.model.Entity;
34 import org.tentackle.wurblet.ModelWurblet;
35
36 import java.io.File;
37 import java.io.IOException;
38 import java.io.PrintStream;
39 import java.util.regex.Pattern;
40
41
42
43
44
45
46
47
48 public class RemoteIncludes {
49
50
51 private final class TemplatePars {
52
53 private final TemplateModel model;
54 private final AbstractGenerator generator;
55
56 private TemplatePars() throws WurbelException {
57
58 NamingRules namingRules = NamingRules.getInstance();
59 String popPackage = wurblet.determinePackageName(popInterface);
60
61 String superPackage;
62 String superImplPackage;
63 String superInterface;
64 String superImplementation;
65
66 switch (superClassName) {
67 case "AbstractPersistentObject":
68 superInterface = "AbstractPersistentObjectRemoteDelegate";
69 superPackage = "org.tentackle.persist.trip";
70 superImplementation = "AbstractPersistentObjectRemoteDelegateImpl";
71 superImplPackage = "org.tentackle.persist.trip";
72 break;
73
74 case "AbstractPersistentOperation":
75 superInterface = "AbstractPersistentOperationRemoteDelegate";
76 superPackage = "org.tentackle.persist.trip";
77 superImplementation = "AbstractPersistentOperationRemoteDelegateImpl";
78 superImplPackage = "org.tentackle.persist.trip";
79 break;
80
81 case "AbstractDbObject":
82
83 superInterface = "AbstractDbObjectRemoteDelegate";
84 superPackage = "org.tentackle.dbms.trip";
85 superImplementation = "AbstractDbObjectRemoteDelegateImpl";
86 superImplPackage = "org.tentackle.dbms.trip";
87 break;
88
89 default:
90 String superJavaClassName = StringHelper.getPlainClassName(wurblet.getSuperClassName());
91 int dotNdx = superJavaClassName.lastIndexOf('.');
92 String superClassPackageName = dotNdx > 0 ?
93 superJavaClassName.substring(0, dotNdx) :
94 wurblet.determinePackageName(superJavaClassName);
95 if (wurblet.isOperation()) {
96 superInterface = namingRules.getOperationRemoteInterface(superClassName);
97 superPackage = namingRules.getOperationRemoteInterfacePackageName(superClassPackageName);
98 superImplementation = namingRules.getOperationRemoteImplementation(superClassName);
99 superImplPackage = namingRules.getOperationRemoteImplementationPackageName(superClassPackageName);
100 }
101 else {
102 superInterface = namingRules.getPdoRemoteInterface(superClassName);
103 superPackage = namingRules.getPdoRemoteInterfacePackageName(superClassPackageName);
104 superImplementation = namingRules.getPdoRemoteImplementation(superClassName);
105 superImplPackage = namingRules.getPdoRemoteImplementationPackageName(superClassPackageName);
106 }
107 }
108
109 model = new TemplateModel();
110 if (wurblet.isOperation()) {
111 model.putValue("operationInterface", popInterface);
112 model.putValue("operationPackage", popPackage);
113 String sourceText = wurblet.getContainer().getProperty(Wurbler.PROPSPACE_WURBLET, Wurbler.WURBLET_FILECONTENTS);
114 model.putValue("abstractOperation",
115 sourceText != null &&
116 Pattern.compile("\\s+extends\\s+" + popInterface + "\\s*<").matcher(sourceText).find());
117 }
118 else {
119 model.putValue("pdoInterface", popInterface);
120 model.putValue("pdoPackage", popPackage);
121 model.putValue("pdoInheritance", entity != null ? entity.getInheritanceType() : "");
122 }
123 model.putValue("persistenceImplementation", className);
124 model.putValue("persistenceImplPackage", packageName);
125 model.putValue("remoteInterface", remoteInterface);
126 model.putValue("remotePackage", remotePackage);
127 model.putValue("remoteImplementation", remoteImplementation);
128 model.putValue("remoteImplPackage", remoteImplPackage);
129 model.putValue("superInterface", superInterface);
130 model.putValue("superPackage", superPackage);
131 model.putValue("superImplementation", superImplementation);
132 model.putValue("superImplPackage", superImplPackage);
133
134 String templateDir = wurblet.getContainer().getProperty(Wurbler.PROPSPACE_EXTRA, "templateDir");
135 if (templateDir == null) {
136 String projectRoot = wurblet.getContainer().getProperty(Wurbler.PROPSPACE_EXTRA, "projectRoot");
137 if (projectRoot == null) {
138 throw new WurbelTerminationException("neither the WurbletProperty \"templateDir\" nor \"projectRoot\" were set.");
139 }
140 templateDir = projectRoot + File.separator + "templates" +
141 File.separator + (wurblet.isOperation() ? "operation" : "pdo");
142 }
143 generator = new AbstractGenerator() {};
144 generator.setTemplateDirectory(new File(templateDir));
145 }
146 }
147
148 private final ModelWurblet wurblet;
149 private final Entity entity;
150 private final String className;
151 private final String packageName;
152 private final String superClassName;
153 private final HeapStream interfaceStream;
154 private final HeapStream implementationStream;
155
156 private final String popInterface;
157 private final String remotePackage;
158 private final String remoteInterface;
159 private final String remoteImplPackage;
160 private final String remoteImplementation;
161
162 private TemplatePars templatePars;
163
164
165
166
167
168
169
170 public RemoteIncludes(ModelWurblet wurblet) throws WurbelException {
171
172 this.wurblet = wurblet;
173
174 className = wurblet.getClassName();
175 entity = wurblet.getEntity();
176 superClassName = entity != null && entity.getSuperEntityName() != null ?
177 entity.getSuperEntityName() :
178 StringHelper.getPlainClassName(wurblet.getSuperClassName());
179 packageName = wurblet.getPackageName();
180 popInterface = determinePopInterface(wurblet);
181
182 NamingRules namingRules = NamingRules.getInstance();
183 Wurbler container = wurblet.getContainer();
184
185 if (wurblet.isOperation()) {
186 remotePackage = namingRules.getOperationRemoteInterfacePackageName(packageName);
187 remoteInterface = namingRules.getOperationRemoteInterface(popInterface);
188 remoteImplPackage = namingRules.getOperationRemoteImplementationPackageName(packageName);
189 remoteImplementation = namingRules.getOperationRemoteImplementation(popInterface);
190 }
191 else {
192 remotePackage = namingRules.getPdoRemoteInterfacePackageName(packageName);
193 remoteInterface = namingRules.getPdoRemoteInterface(popInterface);
194 remoteImplPackage = namingRules.getPdoRemoteImplementationPackageName(packageName);
195 remoteImplementation = namingRules.getPdoRemoteImplementation(popInterface);
196 }
197
198
199 String dirName = container.getProperty(Wurbler.PROPSPACE_WURBLET, Wurbler.WURBLET_DIRNAME);
200 String packagePath = packageName.replace('.', File.separatorChar);
201 int ndx = dirName.indexOf(packagePath);
202 String pathPrefix = ndx > 0 ? dirName.substring(0, ndx) : "";
203
204 String remoteDirName = pathPrefix + File.separator + remotePackage.replace('.', File.separatorChar);
205 String remoteImplDirName = pathPrefix + File.separator + remoteImplPackage.replace('.', File.separatorChar);
206
207
208 interfaceStream = new HeapStream(container, remoteInterface + "/methods");
209 checkFile(remoteDirName, remoteInterface, "RemoteInterface.ftl");
210
211
212 implementationStream = new HeapStream(container, remoteImplementation + "/methods");
213 checkFile(remoteImplDirName, remoteImplementation, "RemoteImplementation.ftl");
214 }
215
216
217
218
219
220
221 public void discard() {
222 implementationStream.discard();
223 interfaceStream.discard();
224 }
225
226
227
228
229
230
231 public PrintStream getInterfaceStream() {
232 return interfaceStream.getStream();
233 }
234
235
236
237
238
239
240 public PrintStream getImplementationStream() {
241 return implementationStream.getStream();
242 }
243
244
245
246
247
248
249
250
251
252 private String determinePopInterface(ModelWurblet wurblet) throws WurbelException {
253 String popInterface = null;
254 try {
255 popInterface = wurblet.getPdoClassName();
256 }
257 catch (WurbelException ex) {
258
259 }
260 if (popInterface == null) {
261 popInterface = wurblet.getClassName();
262 }
263 return popInterface;
264 }
265
266
267
268
269 private void checkFile(String dirName, String remoteName, String templateName) throws WurbelException {
270 File dir = new File(dirName);
271 File file = new File(dir, remoteName + Constants.JAVA_SOURCE_EXTENSION);
272 if (!file.exists()) {
273
274 dir.mkdirs();
275 if (templatePars == null) {
276 templatePars = new TemplatePars();
277 }
278 try {
279 new GeneratedFile(templatePars.generator.createFreemarkerConfiguration(),
280 templatePars.model, templateName, file).generate();
281 }
282 catch (IOException | TemplateException e) {
283 throw new WurbelTerminationException("cannot generate " + file + " from " + templateName, e);
284 }
285 }
286 }
287
288 }