001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.lib.util;
011
012import java.io.File;
013import java.io.FileOutputStream;
014import java.io.IOException;
015import java.io.InputStream;
016import java.net.URL;
017import java.net.URLClassLoader;
018import java.util.jar.Manifest;
019
020
021/**
022 * This class defines various static methods for managing
023 * file-based resources and JAR manifest files.
024 * 
025 * @author W. Burger
026 */
027public abstract class FileUtils {
028
029        /**
030         * Removes the extension part of a pathname.
031         * Examples:<br>
032         * "foo.txt" &rarr; "foo",
033         * "foo" &rarr; "foo",
034         * "foo." &rarr; "foo.",
035         * ".txt" &rarr; ".txt".
036         * @param name the pathname
037         * @return the pathname without the extension (if valid)
038         */
039        public static String stripFileExtension(String name) {
040                int dotInd = name.lastIndexOf('.');
041                // if dot is in the first position,
042                // we are dealing with a hidden file rather than an DefaultFileExtension
043                return (dotInd > 0) ? name.substring(0, dotInd) : name;
044        }
045        
046        /**
047         * Extracts the extension part of a pathname as a string.
048         * Examples:<br>
049         * "foo.txt" &rarr; "txt",
050         * "foo" &rarr; "",
051         * "foo." &rarr; "",
052         * ".txt" &rarr; "".
053         * @param name the pathname
054         * @return the extension or an empty string
055         */
056        public static String getFileExtension(String name) {
057                int dotInd = name.lastIndexOf('.');
058                return (dotInd > 0) ? name.substring(dotInd + 1) : "";
059        }
060        
061        // ----  resources-related stuff ----------------------------------
062        
063        /**
064         * Find the path from which a given class was loaded.
065         * @param clazz a class.
066         * @return the path of the .class file for the given class or null (e.g.
067         * if the class is anonymous).
068         */   
069        public static String getClassPath(Class<?> clazz) {
070                return clazz.getProtectionDomain().getCodeSource().getLocation().getFile();
071        }
072        
073        // ----------------------------------------------------------------
074
075        /**
076         * Lists (to System.out) the paths where classes are loaded from.
077         */
078        public static void printClassPath() {
079                ClassLoader cl = ClassLoader.getSystemClassLoader();
080                URL[] urls = ((URLClassLoader) cl).getURLs();
081                for (URL url : urls) {
082                        System.out.println(url.getPath());
083                }
084        }
085        
086        // ----------------------------------------------------------------
087        
088        /**
089         * Checks 'by name' if a particular class exists.
090         * 
091         * @param classname fully qualified name of the class, e.g. {@literal imagingbook.lib.util.FileUtils}
092         * @return {@code true} if the class was found, {@code false} otherwise
093         */
094        public static boolean checkClass(String classname) {
095                // String logStr = "  checking class " + classname + " ... ";
096                try {
097                        if (Class.forName(classname) != null) {
098                                // IJ.log(logStr + "OK");
099                                return true;
100                        }
101                } catch (ClassNotFoundException e) { }
102                // IJ.log(logStr + "ERROR");
103                return false;
104        }
105        
106        
107        // ----------------------------------------------------------------
108        
109        // from https://bukkit.org/threads/extracting-file-from-jar.16962/
110        /**
111         * Reads all data from the given input stream and copies them
112         * to to a file.
113         * @param in the input stream
114         * @param file the output file
115         * @throws IOException if anything goes wrong
116         */
117        public static void copyToFile(InputStream in, File file) throws IOException {
118                FileOutputStream out = new FileOutputStream(file);
119                try {
120                        byte[] buf = new byte[1024];
121                        int i = 0;
122                        while ((i = in.read(buf)) != -1) {
123                                out.write(buf, 0, i);
124                        }
125                } catch (IOException e) {
126                        throw e;
127                } finally {
128                        if (in != null) {
129                                in.close();
130                        }
131                        if (out != null) {
132                                out.close();
133                        }
134                }
135        }
136        
137        
138        
139        // ----------------------------------------------------------------
140        
141        /**
142         * Finds the manifest (from META-INF/MANIFEST.MF) of the JAR file
143         * from which {@literal clazz} was loaded.
144         * 
145         * See: http://stackoverflow.com/a/1273432
146         * @param clazz A class in the JAR file of interest.
147         * @return A {@link Manifest} object or {@literal null} if {@literal clazz}
148         * was not loaded from a JAR file.
149         */
150        public static Manifest getJarManifest(Class<?> clazz) {
151                String className = clazz.getSimpleName() + ".class";            
152                String classPath = clazz.getResource(className).toString();
153                //IJ.log("classPath = " + classPath);
154                if (!classPath.startsWith("jar")) { // Class not from JAR
155                  return null;
156                }
157                String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";
158                Manifest manifest = null;
159                try {
160                        manifest = new Manifest(new URL(manifestPath).openStream());
161                } catch (IOException ignore) { }
162                return manifest;
163        }
164        
165        
166        // ----------------------------------------------------
167        
168        
169        public static void main(String[] args) {
170                String fileName = ".txt";
171                System.out.println("name = " + fileName);
172                System.out.println("stripped = " + stripFileExtension(fileName));
173                System.out.println("ext = " + getFileExtension(fileName));
174        }
175        
176
177}