/* * Copyright 2014 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * 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 com.navercorp.pinpoint.common.util; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; /** * @author emeroad */ public class StaticFieldLookUp<T> { public interface Filter<T> { boolean FILTERED = true; boolean INCLUDE = false; boolean filter(T serviceType); } public static class BypassFilter<T> implements Filter<T> { @Override public boolean filter(T type) { return INCLUDE; } } public static class ExcludeFilter<T> implements Filter<T> { private final T[] excludeTypeList; public ExcludeFilter(T[] excludeTypeList) { if (excludeTypeList == null) { throw new NullPointerException("excludeTypeList must not be null"); } this.excludeTypeList = excludeTypeList; } @Override public boolean filter(T type) { for (T excludeType : excludeTypeList) { if (excludeType == type) { return FILTERED; } } return Filter.INCLUDE; } } private final Class<?> targetClazz; private final Class<T> findClazz; public StaticFieldLookUp(Class<?> targetClazz, Class<T> findClazz) { if (targetClazz == null) { throw new NullPointerException("targetClazz must not be null"); } if (findClazz == null) { throw new NullPointerException("findClazz must not be null"); } this.targetClazz = targetClazz; this.findClazz = findClazz; } public List<T> lookup(Filter<T> filter) { if (filter == null) { throw new NullPointerException("filter must not be null"); } final List<T> lookup = new ArrayList<T>(); Field[] declaredFields = targetClazz.getDeclaredFields(); for (Field field : declaredFields) { if (!Modifier.isStatic(field.getModifiers())) { continue; } if (!Modifier.isPublic(field.getModifiers())) { continue; } if (!field.getType().equals(findClazz)) { continue; } final Object filedObject = getObject(field); if (findClazz.isInstance(filedObject)) { T type = findClazz.cast(filedObject); if (filter.filter(type) == Filter.FILTERED) { continue; } lookup.add(type); } } return lookup; } public List<T> lookup() { return lookup(new BypassFilter<T>()); } private Object getObject(Field field) { try { return field.get(findClazz); } catch (IllegalAccessException ex) { throw new RuntimeException("service access fail. Caused by:" + ex.getMessage(), ex); } } }