001 /* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 package org.apache.commons.classscan.util; 015 016 import java.lang.reflect.Array; 017 import java.util.Arrays; 018 import java.util.Collection; 019 import java.util.Comparator; 020 021 import org.apache.commons.classscan.HasName; 022 import org.apache.commons.classscan.spi.model.HasResolve; 023 024 public class NameSet<V extends HasName & HasResolve> extends ResolveSet<V> { 025 026 private final static Comparator<HasName> REVERSE_COMPARE = new Comparator<HasName>() { 027 @Override 028 public int compare(HasName l, HasName r) { 029 String left = l.getName(); 030 String right = r.getName(); 031 032 // "quick" compare 033 int diff = left.length() - right.length(); 034 if (diff != 0) { 035 return diff; 036 } 037 // compare from end of strings - the names probably have long equivalent prefixes 038 for (int i = left.length(); --i > 0;) { 039 int d = left.charAt(i) - right.charAt(i); 040 if (d != 0) { 041 return d; 042 } 043 } 044 return 0; 045 } 046 }; 047 048 public NameSet(V[] values) { 049 super(values); 050 if(values!=null && values.length>0) { 051 Arrays.sort(values, REVERSE_COMPARE); 052 } 053 } 054 055 public NameSet(Class<V> clss, Collection<? extends V> workValues) { 056 this(collectionToArray(clss, workValues)); 057 } 058 059 private static <D extends HasName> D[] collectionToArray(Class<D> collectionType, Collection<? extends D> workValues) { 060 if(workValues.isEmpty()) { 061 return null; 062 } 063 @SuppressWarnings("unchecked") 064 D[] newInstance = (D[]) Array.newInstance(collectionType, workValues.size()); 065 return workValues.toArray(newInstance); 066 } 067 068 public V getValue(final String name) { 069 int idx= Arrays.binarySearch(values, new HasName() { 070 @Override 071 public String getName() { 072 return name; 073 } 074 }, REVERSE_COMPARE); 075 return idx<0 ? null : values[idx]; 076 } 077 078 private static interface NameResolve extends HasName, HasResolve {}; 079 private static NameSet<NameResolve> EMPTY_SET = new NameSet<NameResolve>(new NameResolve[0]); 080 081 public static <V extends HasName & HasResolve> NameSet<V> emptyNameSet() { 082 NameSet<?> qrc = (NameSet<?>) EMPTY_SET; 083 @SuppressWarnings("unchecked") 084 NameSet<V> rc = (NameSet<V>) qrc; 085 return rc; 086 } 087 }