View Javadoc

1   /*
2    *  Copyright 2001-2013 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.beans.gen;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  /**
25   * A generator of set methods.
26   * 
27   * @author Stephen Colebourne
28   */
29  abstract class SetterGen {
30  
31      /** The known setter generators. */
32      static final Map<String, SetterGen> SETTERS = new HashMap<String, SetterGen>();
33      static {
34          SETTERS.put("", NoSetterGen.INSTANCE);
35          SETTERS.put("smart", SmartSetterGen.INSTANCE);
36          SETTERS.put("set", SetSetterGen.INSTANCE);
37          SETTERS.put("setClearAddAll", SetClearAddAllSetterGen.INSTANCE);
38          SETTERS.put("setClearPutAll", SetClearPutAllSetterGen.INSTANCE);
39          SETTERS.put("manual", NoSetterGen.INSTANCE);
40      }
41  
42      /**
43       * Generates the setter method.
44       * @param prop  the property data, not null
45       * @return the generated code, not null
46       */
47      static SetterGen of(GeneratableProperty prop) {
48          SetterGen gen = SETTERS.get(prop.getSetStyle());
49          if (gen == null) {
50              throw new RuntimeException("Unable to locate setter generator '" + prop.getSetStyle() + "'");
51          }
52          return gen;
53      }
54  
55      //-----------------------------------------------------------------------
56      /**
57       * Checks if a setter method is possible.
58       * 
59       * @param prop  the property data, not null
60       * @return true if a setter is possible
61       */
62      abstract boolean isSetterGenerated(GeneratableProperty prop);
63  
64      /**
65       * Generates the setter method.
66       * 
67       * @param prop  the property data, not null
68       * @return the generated code, not null
69       */
70      abstract List<String> generateSetter(GeneratableProperty prop);
71  
72      /**
73       * Generates the setter method invocation.
74       * This is just the method name.
75       * 
76       * @param prop  the property data, not null
77       * @return the generated code, null if no setter
78       */
79      String generateSetInvoke(GeneratableProperty prop) {
80          return "set" + prop.getUpperName();
81      }
82  
83      //-----------------------------------------------------------------------
84      static class SmartSetterGen extends SetterGen {
85          static final SetterGen INSTANCE = new SmartSetterGen();
86          @Override
87          boolean isSetterGenerated(GeneratableProperty prop) {
88              if (prop.isFinal()) {
89                  if (prop.isCollectionType() || prop.isMapType()) {
90                      return true;
91                  }
92                  return false;
93              } else {
94                  return SetSetterGen.INSTANCE.isSetterGenerated(prop);
95              }
96          }
97          @Override
98          List<String> generateSetter(GeneratableProperty prop) {
99              if (prop.isFinal()) {
100                 if (prop.isCollectionType()) {
101                     return SetClearAddAllSetterGen.INSTANCE.generateSetter(prop);
102                 }
103                 if (prop.isMapType()) {
104                     return SetClearPutAllSetterGen.INSTANCE.generateSetter(prop);
105                 }
106                 return Collections.emptyList();
107             } else {
108                 return SetSetterGen.INSTANCE.generateSetter(prop);
109             }
110         }
111         @Override
112         String generateSetInvoke(GeneratableProperty prop) {
113             if (prop.isFinal()) {
114                 if (prop.isCollectionType()) {
115                     return SetClearAddAllSetterGen.INSTANCE.generateSetInvoke(prop);
116                 }
117                 if (prop.isMapType()) {
118                     return SetClearPutAllSetterGen.INSTANCE.generateSetInvoke(prop);
119                 }
120                 return null;
121             } else {
122                 return SetSetterGen.INSTANCE.generateSetInvoke(prop);
123             }
124         }
125     }
126 
127     static class SetSetterGen extends SetterGen {
128         static final SetterGen INSTANCE = new SetSetterGen();
129         @Override
130         boolean isSetterGenerated(GeneratableProperty prop) {
131             return true;
132         }
133         @Override
134         List<String> generateSetter(GeneratableProperty prop) {
135             List<String> list = new ArrayList<String>();
136             list.add("\t/**");
137             list.add("\t * Sets " + prop.getFirstComment());
138             for (String comment : prop.getComments()) {
139                 list.add("\t * " + comment);
140             }
141             list.add("\t * @param " + prop.getPropertyName() + "  the new value of the property" +
142                     (prop.isNotNull() ? ", not null" : ""));
143             list.add("\t */");
144             if (prop.isDeprecated()) {
145                 list.add("\t@Deprecated");
146             }
147             list.add("\tpublic void set" + prop.getUpperName() + "(" + prop.getType() +  " " + prop.getPropertyName() + ") {");
148             if (prop.isValidated()) {
149                 list.add("\t\t" + prop.getValidationMethodName() + "(" + prop.getPropertyName() + ", \"" + prop.getPropertyName() + "\");");
150             }
151             list.add("\t\tthis." + prop.getFieldName() + " = " + prop.getPropertyName() + ";");
152             list.add("\t}");
153             list.add("");
154             return list;
155         }
156     }
157 
158     static class SetClearAddAllSetterGen extends SetterGen {
159         static final SetterGen INSTANCE = new SetClearAddAllSetterGen();
160         @Override
161         boolean isSetterGenerated(GeneratableProperty prop) {
162             return true;
163         }
164         @Override
165         List<String> generateSetter(GeneratableProperty prop) {
166             return doGenerateBulkSetter(prop, "addAll");
167         }
168     }
169 
170     static class SetClearPutAllSetterGen extends SetterGen {
171         static final SetterGen INSTANCE = new SetClearPutAllSetterGen();
172         @Override
173         boolean isSetterGenerated(GeneratableProperty prop) {
174             return true;
175         }
176         @Override
177         List<String> generateSetter(GeneratableProperty prop) {
178             return doGenerateBulkSetter(prop, "putAll");
179         }
180     }
181 
182     static class NoSetterGen extends SetterGen {
183         static final SetterGen INSTANCE = new NoSetterGen();
184         @Override
185         boolean isSetterGenerated(GeneratableProperty prop) {
186             return false;
187         }
188         @Override
189         List<String> generateSetter(GeneratableProperty prop) {
190             return Collections.emptyList();
191         }
192     }
193 
194     private static List<String> doGenerateBulkSetter(GeneratableProperty prop, String alterMethod) {
195         List<String> list = new ArrayList<String>();
196         list.add("\t/**");
197         list.add("\t * Sets " + prop.getFirstComment());
198         for (String comment : prop.getComments()) {
199             list.add("\t * " + comment);
200         }
201         list.add("\t * @param " + prop.getPropertyName() + "  the new value of the property");
202         list.add("\t */");
203         if (prop.isDeprecated()) {
204             list.add("\t@Deprecated");
205         }
206         list.add("\tpublic void set" + prop.getUpperName() + "(" + prop.getType() +  " " + prop.getPropertyName() + ") {");
207         list.add("\t\tthis." + prop.getFieldName() + ".clear();");
208         list.add("\t\tthis." + prop.getFieldName() + "." + alterMethod + "(" + prop.getPropertyName() + ");");
209         list.add("\t}");
210         list.add("");
211         return list;
212     }
213 }