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
024package net.sourceforge.cobertura.coveragedata;
025
026import java.util.Collection;
027import java.util.Iterator;
028import java.util.SortedMap;
029import java.util.SortedSet;
030import java.util.TreeMap;
031import java.util.TreeSet;
032
033import net.sourceforge.cobertura.CoverageIgnore;
034
035@CoverageIgnore
036public class PackageData extends CoverageDataContainer
037                implements Comparable<Object>
038{
039
040        private static final long serialVersionUID = 7;
041
042        private String name;
043
044        public PackageData(String name)
045        {
046                if (name == null)
047                        throw new IllegalArgumentException(
048                                        "Package name must be specified.");
049                this.name = name;
050        }
051    
052        public void addClassData(ClassData classData)
053        {
054                lock.lock();
055                try
056                {
057                        if (children.containsKey(classData.getBaseName()))
058                                throw new IllegalArgumentException("Package " + this.name
059                                                + " already contains a class with the name "
060                                                + classData.getBaseName());
061        
062                        // Each key is a class basename, stored as an String object.
063                        // Each value is information about the class, stored as a ClassData object.
064                        children.put(classData.getBaseName(), classData);
065                }
066                finally
067                {
068                        lock.unlock();
069                }
070        }
071
072        /**
073         * This is required because we implement Comparable.
074         */
075        public int compareTo(Object o)
076        {
077                if (!o.getClass().equals(PackageData.class))
078                        return Integer.MAX_VALUE;
079                return this.name.compareTo(((PackageData)o).name);
080        }
081
082        public boolean contains(String name)
083        {
084                lock.lock();
085                try
086                {
087                        return this.children.containsKey(name);
088                }
089                finally
090                {
091                        lock.unlock();
092                }
093        }
094
095        /**
096         * Returns true if the given object is an instance of the
097         * PackageData class, and it contains the same data as this
098         * class.
099         */
100        public boolean equals(Object obj)
101        {
102                if (this == obj)
103                        return true;
104                if ((obj == null) || !(obj.getClass().equals(this.getClass())))
105                        return false;
106
107                PackageData packageData = (PackageData)obj;
108                getBothLocks(packageData);
109                try
110                {
111                        return super.equals(obj) && this.name.equals(packageData.name);
112                }
113                finally
114                {
115                        lock.unlock();
116                        packageData.lock.unlock();
117                }
118        }
119
120        public SortedSet getClasses()
121        {
122                lock.lock();
123                try
124                {
125                        return new TreeSet(this.children.values());
126                }
127                finally
128                {
129                        lock.unlock();
130                }
131        }
132
133        public String getName()
134        {
135                return this.name;
136        }
137
138        public String getSourceFileName()
139        {
140                return this.name.replace('.', '/');
141        }
142
143        public Collection getSourceFiles()
144        {
145                SortedMap sourceFileDatas = new TreeMap();
146                
147                lock.lock();
148                try
149                {
150                        Iterator iter = this.children.values().iterator();
151                        while (iter.hasNext()) {
152                                ClassData classData = (ClassData)iter.next();
153                                String sourceFileName = classData.getSourceFileName();
154                                SourceFileData sourceFileData = (SourceFileData)sourceFileDatas.get(sourceFileName);
155                                if (sourceFileData == null)
156                                {
157                                        sourceFileData = new SourceFileData(sourceFileName);
158                                        sourceFileDatas.put(sourceFileName, sourceFileData);
159                                }
160                                sourceFileData.addClassData(classData);
161                        }
162                }
163                finally
164                {
165                        lock.unlock();
166                }
167                return sourceFileDatas.values();
168        }
169
170        public int hashCode()
171        {
172                return this.name.hashCode();
173        }
174
175}