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

org.etlunit.DirectoryBasedClassLocatorImpl Maven / Gradle / Ivy

package org.etlunit;

import org.etlunit.parser.ETLTestClass;
import org.etlunit.parser.ETLTestParser;
import org.etlunit.util.NeedsTest;

import javax.inject.Inject;
import javax.inject.Named;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

@NeedsTest
public class DirectoryBasedClassLocatorImpl implements ClassLocator
{
	private final File rootDir;
	private Log applicationLog;

	private final List classesList = new ArrayList();
	private int currentClassPointer = 0;

	private final Stack dirStack = new Stack();
	private final Stack classStack = new Stack();

	public DirectoryBasedClassLocatorImpl(File dir)
	{
		rootDir = dir;

		if (!rootDir.exists())
		{
			throw new IllegalArgumentException("Root directory " + rootDir + " does not exist");
		}

		// the implementation has changed.  It used to be a pass-through
		// implementation, but now it caches all classes and sorts after the fact
	}

	@Inject
	void setLogger(@Named("applicationLog") Log log)
	{
		applicationLog = log;
	}

	public boolean hasNext0()
	{
		if (classStack.size() != 0)
		{
			return true;
		}

		if (dirStack.size() == 0)
		{
			return false;
		}

		// at this point, the class stack is empty and the dir stack is not.
		// now pop the next dir and process until either the dir stack is
		// depleted or we have at least one class to process
		while (classStack.size() == 0)
		{
			if (dirStack.size() == 0)
			{
				return false;
			}

			File dir = dirStack.pop();

			// try to determine the package name
			String
					_package =
					dir.getAbsolutePath().substring(rootDir.getAbsolutePath().length()).replace(File.separatorChar, '.');

			if (_package.startsWith("."))
			{
				_package = _package.substring(1);
			}

			if (_package.endsWith("."))
			{
				_package = _package.substring(_package.length() - 1);
			}

			final String __package = _package;

			// scan the dir.  Every .etlunit class is loaded, parsed, and added to the
			// classes stack.  Every directory is pushed onto the stack.  This will have the
			// affect of a depth-first traversal of the directory tree
			dir.listFiles(new FileFilter()
			{
				@Override
				public boolean accept(File pathname)
				{
					if (pathname.isDirectory())
					{
						dirStack.push(pathname);
					}
					else if (pathname.isFile() && pathname.getName().toLowerCase().endsWith(".etlunit"))
					{
						// parse the class file and add to the stack
						try
						{
							Reader fileReader = new BufferedReader(new FileReader(pathname));

							try
							{
								List list = ETLTestParser.load(fileReader, __package);

								classStack.addAll(list);
							}
							finally
							{
								fileReader.close();
							}
						}
						catch (Exception e)
						{
							// log the error somewhere
							applicationLog.severe("", e);
						}
					}

					return false;
				}
			});
		}

		return true;
	}

	public ETLTestClass next0()
	{
		return classStack.pop();
	}

	@Override
	public boolean hasNext()
	{
		if (classesList.size() == 0)
		{
			//seed the stack with the root dir
			dirStack.clear();
			classStack.clear();

			dirStack.push(rootDir);

			while (hasNext0())
			{
				ETLTestClass class_ = next0();

				classesList.add(class_);
			}

			Collections.sort(classesList);
		}

		return currentClassPointer < classesList.size();
	}

	@Override
	public ETLTestClass next()
	{
		return classesList.get(currentClassPointer++);
	}

	@Override
	public void remove()
	{
		throw new UnsupportedOperationException();
	}

	@Override
	public void reset()
	{
		// just reset the current class pointer to 0;
		currentClassPointer = 0;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy