Project Report: fawkez

Packagesummary org.jcoderz.phoenix.report

org.jcoderz.phoenix.report.ResourceInfo

LineHitsNoteSource
1  /*
2   * $Id: ResourceInfo.java 1497 2009-06-07 17:30:27Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.phoenix.report;
34  
35  import java.io.BufferedReader;
36  import java.io.File;
37  import java.io.FileNotFoundException;
38  import java.io.FileReader;
39  import java.io.IOException;
40  import java.util.Collections;
41  import java.util.HashMap;
42  import java.util.Map;
43  import java.util.logging.Level;
44  import java.util.logging.Logger;
45  
46  import org.jcoderz.commons.util.Assert;
47  import org.jcoderz.commons.util.HashCode;
48  import org.jcoderz.commons.util.IoUtil;
49  import org.jcoderz.commons.util.ObjectUtil;
50  
51  /**
52   * This class holds resource information about a Java class.
53   *
54   * @author Michael Griffel
55   */
56  public final class ResourceInfo
57  {
58     /** holds a map from resource name to ResourceInfo */
590     private static final Map<String, ResourceInfo> RESOURCES
60          = Collections.synchronizedMap(new HashMap<String, ResourceInfo>());
61      /** holds a map from package / classname to ResourceInfo */
620     private static final Map<String, ResourceInfo> RESOURCES_BY_CLASS
63          = Collections.synchronizedMap(new HashMap<String, ResourceInfo>());
64  
650     private static final String CLASSNAME = ResourceInfo.class.getName();
660     private static final Logger logger = Logger.getLogger(CLASSNAME);
67  
68      private final String mResourceName;
69      private final String mPackage;
70      private final String mSourcDir;
71      private final String mClassname;
72  
73      /** Lazy initialized number of source lines value. */
740     private int mLinesOfCode = -1;
75      /** Lazy initialized hash code value. */
760     private int mHashCode = -1;
77  
78      private ResourceInfo (String name, String pkg, String sourceDir)
790     {
800         if (logger.isLoggable(Level.FINER))
81          {
820             logger.entering(CLASSNAME, "<init>",
83                  new Object[]{name, pkg, sourceDir});
84          }
850         Assert.notNull(name, "name");
860         Assert.notNull(sourceDir, "sourceDir");
870         mResourceName = checkName(name).intern();
880         mPackage = ObjectUtil.toStringOrEmpty(pkg);
890         mSourcDir = checkName(sourceDir).intern();
900         mClassname = determineClassName(name).intern();
910         if (logger.isLoggable(Level.FINER))
92          {
930             logger.exiting(CLASSNAME, "<init>", this);
94          }
950     }
96  
97      /**
98       * Registers the a new resource with the given parameters.
99       * @param name the name of the resource.
100       * @param pkg the Java package of the resource.
101       * @param sourceDir the source directory of the resource.
102       * @return the registered resource info.
103       */
104      public static ResourceInfo register (String name, String pkg,
105              String sourceDir)
106      {
1070         final String resourceName = checkName(name);
108          final ResourceInfo result;
1090         if (!RESOURCES.containsKey(resourceName))
110          {
1110             result = new ResourceInfo(resourceName, pkg, sourceDir);
1120             add(resourceName, result);
113          }
114          else
115          {
1160             result = RESOURCES.get(resourceName);
1170             final ResourceInfo newInfo
118                  = new ResourceInfo(resourceName, pkg, sourceDir);
119              // sanity check
1200             Assert.assertEquals("Ups, the ResourceInfo w/ the name "
121                  + resourceName
122                  + " is already registered with different parameters!",
123                  result, newInfo);
124          }
1250         return result;
126      }
127  
128      /**
129       * Locates the resource with the given name.
130       *
131       * @param name resource name.
132       * @return the resource for the given name or <tt>null</tt> if not found.
133       */
134      public static ResourceInfo lookup (String name)
135      {
1360         String lookupName = name;
1370         ResourceInfo result = RESOURCES.get(lookupName);
1380         if (result == null)
139          {
1400             lookupName = checkName(name);
1410             result = RESOURCES.get(lookupName);
142          }
1430         if (result == null)
144          {
1450             logger.finer("### ResourceInfo not found for '"
146                  + lookupName + "'");
147          }
1480         return result;
149      }
150  
151      /**
152       * Searches the resource with the given class name and package.
153       *
154       * @param packageName resource package name.
155       * @param className resource class name.
156       * @return the resource for the given name or <tt>null</tt> if not found.
157       */
158      public static ResourceInfo lookup (String packageName, String className)
159      {
1600         final String key = combineName(packageName, className);
1610         final ResourceInfo result = RESOURCES_BY_CLASS.get(key);
1620         if (result == null)
163          {
1640             logger.finer("### ResourceInfo not found for '"
165                  + key + "'");
166          }
1670         return result;
168      }
169  
170      static String dump ()
171      {
1720         return RESOURCES.toString();
173      }
174  
175      /**
176       * Returns the number of lines for the given file <tt>filename</tt>.
177       * @param fileName the name of the file.
178       * @return the number of lines.
179       * @throws IOException in case of an I/O problem.
180       * @throws FileNotFoundException in case the named file does
181       *      not exists or is a directory.
182       */
183      public static int countLinesOfCode (String fileName)
184              throws IOException, FileNotFoundException
185      {
1860         int counter = 0;
1870         final BufferedReader reader
188                  = new BufferedReader(new FileReader(fileName));
189          try
190          {
1910(1)            while (reader.readLine() != null)
192              {
1930                 ++counter;
194              }
195          }
196          finally
197          {
1980             IoUtil.close(reader);
1990         }
2000         return counter;
201      }
202  
203      /** {@inheritDoc} */
204      public boolean equals (Object obj)
205      {
2060         boolean result = false;
2070         if (this == obj)
208          {
2090             result = true;
210          }
2110         else if (obj instanceof ResourceInfo)
212          {
2130             final ResourceInfo o = (ResourceInfo) obj;
2140             result = ObjectUtil.equals(mResourceName, o.getResourceName())
215                  && ObjectUtil.equals(mPackage, o.getPackage())
216                  && ObjectUtil.equals(mSourcDir, o.getSourcDir());
2170         }
218          else
219          {
2200             result = false;
221          }
2220         return result;
223      }
224  
225      /** {@inheritDoc} */
226      public int hashCode ()
227      {
2280         if (mHashCode == -1)
229          {
2300             final HashCode hashCode = new HashCode();
2310             hashCode.hash(mResourceName);
2320             hashCode.hash(mPackage);
2330             hashCode.hash(mSourcDir);
2340             mHashCode  = hashCode.hashCode();
235          }
2360         return mHashCode;
237      }
238  
239      /**
240       * Returns the linesOfCode.
241       *
242       * @return the linesOfCode.
243       */
244      public int getLinesOfCode ()
245      {
2460         if (mLinesOfCode == -1)
247          {
248              try
249              {
2500                 mLinesOfCode = countLinesOfCode(mResourceName);
251              }
2520             catch (IOException e)
253              {
2540                 mLinesOfCode = 0;
2550                 logger.log(Level.FINER,
256                          "Cannot read the resource with the name "
257                                  + mResourceName, e);
2580             }
259          }
2600         return mLinesOfCode;
261      }
262  
263      /**
264       * Returns the package.
265       *
266       * @return the package.
267       */
268      public String getPackage ()
269      {
2700         return mPackage;
271      }
272  
273      /**
274       * Returns the resourceName.
275       *
276       * @return the resourceName.
277       */
278      public String getResourceName ()
279      {
2800         return mResourceName;
281      }
282  
283      /**
284       * Returns the sourcDir.
285       *
286       * @return the sourcDir.
287       */
288      public String getSourcDir ()
289      {
2900         return mSourcDir;
291      }
292  
293      /** {@inheritDoc} */
294      public String toString ()
295      {
2960         return "[ResourceInfo: name=" + mResourceName + ", pkg=" + mPackage
297                  + ", sourceDir=" + mSourcDir + ", mClassname=" + mClassname
298                  + "]";
299      }
300  
301      /**
302       * Returns the class name.
303       * @return the class name.
304       */
305      public String getClassname ()
306      {
3070         return mClassname;
308      }
309  
310  
311      private String determineClassName (String name)
312      {
3130         String result = "";
314  
3150         final String magic = ".java";
3160         if (name.endsWith(magic))
317          {
3180             final int lastSlashPos = name.lastIndexOf(File.separator);
3190             if (lastSlashPos != -1)
320              {
3210                 result = name.substring(lastSlashPos + File.separator.length());
3220                 result = result.substring(0, result.indexOf(magic));
323              }
324          }
3250         return result;
326      }
327  
328      private static void add (String name, ResourceInfo info)
329      {
3300         synchronized (RESOURCES)
331          {
3320(2)            RESOURCES.put(name, info);
3330(3)            RESOURCES_BY_CLASS.put(
334                  combineName(info.getPackage(), info.getClassname()), info);
3350         }
3360     }
337  
338      private static String combineName (String packageName, String className)
339      {
3400         return ObjectUtil.toStringOrEmpty(packageName) + "--"
341              + ObjectUtil.toStringOrEmpty(className);
342      }
343  
344      private static String checkName (String lookupName)
345      {
3460         String name = ObjectUtil.toStringOrEmpty(lookupName);
3470         if (!RESOURCES.containsKey(name))
348          {
349              try
350              {
3510                 name = new File(name).getCanonicalPath();
352              }
3530             catch (IOException ex)
354              {
3550                 throw new RuntimeException(
356                      "Uuppss, this was not expected in 'getCanonicalPath' "
357                          + " for '" + name + "'.",
358                      ex);
3590             }
360          }
3610         return name;
362      }
363  
364  }

Findings in this File

w (1) 191 : 0 org.jcoderz.phoenix.report.ResourceInfo.countLinesOfCode(String) discards result of readLine after checking if it is nonnull
w (2) 332 : 0 class org.jcoderz.phoenix.report.ResourceInfo defines static field that appears to allow memory bloat
w (3) 333 : 0 class org.jcoderz.phoenix.report.ResourceInfo defines static field that appears to allow memory bloat