001 /*
002 * Cobertura - http://cobertura.sourceforge.net/
003 *
004 * Copyright (C) 2003 jcoverage ltd.
005 * Copyright (C) 2005 Mark Doliner
006 * Copyright (C) 2005 Jeremy Thomerson
007 *
008 * Cobertura is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License as published
010 * by the Free Software Foundation; either version 2 of the License,
011 * or (at your option) any later version.
012 *
013 * Cobertura is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with Cobertura; if not, write to the Free Software
020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
021 * USA
022 */
023
024 package net.sourceforge.cobertura.coveragedata;
025
026 import java.util.Collection;
027 import java.util.Iterator;
028 import java.util.SortedMap;
029 import java.util.SortedSet;
030 import java.util.TreeMap;
031 import java.util.TreeSet;
032
033 public class PackageData extends CoverageDataContainer
034 implements Comparable, HasBeenInstrumented
035 {
036
037 private static final long serialVersionUID = 7;
038
039 private String name;
040
041 public PackageData(String name)
042 {
043 if (name == null)
044 throw new IllegalArgumentException(
045 "Package name must be specified.");
046 this.name = name;
047 }
048
049 public void addClassData(ClassData classData)
050 {
051 lock.lock();
052 try
053 {
054 if (children.containsKey(classData.getBaseName()))
055 throw new IllegalArgumentException("Package " + this.name
056 + " already contains a class with the name "
057 + classData.getBaseName());
058
059 // Each key is a class basename, stored as an String object.
060 // Each value is information about the class, stored as a ClassData object.
061 children.put(classData.getBaseName(), classData);
062 }
063 finally
064 {
065 lock.unlock();
066 }
067 }
068
069 /**
070 * This is required because we implement Comparable.
071 */
072 public int compareTo(Object o)
073 {
074 if (!o.getClass().equals(PackageData.class))
075 return Integer.MAX_VALUE;
076 return this.name.compareTo(((PackageData)o).name);
077 }
078
079 public boolean contains(String name)
080 {
081 lock.lock();
082 try
083 {
084 return this.children.containsKey(name);
085 }
086 finally
087 {
088 lock.unlock();
089 }
090 }
091
092 /**
093 * Returns true if the given object is an instance of the
094 * PackageData class, and it contains the same data as this
095 * class.
096 */
097 public boolean equals(Object obj)
098 {
099 if (this == obj)
100 return true;
101 if ((obj == null) || !(obj.getClass().equals(this.getClass())))
102 return false;
103
104 PackageData packageData = (PackageData)obj;
105 getBothLocks(packageData);
106 try
107 {
108 return super.equals(obj) && this.name.equals(packageData.name);
109 }
110 finally
111 {
112 lock.unlock();
113 packageData.lock.unlock();
114 }
115 }
116
117 public SortedSet getClasses()
118 {
119 lock.lock();
120 try
121 {
122 return new TreeSet(this.children.values());
123 }
124 finally
125 {
126 lock.unlock();
127 }
128 }
129
130 public String getName()
131 {
132 return this.name;
133 }
134
135 public String getSourceFileName()
136 {
137 return this.name.replace('.', '/');
138 }
139
140 public Collection getSourceFiles()
141 {
142 SortedMap sourceFileDatas = new TreeMap();
143
144 lock.lock();
145 try
146 {
147 Iterator iter = this.children.values().iterator();
148 while (iter.hasNext()) {
149 ClassData classData = (ClassData)iter.next();
150 String sourceFileName = classData.getSourceFileName();
151 SourceFileData sourceFileData = (SourceFileData)sourceFileDatas.get(sourceFileName);
152 if (sourceFileData == null)
153 {
154 sourceFileData = new SourceFileData(sourceFileName);
155 sourceFileDatas.put(sourceFileName, sourceFileData);
156 }
157 sourceFileData.addClassData(classData);
158 }
159 }
160 finally
161 {
162 lock.unlock();
163 }
164 return sourceFileDatas.values();
165 }
166
167 public int hashCode()
168 {
169 return this.name.hashCode();
170 }
171
172 }