001 
002 /*
003  *  JavaDoq 1.0 - DOCUment JAVA In Source
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.javadoq.com>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package com.javadoq;
021 
022 import java.util.HashMap;
023 import java.util.Map;
024 
025 /**
026  * <p>Represents a Java type, either a class, an interface or enum.</p>
027  * 
028  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.javadoq.com" target="_blank">http://www.javadoq.com</a>
029  */
030 public class JavaType
031 {
032     /**
033      * <p>The inner type map with the simple names as the keys.</p>
034      * @since 1.0
035      */
036     public final Map<String, JavaNestedType> inners = new HashMap<String, JavaNestedType>();
037     /**
038      * <p>The super type map with the fully qualified names as the keys.</p>
039      * @since 1.0
040      */
041     public final Map<String, JavaType> supers = new HashMap<String, JavaType>();
042     /**
043      * <p>The source file that defines this type.</p>
044      * @since 1.0
045      */
046     public final SourceFile file;
047     /**
048      * <p>The simple name of this type.</p>
049      * @since 1.0
050      */
051     public final String name;
052     /**
053      * <p>The fully qualified name of this type.</p>
054      * @since 1.0
055      */
056     public final JavaName qname;
057 
058     /**
059      * <p>Constructs a {@link JavaType}.</p>
060      * @param file The source file that defines the type being constructed.
061      * @param name The simple name for the type.
062      * @param qname The fully qualified name of the type.
063      * @since 1.0
064      */
065     protected JavaType(SourceFile file, String name, JavaName qname) {
066         this.file = file;
067         this.name = name;
068         this.qname = qname;
069     }
070 
071     /**
072      * <p>Constructs a {@link JavaType}.</p>
073      * @param file The source file that defines the type being constructed.
074      * @param name The simple name for the type.
075      * @since 1.0
076      */
077     public JavaType(SourceFile file, String name) {
078         this.file = file;
079         this.name = name;
080         qname = file.pckg.name.addLast(name);
081         file.pckg.types.put(name, this);
082     }
083 
084     /**
085      * <p>Finds a Java type nested in this type.</p>
086      * @param name The simple name for the type being found.
087      * @return The matched Java type or <tt>null</tt> if it is not found.
088      * @since 1.0
089      */
090     protected final JavaType findNestedType(JavaName name) {
091         JavaType t = inners.get(name.text);
092         if (!name.isSimple) {
093             t = inners.get(name.getFirst());
094             if (t != null) {
095                 t = t.findNestedType(name.chopFirst());
096             }
097         }
098         return t;
099     }
100 
101     /**
102      * <p>Finds a Java type locally defined within this type or its super types.</p>
103      * @param name The simple name for the type being found.
104      * @return The matched Java type or <tt>null</tt> if it is not found.
105      * @since 1.0
106      */
107     protected JavaType findLocalType(JavaName name) {
108         JavaType t = findNestedType(name);
109         if (t == null) {
110             for (JavaType s : supers.values()) {
111                 t = s.findLocalType(name);
112                 if (t != null) {
113                     break;
114                 }
115             }
116         }
117         return t;
118     }
119 
120     /**
121      * <p>Finds a Java type in the scope of this type.</p>
122      * @param name The name for the type being found.
123      * @return The matched Java type or <tt>null</tt> if it is not found.
124      * @since 1.0
125      */
126     public final JavaType findType(JavaName name) {
127         JavaType t = findLocalType(name);
128         return t != null ? t : file.findType(name);
129     }
130 
131     /**
132      * <p>Searches for a Java type from the scope of this type.</p>
133      * @param name The name for the type being searched for.
134      * @return The matched Java type or <tt>null</tt> if it is not found.
135      * @since 1.0
136      */
137     public final JavaType searchType(JavaName name) {
138         while (true) {
139             JavaType t = findType(name);
140             if (t != null) {
141                 return t;
142             }
143             t = file.findType(name);
144             if (t != null) {
145                 return t;
146             }
147             if (name.isSimple) {
148                 return null;
149             }
150             name = name.chopLast();
151         }
152     }
153 
154     /**
155      * <p>Determines if the current {@link JavaType} equals another object.</p>
156      * @param o An object.
157      * @return <tt>true</tt> if the given object is an instance of {@link JavaType} and its
158      * {@link #qname} is equal to that of the current one.
159      * @since 1.0
160      */
161     @Override
162     public boolean equals(Object o) {
163         return o instanceof JavaType && ((JavaType)o).qname.equals(qname);
164     }
165 
166 
167     /**
168      * <p>Returns a hash code of the current {@link JavaType}.</p>
169      * @return A hash code of the current {@link JavaType} that is same as that of its {@link #qname}.
170      * @since 1.0
171      */
172     @Override
173     public int hashCode() {
174         return qname.hashCode();
175     }
176 
177     /**
178      * <p>Returns a string representation of this type.</p>
179      * @return The string representation of this type, that is, the fully
180      * qualified name of the type.
181      * @since 1.0
182      */
183     @Override
184     public String toString() {
185         return qname.toString();
186     }
187 }