1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.nuiton.topia.generator;
26
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.codehaus.plexus.component.annotations.Component;
31 import org.nuiton.eugene.GeneratorUtil;
32 import org.nuiton.eugene.Template;
33 import org.nuiton.eugene.java.ObjectModelTransformerToJava;
34 import org.nuiton.eugene.models.object.ObjectModel;
35 import org.nuiton.eugene.models.object.ObjectModelClass;
36 import org.nuiton.eugene.models.object.ObjectModelInterface;
37 import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
38 import org.nuiton.eugene.models.object.ObjectModelModifier;
39 import org.nuiton.eugene.models.object.ObjectModelOperation;
40 import org.nuiton.eugene.models.object.ObjectModelParameter;
41 import org.nuiton.i18n.I18n;
42 import org.nuiton.topia.TopiaContext;
43 import org.nuiton.topia.TopiaException;
44
45 import java.util.ArrayList;
46 import java.util.LinkedHashMap;
47 import java.util.Map;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 @Component(role = Template.class, hint = "org.nuiton.topia.generator.ServiceTransformer")
190 public class ServiceTransformer extends ObjectModelTransformerToJava {
191
192
193 private static final Log log = LogFactory.getLog(ServiceTransformer.class);
194 protected String modelName;
195
196 protected String defaultPackageName;
197
198 protected String exceptionName;
199
200 private static final String OP_NAME_BEGIN_TRANSACTION = "beginTransaction";
201
202 private static final String OP_NAME_COMMIT_TRANSACTION = "commitTransaction";
203
204 private static final String OP_NAME_CLOSE_TRANSACTION = "closeTransaction";
205
206 private static final String OP_NAME_TREATE_ERROR = "treateError";
207
208 public static final String PARAMETER_TRANSACTION = "transaction";
209
210 protected String getServiceAbstractClassName(String serviceName) {
211 return serviceName + "Abstract";
212 }
213
214 @Override
215 public void transformFromModel(ObjectModel model) {
216 exceptionName = TopiaGeneratorUtil.getExceptionClassTagValue(model);
217 modelName = model.getName();
218 }
219
220 @Override
221 public void transformFromInterface(ObjectModelInterface input) {
222 if (!TopiaGeneratorUtil.hasServiceStereotype(input)) {
223 return;
224 }
225
226
227 boolean needTransaction = isTransactionNeeded(input);
228
229 ObjectModelInterface serviceContract = createServiceContract(input);
230
231 createServiceAbstract(input,
232 serviceContract,
233 needTransaction);
234 }
235
236
237
238
239
240
241
242
243 protected ObjectModelInterface createServiceContract(
244 ObjectModelInterface source) {
245
246 ObjectModelInterface serviceContract =
247 createInterface(source.getName(), source.getPackageName());
248
249 setDocumentation(serviceContract, source.getDocumentation());
250 for (ObjectModelOperation op : source.getOperations()) {
251 ObjectModelOperation newOp = addOperation(serviceContract,
252 op.getName(),
253 op.getReturnType()
254 );
255 setDocumentation(newOp.getReturnParameter(),
256 op.getReturnParameter().getDocumentation()
257 );
258 for (ObjectModelParameter param : op.getParameters()) {
259 ObjectModelParameter newParam = addParameter(newOp,
260 param.getType(),
261 param.getName()
262 );
263 setDocumentation(newParam, param.getDocumentation());
264 }
265 for (String ex : op.getExceptions()) {
266 addException(newOp, ex);
267 }
268 if (exceptionName != null) {
269 addException(newOp, exceptionName);
270 }
271 setDocumentation(newOp, op.getDocumentation());
272 }
273 return serviceContract;
274 }
275
276 protected void createBeginTransactionMethod(ObjectModelInterface source,
277 ObjectModelInterface serviceContract,
278 ObjectModelClass serviceAbstract) {
279 ObjectModelOperation operation =
280 addOperation(serviceAbstract, OP_NAME_BEGIN_TRANSACTION,
281 TopiaContext.class,
282 ObjectModelJavaModifier.ABSTRACT,
283 ObjectModelJavaModifier.PROTECTED);
284 addException(operation, TopiaException.class);
285 }
286
287 protected void createCommitTransactionMethod(ObjectModelClass serviceAbstract) {
288 ObjectModelOperation operation =
289 addOperation(serviceAbstract,
290 OP_NAME_COMMIT_TRANSACTION,
291 "void",
292 ObjectModelJavaModifier.PROTECTED);
293 addParameter(operation, TopiaContext.class, PARAMETER_TRANSACTION);
294 addException(operation, TopiaException.class);
295 setOperationBody(operation,""
296
297
298
299 );
300
301 }
302
303 protected void createCloseTransactionMethod(ObjectModelInterface source,
304 ObjectModelInterface serviceContract,
305 ObjectModelClass serviceAbstract) {
306 ObjectModelOperation operation =
307 addOperation(serviceAbstract,
308 OP_NAME_CLOSE_TRANSACTION,
309 "void",
310 ObjectModelJavaModifier.ABSTRACT,
311 ObjectModelJavaModifier.PROTECTED);
312 addParameter(operation, TopiaContext.class, PARAMETER_TRANSACTION);
313 addException(operation, TopiaException.class);
314 }
315
316 protected void createTreateErrorMethod(ObjectModelInterface source,
317 ObjectModelInterface serviceContract,
318 ObjectModelClass serviceAbstract,
319 boolean needTransaction) {
320
321 ObjectModelOperation treateError1 =
322 addOperation(serviceAbstract,
323 OP_NAME_TREATE_ERROR,
324 "void",
325 ObjectModelJavaModifier.ABSTRACT,
326 ObjectModelJavaModifier.PROTECTED);
327 if (needTransaction) {
328 addParameter(treateError1, TopiaContext.class, PARAMETER_TRANSACTION);
329 }
330 addParameter(treateError1, Exception.class, "eee");
331 addParameter(treateError1, String.class, "message");
332 addParameter(treateError1, "Object...", "args");
333 if (exceptionName != null) {
334 addException(treateError1, exceptionName);
335 }
336
337 if (needTransaction) {
338 ObjectModelOperation treateError2 =
339 addOperation(serviceAbstract, OP_NAME_TREATE_ERROR, "void",
340 ObjectModelJavaModifier.PROTECTED);
341 addParameter(treateError2, Exception.class, "eee");
342 addParameter(treateError2, String.class, "message");
343 addParameter(treateError2, "Object...", "args");
344 if (exceptionName != null) {
345 addException(treateError2, exceptionName);
346 }
347
348 setOperationBody(treateError2, ""
349
350
351
352 );
353 }
354 }
355
356
357
358
359
360
361
362
363
364 protected void createServiceAbstract(ObjectModelInterface source,
365 ObjectModelInterface serviceContract,
366 boolean needTransaction) {
367
368 ObjectModelClass serviceAbstract = createAbstractClass(
369 getServiceAbstractClassName(serviceContract.getName()),
370 serviceContract.getPackageName());
371
372
373 if (needTransaction) {
374 addImport(serviceAbstract, TopiaContext.class);
375 }
376 addImport(serviceAbstract, I18n.class);
377
378
379 addInterface(serviceAbstract, serviceContract.getQualifiedName());
380
381
382
383 if (needTransaction) {
384 createBeginTransactionMethod(source,
385 serviceContract,
386 serviceAbstract);
387
388 createCommitTransactionMethod(serviceAbstract);
389
390 createCloseTransactionMethod(source,
391 serviceContract,
392 serviceAbstract);
393 }
394
395 createTreateErrorMethod(source,
396 serviceContract,
397 serviceAbstract,
398 needTransaction
399 );
400
401
402
403
404 Map<ObjectModelOperation, ObjectModelOperation> abstractExecuteMethods =
405 new LinkedHashMap<ObjectModelOperation, ObjectModelOperation>();
406
407
408 for (ObjectModelOperation operation : source.getOperations()) {
409
410 ObjectModelOperation executeOp = createOperationExecuteAbstract(
411 serviceAbstract,
412 operation,
413 needTransaction
414 );
415
416 abstractExecuteMethods.put(operation , executeOp);
417 }
418
419
420 for (Map.Entry<ObjectModelOperation, ObjectModelOperation> entry :
421 abstractExecuteMethods.entrySet()) {
422 ObjectModelOperation operation = entry.getKey();
423 ObjectModelOperation executeOperation = entry.getValue();
424 createOperationImplementation(
425 serviceAbstract,
426 executeOperation,
427 operation,
428 source.getName(),
429 needTransaction
430 );
431 }
432 }
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 protected ObjectModelOperation createOperationExecuteAbstract(
451 ObjectModelClass serviceAbstract,
452 ObjectModelOperation source,
453 boolean needTransaction) {
454 String opName = StringUtils.capitalize(source.getName());
455
456
457 ObjectModelOperation executeOperation =
458 addOperation(serviceAbstract, "execute" + opName,
459 source.getReturnType(),
460 ObjectModelJavaModifier.ABSTRACT,
461 ObjectModelJavaModifier.PROTECTED);
462
463
464
465 addException(executeOperation, Exception.class);
466
467 if (needTransaction && isTransactionNeeded(source)) {
468 addParameter(executeOperation, TopiaContext.class, PARAMETER_TRANSACTION);
469 }
470
471 if (isErrorArgsNeeded(source)) {
472
473 addParameter(executeOperation, "java.util.List<Object>", "errorArgs");
474 }
475
476
477 for (ObjectModelParameter param : source.getParameters()) {
478 addParameter(executeOperation, param.getType(), param.getName());
479 }
480 return executeOperation;
481 }
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499 protected void createOperationImplementation(
500 ObjectModelClass serviceAbstract,
501 ObjectModelOperation abstOp,
502 ObjectModelOperation source,
503 String serviceContractName,
504 boolean needTransaction) {
505
506
507
508
509 needTransaction &= isTransactionNeeded(source);
510
511
512
513
514 boolean needErrorArgs = isErrorArgsNeeded(source);
515
516
517 ObjectModelOperation implOp =
518 addOperation(serviceAbstract,
519 source.getName(),
520 source.getReturnType(),
521 ObjectModelJavaModifier.PUBLIC);
522
523 addAnnotation(serviceAbstract, implOp, Override.class.getSimpleName());
524
525 String toStringAppend = "";
526 String separatorLog = " : ";
527
528 for (ObjectModelParameter param : source.getParameters()) {
529 String paramName = param.getName();
530 addParameter(implOp, param.getType(), paramName);
531 }
532
533
534 StringBuilder buffer = new StringBuilder();
535
536
537 String abstName = abstOp.getName();
538 String abstParams =
539 GeneratorUtil.getOperationParametersListName(abstOp);
540
541
542 String abstReturnType = "";
543 String abstReturn = "";
544 String finalReturn = "";
545 String returnType = GeneratorUtil.getSimpleName(abstOp.getReturnType(),
546 true
547 );
548 if (!returnType.equals("void")) {
549 abstReturnType = returnType + " result = ";
550 abstReturn = "return result;";
551 finalReturn = "return " +
552 getReturnValue(abstOp.getReturnType()) + ";";
553 }
554
555
556 String contract =
557 GeneratorUtil.toLowerCaseFirstLetter(serviceContractName);
558 String errorKey = StringUtils.lowerCase(modelName) + ".error." +
559 contract + "." + source.getName();
560
561 String treateErrorParams = "eee, I18n.n_(\"" + errorKey + "\")";
562
563 if (needErrorArgs) {
564 addImport(serviceAbstract, ArrayList.class);
565
566 buffer.append(""
567
568
569 );
570 treateErrorParams += ", errorArgs.toArray()";
571 }
572
573 if (needTransaction) {
574
575 buffer.append(""
576
577
578
579
580
581
582 );
583
584 treateErrorParams = "transaction, " + treateErrorParams;
585 } else {
586 buffer.append(""
587
588
589
590 );
591 }
592 String implName = StringUtils.capitalize(implOp.getName());
593 String first = modelName.substring(0, 1);
594
595 buffer.append(""
596
597 );
598
599 if (needTransaction && isCommit(source, model)) {
600
601
602 buffer.append(""
603
604 );
605
606 }
607 buffer.append(""
608
609 );
610
611 if (needTransaction) {
612
613 buffer.append(""
614
615
616
617
618
619 );
620
621 }
622
623 for (String ex : source.getExceptions()) {
624 addException(implOp, ex);
625
626 String exName = GeneratorUtil.getSimpleName(ex);
627 buffer.append(""
628
629
630 );
631 }
632 if (exceptionName != null) {
633 addException(implOp, exceptionName);
634 }
635
636 buffer.append(""
637
638
639 );
640
641
642 buffer.append(""
643
644
645
646
647 );
648
649 setOperationBody(implOp, buffer.toString());
650 }
651
652
653
654
655
656
657
658
659
660 protected boolean isTransactionNeeded(ObjectModelInterface op) {
661 boolean needTransaction = true;
662
663 String transactionTag = TopiaGeneratorUtil.getTransactionTagValue(op);
664
665 if (transactionTag != null) {
666 needTransaction = Boolean.parseBoolean(transactionTag);
667 }
668 return needTransaction;
669 }
670
671
672
673
674
675
676
677
678
679 protected boolean isTransactionNeeded(ObjectModelOperation op) {
680 boolean needTransaction = true;
681
682 String transactionTag = TopiaGeneratorUtil.getTransactionTagValue(op);
683
684 if (transactionTag != null) {
685 needTransaction = Boolean.parseBoolean(transactionTag);
686 }
687 return needTransaction;
688 }
689
690
691
692
693
694
695
696
697
698
699 protected boolean isCommit(ObjectModelOperation op, ObjectModel model) {
700 boolean needCommit = false;
701
702 String tagValue = TopiaGeneratorUtil.getDoCommitTagValue(
703 op,
704 model
705 );
706 if (tagValue != null) {
707 needCommit = Boolean.parseBoolean(tagValue);
708 }
709 if (isVerbose()) {
710 log.info("commit needed for op [" + op.getName() + "] : " + needCommit);
711 }
712 return needCommit;
713 }
714
715
716
717
718
719
720
721
722
723 protected boolean isErrorArgsNeeded(ObjectModelOperation op) {
724
725 boolean needErrorArgs = false;
726
727 String errorArgsTag = TopiaGeneratorUtil.getErrorArgsTagValue(op);
728
729 if (errorArgsTag != null) {
730 needErrorArgs = Boolean.parseBoolean(errorArgsTag);
731 }
732 return needErrorArgs;
733 }
734
735
736
737
738
739
740
741
742
743 protected String getReturnValue(String returnType) {
744 try {
745
746 Primitive prim =
747 Primitive.valueOf(StringUtils.upperCase(returnType));
748 return prim.getValue();
749
750 } catch (IllegalArgumentException eee) {
751 return null;
752 }
753 }
754
755
756 protected enum Primitive {
757 BYTE("0"),
758 SHORT("0"),
759 INT("0"),
760 LONG("0"),
761 FLOAT("0."),
762 DOUBLE("0."),
763 CHAR("''"),
764 BOOLEAN("false");
765
766 private String value;
767
768 Primitive(String value) {
769 this.value = value;
770 }
771
772 public String getValue() {
773 return value;
774 }
775 }
776 }