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 }