All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.util.SuggestMissingFactories Maven / Gradle / Ivy

The newest version!
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.solr.util;

import java.io.Reader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.jar.*;

/**
 * Given a list of Jar files, suggest missing analysis factories.
 *
 * @version $Id: SuggestMissingFactories.java 701485 2008-10-03 18:43:57Z ryan $
 */
public class SuggestMissingFactories {

    public static void main(String[] args) throws ClassNotFoundException, IOException, NoSuchMethodException {

        final File[] files = new File[args.length];
        for (int i = 0; i < args.length; i++) {
            files[i] = new File(args[i]);
        }
        final FindClasses finder = new FindClasses(files);
        final ClassLoader cl = finder.getClassLoader();

        final Class TOKENSTREAM
            = cl.loadClass("org.apache.lucene.analysis.TokenStream");
        final Class TOKENIZER
            = cl.loadClass("org.apache.lucene.analysis.Tokenizer");
        final Class TOKENFILTER
            = cl.loadClass("org.apache.lucene.analysis.TokenFilter");
        final Class TOKENIZERFACTORY
            = cl.loadClass("org.apache.solr.analysis.TokenizerFactory");
        final Class TOKENFILTERFACTORY
            = cl.loadClass("org.apache.solr.analysis.TokenFilterFactory");
        
        
        final HashSet result
            = new HashSet(finder.findExtends(TOKENIZER));
        result.addAll(finder.findExtends(TOKENFILTER));
        
        result.removeAll(finder.findMethodReturns
                         (finder.findExtends(TOKENIZERFACTORY),
                          "create",
                          Reader.class).values());
        result.removeAll(finder.findMethodReturns
                         (finder.findExtends(TOKENFILTERFACTORY),
                          "create",
                          TOKENSTREAM).values());
        
        for (final Class c : result) {
            System.out.println(c.getName());
        }
    }
    
}

/**
 * Takes in a clazz name and a jar and finds
 * all classes in that jar that extend clazz.
 */
class FindClasses {

  /**
   * Simple command line test method
   */
  public static void main(String[] args)
    throws ClassNotFoundException, IOException, NoSuchMethodException {

    FindClasses finder = new FindClasses(new File(args[1]));
    ClassLoader cl = finder.getClassLoader();
    Class clazz = cl.loadClass(args[0]);
    if (args.length == 2) {
            
      System.out.println("Finding all extenders of " + clazz.getName());
      for (Class c : finder.findExtends(clazz)) {
        System.out.println(c.getName());
      }
    } else {
      String methName = args[2];
      System.out.println("Finding all extenders of " + clazz.getName() +
                         " with method: " + methName);
            
      Class[] methArgs = new Class[args.length-3];
      for (int i = 3; i < args.length; i++) {
        methArgs[i-3] = cl.loadClass(args[i]);
      }
      Map map = finder.findMethodReturns
        (finder.findExtends(clazz),methName, methArgs);

      for (Class key : map.keySet()) {
        System.out.println(key.getName() + " => " + map.get(key).getName());
      }
           

    }
  }

  private JarFile[] jarFiles;
  private ClassLoader cl;
  public FindClasses(File... jars) throws IOException {

        
    jarFiles = new JarFile[jars.length];
    URL[] urls = new URL[jars.length];
    try {
      for (int i =0; i < jars.length; i++) {
        jarFiles[i] = new JarFile(jars[i]);
        urls[i] = jars[i].toURI().toURL();
      }
    } catch (MalformedURLException e) {
      throw new RuntimeException
        ("WTF, how can JarFile.toURL() be malformed?", e);
    }
        
    this.cl = new URLClassLoader(urls, this.getClass().getClassLoader());
  }

  /**
   * returns a class loader that includes the jar used to
   * construct this instance
   */
  public ClassLoader getClassLoader() {
    return this.cl;
  }
    
  /**
   * Find useful concrete (ie: not anonymous, not abstract, not an interface)
   * classes that extend clazz
   */
  public Collection findExtends(Class clazz)
    throws ClassNotFoundException {
        
    HashSet results = new HashSet();

    for (JarFile jarFile : jarFiles) {
      for (Enumeration e = jarFile.entries();
           e.hasMoreElements() ;) {
                
        String n = e.nextElement().getName();
        if (n.endsWith(".class")) {
          String cn = n.replace("/",".").substring(0,n.length()-6);
          Class target;
          try {
            target = cl.loadClass(cn);
          } catch (NoClassDefFoundError e1) {
            throw new ClassNotFoundException
              ("Can't load: " + cn, e1);
          }
                                                        
          if (clazz.isAssignableFrom(target)
              && !target.isAnonymousClass()) {
                        
            int mods = target.getModifiers();
            if (!(Modifier.isAbstract(mods) ||
                  Modifier.isInterface(mods))) {
              results.add(target);
            }
          }
        }
      }
    }
    return results;
  }

  /**
   * Given a collection of classes, returns a Map containing the
   * subset of those classes that impliment the method specified,
   * where the value in the map is the return type of the method
   */
  public Map findMethodReturns(Collection clazzes,
                                            String methodName,
                                            Class... parameterTypes)
    throws NoSuchMethodException{

    HashMap results = new HashMap();
    for (Class clazz : clazzes) {
      try {
        Method m = clazz.getMethod(methodName, parameterTypes);
        results.put(clazz, m.getReturnType());
      } catch (NoSuchMethodException e) {
        /* :NOOP: we expect this and skip clazz */
      }
    }
    return results;
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy