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-2016 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 java.lang.reflect.Modifier;
44  import java.util.Iterator;
45  import java.util.List;
46  
47  import javax.annotation.Nonnull;
48  import javax.annotation.Nullable;
49  
50  import com.helger.jcodemodel.util.JCNameUtilities;
51  
52  /**
53   * References to existing classes.
54   * <p>
55   * {@link JReferencedClass} is kept in a pool so that they are shared. There is
56   * one pool for each {@link JCodeModel} object.
57   * <p>
58   * It is impossible to cache JReferencedClass globally only because there is the
59   * {@link #_package()} method, which obtains the owner {@link JPackage} object,
60   * which is scoped to JCodeModel.
61   */
62  class JReferencedClass extends AbstractJClass implements IJDeclaration
63  {
64    private final Class <?> m_aClass;
65  
66    JReferencedClass (@Nonnull final JCodeModel aOwner, @Nonnull final Class <?> aClass)
67    {
68      super (aOwner);
69      m_aClass = aClass;
70      assert !m_aClass.isArray ();
71    }
72  
73    @Override
74    public String name ()
75    {
76      return m_aClass.getSimpleName ();
77    }
78  
79    @Override
80    @Nonnull
81    public String fullName ()
82    {
83      return JCNameUtilities.getFullName (m_aClass);
84    }
85  
86    @Override
87    public String binaryName ()
88    {
89      return m_aClass.getName ();
90    }
91  
92    @Override
93    public AbstractJClass outer ()
94    {
95      final Class <?> p = m_aClass.getDeclaringClass ();
96      if (p == null)
97        return null;
98      return owner ().ref (p);
99    }
100 
101   @Override
102   @Nonnull
103   public JPackage _package ()
104   {
105     final String name = fullName ();
106 
107     // this type is array
108     if (name.indexOf ('[') != -1)
109       return owner ()._package ("");
110 
111     // other normal case
112     final int idx = name.lastIndexOf ('.');
113     if (idx < 0)
114       return owner ()._package ("");
115     return owner ()._package (name.substring (0, idx));
116   }
117 
118   @Override
119   public AbstractJClass _extends ()
120   {
121     final Class <?> sp = m_aClass.getSuperclass ();
122     if (sp == null)
123     {
124       if (isInterface ())
125         return owner ().ref (Object.class);
126       return null;
127     }
128     return owner ().ref (sp);
129   }
130 
131   @Override
132   public Iterator <AbstractJClass> _implements ()
133   {
134     final Class <?> [] aInterfaces = m_aClass.getInterfaces ();
135     return new Iterator <AbstractJClass> ()
136     {
137       private int m_nIdx = 0;
138 
139       public boolean hasNext ()
140       {
141         return m_nIdx < aInterfaces.length;
142       }
143 
144       @Nonnull
145       public AbstractJClass next ()
146       {
147         return owner ().ref (aInterfaces[m_nIdx++]);
148       }
149 
150       public void remove ()
151       {
152         throw new UnsupportedOperationException ();
153       }
154     };
155   }
156 
157   @Override
158   public boolean isInterface ()
159   {
160     return m_aClass.isInterface ();
161   }
162 
163   @Override
164   public boolean isAbstract ()
165   {
166     return Modifier.isAbstract (m_aClass.getModifiers ());
167   }
168 
169   @Override
170   @Nullable
171   public JPrimitiveType getPrimitiveType ()
172   {
173     final Class <?> v = JCodeModel.boxToPrimitive.get (m_aClass);
174     if (v != null)
175       return AbstractJType.parse (owner (), v.getName ());
176     return null;
177   }
178 
179   public void declare (final JFormatter f)
180   {
181     // Nothing to do here...
182   }
183 
184   @Override
185   public JTypeVar [] typeParams ()
186   {
187     // TODO: does JDK 1.5 reflection provides these information?
188     return super.typeParams ();
189   }
190 
191   @Override
192   protected AbstractJClass substituteParams (final JTypeVar [] variables,
193                                              final List <? extends AbstractJClass> bindings)
194   {
195     // TODO: does JDK 1.5 reflection provides these information?
196     return this;
197   }
198 }