alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ExtCheck.java)

This example Java source code file (ExtCheck.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributes, extcheck, file, implementation, ioexception, jar, jarfile, jarloader, malformedurlexception, manifest, net, network, security, specification, string, stringtokenizer, url, util, www

The ExtCheck.java Java example source code

/*
 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.extcheck;

import java.util.*;
import java.net.MalformedURLException;
import java.util.Vector;
import java.io.*;
import java.util.StringTokenizer;
import java.net.URL;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.net.URLConnection;
import java.security.Permission;
import java.util.jar.*;
import java.net.JarURLConnection;
import sun.net.www.ParseUtil;

/**
 * ExtCheck reports on clashes between a specified (target)
 * jar file and jar files already installed in the extensions
 * directory.
 *
 * @author Benedict Gomes
 * @since 1.2
 */

public class ExtCheck {

    private static final boolean DEBUG = false;

    // The following strings hold the values of the version variables
    // for the target jar file
    private String targetSpecTitle;
    private String targetSpecVersion;
    private String targetSpecVendor;
    private String targetImplTitle;
    private String targetImplVersion;
    private String targetImplVendor;
    private String targetsealed;

    /* Flag to indicate whether extra information should be dumped to stdout */
    private boolean verboseFlag;

    /*
     * Create a new instance of the jar reporting tool for a particular
     * targetFile.
     * @param targetFile is the file to compare against.
     * @param verbose indicates whether to dump filenames and manifest
     *                information (on conflict) to the standard output.
     */
    static ExtCheck create(File targetFile, boolean verbose) {
        return new ExtCheck(targetFile, verbose);
    }

    private ExtCheck(File targetFile, boolean verbose) {
        verboseFlag = verbose;
        investigateTarget(targetFile);
    }


    private void investigateTarget(File targetFile) {
        verboseMessage("Target file:" + targetFile);
        Manifest targetManifest = null;
        try {
            File canon = new File(targetFile.getCanonicalPath());
            URL url = ParseUtil.fileToEncodedURL(canon);
            if (url != null){
                JarLoader loader = new JarLoader(url);
                JarFile jarFile = loader.getJarFile();
                targetManifest = jarFile.getManifest();
            }
        } catch (MalformedURLException e){
            error("Malformed URL ");
        } catch (IOException e) {
            error("IO Exception ");
        }
        if (targetManifest == null)
            error("No manifest available in "+targetFile);
        Attributes attr = targetManifest.getMainAttributes();
        if (attr != null) {
            targetSpecTitle   = attr.getValue(Name.SPECIFICATION_TITLE);
            targetSpecVersion = attr.getValue(Name.SPECIFICATION_VERSION);
            targetSpecVendor  = attr.getValue(Name.SPECIFICATION_VENDOR);
            targetImplTitle   = attr.getValue(Name.IMPLEMENTATION_TITLE);
            targetImplVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
            targetImplVendor  = attr.getValue(Name.IMPLEMENTATION_VENDOR);
            targetsealed      = attr.getValue(Name.SEALED);
        } else {
            error("No attributes available in the manifest");
        }
        if (targetSpecTitle == null)
            error("The target file does not have a specification title");
        if (targetSpecVersion == null)
            error("The target file does not have a specification version");
        verboseMessage("Specification title:" + targetSpecTitle);
        verboseMessage("Specification version:" + targetSpecVersion);
        if (targetSpecVendor != null)
            verboseMessage("Specification vendor:" + targetSpecVendor);
        if (targetImplVersion != null)
            verboseMessage("Implementation version:" + targetImplVersion);
        if (targetImplVendor != null)
            verboseMessage("Implementation vendor:" + targetImplVendor);
        verboseMessage("");
    }

    /**
     * Verify that none of the jar files in the install directory
     * has the same specification-title and the same or a newer
     * specification-version.
     *
     * @return Return true if the target jar file is newer
     *        than any installed jar file with the same specification-title,
     *        otherwise return false
     */
    boolean checkInstalledAgainstTarget(){
        String s = System.getProperty("java.ext.dirs");
        File [] dirs;
        if (s != null) {
            StringTokenizer st =
                new StringTokenizer(s, File.pathSeparator);
            int count = st.countTokens();
            dirs = new File[count];
            for (int i = 0; i < count; i++) {
                dirs[i] = new File(st.nextToken());
            }
        } else {
            dirs = new File[0];
        }

        boolean result = true;
        for (int i = 0; i < dirs.length; i++) {
            String[] files = dirs[i].list();
            if (files != null) {
                for (int j = 0; j < files.length; j++) {
                    try {
                        File f = new File(dirs[i],files[j]);
                        File canon = new File(f.getCanonicalPath());
                        URL url = ParseUtil.fileToEncodedURL(canon);
                        if (url != null){
                            result = result && checkURLRecursively(1,url);
                        }
                    } catch (MalformedURLException e){
                        error("Malformed URL");
                    } catch (IOException e) {
                        error("IO Exception");
                    }
                }
            }
        }
        if (result) {
            generalMessage("No conflicting installed jar found.");
        } else {
            generalMessage("Conflicting installed jar found. "
                           + " Use -verbose for more information.");
        }
        return result;
    }

    /**
     * Recursively verify that a jar file, and any urls mentioned
     * in its class path, do not conflict with the target jar file.
     *
     * @param indent is the current nesting level
     * @param url is the path to the jar file being checked.
     * @return true if there is no newer URL, otherwise false
     */
    private boolean checkURLRecursively(int indent, URL url)
        throws IOException
    {
        verboseMessage("Comparing with " + url);
        JarLoader jarloader = new JarLoader(url);
        JarFile j = jarloader.getJarFile();
        Manifest man = j.getManifest();
        if (man != null) {
            Attributes attr = man.getMainAttributes();
            if (attr != null){
                String title   = attr.getValue(Name.SPECIFICATION_TITLE);
                String version = attr.getValue(Name.SPECIFICATION_VERSION);
                String vendor  = attr.getValue(Name.SPECIFICATION_VENDOR);
                String implTitle   = attr.getValue(Name.IMPLEMENTATION_TITLE);
                String implVersion
                    = attr.getValue(Name.IMPLEMENTATION_VERSION);
                String implVendor  = attr.getValue(Name.IMPLEMENTATION_VENDOR);
                String sealed      = attr.getValue(Name.SEALED);
                if (title != null){
                    if (title.equals(targetSpecTitle)){
                        if (version != null){
                            if (version.equals(targetSpecVersion) ||
                                isNotOlderThan(version,targetSpecVersion)){
                                verboseMessage("");
                                verboseMessage("CONFLICT DETECTED ");
                                verboseMessage("Conflicting file:"+ url);
                                verboseMessage("Installed Version:" +
                                               version);
                                if (implTitle != null)
                                    verboseMessage("Implementation Title:"+
                                                   implTitle);
                                if (implVersion != null)
                                    verboseMessage("Implementation Version:"+
                                                   implVersion);
                                if (implVendor != null)
                                    verboseMessage("Implementation Vendor:"+
                                                   implVendor);
                                return false;
                            }
                        }
                    }
                }
            }
        }
        boolean result = true;
        URL[] loaderList = jarloader.getClassPath();
        if (loaderList != null) {
            for(int i=0; i < loaderList.length; i++){
                if (url != null){
                    boolean res =  checkURLRecursively(indent+1,loaderList[i]);
                    result = res && result;
                }
            }
        }
        return result;
    }

    /**
     *  See comment in method java.lang.Package.isCompatibleWith.
     *  Return true if already is not older than target. i.e. the
     *  target file may be superseded by a file already installed
     */
    private boolean isNotOlderThan(String already,String target)
        throws NumberFormatException
    {
            if (already == null || already.length() < 1) {
            throw new NumberFormatException("Empty version string");
        }

            // Until it matches scan and compare numbers
            StringTokenizer dtok = new StringTokenizer(target, ".", true);
            StringTokenizer stok = new StringTokenizer(already, ".", true);
        while (dtok.hasMoreTokens() || stok.hasMoreTokens()) {
            int dver;
            int sver;
            if (dtok.hasMoreTokens()) {
                dver = Integer.parseInt(dtok.nextToken());
            } else
                dver = 0;

            if (stok.hasMoreTokens()) {
                sver = Integer.parseInt(stok.nextToken());
            } else
                sver = 0;

                if (sver < dver)
                        return false;                // Known to be incompatible
                if (sver > dver)
                        return true;                // Known to be compatible

                // Check for and absorb separators
                if (dtok.hasMoreTokens())
                        dtok.nextToken();
                if (stok.hasMoreTokens())
                        stok.nextToken();
                // Compare next component
            }
            // All components numerically equal
        return true;
    }


    /**
     * Prints out message if the verboseFlag is set
     */
    void verboseMessage(String message){
        if (verboseFlag) {
            System.err.println(message);
        }
    }

    void generalMessage(String message){
        System.err.println(message);
    }

    /**
     * Throws a RuntimeException with a message describing the error.
     */
    static void error(String message) throws RuntimeException {
        throw new RuntimeException(message);
    }


    /**
     * Inner class used to represent a loader of resources and classes
     * from a base URL. Somewhat modified version of code in
     * sun.misc.URLClassPath.JarLoader
     */
    private static class JarLoader {
        private final URL base;
        private JarFile jar;
        private URL csu;

        /*
         * Creates a new Loader for the specified URL.
         */
        JarLoader(URL url) {
            String urlName = url + "!/";
            URL tmpBaseURL = null;
            try {
                tmpBaseURL = new URL("jar","",urlName);
                jar = findJarFile(url);
                csu = url;
            } catch (MalformedURLException e) {
                ExtCheck.error("Malformed url "+urlName);
            } catch (IOException e) {
                ExtCheck.error("IO Exception occurred");
            }
            base = tmpBaseURL;

        }

        /*
         * Returns the base URL for this Loader.
         */
        URL getBaseURL() {
            return base;
        }

        JarFile getJarFile() {
            return jar;
        }

        private JarFile findJarFile(URL url) throws IOException {
             // Optimize case where url refers to a local jar file
             if ("file".equals(url.getProtocol())) {
                 String path = url.getFile().replace('/', File.separatorChar);
                 File file = new File(path);
                 if (!file.exists()) {
                     throw new FileNotFoundException(path);
                 }
                 return new JarFile(path);
             }
             URLConnection uc = getBaseURL().openConnection();
             //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
             return ((JarURLConnection)uc).getJarFile();
         }


        /*
         * Returns the JAR file local class path, or null if none.
         */
        URL[] getClassPath() throws IOException {
            Manifest man = jar.getManifest();
            if (man != null) {
                Attributes attr = man.getMainAttributes();
                if (attr != null) {
                    String value = attr.getValue(Name.CLASS_PATH);
                    if (value != null) {
                        return parseClassPath(csu, value);
                    }
                }
            }
            return null;
        }

        /*
         * Parses value of the Class-Path manifest attribute and returns
         * an array of URLs relative to the specified base URL.
         */
        private URL[] parseClassPath(URL base, String value)
            throws MalformedURLException
        {
            StringTokenizer st = new StringTokenizer(value);
            URL[] urls = new URL[st.countTokens()];
            int i = 0;
            while (st.hasMoreTokens()) {
                String path = st.nextToken();
                urls[i] = new URL(base, path);
                i++;
            }
            return urls;
        }
    }


}

Other Java examples (source code examples)

Here is a short list of links related to this Java ExtCheck.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.