/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package org.ant4eclipse.lib.jdt.ecj.internal.tools.loader;
import org.ant4eclipse.lib.core.Assure;
import org.ant4eclipse.lib.core.ClassName;
import org.ant4eclipse.lib.core.util.Utilities;
import org.ant4eclipse.lib.jdt.ecj.ClassFile;
import org.ant4eclipse.lib.jdt.ecj.ClassFileLoader;
import org.ant4eclipse.lib.jdt.ecj.ReferableSourceFile;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class CompoundClassFileLoaderImpl implements ClassFileLoader {
private ClassFileLoader[] _classFileLoaders;
/** maps packages to a package provider that contains a list of one or more class path entries */
private Map<String, List<ClassFileLoader>> _allPackages;
public CompoundClassFileLoaderImpl(ClassFileLoader[] classFileLoaders) {
Assure.notNull("classFileLoaders", classFileLoaders);
this._classFileLoaders = classFileLoaders;
this._allPackages = new HashMap<String, List<ClassFileLoader>>();
initialise();
}
/**
* {@inheritDoc}
*/
public File[] getClasspath() {
List<File> files = new ArrayList<File>();
List<String> set = new ArrayList<String>();
for (ClassFileLoader loader : this._classFileLoaders) {
File[] entries = loader.getClasspath();
for (File entry : entries) {
entry = Utilities.getCanonicalFile(entry);
String path = entry.getAbsolutePath();
if (Utilities.isWindows()) {
// for windows the case makes no difference
path = path.toLowerCase();
}
if (!set.contains(path)) {
set.add(path);
files.add(entry);
}
}
}
return files.toArray(new File[files.size()]);
}
/**
* {@inheritDoc}
*/
public String[] getAllPackages() {
return this._allPackages.keySet().toArray(new String[0]);
}
/**
* {@inheritDoc}
*/
public boolean hasPackage(String packageName) {
return this._allPackages.containsKey(packageName);
}
/**
* {@inheritDoc}
*/
public ClassFile loadClass(ClassName className) {
// get the class file loader list
List<ClassFileLoader> classFileLoaderList = this._allPackages.get(className.getPackageName());
// return if class file loader list is null
if (classFileLoaderList == null) {
return null;
}
// declare the result
ClassFile result = null;
// try to find the class file...
for (ClassFileLoader classFileLoader : classFileLoaderList) {
// try to load class file...
ClassFile classFile = classFileLoader.loadClass(className);
// class file was found...
if (classFile != null) {
// if the class file has no access restrictions, return the class file...
if (!classFile.hasAccessRestriction()) {
return classFile;
}
// else set the class file a result, if result is null
else if (result == null) {
result = classFile;
}
}
}
// return the result
return result;
}
/**
* {@inheritDoc}
*/
public ReferableSourceFile loadSource(ClassName className) {
// TODO: Access restrictions for source files!!
// if the package name is not in the map of all packages, return immediately
List<ClassFileLoader> classFileLoaderList = this._allPackages.get(className.getPackageName());
if (classFileLoaderList == null) {
return null;
}
// search for the source file
for (ClassFileLoader classFileLoader : classFileLoaderList) {
ReferableSourceFile sourceFile = classFileLoader.loadSource(className);
if (sourceFile != null) {
return sourceFile;
}
}
// last resort: return null
return null;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[CompoundClassFileLoader:");
buffer.append(" { ");
for (int i0 = 0; (this._classFileLoaders != null) && (i0 < this._classFileLoaders.length); i0++) {
buffer.append(" _classFileLoaders[" + i0 + "]: ");
buffer.append(this._classFileLoaders[i0]);
}
buffer.append(" } ");
// buffer.append(" _allPackages: ");
// buffer.append(this._allPackages);
buffer.append("]");
return buffer.toString();
}
private void initialise() {
for (ClassFileLoader classFileLoader : this._classFileLoaders) {
String[] packages = classFileLoader.getAllPackages();
for (String aPackage : packages) {
if (this._allPackages.containsKey(aPackage)) {
List<ClassFileLoader> classFileLoaderList = this._allPackages.get(aPackage);
if (!classFileLoaderList.contains(classFileLoader)) {
classFileLoaderList.add(classFileLoader);
}
} else {
List<ClassFileLoader> classFileLoaderList = new LinkedList<ClassFileLoader>();
classFileLoaderList.add(classFileLoader);
this._allPackages.put(aPackage, classFileLoaderList);
}
}
}
}
}