root/trunk/src/java/org/jcoderz/phoenix/report/ResourceInfo.java

Revision 1497, 10.7 kB (checked in by amandel, 3 years ago)

Make resource available by qualified classname.

  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
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 */
33package org.jcoderz.phoenix.report;
34
35import java.io.BufferedReader;
36import java.io.File;
37import java.io.FileNotFoundException;
38import java.io.FileReader;
39import java.io.IOException;
40import java.util.Collections;
41import java.util.HashMap;
42import java.util.Map;
43import java.util.logging.Level;
44import java.util.logging.Logger;
45
46import org.jcoderz.commons.util.Assert;
47import org.jcoderz.commons.util.HashCode;
48import org.jcoderz.commons.util.IoUtil;
49import org.jcoderz.commons.util.ObjectUtil;
50
51/**
52 * This class holds resource information about a Java class.
53 *
54 * @author Michael Griffel
55 */
56public final class ResourceInfo
57{
58   /** holds a map from resource name to ResourceInfo */
59    private static final Map<String, ResourceInfo> RESOURCES
60        = Collections.synchronizedMap(new HashMap<String, ResourceInfo>());
61    /** holds a map from package / classname to ResourceInfo */
62    private static final Map<String, ResourceInfo> RESOURCES_BY_CLASS
63        = Collections.synchronizedMap(new HashMap<String, ResourceInfo>());
64
65    private static final String CLASSNAME = ResourceInfo.class.getName();
66    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. */
74    private int mLinesOfCode = -1;
75    /** Lazy initialized hash code value. */
76    private int mHashCode = -1;
77
78    private ResourceInfo (String name, String pkg, String sourceDir)
79    {
80        if (logger.isLoggable(Level.FINER))
81        {
82            logger.entering(CLASSNAME, "<init>",
83                new Object[]{name, pkg, sourceDir});
84        }
85        Assert.notNull(name, "name");
86        Assert.notNull(sourceDir, "sourceDir");
87        mResourceName = checkName(name).intern();
88        mPackage = ObjectUtil.toStringOrEmpty(pkg);
89        mSourcDir = checkName(sourceDir).intern();
90        mClassname = determineClassName(name).intern();
91        if (logger.isLoggable(Level.FINER))
92        {
93            logger.exiting(CLASSNAME, "<init>", this);
94        }
95    }
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    {
107        final String resourceName = checkName(name);
108        final ResourceInfo result;
109        if (!RESOURCES.containsKey(resourceName))
110        {
111            result = new ResourceInfo(resourceName, pkg, sourceDir);
112            add(resourceName, result);
113        }
114        else
115        {
116            result = RESOURCES.get(resourceName);
117            final ResourceInfo newInfo
118                = new ResourceInfo(resourceName, pkg, sourceDir);
119            // sanity check
120            Assert.assertEquals("Ups, the ResourceInfo w/ the name "
121                + resourceName
122                + " is already registered with different parameters!",
123                result, newInfo);
124        }
125        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    {
136        String lookupName = name;
137        ResourceInfo result = RESOURCES.get(lookupName);
138        if (result == null)
139        {
140            lookupName = checkName(name);
141            result = RESOURCES.get(lookupName);
142        }
143        if (result == null)
144        {
145            logger.finer("### ResourceInfo not found for '"
146                + lookupName + "'");
147        }
148        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    {
160        final String key = combineName(packageName, className);
161        final ResourceInfo result = RESOURCES_BY_CLASS.get(key);
162        if (result == null)
163        {
164            logger.finer("### ResourceInfo not found for '"
165                + key + "'");
166        }
167        return result;
168    }
169
170    static String dump ()
171    {
172        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    {
186        int counter = 0;
187        final BufferedReader reader
188                = new BufferedReader(new FileReader(fileName));
189        try
190        {
191            while (reader.readLine() != null)
192            {
193                ++counter;
194            }
195        }
196        finally
197        {
198            IoUtil.close(reader);
199        }
200        return counter;
201    }
202
203    /** {@inheritDoc} */
204    public boolean equals (Object obj)
205    {
206        boolean result = false;
207        if (this == obj)
208        {
209            result = true;
210        }
211        else if (obj instanceof ResourceInfo)
212        {
213            final ResourceInfo o = (ResourceInfo) obj;
214            result = ObjectUtil.equals(mResourceName, o.getResourceName())
215                && ObjectUtil.equals(mPackage, o.getPackage())
216                && ObjectUtil.equals(mSourcDir, o.getSourcDir());
217        }
218        else
219        {
220            result = false;
221        }
222        return result;
223    }
224
225    /** {@inheritDoc} */
226    public int hashCode ()
227    {
228        if (mHashCode == -1)
229        {
230            final HashCode hashCode = new HashCode();
231            hashCode.hash(mResourceName);
232            hashCode.hash(mPackage);
233            hashCode.hash(mSourcDir);
234            mHashCode  = hashCode.hashCode();
235        }
236        return mHashCode;
237    }
238
239    /**
240     * Returns the linesOfCode.
241     *
242     * @return the linesOfCode.
243     */
244    public int getLinesOfCode ()
245    {
246        if (mLinesOfCode == -1)
247        {
248            try
249            {
250                mLinesOfCode = countLinesOfCode(mResourceName);
251            }
252            catch (IOException e)
253            {
254                mLinesOfCode = 0;
255                logger.log(Level.FINER,
256                        "Cannot read the resource with the name "
257                                + mResourceName, e);
258            }
259        }
260        return mLinesOfCode;
261    }
262
263    /**
264     * Returns the package.
265     *
266     * @return the package.
267     */
268    public String getPackage ()
269    {
270        return mPackage;
271    }
272
273    /**
274     * Returns the resourceName.
275     *
276     * @return the resourceName.
277     */
278    public String getResourceName ()
279    {
280        return mResourceName;
281    }
282
283    /**
284     * Returns the sourcDir.
285     *
286     * @return the sourcDir.
287     */
288    public String getSourcDir ()
289    {
290        return mSourcDir;
291    }
292
293    /** {@inheritDoc} */
294    public String toString ()
295    {
296        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    {
307        return mClassname;
308    }
309
310
311    private String determineClassName (String name)
312    {
313        String result = "";
314
315        final String magic = ".java";
316        if (name.endsWith(magic))
317        {
318            final int lastSlashPos = name.lastIndexOf(File.separator);
319            if (lastSlashPos != -1)
320            {
321                result = name.substring(lastSlashPos + File.separator.length());
322                result = result.substring(0, result.indexOf(magic));
323            }
324        }
325        return result;
326    }
327
328    private static void add (String name, ResourceInfo info)
329    {
330        synchronized (RESOURCES)
331        {
332            RESOURCES.put(name, info);
333            RESOURCES_BY_CLASS.put(
334                combineName(info.getPackage(), info.getClassname()), info);
335        }
336    }
337
338    private static String combineName (String packageName, String className)
339    {
340        return ObjectUtil.toStringOrEmpty(packageName) + "--" 
341            + ObjectUtil.toStringOrEmpty(className);
342    }
343
344    private static String checkName (String lookupName)
345    {
346        String name = ObjectUtil.toStringOrEmpty(lookupName);
347        if (!RESOURCES.containsKey(name))
348        {
349            try
350            {
351                name = new File(name).getCanonicalPath();
352            }
353            catch (IOException ex)
354            {
355                throw new RuntimeException(
356                    "Uuppss, this was not expected in 'getCanonicalPath' "
357                        + " for '" + name + "'.",
358                    ex);
359            }
360        }
361        return name;
362    }
363
364}
Note: See TracBrowser for help on using the browser.