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.FilenameFilter;
019import java.net.MalformedURLException;
020import java.net.URL;
021import java.util.ArrayList;
022import java.util.List;
023
024import org.jadira.scanner.core.api.Locator;
025import org.jadira.scanner.core.exception.ClasspathAccessException;
026import org.jadira.scanner.core.helper.filenamefilter.JarFilenameFilter;
027
028/**
029 * Resolves a list of classpaths representing the core 'rt.jar' and any endorsed libraries
030 */
031public class JdkBaseClasspathUrlLocator implements Locator<URL> {
032
033        private static final FilenameFilter JAR_FILENAME_FILTER = new JarFilenameFilter();
034    
035        private boolean includeRtJar;
036
037        public JdkBaseClasspathUrlLocator() {
038        this(true);
039    }
040        
041        public JdkBaseClasspathUrlLocator(boolean includeRtJar) {
042            this.includeRtJar = includeRtJar;
043        }
044        
045        @Override
046        public List<URL> locate() {
047
048        List<URL> classpaths = new ArrayList<URL>();
049
050        String[] endorsedDirs = System.getProperty("java.endorsed.dirs").split(System.getProperty("path.separator"));
051        processClasspathDefinition(classpaths, endorsedDirs);
052
053        try {
054            // Can't resolve using sun.boot.class.path - vendor specific
055            if (includeRtJar) {
056                URL javaClasspath = new java.io.File(System.getProperty("java.home") + System.getProperty("file.separator") + "lib" + System.getProperty("file.separator") + "rt.jar").toURI().toURL();
057                classpaths.add(javaClasspath);
058            }
059        } catch (MalformedURLException e) {
060            throw new ClasspathAccessException("Problem constructing Java classpath: " + e.getMessage(), e);
061        }
062
063        String[] extensionDirs = System.getProperty("java.ext.dirs").split(System.getProperty("path.separator"));
064        processClasspathDefinition(classpaths, extensionDirs);
065
066
067        return classpaths;
068    }
069
070    private static void processClasspathDefinition(List<URL> classpaths, String[] extensionDirs) {
071        for (int i = 0; i < extensionDirs.length; i++) {
072            java.io.File nextDir = new java.io.File(extensionDirs[i]);
073            
074            String[] jars = nextDir.list(JAR_FILENAME_FILTER);
075            
076            if (jars != null) {
077                for (int jarIdx = 0; jarIdx < jars.length; jarIdx++) {
078                    try {
079                        URL nextJar = new URL(nextDir.toURI().toURL().toString() + jars[jarIdx]);
080                        classpaths.add(nextJar);
081                    } catch (MalformedURLException e) {
082                        throw new ClasspathAccessException("Problem constructing Java extension classpath: " + e.getMessage(), e);
083                    }
084                }
085            }
086        }
087    }
088}
089