View Javadoc

1   /* ====================================================================
2    *   Copyright 2003-2005 Fabrizio Giustina.
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   */
17  package net.sf.commonclipse;
18  
19  import org.eclipse.jdt.core.IBuffer;
20  import org.eclipse.jdt.core.IMethod;
21  import org.eclipse.jdt.core.ISourceRange;
22  import org.eclipse.jdt.core.IType;
23  import org.eclipse.jdt.core.ITypeHierarchy;
24  import org.eclipse.jdt.core.JavaModelException;
25  
26  
27  /***
28   * Generator for compareTo(Object) methods.
29   * @author fgiust
30   * @version $Revision: 1.8 $ ($Author: fgiust $)
31   */
32  public final class CompareToGenerator extends Generator
33  {
34  
35      /***
36       * class name for the CompareTo builder.
37       */
38      private static final String BUILDER_CLASS = "org.apache.commons.lang.builder.CompareToBuilder"; //$NON-NLS-1$
39  
40      /***
41       * singleton for CompareToGenerator.
42       */
43      private static Generator instance = new CompareToGenerator();
44  
45      /***
46       * use getInstance() to obtain an instance of EqualsGenerator.
47       */
48      private CompareToGenerator()
49      {
50      }
51  
52      /***
53       * returns the CompareToGenerator instance.
54       * @return instance of CompareToGenerator
55       */
56      public static Generator getInstance()
57      {
58          return instance;
59      }
60  
61      /***
62       * @see net.sf.commonclipse.Generator#getMethodName()
63       */
64      protected String getMethodName()
65      {
66          return "compareTo"; //$NON-NLS-1$
67      }
68  
69      /***
70       * @see net.sf.commonclipse.Generator#createMethod(org.eclipse.jdt.core.IType)
71       */
72      protected String createMethod(IType type) throws JavaModelException
73      {
74  
75          StringBuffer buffer = new StringBuffer();
76  
77          buffer.append(getJavadoc());
78  
79          String className = type.getElementName();
80  
81          buffer.append("public int compareTo("); //$NON-NLS-1$
82  
83          if (CCPluginPreferences.getPreferences().useFinalParameters())
84          {
85              buffer.append("final "); //$NON-NLS-1$
86          }
87  
88          buffer.append("Object object) {\n"); //$NON-NLS-1$
89  
90          buffer.append(className);
91          buffer.append(" myClass = ("); //$NON-NLS-1$
92          buffer.append(className);
93          buffer.append(") object;\nreturn new CompareToBuilder()\n"); //$NON-NLS-1$
94  
95          if (CCPluginPreferences.getPreferences().appendSuperToCompareTo())
96          {
97              // add only if superclass implements the Comparable interface
98              if (doesSuperImplementsComparable(type))
99              {
100                 buffer.append(".appendSuper(super.compareTo(object))\n"); //$NON-NLS-1$
101             }
102         }
103 
104         buffer.append(buildAppenderList(type));
105 
106         buffer.append(".toComparison();\n}\n"); //$NON-NLS-1$
107         return buffer.toString();
108     }
109 
110     /***
111      * Checks if superclass implements comparable.
112      * @param type IType
113      * @return <code>true</code> if superclass implements comparable
114      * @throws JavaModelException exception thrown when analyzing type hierarchy
115      */
116     private boolean doesSuperImplementsComparable(IType type) throws JavaModelException
117     {
118         // get hierarchy
119         ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);
120 
121         // get superclass
122         IType superTypes = hierarchy.getSuperclass(type);
123 
124         // get interfaces starting from superclass
125         IType[] interfaces = hierarchy.getSuperInterfaces(superTypes);
126 
127         // does superclass implements comparable?
128         for (int j = 0; j < interfaces.length; j++)
129         {
130             if (interfaces[j].getFullyQualifiedName().equals("java.lang.Comparable")) //$NON-NLS-1$
131             {
132                 return true;
133             }
134         }
135 
136         return false;
137     }
138 
139     /***
140      * @see net.sf.commonclipse.Generator#getFieldAppender(java.lang.String, java.lang.String)
141      */
142     protected String getFieldAppender(String fieldName, String accessor)
143     {
144         return ".append(this." + fieldName + ", myClass." + fieldName + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
145     }
146 
147     /***
148      * @see net.sf.commonclipse.Generator#getExistingMethod(org.eclipse.jdt.core.IType)
149      */
150     protected IMethod getExistingMethod(IType type)
151     {
152         return type.getMethod(getMethodName(), new String[]{"QObject;"}); //$NON-NLS-1$
153     }
154 
155     /***
156      * @see net.sf.commonclipse.Generator#addImports(org.eclipse.jdt.core.IType)
157      */
158     protected void addImports(IType type) throws JavaModelException
159     {
160         type.getCompilationUnit().createImport(BUILDER_CLASS, null, null);
161 
162         addImplementsComparable(type);
163 
164     }
165 
166     /***
167      * Adds "implements Comparable" to class declaration.
168      * @param type IType
169      * @throws JavaModelException model exception
170      */
171     private void addImplementsComparable(IType type) throws JavaModelException
172     {
173 
174         // does class already implements comparable?
175         IType[] interfaces = type.newSupertypeHierarchy(null).getAllInterfaces();
176         for (int j = 0, size = interfaces.length; j < size; j++)
177         {
178             if (interfaces[j].getFullyQualifiedName().equals("java.lang.Comparable")) //$NON-NLS-1$
179             {
180                 return;
181             }
182         }
183 
184         // find class declaration
185         ISourceRange nameRange = type.getNameRange();
186 
187         // no declaration??
188         if (nameRange == null)
189         {
190             return;
191         }
192 
193         // offset for END of class name
194         int offset = nameRange.getOffset() + nameRange.getLength();
195 
196         IBuffer buffer = type.getCompilationUnit().getBuffer();
197         String contents = buffer.getText(offset, buffer.getLength() - offset);
198 
199         // warning, this doesn't handle "implements" and "{" contained in comments in the middle of the declaration!
200         int indexOfPar = contents.indexOf("{"); //$NON-NLS-1$
201 
202         contents = contents.substring(0, indexOfPar);
203 
204         int indexOfImplements = contents.indexOf("implements"); //$NON-NLS-1$
205         if (indexOfImplements > -1)
206         {
207             buffer.replace(offset + indexOfImplements + "implements".length()//$NON-NLS-1$
208             , 0, " Comparable,"); //$NON-NLS-1$
209         }
210         else
211         {
212             buffer.replace(offset, 0, " implements Comparable"); //$NON-NLS-1$
213         }
214 
215         buffer.save(null, false);
216         buffer.close();
217 
218     }
219 
220     /***
221      * Generates the method javadoc.
222      * @return String javadoc
223      */
224     private String getJavadoc()
225     {
226         return "/**\n * @see java.lang.Comparable#compareTo(Object)\n */\n"; //$NON-NLS-1$
227     }
228 
229 }