001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.generator.ant;
022
023import java.io.File;
024import java.lang.annotation.Annotation;
025import java.util.ArrayList;
026import java.util.List;
027
028import org.apache.tools.ant.BuildException;
029import org.apache.tools.ant.types.Parameter;
030import org.apache.tools.ant.types.selectors.BaseExtendSelector;
031
032/**
033 * @author Franck WOLFF
034 */
035public class ClassSelector extends BaseExtendSelector {
036
037        Class<? extends Annotation>[] annotations = null;
038        Class<?>[] superclasses = null;
039        Class<?>[] classes = null;
040        
041        @SuppressWarnings("unchecked")
042        private void initializeParameters() throws BuildException {
043                log("init...");
044                if (annotations == null) {
045                        List<Class<?>> annotationsList = new ArrayList<Class<?>>();
046                        List<Class<?>> superclassesList = new ArrayList<Class<?>>();
047                        List<Class<?>> classesList = new ArrayList<Class<?>>();
048
049                        for (Parameter parameter : getParameters()) {
050                                if ("annotatedwith".equalsIgnoreCase(parameter.getName())) {
051                                        try {
052                                                Class<?> annotation = Thread.currentThread().getContextClassLoader().loadClass(parameter.getValue());
053                                                annotationsList.add(annotation);
054                                        } catch (Exception e) {
055                                                throw new BuildException("Could not load annotation: " + parameter.getValue());
056                                        }
057                                }
058                                else if ("instanceof".equalsIgnoreCase(parameter.getName())) {
059                                        try {
060                                                Class<?> superclass = Thread.currentThread().getContextClassLoader().loadClass(parameter.getValue());
061                                                superclassesList.add(superclass);
062                                        } catch (Exception e) {
063                                                throw new BuildException("Could not load superclass: " + parameter.getValue());
064                                        }
065                                }
066                                else if ("type".equalsIgnoreCase(parameter.getName())) {
067                                        try {
068                                                Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(parameter.getValue());
069                                                classesList.add(clazz);
070                                        } catch (Exception e) {
071                                                throw new BuildException("Could not load type: " + parameter.getValue());
072                                        }
073                                }
074                                else
075                                        throw new BuildException("Illegal param name: " + parameter.getName());
076                        }
077
078                        annotations = (Class<? extends Annotation>[])annotationsList.toArray(new Class<?>[annotationsList.size()]);
079                        superclasses = superclassesList.toArray(new Class<?>[superclassesList.size()]);
080                        classes = classesList.toArray(new Class<?>[classesList.size()]);
081                }
082        }
083        
084        @Override
085        public boolean isSelected(File basedir, String fileName, File file) throws BuildException {
086                initializeParameters();
087                log(fileName);
088                if (!fileName.endsWith(".class"))
089                        return false;
090                
091                String className = fileName.substring(0, fileName.length() - 6).replace(File.separatorChar, '.');
092                try {
093                        Class<?> type = Thread.currentThread().getContextClassLoader().loadClass(className);
094                        for (Class<?> clazz : classes) {
095                                if (clazz.equals(type))
096                                        return true;
097                        }
098                        for (Class<?> superclass : superclasses) {
099                                if (superclass.isAssignableFrom(type))
100                                        return true;
101                        }
102                        for (Class<? extends Annotation> annotation : annotations) {
103                                if (type.isAnnotationPresent(annotation))
104                                        return true;
105                        }
106                } catch (Exception e) {
107                        throw new BuildException("Could not load class: " + className, e);
108                }
109                
110                return false;
111        }
112}