/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.fib.editor.test;
import java.net.URL;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Vector;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.Icon;
import org.openflexo.fib.utils.FIBIconLibrary;
import org.openflexo.toolbox.ClassScope;
import org.openflexo.toolbox.StringUtils;
public class LoadedClassesInfo extends Observable {
private static final Logger logger = Logger.getLogger(LoadedClassesInfo.class.getPackage().getName());
static ClassLoader appLoader = ClassLoader.getSystemClassLoader();
static ClassLoader currentLoader = LoadedClassesInfo.class.getClassLoader();
static ClassLoader[] loaders = new ClassLoader[] { appLoader, currentLoader };
public static LoadedClassesInfo instance;
static {
appLoader = ClassLoader.getSystemClassLoader();
currentLoader = LoadedClassesInfo.class.getClassLoader();
if (appLoader != currentLoader) {
loaders = new ClassLoader[] { appLoader, currentLoader };
} else {
loaders = new ClassLoader[] { appLoader };
}
instance = new LoadedClassesInfo();
}
private final Map<Package, PackageInfo> packages;
private Vector<PackageInfo> packageList;
private boolean needsReordering = true;
private final Hashtable<String, Vector<ClassInfo>> classesForName;
private LoadedClassesInfo() {
classesForName = new Hashtable<String, Vector<ClassInfo>>();
packages = Collections.synchronizedMap(new HashMap<Package, PackageInfo>() {
@Override
public synchronized PackageInfo put(Package key, PackageInfo value) {
PackageInfo returned = super.put(key, value);
needsReordering = true;
setChanged();
notifyObservers();
return returned;
};
});
for (Package p : Package.getPackages()) {
registerPackage(p);
}
final Class<?>[] classes = ClassScope.getLoadedClasses(loaders);
for (Class<?> cls : classes) {
registerClass(cls);
String className = cls.getName();
URL classLocation = ClassScope.getClassLocation(cls);
// System.out.println("Registered class: " + className + " from " +classLocation);
}
}
public List<PackageInfo> getPackages() {
if (needsReordering) {
packageList = new Vector<PackageInfo>();
for (Package p : packages.keySet()) {
packageList.add(packages.get(p));
}
Collections.sort(packageList, new Comparator<PackageInfo>() {
@Override
public int compare(PackageInfo o1, PackageInfo o2) {
return Collator.getInstance().compare(o1.packageName, o2.packageName);
}
});
needsReordering = false;
}
return packageList;
}
private PackageInfo registerPackage(Package p) {
PackageInfo returned = packages.get(p);
if (returned == null) {
packages.put(p, returned = new PackageInfo(p));
}
return returned;
}
private ClassInfo registerClass(Class c) {
PackageInfo p = registerPackage(c.getPackage());
logger.fine("Register class " + c);
if (!c.isMemberClass() && !c.isAnonymousClass() && !c.isLocalClass()) {
ClassInfo returned = p.classes.get(c);
if (returned == null) {
p.classes.put(c, returned = new ClassInfo(c));
logger.fine("Store " + returned + " in package " + p.packageName);
}
return returned;
} else if (c.isMemberClass()) {
// System.out.println("Member class: "+c+" of "+c.getDeclaringClass());
ClassInfo parentClass = registerClass(c.getEnclosingClass());
ClassInfo returned = parentClass.declareMember(c);
return returned;
} else {
// System.out.println("Ignored class: "+c);
return null;
}
}
public class PackageInfo extends Observable {
public String packageName;
private final Hashtable<Class, ClassInfo> classes = new Hashtable<Class, ClassInfo>() {
@Override
public synchronized ClassInfo put(Class key, ClassInfo value) {
ClassInfo returned = super.put(key, value);
needsReordering = true;
setChanged();
notifyObservers();
return returned;
};
};
private Vector<ClassInfo> classesList;
private boolean needsReordering = true;
public PackageInfo(Package aPackage) {
if (aPackage != null) {
packageName = aPackage.getName();
}
}
public List<ClassInfo> getClasses() {
if (needsReordering) {
classesList = new Vector<ClassInfo>();
for (Class c : classes.keySet()) {
classesList.add(classes.get(c));
}
Collections.sort(classesList, new Comparator<ClassInfo>() {
@Override
public int compare(ClassInfo o1, ClassInfo o2) {
return Collator.getInstance().compare(o1.className, o2.className);
}
});
needsReordering = false;
}
return classesList;
}
public boolean isFiltered() {
if (getFilteredPackageName() == null || StringUtils.isEmpty(getFilteredPackageName())) {
return false;
}
if (packageName == null) {
return true;
}
if (packageName.startsWith(getFilteredPackageName())) {
return false;
}
String patternString = getFilteredPackageName();
if (patternString.startsWith("*")) {
patternString = "." + getFilteredPackageName();
}
try {
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(packageName);
return !matcher.find();
} catch (PatternSyntaxException e) {
logger.warning("PatternSyntaxException: " + patternString);
return false;
}
}
public Icon getIcon() {
return FIBIconLibrary.PACKAGE_ICON;
}
}
public class ClassInfo extends Observable {
private final Class clazz;
public String className;
public String packageName;
public String fullQualifiedName;
private final Hashtable<Class, ClassInfo> memberClasses = new Hashtable<Class, ClassInfo>() {
@Override
public synchronized ClassInfo put(Class key, ClassInfo value) {
ClassInfo returned = super.put(key, value);
needsReordering = true;
setChanged();
notifyObservers();
return returned;
};
};
private Vector<ClassInfo> memberClassesList;
private boolean needsReordering = true;
public ClassInfo(Class aClass) {
Vector<ClassInfo> listOfClassesWithThatName = classesForName.get(aClass.getSimpleName());
if (listOfClassesWithThatName == null) {
classesForName.put(aClass.getSimpleName(), listOfClassesWithThatName = new Vector<ClassInfo>());
}
listOfClassesWithThatName.add(this);
className = aClass.getSimpleName();
if (aClass.getPackage() != null) {
packageName = aClass.getPackage().getName();
}
fullQualifiedName = aClass.getName();
clazz = aClass;
logger.fine("Instanciate new ClassInfo for " + aClass);
}
private ClassInfo declareMember(Class c) {
ClassInfo returned = memberClasses.get(c);
if (returned == null) {
memberClasses.put(c, returned = new ClassInfo(c));
needsReordering = true;
logger.fine(toString() + ": declare member: " + returned);
}
return returned;
}
public List<ClassInfo> getMemberClasses() {
if (needsReordering) {
memberClassesList = new Vector<ClassInfo>();
for (Class<?> c : memberClasses.keySet()) {
memberClassesList.add(memberClasses.get(c));
}
Collections.sort(memberClassesList, new Comparator<ClassInfo>() {
@Override
public int compare(ClassInfo o1, ClassInfo o2) {
return Collator.getInstance().compare(o1.className, o2.className);
}
});
needsReordering = false;
}
return memberClassesList;
}
@Override
public String toString() {
return "ClassInfo[" + clazz.getName() + "]";
}
public Icon getIcon() {
if (clazz.isEnum()) {
return FIBIconLibrary.ENUM_ICON;
}
if (clazz.isInterface()) {
return FIBIconLibrary.INTERFACE_ICON;
}
return FIBIconLibrary.CLASS_ICON;
}
}
private String filteredPackageName = "*";
private String filteredClassName = "";
public String getFilteredPackageName() {
return filteredPackageName;
}
public void setFilteredPackageName(String filter) {
if (filter == null || !filter.equals(this.filteredPackageName)) {
this.filteredPackageName = filter;
updateMatchingClasses();
}
}
public String getFilteredClassName() {
return filteredClassName;
}
public void setFilteredClassName(String filteredClassName) {
if (filteredClassName == null || !filteredClassName.equals(this.filteredClassName)) {
this.filteredClassName = filteredClassName;
for (Package p : packages.keySet()) {
try {
String packagePrefix = p == null || p.getName().length() == 0 ? "" : p.getName() + ".";
Class<?> foundClass = Class.forName(packagePrefix + filteredClassName);
registerClass(foundClass);
logger.info("Found class " + foundClass);
} catch (ClassNotFoundException e) {
}
}
updateMatchingClasses();
}
}
private void updateMatchingClasses() {
matchingClasses.clear();
if (!StringUtils.isEmpty(filteredClassName)) {
String patternString = filteredClassName;
if (patternString.startsWith("*")) {
patternString = "." + filteredClassName;
}
try {
Vector<ClassInfo> exactMatches = new Vector<ClassInfo>();
if (classesForName.get(filteredClassName) != null) {
exactMatches = classesForName.get(filteredClassName);
matchingClasses.addAll(exactMatches);
}
Pattern pattern = Pattern.compile(patternString);
for (String s : classesForName.keySet()) {
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
for (ClassInfo potentialMatch : classesForName.get(s)) {
PackageInfo packageInfo = registerPackage(potentialMatch.clazz.getPackage());
if (!packageInfo.isFiltered()) {
if (!exactMatches.contains(potentialMatch)) {
matchingClasses.add(potentialMatch);
// System.out.println("Found "+potentialMatch);
}
}
}
}
}
} catch (PatternSyntaxException e) {
logger.warning("PatternSyntaxException: " + patternString);
}
if (matchingClasses.size() == 1) {
setSelectedClassInfo(matchingClasses.firstElement());
}
}
setChanged();
notifyObservers();
}
public Vector<ClassInfo> matchingClasses = new Vector<ClassInfo>();
private ClassInfo selectedClassInfo;
public ClassInfo getSelectedClassInfo() {
return selectedClassInfo;
}
public void setSelectedClassInfo(ClassInfo selectedClassInfo) {
if (selectedClassInfo != this.selectedClassInfo) {
logger.info("setSelectedClassInfo with " + selectedClassInfo);
this.selectedClassInfo = selectedClassInfo;
setChanged();
notifyObservers();
}
}
/*public static void main(String[] args)
{
System.out.println("Hello world");
try {
Class.forName("org.openflexo.fib.TestFIBBrowser");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//updateClasses();
String classPath = System.getProperty("java.class.path",".");
System.out.println("classPath="+classPath);
String libraryPath = System.getProperty("java.library.path",".");
System.out.println("libraryPath="+libraryPath);
System.out.println("java.home="+System.getProperty("java.home","."));
System.out.println("Packages: "+Package.getPackages());
for (Package p : Package.getPackages()) {
System.out.println("package:"+p.getName());
}
}*/
public static void main(String[] args) {
Pattern pattern = Pattern.compile("javadsq.*");
Matcher matcher = pattern.matcher("java.util.coucou");
boolean found = false;
while (matcher.find()) {
System.out.println("I found the text starting at index and ending at index" + matcher.group() + matcher.start()
+ matcher.end());
found = true;
}
if (!found) {
System.out.println("No match found.");
}
}
}