001 // Copyright 2006, 2007, 2008, 2012 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.ioc.internal.util;
016
017 import org.apache.tapestry5.ioc.Resource;
018
019 import java.net.URL;
020
021 /**
022 * Implementation of {@link Resource} for files on the classpath (as defined by a {@link ClassLoader}).
023 */
024 public final class ClasspathResource extends AbstractResource
025 {
026 private final ClassLoader classLoader;
027
028 // Guarded by lock
029 private URL url;
030
031 // Guarded by lock
032 private boolean urlResolved;
033
034 public ClasspathResource(String path)
035 {
036 this(Thread.currentThread().getContextClassLoader(), path);
037 }
038
039 public ClasspathResource(ClassLoader classLoader, String path)
040 {
041 super(path);
042 assert classLoader != null;
043
044 this.classLoader = classLoader;
045 }
046
047 @Override
048 protected Resource newResource(String path)
049 {
050 return new ClasspathResource(classLoader, path);
051 }
052
053 public URL toURL()
054 {
055 try
056 {
057 acquireReadLock();
058
059 if (!urlResolved)
060 {
061 resolveURL();
062 }
063
064 return url;
065 } finally
066 {
067 releaseReadLock();
068 }
069 }
070
071 private void resolveURL()
072 {
073 try
074 {
075 upgradeReadLockToWriteLock();
076
077 if (!urlResolved)
078 {
079 url = classLoader.getResource(getPath());
080 urlResolved = true;
081 }
082 } finally
083 {
084 downgradeWriteLockToReadLock();
085 }
086 }
087
088 @Override
089 public boolean equals(Object obj)
090 {
091 if (obj == null) return false;
092
093 if (obj == this) return true;
094
095 if (obj.getClass() != getClass()) return false;
096
097 ClasspathResource other = (ClasspathResource) obj;
098
099 return other.classLoader == classLoader && other.getPath().equals(getPath());
100 }
101
102 @Override
103 public int hashCode()
104 {
105 return 227 ^ getPath().hashCode();
106 }
107
108 @Override
109 public String toString()
110 {
111 return "classpath:" + getPath();
112 }
113
114 }