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    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
081                validateURL(url);
082
083                urlResolved = true;
084            }
085        } finally
086        {
087            downgradeWriteLockToReadLock();
088        }
089
090
091    }
092
093    @Override
094    public boolean equals(Object obj)
095    {
096        if (obj == null) return false;
097
098        if (obj == this) return true;
099
100        if (obj.getClass() != getClass()) return false;
101
102        ClasspathResource other = (ClasspathResource) obj;
103
104        return other.classLoader == classLoader && other.getPath().equals(getPath());
105    }
106
107    @Override
108    public int hashCode()
109    {
110        return 227 ^ getPath().hashCode();
111    }
112
113    @Override
114    public String toString()
115    {
116        return "classpath:" + getPath();
117    }
118
119}