com.impetus.kundera.classreading.ClasspathReader Maven / Gradle / Ivy
/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
* *
* * 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.impetus.kundera.classreading;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.impetus.kundera.Constants;
import com.impetus.kundera.loader.PersistenceXMLLoader.AllowedProtocol;
/**
* The Class ClasspathReader.
*
* @author animesh.kumar
*/
public class ClasspathReader extends Reader
{
private static Logger logger = LoggerFactory.getLogger(ClasspathReader.class);
/**
* The filter.
*/
private Filter filter;
/** The classes to scan. */
private List classesToScan;
/**
* Instantiates a new classpath reader.
*/
public ClasspathReader()
{
filter = new FilterImpl();
}
/**
* Instantiates a new classpath reader.
*
* @param classesToScan
* the classes to scan
*/
public ClasspathReader(List classesToScan)
{
this();
this.classesToScan = classesToScan;
}
@Override
public final void read()
{
URL[] resources = findResources();
for (URL resource : resources)
{
try
{
ResourceIterator itr = getResourceIterator(resource, getFilter());
InputStream is = null;
while ((is = itr.next()) != null)
{
scanClass(is);
}
}
catch (IOException e)
{
logger.error("Error during reading via classpath, Caused by:" + e.getMessage());
throw new ResourceReadingException(e);
}
}
}
/**
* Uses the java.class.path system property to obtain a list of URLs that
* represent the CLASSPATH
*
* @return the URl[]
*/
@SuppressWarnings("deprecation")
@Override
public final URL[] findResourcesByClasspath()
{
List list = new ArrayList();
String classpath = System.getProperty("java.class.path");
StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
while (tokenizer.hasMoreTokens())
{
String path = tokenizer.nextToken();
File fp = new File(path);
if (!fp.exists())
throw new ResourceReadingException("File in java.class.path does not exist: " + fp);
try
{
list.add(fp.toURL());
}
catch (MalformedURLException e)
{
throw new ResourceReadingException(e);
}
}
return list.toArray(new URL[list.size()]);
}
/**
* Scan class resource in the provided urls with the additional Class-Path
* of each jar checking
*
* @param classRelativePath
* relative path to a class resource
* @param urls
* urls to be checked
* @return list of class path included in the base package
*/
private URL[] findResourcesInUrls(String classRelativePath, URL[] urls)
{
List list = new ArrayList();
for (URL url : urls)
{
if (AllowedProtocol.isValidProtocol(url.getProtocol().toUpperCase()) && url.getPath().endsWith(".jar"))
{
try
{
JarFile jarFile = new JarFile(URLDecoder.decode(url.getFile(), Constants.CHARSET_UTF8));
// Checking the dependencies of this jar file
Manifest manifest = jarFile.getManifest();
if (manifest != null)
{
String classPath = manifest.getMainAttributes().getValue("Class-Path");
// Scan all entries in the classpath if they are
// specified in the jar
if (!StringUtils.isEmpty(classPath))
{
List subList = new ArrayList();
for (String cpEntry : classPath.split(" "))
{
try
{
subList.add(new URL(cpEntry));
}
catch (MalformedURLException e)
{
URL subResources = ClasspathReader.class.getClassLoader().getResource(cpEntry);
if (subResources != null)
{
subList.add(subResources);
}
// logger.warn("Incorrect URL in the classpath of a jar file ["
// + url.toString()
// + "]: " + cpEntry);
}
}
list.addAll(Arrays.asList(findResourcesInUrls(classRelativePath,
subList.toArray(new URL[subList.size()]))));
}
}
JarEntry present = jarFile.getJarEntry(classRelativePath + ".class");
if (present != null)
{
list.add(url);
}
}
catch (IOException e)
{
logger.warn("Error during loading from context , Caused by:" + e.getMessage());
}
}
else if (url.getPath().endsWith("/"))
{
File file = new File(url.getPath() + classRelativePath + ".class");
if (file.exists())
{
try
{
list.add(file.toURL());
}
catch (MalformedURLException e)
{
throw new ResourceReadingException(e);
}
}
}
}
return list.toArray(new URL[list.size()]);
}
/**
* Scan class resources into a basePackagetoScan path.
*
* @return list of class path included in the base package
*/
private final URL[] findResourcesByContextLoader()
{
List list = new ArrayList();
ClassLoader classLoader = this.getClass().getClassLoader();
assert classLoader != null;
URL[] urls = ((URLClassLoader) classLoader).getURLs();
for (String fullyQualifiedClassName : classesToScan)
{
String classRelativePath = fullyQualifiedClassName.replace(".", "/");
list.addAll(Arrays.asList(findResourcesInUrls(classRelativePath, urls)));
}
return list.toArray(new URL[list.size()]);
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.classreading.Reader#findResources()
*/
@Override
public URL[] findResources()
{
URL[] result = null;
if (classesToScan != null && !classesToScan.isEmpty())
{
result = findResourcesByContextLoader();
}
// else
// {
// result = findResourcesByClasspath();
// }
return result;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.classreading.Reader#getFilter()
*/
public final Filter getFilter()
{
return filter;
}
/**
* Sets the filter.
*
* @param filter
* the new filter
*/
public final void setFilter(Filter filter)
{
this.filter = filter;
}
@Override
public InputStream[] findResourcesAsStream()
{
ClassLoader classLoader = this.getClass().getClassLoader();
assert classLoader != null;
InputStream[] iStreams = null;
int counter = 0;
if(classesToScan != null)
{
for (String fullyQualifiedClassName : classesToScan)
{
if (iStreams == null)
{
iStreams = new InputStream[classesToScan.size()];
}
String classRelativePath = fullyQualifiedClassName.replace(".", "/");
InputStream is = this.getClass().getClassLoader().getResourceAsStream(classRelativePath + ".class");
iStreams[counter++] = is;
}
}
return iStreams;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy