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    }