View Javadoc
1   /*
2    * #%L
3    * ToPIA :: Persistence
4    * $Id$
5    * $HeadURL$
6    * %%
7    * Copyright (C) 2004 - 2014 CodeLutin
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as 
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Lesser Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * #L%
23   */
24  
25  package org.nuiton.topia.generator;
26  
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.commons.lang3.builder.ToStringBuilder;
29  import org.codehaus.plexus.component.annotations.Component;
30  import org.nuiton.eugene.GeneratorUtil;
31  import org.nuiton.eugene.Template;
32  import org.nuiton.eugene.java.ObjectModelTransformerToJava;
33  import org.nuiton.eugene.models.object.ObjectModelAssociationClass;
34  import org.nuiton.eugene.models.object.ObjectModelAttribute;
35  import org.nuiton.eugene.models.object.ObjectModelClass;
36  import org.nuiton.eugene.models.object.ObjectModelClassifier;
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  
41  import java.beans.PropertyChangeListener;
42  import java.beans.PropertyChangeSupport;
43  import java.io.Serializable;
44  
45  import static org.nuiton.topia.generator.TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType;
46  import static org.nuiton.topia.generator.TopiaGeneratorUtil.shouldGenerateDTOTopiaIdTagValue;
47  
48  
49  /*{generator option: parentheses = false}*/
50  
51  /*{generator option: writeString = +}*/
52  
53  /**
54   * Created: 14 déc. 2009
55   *
56   * @author tchemit &lt;chemit@codelutin.com&gt;
57   * @version $Id$ 
58   * @since 2.3.0
59   */
60  @Component(role = Template.class, hint = "org.nuiton.topia.generator.EntityDTOTransformer")
61  public class EntityDTOTransformer extends ObjectModelTransformerToJava {
62  
63      public boolean isEntity(String type) {
64          ObjectModelClassifier clazz = model.getClassifier(type);
65          return clazz != null && ! clazz.isEnum()
66                 && TopiaGeneratorUtil.isEntity(clazz);
67      }
68  
69      @Override
70      public void transformFromClass(ObjectModelClass clazz) {
71          if (!TopiaGeneratorUtil.isEntity(clazz)) {
72              return;
73          }
74          String clazzName = clazz.getName();
75          ObjectModelClass result;
76          result = createClass(clazzName + "DTO", clazz.getPackageName());
77          addImport(result, ToStringBuilder.class);
78          addImport(result, PropertyChangeListener.class);
79  
80          setDocumentation(result, "Implantation DTO pour l'entité " + StringUtils.capitalize(clazzName) + ".");
81          String extendClass = "";
82          for (ObjectModelClass parent : clazz.getSuperclasses()) {
83              extendClass = parent.getQualifiedName() + "DTO";
84              // no multi-inheritance in java
85              break;
86          }
87          if (extendClass.length() > 0) {
88              setSuperClass(result, extendClass);
89          }
90          addInterface(result, Serializable.class);
91  
92  
93          addAttributes(result,clazz);
94          
95          addOperations(result,clazz);
96  
97      }
98  
99      protected void addAttributes(ObjectModelClass result, ObjectModelClass clazz) {
100 
101         String svUID = TopiaGeneratorUtil.findTagValue("dto-serialVersionUID", clazz, model);
102         if (svUID != null) {
103             addAttribute(result, "serialVersionUID", "long", svUID, ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
104         }
105 
106         boolean generateDTOId = shouldGenerateDTOTopiaIdTagValue(clazz, model);
107         if (generateDTOId) {
108             addAttribute(result, "topiaId", "String");
109         }
110 
111         ObjectModelAttribute attr2;
112         for (ObjectModelAttribute attr : clazz.getAttributes()) {
113             ObjectModelAttribute reverse = attr.getReverseAttribute();
114 
115             // pour les asso quoi qu'il arrive il faut les lier des 2 cotes
116             // pour pouvoir supprimer en cascade l'asso lors de la suppression
117             // d'un des cotes
118             if (!(attr.isNavigable()
119                     || hasUnidirectionalRelationOnAbstractType(reverse, model)
120                     || attr.hasAssociationClass())) {
121                 continue;
122             }
123 
124             String attrVisibility = attr.getVisibility();
125             ObjectModelModifier modifier = ObjectModelJavaModifier.fromVisibility(attrVisibility);
126             if (!attr.hasAssociationClass()) {
127                 String attrType = attr.getType();
128                 String attrName = attr.getName();
129                 if (isEntity(attrType)) {
130                     attrType += "DTO";
131                 }
132                 if (!GeneratorUtil.isNMultiplicity(attr)) {
133                     attr2 = addAttribute(result, attrName, attrType, null, modifier);
134                 } else {
135                     attr2 = addAttribute(result, attrName, attrType + "[]", null, modifier);
136                 }
137             } else {
138                 String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr);
139                 String assocClassFQN = attr.getAssociationClass().getQualifiedName();
140                 if (!GeneratorUtil.isNMultiplicity(attr)) {
141                     attr2 = addAttribute(result, GeneratorUtil.toLowerCaseFirstLetter(assocAttrName), assocClassFQN + "DTO", null, modifier);
142                 } else {
143                     attr2 = addAttribute(result, GeneratorUtil.toLowerCaseFirstLetter(assocAttrName), assocClassFQN + "DTO[]", null, modifier);
144                 }
145             }
146             if (attr2 != null) {
147                 if (TopiaGeneratorUtil.hasDocumentation(attr)) {
148                     setDocumentation(attr2, attr.getDocumentation());
149                 }
150 
151                 String annotation = TopiaGeneratorUtil.getAnnotationTagValue(attr);
152                 if (!StringUtils.isEmpty(annotation)) {
153                     addAnnotation(result, attr2, annotation);
154                 }
155             }
156         }
157 
158         //Déclaration des attributs d'une classe d'associations
159         if (clazz instanceof ObjectModelAssociationClass) {
160             ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) clazz;
161             for (ObjectModelAttribute attr : assoc.getParticipantsAttributes()) {
162                 if (attr != null) {
163                     String attrVisibility = attr.getVisibility();
164                     ObjectModelModifier modifier = ObjectModelJavaModifier.fromVisibility(attrVisibility);
165                     String attrType = attr.getType();
166                     String attrName = attr.getName();
167                     if (isEntity(attrType)) {
168                         attrType += "DTO";
169                     }
170                     addAttribute(result, GeneratorUtil.toLowerCaseFirstLetter(attrName), attrType, null, modifier);
171                 }
172             }
173         }
174 
175         addAttribute(result,"p", PropertyChangeSupport.class,"new PropertyChangeSupport(this)",ObjectModelJavaModifier.PROTECTED,ObjectModelJavaModifier.FINAL);
176     }
177 
178     protected void addOperations(ObjectModelClass result,ObjectModelClass clazz) {
179 
180         boolean generateDTOId = shouldGenerateDTOTopiaIdTagValue(clazz, model);
181         ObjectModelOperation op;
182         if (generateDTOId) {
183             op = addOperation(result, "setTopiaId", "void", ObjectModelJavaModifier.PUBLIC);
184             addParameter(op, "String", "topiaId");
185             setOperationBody(op, ""
186 /*{
187         this.topiaId = topiaId;
188     }*/
189             );
190 
191             op = addOperation(result, "getTopiaId", "String", ObjectModelJavaModifier.PUBLIC);
192             setOperationBody(op, ""
193 /*{
194         return topiaId;
195     }*/
196             );
197         }
198 
199         op = addOperation(result, "addPropertyChangeListener", "void");
200         addParameter(op,PropertyChangeListener.class,"listener");
201         setOperationBody(op,""
202 /*{
203         p.addPropertyChangeListener(listener);
204     }*/
205         );
206 
207         op = addOperation(result, "addPropertyChangeListener", "void");
208         addParameter(op, String.class, "propertyName");
209         addParameter(op, PropertyChangeListener.class, "listener");
210         setOperationBody(op, ""
211 /*{
212         p.addPropertyChangeListener(propertyName, listener);
213     }*/
214         );
215 
216         op = addOperation(result, "removePropertyChangeListener", "void");
217         addParameter(op, PropertyChangeListener.class, "listener");
218         setOperationBody(op, ""
219 /*{
220         p.removePropertyChangeListener(listener);
221     }*/
222         );
223 
224         op = addOperation(result, "removePropertyChangeListener", "void");
225         addParameter(op, String.class, "propertyName");
226         addParameter(op, PropertyChangeListener.class, "listener");
227         setOperationBody(op, ""
228 /*{
229         p.removePropertyChangeListener(propertyName, listener);
230     }*/
231         );
232 
233         for (ObjectModelAttribute attr : clazz.getAttributes()) {
234 
235             ObjectModelAttribute reverse = attr.getReverseAttribute();
236 
237             if (!(attr.isNavigable() || hasUnidirectionalRelationOnAbstractType(reverse, model))) {
238                 continue;
239             }
240 
241             String attrName = attr.getName();
242 
243             if (!attr.hasAssociationClass()) {
244                 String attrType = attr.getType();
245                 if (isEntity(attrType)) {
246                     attrType += "DTO";
247                 }
248                 String setterName = getJavaBeanMethodName("set", attrName);
249                 String getterName = getJavaBeanMethodName("get", attrName);
250                 if (!GeneratorUtil.isNMultiplicity(attr)) {
251                     op = addOperation(result, setterName, "void", ObjectModelJavaModifier.PUBLIC);
252                     addParameter(op, attrType, "value");
253                     setOperationBody(op, ""
254 /*{
255         <%=attrType%> oldValue = this.<%=attrName%>;
256         this.<%=attrName%> = value;
257         p.firePropertyChange("<%=attrName%>", oldValue, value);
258     }*/
259                     );
260 
261                     op = addOperation(result, getterName, attrType, ObjectModelJavaModifier.PUBLIC);
262                     setOperationBody(op, ""
263 /*{
264         return <%=attrName%>;
265     }*/
266                     );
267 
268                        } else {
269 
270                     op = addOperation(result, setterName, "void", ObjectModelJavaModifier.PUBLIC);
271                     addParameter(op, attrType+"[]", "values");
272                     setOperationBody(op, ""
273 /*{
274         <%=attrType%>[] oldValues = this.<%=attrName%>;
275         this.<%=attrName%> = values;
276         p.firePropertyChange("<%=attrName%>", oldValues, values);
277     }*/
278                     );
279 
280                     op = addOperation(result, getterName, attrType+"[]", ObjectModelJavaModifier.PUBLIC);
281                     setOperationBody(op, ""
282 /*{
283         return <%=attrName%>;
284     }*/
285                     );
286                 }
287             } else {
288                 String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr);
289                 String propertyName = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName);
290                 String assocClassFQN = attr.getAssociationClass().getQualifiedName();
291                 String setterName = getJavaBeanMethodName("set", assocAttrName);
292                 String getterName = getJavaBeanMethodName("get", assocAttrName);
293                 if (!GeneratorUtil.isNMultiplicity(attr)) {
294                     op = addOperation(result, setterName, "void", ObjectModelJavaModifier.PUBLIC);
295                     addParameter(op, assocClassFQN + "DTO", "association");
296                     setOperationBody(op, ""
297 /*{
298         <%=assocClassFQN%>DTO oldAssocation= this.<%=propertyName%>;
299         this.<%=propertyName%> = association;
300         p.firePropertyChange("<%=attrName%>", oldAssocation, assocation);
301     }*/
302                     );
303 
304                     op = addOperation(result, getterName, assocClassFQN + "DTO", ObjectModelJavaModifier.PUBLIC);
305                     setOperationBody(op, ""
306 /*{
307         return <%=propertyName%>;
308     }*/
309                     );
310 
311                 } else {
312                     op = addOperation(result, setterName, "void", ObjectModelJavaModifier.PUBLIC);
313                     addParameter(op, assocClassFQN + "DTO[]", "values");
314                     setOperationBody(op, ""
315 /*{
316         <%=assocClassFQN%>DTO[] oldValues = this.<%=propertyName%>;
317         this.<%=propertyName%> = values;
318         p.firePropertyChange("<%=attrName%>", oldValues, values);
319     }*/
320                     );
321 
322                     op = addOperation(result, getterName, assocClassFQN + "DTO[]", ObjectModelJavaModifier.PUBLIC);
323                     setOperationBody(op, ""
324 /*{
325         return this.<%=propertyName%>;
326     }*/
327                     );
328                 }
329             }
330         }
331 
332         op = addOperation(result,"toString",String.class, ObjectModelJavaModifier.PUBLIC);
333         StringBuilder buffer = new StringBuilder();
334 
335         buffer.append(""
336 /*{
337         String result = new ToStringBuilder(this).
338 }*/
339                 );
340 
341         for (Object o : clazz.getAttributes()) {
342             ObjectModelAttribute attr = (ObjectModelAttribute) o;
343             //FIXME possibilité de boucles (non directes)
344             ObjectModelClass attrEntity = null;
345             if (model.hasClass(attr.getType())) {
346                 attrEntity = model.getClass(attr.getType());
347             }
348             boolean isEntity = attrEntity != null && TopiaGeneratorUtil.isEntity(attrEntity);
349             ObjectModelAttribute reverse = attr.getReverseAttribute();
350             if (isEntity && (reverse == null || !reverse.isNavigable()) && !attr.hasAssociationClass() || !isEntity) {
351             	String attrName = attr.getName();
352                 buffer.append(""
353 /*{            append("<%=attrName%>", this.<%=attrName%>).
354 }*/
355                 );
356             }
357         }
358         buffer.append(""
359 /*{         toString();
360         return result;
361 }*/
362         );
363         setOperationBody(op, buffer.toString());
364     }
365 }