001/*
002 *  Copyright 2012 Chris Pheby
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.jadira.scanner.file.locator;
017
018import java.io.File;
019import java.net.MalformedURLException;
020import java.net.URL;
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Set;
024
025import javax.servlet.ServletContext;
026
027import org.jadira.scanner.core.api.Locator;
028import org.jadira.scanner.core.exception.ClasspathAccessException;
029
030/**
031 * Utilities for resolving urls against the classpath of a Web Archive
032 */
033public class WebappClasspathUrlLocator implements Locator<URL> {
034
035        private final ServletContext servletContext;
036
037        public WebappClasspathUrlLocator(ServletContext servletContext) {
038                this.servletContext = servletContext;
039        }
040        
041        @Override
042        public List<URL> locate() {
043
044        List<URL> list = new ArrayList<URL>();
045        @SuppressWarnings("unchecked") Set<String> libJars = servletContext.getResourcePaths("/WEB-INF/lib");
046        for (String jar : libJars) {
047            try {
048                list.add(servletContext.getResource(jar));
049            } catch (MalformedURLException e) {
050                throw new ClasspathAccessException(e);
051            }
052        }
053        list.add(findWebInfClassesPath(servletContext));
054        return list;
055    }
056
057    /**
058     * Find the URL pointing to "/WEB-INF/classes" This method may not work in conjunction with
059     * IteratorFactory if your servlet container does not extract the /WEB-INF/classes into a real
060     * file-based directory
061     * @param servletContext
062     * @return null if cannot determin /WEB-INF/classes
063     */
064    private static URL findWebInfClassesPath(ServletContext servletContext) {
065        String path = servletContext.getRealPath("/WEB-INF/classes");
066        if (path == null) {
067            return null;
068        }
069        File fp = new File(path);
070        if (!fp.exists()) {
071            return null;
072        }
073        try {
074            return fp.toURI().toURL();
075        } catch (MalformedURLException e) {
076            throw new ClasspathAccessException(e);
077        }
078    }
079}