org.kawanfw.file.reflection.ClassFileLocatorNew Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of awake-file-server Show documentation
Show all versions of awake-file-server Show documentation
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.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.kawanfw.commons.util.ClientLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.Tag;
/**
* 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 - 2025 Weber Informatics LLC | Privacy Policy