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

org.atmosphere.util.annotation.ClassFileIterator Maven / Gradle / Ivy

There is a newer version: 3.0.13
Show newest version
/*
 * Copyright 2008-2024 Async-IO.org
 *
 * 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.
 */
/* ClassFileIterator.java
 *
 * Created: 2011-10-10 (Year-Month-Day)
 * Character encoding: UTF-8
 *
 ****************************************** LICENSE *******************************************
 *
 * Copyright (c) 2011 - 2018 XIAM Solutions B.V. (http://www.xiam.nl)
 *
 * 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 org.atmosphere.util.annotation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipFile;

/**
 * {@code ClassFileIterator} is used to iterate over all Java ClassFile files available within
 * a specific context.
 * 

* For every Java ClassFile ({@code .class}) an {@link InputStream} is returned. * * @author Ronald K. Muller * @since annotation-detector 3.0.0 */ final class ClassFileIterator { private final Logger logger = LoggerFactory.getLogger(AnnotationDetector.class); private final FileIterator fileIterator; private final String[] pkgNameFilter; private ZipFileIterator zipIterator; private boolean isFile; private final InputStreamIterator inputStreamIterator; /** * Create a new {@code ClassFileIterator} returning all Java ClassFile files available * from the class path ({@code System.getProperty("java.class.path")}). */ ClassFileIterator() throws IOException { this(classPath(), null); } /** * Create a new {@code ClassFileIterator} returning all Java ClassFile files available * from the specified files and/or directories, including sub directories. *

* If the (optional) package filter is defined, only class files staring with one of the * defined package names are returned. * NOTE: package names must be defined in the native format (using '/' instead of '.'). */ ClassFileIterator(final File[] filesOrDirectories, final String[] pkgNameFilter) { this.fileIterator = new FileIterator(filesOrDirectories); this.pkgNameFilter = pkgNameFilter; this.inputStreamIterator = null; } /** * Create a new {@code ClassFileIterator} returning all Java ClassFile files available * from the specified files and/or directories, including sub directories. *

* If the (optional) package filter is defined, only class files staring with one of the * defined package names are returned. * NOTE: package names must be defined in the native format (using '/' instead of '.'). */ ClassFileIterator(final InputStream[] filesOrDirectories, final String[] pkgNameFilter) { this.fileIterator = null; this.pkgNameFilter = pkgNameFilter; this.inputStreamIterator = new InputStreamIterator(filesOrDirectories); } /** * Return the name of the Java ClassFile returned from the last call to {@link #next()}. * The name is either the path name of a file or the name of an ZIP/JAR file entry. */ public String getName() { // Both getPath() and getName() are very light weight method calls return zipIterator == null ? fileIterator.getFile().getPath() : zipIterator.getEntry().getName(); } /** * Return {@code true} if the current {@link InputStream} is reading from a plain * {@link File}. Return {@code false} if the current {@link InputStream} is reading from a * ZIP File Entry. */ public boolean isFile() { return isFile; } /** * Return the next Java ClassFile as an {@code InputStream}. *

* NOTICE: Client code MUST close the returned {@code InputStream}! */ public InputStream next() throws IOException { try { while (true) { if (fileIterator != null) { if (zipIterator == null) { final File file = fileIterator.next(); if (file == null) { return null; } else { final String name = file.getName(); if (name.endsWith(".class")) { isFile = true; return new FileInputStream(file); } else if (fileIterator.isRootFile() && (endsWithIgnoreCase(name, ".jar") || isZipFile(file)) && file.exists()) { try { zipIterator = new ZipFileIterator(new ZipFile(file), pkgNameFilter); } catch (Exception ex) { logger.debug("Unable to construct file {}", file); return null; } } // else just ignore } } else { final InputStream is = zipIterator.next(); if (is == null) { zipIterator = null; } else { isFile = false; return is; } } } else { return inputStreamIterator.next(); } } } catch (Exception ex) { logger.error("Unable to scan classes", ex); return null; } } // private private boolean isZipFile(File file) throws IOException { DataInputStream in = null; try { in = new DataInputStream(new FileInputStream(file)); int n = in.readInt(); in.close(); return n == 0x504b0304; } catch (Exception ex) { if (in != null) in.close(); return false; } finally { if (in != null) { try { in.close(); } catch (IOException ex) { // ignore } } } } /** * Returns the class path of the current JVM instance as an array of {@link File} objects. */ private static File[] classPath() { final String[] fileNames = System.getProperty("java.class.path") .split(File.pathSeparator); final File[] files = new File[fileNames.length]; for (int i = 0; i < files.length; ++i) { files[i] = new File(fileNames[i]); } return files; } private static boolean endsWithIgnoreCase(final String value, final String suffix) { final int n = suffix.length(); return value.regionMatches(true, value.length() - n, suffix, 0, n); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy