001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar 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 GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.java.bytecode.asm;
021
022 import java.util.Collection;
023 import java.util.HashMap;
024 import java.util.HashSet;
025 import java.util.Map;
026 import java.util.Set;
027
028 import org.sonar.java.bytecode.asm.AsmClassProvider.DETAIL_LEVEL;
029 import org.sonar.squid.api.SourceCodeEdgeUsage;
030
031 public final class AsmClass extends AsmResource {
032
033 private String internalName;
034 private DETAIL_LEVEL level;
035 private AsmClass superClass;
036 private Set<AsmClass> children;
037 private Map<String, AsmMethod> methods = new HashMap<String, AsmMethod>();
038 private Map<String, AsmField> fields = new HashMap<String, AsmField>();
039 private int noc = 0;
040
041 public AsmClass(String internalName, DETAIL_LEVEL level) {
042 this.internalName = internalName;
043 setDetailLevel(level);
044 }
045
046 public AsmClass(String internalName) {
047 this.internalName = internalName;
048 }
049
050 void setDetailLevel(DETAIL_LEVEL level) {
051 this.level = level;
052 }
053
054 DETAIL_LEVEL getDetailLevel() {
055 return level;
056 }
057
058 public String getInternalName() {
059 return internalName;
060 }
061
062 void addMethod(AsmMethod asmMethod) {
063 methods.put(asmMethod.getKey(), asmMethod);
064 }
065
066 public Collection<AsmMethod> getMethods() {
067 return methods.values();
068 }
069
070 public Collection<AsmField> getFields() {
071 return fields.values();
072 }
073
074 void addField(AsmField field) {
075 fields.put(field.getName(), field);
076 }
077
078 public AsmField getField(String fieldName) {
079 return fields.get(fieldName);
080 }
081
082 AsmField getFieldOrCreateIt(String fieldName) {
083 AsmField field = getField(fieldName);
084 if (field != null) {
085 return field;
086 }
087 field = new AsmField(this, fieldName);
088 addField(field);
089 return field;
090 }
091
092 public AsmMethod getMethod(String key) {
093 return methods.get(key);
094 }
095
096 AsmMethod getMethodOrCreateIt(String key) {
097 AsmMethod method = getMethod(key);
098 if (method != null) {
099 return method;
100 }
101 method = new AsmMethod(this, key);
102 method.setBodyLoaded(false);
103 addMethod(method);
104 return method;
105 }
106
107 void setSuperClass(AsmClass superClass) {
108 this.superClass = superClass;
109 superClass.addChildren(this);
110 addEdge(new AsmEdge(this, superClass, SourceCodeEdgeUsage.EXTENDS));
111 }
112
113 private void addChildren(AsmClass asmClass) {
114 if ("java/lang/Object".equals(getInternalName())) {
115 return;
116 }
117 if (children == null) {
118 children = new HashSet<AsmClass>();
119 }
120 children.add(asmClass);
121 }
122
123 public AsmClass getSuperClass() {
124 return superClass;
125 }
126
127 void addInterface(AsmClass implementedInterface) {
128 implementedInterface.addChildren(this);
129 addEdge(new AsmEdge(this, implementedInterface, SourceCodeEdgeUsage.IMPLEMENTS));
130 }
131
132 Set<AsmClass> getInterfaces() {
133 return getImplementedInterfaces();
134 }
135
136 @Override
137 public boolean equals(Object object) {
138 if (this == object) {
139 return true;
140 }
141 if (object instanceof AsmClass) {
142 return internalName.equals(((AsmClass) object).internalName);
143 }
144 return false;
145 }
146
147 @Override
148 public int hashCode() {
149 return internalName.hashCode();
150 }
151
152 public int getNumberOfChildren() {
153 if (children != null && noc == 0) {
154 for (AsmClass child : children) {
155 noc += child.getNumberOfChildren() + 1;
156 }
157 }
158 return noc;
159 }
160
161 }