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

src-main.org.kawanfw.file.reflection.ClassFileLocatorNew Maven / Gradle / Ivy

Go to download

Awake FILE is a secure Open Source framework that allows to program very easily file uploads/downloads and RPC through http. File transfers include powerful features like file chunking and automatic recovery mechanism. Security has been taken into account from the design: server side allows to specify strong security rules in order to protect the files and to secure the RPC calls.

The newest version!
/*
 * This file is part of Awake FILE. 
 * Awake file: Easy file upload & download over HTTP with Java.                                    
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * Awake FILE is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * Awake FILE 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             
 * Lesser General Public License for more details.                               
 *                                                                               
 * You should have received a copy of the GNU Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.file.reflection;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.kawanfw.commons.util.ClientLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.FrameworkFileUtil;
import org.kawanfw.commons.util.FrameworkSystemUtil;
import org.kawanfw.commons.util.Tag;
import org.kawanfw.file.util.android.AndroidUtil;

/**
 * Allows to find the ".class" or ".jar" file of an instance, allows to open a InputStream on it.
 * 
 * @author Nicolas de Pomereu
 *
 */
public class ClassFileLocatorNew {

    /** For debug info */
    private static boolean DEBUG = FrameworkDebug.isSet(ClassFileLocatorNew.class);
    
    /** The class to locate */
    private Class clazz = null;
    
    /** The name of the class that calls RemoteFile.list(filter) or RemoteFile.listFile(filter) */
    private String callerClassName = null;

    /**
     * Constructor
     * @param clazz	The class to locate
     * @param callerClassName the name of the class that called clazz
     */
    public ClassFileLocatorNew(Class clazz, String callerClassName) {
	
	if (clazz == null) {
	    throw new IllegalArgumentException("class is null!");
	}
	this.clazz = clazz;
	this.callerClassName = callerClassName;
	
    }
    
    /**
     * Exports the class to a temp file "./kawansoft/tmp/className.class"
     * 
Note: className includes package as in Class.getName(). * * @return the exported temp file "./kawansoft/tmp/className.class" * @throws IOException */ public File exportClassToTempFile() throws IOException { String tempDir = FrameworkFileUtil.getKawansoftTempDir(); File outFile = new File(tempDir + File.separator + clazz.getName() + ".class"); byte [] byteArray = null; if (FrameworkSystemUtil.isAndroid()) { String classname = clazz.getName(); byteArray = AndroidUtil.extractClassFileBytecode(classname); } else { byteArray = this.extractClassFileBytecode(); } debug("class name : " + clazz.getName()); debug("byteArray.length: " + byteArray.length); FileUtils.writeByteArrayToFile(outFile, byteArray); return outFile; } /** * Gets the container of the class, ie the .jar file or the .class file * @return the container of the class, ie the .jar file or the .class file * @throws IOException */ public File getContainerFile() throws IOException { if (isContainerJar()) { //url : jar:file:/I:/_dev_awake/awake-file-3.0/lib/stringtemplate.jar!/org/antlr/stringtemplate/StringTemplate.class URL url = getUrl(); String urlString = url.toString(); urlString = StringUtils.substringBefore(urlString, "!"); urlString = StringUtils.substringAfter(urlString, "jar:"); File file = null; try { file = new File(new URL(urlString).toURI()); } catch (URISyntaxException e) { throw new IOException(e); } return file; } else { return getDotClassFile(); } } /** * Returns a byte array of the class container (.class or .jar container) * @return a byte array of the class container (.class or .jar container) * @throws IOException */ public byte [] extractClassFileBytecode() throws IOException { InputStream in = null; try { if (isContainerJar()) { in = getUrl().openStream(); } else { File file = getDotClassFile(); in = new BufferedInputStream(new FileInputStream(file)); } ByteArrayOutputStream out = new ByteArrayOutputStream(); IOUtils.copy(in, out); return out.toByteArray(); } finally { IOUtils.closeQuietly(in); } } /** * Returns true if the container is jar file * @return true if the container is jar file */ public boolean isContainerJar() { URL url = getUrl(); if (url == null) { return false; } if (url.toString().startsWith("jar:")) { return true; } else { return false; } } /** * Returns true if the container is .class file * @return true if the container is .class file */ public boolean isContainerDotClass() { URL url = getUrl(); if (url == null) { return false; } if (url.toString().startsWith("file:")) { return true; } else { return false; } } /** * Get the file corresponding to our class stored in .class file * @return file corresponding to our class stored in .class file * @throws FileNotFoundException * @throws IOException */ public File getDotClassFile() throws FileNotFoundException, IOException { if (! isContainerDotClass()) { throw new IllegalArgumentException("class is stored in a jar file. No \".class\" file exists!"); } File file = null; try { file = new File(getUrl().toURI()); } catch (URISyntaxException e) { throw new IOException(e); } debug("file: " + file); if (file.isFile()) { return file; } debug("dir: " + file); if (! file.exists() ) { throw new FileNotFoundException("Class file does nots exists: " + file); } // It is a directory ==> Find all classe that matches name // Its not a regular class but a private static inner class whose name // ends with $ // Get the first one we find in the directory FilenameFilter filenameFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { if (name.endsWith("$" + clazz.getSimpleName() + ".class")) return true; else return false; } }; File[] files = file.listFiles(filenameFilter); if (files == null || files.length == 0) { throw new FileNotFoundException(Tag.PRODUCT + " Impossible to find the static inner class file for " + clazz.getSimpleName()); } for (File file2 : files) { debug("file2 : " + file2); } // Easy case if (files.length == 1) { debug("OK: returning " + files[0]); return files[0]; } if (callerClassName == null) { throw new FileNotFoundException(Tag.PRODUCT + " More than one inner class matching inner class name. " + "Impossible to find the correct static inner class file for " + clazz.getSimpleName() + " without the caller class name."); } // More that one class and we know the caller if (callerClassName.contains(".")) { callerClassName = StringUtils.substringAfterLast(callerClassName, "."); } for (File theFile : files) { String filename = theFile.getName(); if (filename.startsWith(callerClassName)) { debug("OK: returning " + theFile); return theFile; } } throw new FileNotFoundException(Tag.PRODUCT + " More than one inner class matching inner class name. Impossible to find the correct static inner class file for " + clazz.getSimpleName()); } /** * Returns the URL of the class. If the class is an inner class, will return the directory * @return the URL of the class. If the class is an inner class, will return the directory */ public URL getUrl() { URL url = clazz.getResource(clazz.getSimpleName() + ".class"); // URL null ==> inner class ==> Return the directory location if (url == null) { url = clazz.getResource(""); } return url; } /** * Returns the pathname with "/" file separator notation corresponding to the package organization. *
* Example : for class org.kawanfw.file.reflection.ClassFileLocator, will * return /org/kawanfw/file/reflection/ * @return the pathname corresponding to the package organization */ public static String getClassSubdirectories(String className) { if (className == null) { throw new IllegalArgumentException("className is null!"); } String directoryPath = className; if (! directoryPath.contains(".")) { return ""; // No subdirectories. it's a default package class } directoryPath = StringUtils.substringBeforeLast(directoryPath, "."); directoryPath = directoryPath.replace('.', '/'); directoryPath = "/" + directoryPath + "/"; return directoryPath; } /** * debug tool */ private void debug(String s) { if (DEBUG) { ClientLogger.getLogger().log(Level.WARNING, s); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy