001// Copyright 2006-2013 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
015package org.apache.tapestry5.ioc.internal.util;
016
017import org.apache.tapestry5.ioc.Resource;
018
019import java.net.URL;
020
021/**
022 * Implementation of {@link Resource} for files on the classpath (as defined by a {@link ClassLoader}).
023 */
024public 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    @Override
054    public URL toURL()
055    {
056        try
057        {
058            acquireReadLock();
059
060            if (!urlResolved)
061            {
062                resolveURL();
063            }
064
065            return url;
066        } finally
067        {
068            releaseReadLock();
069        }
070    }
071
072    private void resolveURL()
073    {
074        try
075        {
076            upgradeReadLockToWriteLock();
077
078            if (!urlResolved)
079            {
080                url = classLoader.getResource(getPath());
081
082                validateURL(url);
083
084                urlResolved = true;
085            }
086        } finally
087        {
088            downgradeWriteLockToReadLock();
089        }
090
091
092    }
093
094    @Override
095    public boolean equals(Object obj)
096    {
097        if (obj == null) return false;
098
099        if (obj == this) return true;
100
101        if (obj.getClass() != getClass()) return false;
102
103        ClasspathResource other = (ClasspathResource) obj;
104
105        return other.classLoader == classLoader && other.getPath().equals(getPath());
106    }
107
108    @Override
109    public int hashCode()
110    {
111        return 227 ^ getPath().hashCode();
112    }
113
114    @Override
115    public String toString()
116    {
117        return "classpath:" + getPath();
118    }
119
120}