All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.facelets.util.Classpath Maven / Gradle / Ivy

Go to download

This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.

There is a newer version: 2.2.20
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2005-2007 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.faces.facelets.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * @author Jacob Hookom
 * @author Roland Huss
 * @author Ales Justin ([email protected])
 */
public final class Classpath {

    // discard any urls that begin with rar: and sar:
    // or end with their counterparts
    // as these should not be looked at for JSF related content.
    private static final String [] PREFIXES_TO_EXCLUDE = {
        "rar:",
        "sar:"
    };
    private static final String [] EXTENSIONS_TO_EXCLUDE = {
        ".rar",
        ".sar"
    };

    /**
     *
     */
    public Classpath() {
        super();
    }

    public static URL[] search(String prefix, String suffix)
          throws IOException {
        return search(Thread.currentThread().getContextClassLoader(), prefix,
                      suffix);
    }

    public static URL[] search(ClassLoader cl, String prefix, String suffix)
          throws IOException {
        Enumeration[] e = new Enumeration[]{
              cl.getResources(prefix),
              cl.getResources(prefix + "MANIFEST.MF")
        };
        Set all = new LinkedHashSet();
        URL url;
        URLConnection conn;
        JarFile jarFile;
        for (int i = 0, s = e.length; i < s; ++i) {
            while (e[i].hasMoreElements()) {
                url = (URL) e[i].nextElement();
                // Defensive programming.  Due to issue 13045 this collection
                // can contain URLs that have their spaces incorrectly escaped
                // by having %20 replaced with %2520.  This quick conditional 
                // check catches this particular case and averts it.
                String str = url.getPath();
                if (-1 != str.indexOf("%2520")) {
                    str = url.toExternalForm();
                    str = str.replace("%2520", "%20");
                    url = new URL(str);
                }
                conn = url.openConnection();
                conn.setUseCaches(false);
                if (conn instanceof JarURLConnection) {
                    jarFile = ((JarURLConnection) conn).getJarFile();
                } else {
                    jarFile = getAlternativeJarFile(url);
                }
                if (jarFile != null) {
                    searchJar(cl, all, jarFile, prefix, suffix);
                } else {
                    boolean searchDone =
                          searchDir(all, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix);
                    if (!searchDone) {
                        searchFromURL(all, prefix, suffix, url);
                    }
                }
            }
        }
        URL[] urlArray = (URL[]) all.toArray(new URL[all.size()]);
        return urlArray;
    }

    private static boolean searchDir(Set result, File file, String suffix)
          throws IOException {
        if (file.exists() && file.isDirectory()) {
            File[] fc = file.listFiles();
            String path;
            URL src;
            // protect against Windows JDK bugs for listFiles -
            // if it's null (even though it shouldn't be) return false
            if (fc == null) return false;

            for (int i = 0; i < fc.length; i++) {
                path = fc[i].getAbsolutePath();
                if (fc[i].isDirectory()) {
                    searchDir(result, fc[i], suffix);
                } else if (path.endsWith(suffix)) {
                    // result.add(new URL("file:/" + path));
                    result.add(fc[i].toURL());
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Search from URL. Fall back on prefix tokens if not able to read from
     * original url param.
     *
     * @param result the result urls
     * @param prefix the current prefix
     * @param suffix the suffix to match
     * @param url    the current url to start search
     *
     * @throws IOException for any error
     */
    private static void searchFromURL(Set result, String prefix, String suffix,
                                      URL url) throws IOException {
        boolean done = false;
        InputStream is = getInputStream(url);
        if (is != null) {
            ZipInputStream zis;
            if (is instanceof ZipInputStream) {
                zis = (ZipInputStream) is;
            } else {
                zis = new ZipInputStream(is);
            }
            try {
                ZipEntry entry = zis.getNextEntry();
                // initial entry should not be null
                // if we assume this is some inner jar
                done = (entry != null);
                while (entry != null) {
                    String entryName = entry.getName();
                    if (entryName.endsWith(suffix)) {
                        String urlString = url.toExternalForm();
                        result.add(new URL(urlString + entryName));
                    }
                    entry = zis.getNextEntry();
                }
            } finally {
                zis.close();
            }
        }
        if (!done && prefix.length() > 0) {
            // we add '/' at the end since join adds it as well
            String urlString = url.toExternalForm() + "/";
            String[] split = prefix.split("/");
            prefix = join(split, true);
            String end = join(split, false);
            int p = urlString.lastIndexOf(end);
            urlString = urlString.substring(0, p);
            for (String cur : PREFIXES_TO_EXCLUDE) {
                if (urlString.startsWith(cur)) {
                    return;
                }
            }
            url = new URL(urlString);
            searchFromURL(result, prefix, suffix, url);
        }
    }

    /**
     * Join tokens, exlude last if param equals true.
     *
     * @param tokens      the tokens
     * @param excludeLast do we exclude last token
     *
     * @return joined tokens
     */
    private static String join(String[] tokens, boolean excludeLast) {
        StringBuffer join = new StringBuffer();
        for (int i = 0; i < tokens.length - (excludeLast ? 1 : 0); i++) {
            join.append(tokens[i]).append("/");
        }
        return join.toString();
    }

    /**
     * Open input stream from url. Ignore any errors.
     *
     * @param url the url to open
     *
     * @return input stream or null if not possible
     */
    private static InputStream getInputStream(URL url) {
        try {
            return url.openStream();
        } catch (Throwable t) {
            return null;
        }
    }

    /**
     * For URLs to JARs that do not use JarURLConnection - allowed by the servlet
     * spec - attempt to produce a JarFile object all the same. Known servlet
     * engines that function like this include Weblogic and OC4J. This is not a
     * full solution, since an unpacked WAR or EAR will not have JAR "files" as
     * such.
     */
    private static JarFile getAlternativeJarFile(URL url) throws IOException {
        String urlFile = url.getFile();
        return getAlternativeJarFile(urlFile);
    }
    
    static JarFile getAlternativeJarFile(String urlFile) throws IOException {
        JarFile result = null;
        // Trim off any suffix - which is prefixed by "!/" on Weblogic
        int bangSlash = urlFile.indexOf("!/");
        // Try the less safe "!", used on OC4J
        int bang = urlFile.indexOf('!');
        int separatorIndex = -1;
        
        // if either are found, take the first one.
        if (-1 != bangSlash || -1 != bang) {
            if (bangSlash < bang) {
                separatorIndex = bangSlash;
            } else {
                separatorIndex = bang;
            }
        }

        if (separatorIndex != -1) {
            String jarFileUrl = urlFile.substring(0, separatorIndex);
            // And trim off any "file:" prefix.
            if (jarFileUrl.startsWith("file:")) {
                jarFileUrl = jarFileUrl.substring("file:".length());
                jarFileUrl = URLDecoder.decode(jarFileUrl, "UTF-8");
            }
            boolean foundExclusion = false;
            for (int i = 0; i < PREFIXES_TO_EXCLUDE.length; i++) {
                if (jarFileUrl.startsWith(PREFIXES_TO_EXCLUDE[i]) ||
                    jarFileUrl.endsWith(EXTENSIONS_TO_EXCLUDE[i])) {
                    foundExclusion = true;
                    break;
                }
            }
            if (!foundExclusion) {
                result = new JarFile(jarFileUrl);
            }

            return result;
        }
        return null;
    }

    private static void searchJar(ClassLoader cl, Set result, JarFile file,
                                  String prefix, String suffix)
          throws IOException {
        Enumeration e = file.entries();
        JarEntry entry;
        String name;
        while (e.hasMoreElements()) {
            try {
                entry = (JarEntry) e.nextElement();
            } catch (Throwable t) {
                continue;
            }
            name = entry.getName();
            if (name.startsWith(prefix) && name.endsWith(suffix)) {
                Enumeration e2 = cl.getResources(name);
                while (e2.hasMoreElements()) {
					result.add(e2.nextElement());
				}
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy