/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.controller.classloader; import java.util.ArrayList; import org.civilian.util.Check; import org.civilian.util.ClassUtil; import org.civilian.util.StringUtil; /** * ClassList defines a list of classes, either by specifying * them directly, or by defining match criteria for class or * package names. */ public class ClassList { /** * Returns the size of the list. */ public int size() { return list_.size(); } /** * Adds a Item to the list. */ private ClassList add(Item item) { if (!list_.contains(item)) list_.add(item); return this; } /** * Adds an item to the lists. * The passed name can be * <ul> * <li>either a qualified class name, therefore including that class. * <li>or a string ending with '*' or '.', therefore including * all classes whose qualified name starts with that package * </ul> */ public ClassList add(String name) { Check.notNull(name, "name"); if (name.endsWith("*") || name.endsWith(".")) { name = StringUtil.cutRight(name, "*"); add(new StartsWith(name)); } else { String simpleName = ClassUtil.cutPackageName(name); if ((simpleName.length() > 0) && Character.isUpperCase(simpleName.charAt(0))) add(new ExactMatch(name)); else add(new StartsWith(name)); } return this; } /** * Adds multiple names. * @see #add(String) */ public ClassList add(String... names) { for (String name : names) add(name); return this; } /** * Adds a class. */ public ClassList addClass(Class<?> c) { return add(new ExactMatch(c.getName())); } /** * Adds a package. All class in or below that package are included. */ public ClassList addPackage(Class<?> c) { return add(new StartsWith(ClassUtil.getPackageName(c) + ".")); } /** * Tests if the name is in the list.. */ public boolean contains(String name) { if (name != null) { for (Item item : list_) { if (item.match(name)) return true; } } return false; } @Override public String toString() { return list_.toString(); } private abstract static class Item { public abstract boolean match(String name); @Override public abstract String toString(); @Override public abstract boolean equals(Object other); } private static class ExactMatch extends Item { public ExactMatch(String name) { name_ = name; } @Override public boolean match(String name) { return name_.equals(name); } @Override public boolean equals(Object other) { return (other instanceof ExactMatch) && ((ExactMatch)other).name_.equals(name_); } @Override public int hashCode() { return name_.hashCode(); } @Override public String toString() { return "equals:" + name_; } private String name_; } private static class StartsWith extends Item { public StartsWith(String name) { name_ = name; } @Override public boolean match(String name) { return name.startsWith(name_); } @Override public boolean equals(Object other) { return (other instanceof StartsWith) && ((StartsWith)other).name_.equals(name_); } @Override public int hashCode() { return name_.hashCode(); } @Override public String toString() { return "startsWith:" + name_; } private String name_; } private ArrayList<Item> list_ = new ArrayList<>(); }