View Javadoc
1   /**
2    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3    *
4    * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
5    * Portions Copyright 2013-2017 Philip Helger + contributors
6    *
7    * The contents of this file are subject to the terms of either the GNU
8    * General Public License Version 2 only ("GPL") or the Common Development
9    * and Distribution License("CDDL") (collectively, the "License").  You
10   * may not use this file except in compliance with the License.  You can
11   * obtain a copy of the License at
12   * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
13   * or packager/legal/LICENSE.txt.  See the License for the specific
14   * language governing permissions and limitations under the License.
15   *
16   * When distributing the software, include this License Header Notice in each
17   * file and include the License file at packager/legal/LICENSE.txt.
18   *
19   * GPL Classpath Exception:
20   * Oracle designates this particular file as subject to the "Classpath"
21   * exception as provided by Oracle in the GPL Version 2 section of the License
22   * file that accompanied this code.
23   *
24   * Modifications:
25   * If applicable, add the following below the License Header, with the fields
26   * enclosed by brackets [] replaced by your own identifying information:
27   * "Portions Copyright [year] [name of copyright owner]"
28   *
29   * Contributor(s):
30   * If you wish your version of this file to be governed by only the CDDL or
31   * only the GPL Version 2, indicate your decision by adding "[Contributor]
32   * elects to include this software in this distribution under the [CDDL or GPL
33   * Version 2] license."  If you don't indicate a single choice of license, a
34   * recipient has the option to distribute your version of this file under
35   * either the CDDL, the GPL Version 2 or to extend the choice of license to
36   * its licensees as provided above.  However, if you add GPL Version 2 code
37   * and therefore, elected the GPL Version 2 license, then the option applies
38   * only if the new code is made subject to such option by the copyright
39   * holder.
40   */
41  package com.helger.jcodemodel;
42  
43  import static com.helger.jcodemodel.util.JCEqualsHelper.isEqual;
44  import static com.helger.jcodemodel.util.JCHashCodeGenerator.getHashCode;
45  
46  import java.lang.annotation.Annotation;
47  import java.util.ArrayList;
48  import java.util.Collection;
49  import java.util.Collections;
50  import java.util.List;
51  
52  import javax.annotation.Nonnull;
53  import javax.annotation.Nullable;
54  
55  import com.helger.jcodemodel.util.JCValueEnforcer;
56  
57  /**
58   * Variables and fields.
59   */
60  public class JVar implements IJAssignmentTarget, IJDeclaration, IJAnnotatable
61  {
62    /**
63     * Modifiers.
64     */
65    private final JMods m_aMods;
66  
67    /**
68     * Type of the variable
69     */
70    private AbstractJType m_aType;
71  
72    /**
73     * Name of the variable
74     */
75    private String m_sName;
76  
77    /**
78     * Initialization of the variable in its declaration
79     */
80    private IJExpression m_aInitExpr;
81  
82    /**
83     * Annotations on this variable. Lazily created.
84     */
85    private List <JAnnotationUse> m_aAnnotations;
86  
87    /**
88     * JVar constructor
89     *
90     * @param aMods
91     *        Modifiers to use
92     * @param aType
93     *        Data type of this variable
94     * @param sName
95     *        Name of this variable
96     * @param aInitExpr
97     *        Value to initialize this variable to
98     */
99    public JVar (@Nonnull final JMods aMods,
100                @Nonnull final AbstractJType aType,
101                @Nonnull final String sName,
102                @Nullable final IJExpression aInitExpr)
103   {
104     JCValueEnforcer.isTrue (JJavaName.isJavaIdentifier (sName), () -> "Illegal variable name '" + sName + "'");
105     m_aMods = aMods;
106     m_aType = aType;
107     m_sName = sName;
108     m_aInitExpr = aInitExpr;
109   }
110 
111   /**
112    * Initialize this variable
113    *
114    * @param aInitExpr
115    *        Expression to be used to initialize this field
116    * @return this for chaining
117    */
118   @Nonnull
119   public JVar init (@Nullable final IJExpression aInitExpr)
120   {
121     m_aInitExpr = aInitExpr;
122     return this;
123   }
124 
125   /**
126    * @return The init expression. May be <code>null</code>.
127    */
128   @Nullable
129   public IJExpression init ()
130   {
131     return m_aInitExpr;
132   }
133 
134   /**
135    * Get the name of this variable
136    *
137    * @return Name of the variable
138    */
139   @Nonnull
140   public String name ()
141   {
142     return m_sName;
143   }
144 
145   /**
146    * Changes the name of this variable.
147    *
148    * @param sName
149    *        New name of the variable
150    */
151   public void name (@Nonnull final String sName)
152   {
153     JCValueEnforcer.isTrue (JJavaName.isJavaIdentifier (sName), () -> "Illegal variable name '" + sName + "'");
154     m_sName = sName;
155   }
156 
157   /**
158    * Return the type of this variable.
159    *
160    * @return always non-null.
161    */
162   @Nonnull
163   public AbstractJType type ()
164   {
165     return m_aType;
166   }
167 
168   /**
169    * @return the current modifiers of this method. Always return non-null valid
170    *         object.
171    */
172   @Nonnull
173   public JMods mods ()
174   {
175     return m_aMods;
176   }
177 
178   /**
179    * Sets the type of this variable.
180    *
181    * @param aNewType
182    *        must not be null.
183    * @return the old type value. always non-null.
184    */
185   @Nonnull
186   public AbstractJType type (@Nonnull final AbstractJType aNewType)
187   {
188     JCValueEnforcer.notNull (aNewType, "NewType");
189     final AbstractJType aOldType = m_aType;
190     m_aType = aNewType;
191     return aOldType;
192   }
193 
194   /**
195    * Adds an annotation to this variable.
196    *
197    * @param aClazz
198    *        The annotation class to annotate the field with
199    * @return New {@link JAnnotationUse}
200    */
201   @Nonnull
202   public JAnnotationUse annotate (@Nonnull final AbstractJClass aClazz)
203   {
204     if (m_aAnnotations == null)
205       m_aAnnotations = new ArrayList <> ();
206     final JAnnotationUse a = new JAnnotationUse (aClazz);
207     m_aAnnotations.add (a);
208     return a;
209   }
210 
211   /**
212    * Adds an annotation to this variable.
213    *
214    * @param aClazz
215    *        The annotation class to annotate the field with
216    * @return New {@link JAnnotationUse}
217    */
218   @Nonnull
219   public JAnnotationUse annotate (@Nonnull final Class <? extends Annotation> aClazz)
220   {
221     return annotate (m_aType.owner ().ref (aClazz));
222   }
223 
224   @Nonnull
225   public Collection <JAnnotationUse> annotations ()
226   {
227     if (m_aAnnotations == null)
228       m_aAnnotations = new ArrayList <> ();
229     return Collections.unmodifiableList (m_aAnnotations);
230   }
231 
232   protected boolean isAnnotated ()
233   {
234     return m_aAnnotations != null;
235   }
236 
237   public void bind (@Nonnull final JFormatter f)
238   {
239     if (m_aAnnotations != null)
240       for (final JAnnotationUse annotation : m_aAnnotations)
241         f.generable (annotation).newline ();
242     f.generable (m_aMods).generable (m_aType).id (m_sName);
243     if (m_aInitExpr != null)
244       f.print ('=').generable (m_aInitExpr);
245   }
246 
247   public void declare (@Nonnull final JFormatter f)
248   {
249     f.var (this).print (';').newline ();
250   }
251 
252   public void generate (@Nonnull final JFormatter f)
253   {
254     f.id (m_sName);
255   }
256 
257   @Override
258   public boolean equals (final Object o)
259   {
260     if (o == this)
261       return true;
262     if (o == null || getClass () != o.getClass ())
263       return false;
264     final JVar rhs = (JVar) o;
265     return isEqual (m_sName, rhs.m_sName);
266   }
267 
268   @Override
269   public int hashCode ()
270   {
271     return getHashCode (this, m_sName);
272   }
273 }