Reflection und dazugeöriges Java1.4.x

takidoso

Erfahrenes Mitglied
Hallo und Halli,
Kennt zufälligerweise jemand eine Möglichkeit bei Bekanntsein eines Packages und einer Oberklasse die Klassen aus gegebenen Package herauszufiltern, die Kinder der gegebenen Oberklasse sind?
Irgendwie habe ich nichts gescheites im Reflection-Api ausfindig machen können, andererseits müsste dass doch irgenwie möglich sein, woher sollten sont die IDE solche Stukturen aufbauen können.
für Hinweise bin ich herzlich dankbar

Takidoso
 
Hallo!

Die einfachste Lösung wäre wohl das Tools.jar in den Classpath aufzunehmen und die Mittel nutzen, die JavaDoc mit sich bringt.
In der Regel verwalten IDE's einen ganzen Batzen an Metainformationen über die enthaltenen Java Klassen. Netbeans parst beispielsweise beim ersten start das komplette rt.jar und legt die dadruch gewonnen Metainformationen in einem internen Cache ab. Eclipse macht das IMHO "on the fly".

Gruß Thomas
 
Danke Tom für Deine Tips,
ich habe jetzt bei mir in einer alten "Werkzeugkiste" gerkramt und stieß auf was heimgemachtes, was ich damals mir irgendwo abgekupfert hatte und so umgebaut bis es passte.
Das ganze habe ich damals ClassCollector genannt und fand es glücklicherweise auf meinem Rechner zu Hause (sonst hätte ich auf dem Boden gehen müssen und meine alte 200 MMX Gurke reanimieren müssen)

Für Neugierige (in der Hoffnung das es nach der heute gemachten Kosmetik noch )...
Code:
import java.util.Vector;
import java.util.Enumeration;
import java.util.zip.*;
import java.util.jar.*;
import java.net.*;
import java.io.*;

import javax.swing.JProgressBar;

/**
* ClassCollector sammelt Klassen einer Gegebenen unter Vorgabe eines
* Unterverzeichnises, welches direkt unter dem Package der gegebenen Klasse
* liegt.
* Diese Klasse ist zum dynamischen Zuladen von Klassen geeignet. Auf diese Weise
* können z.B. Unterdialoge zur Laufzeit einem Übergeordneten Panel zugeordnet werden
*/

public class ClassCollector
{
    Vector m_classNames = new Vector();
    String m_path;
    String m_packageName;
    String m_subPackageName;
    String m_lastQual;
    Class  m_class;



    public ClassCollector(Class klasse, String lastQualifier)
    {
        m_class          = klasse;
        m_path           = m_class.getResource("").getFile();
        m_lastQual       = lastQualifier;
        m_packageName    = m_class.getName().substring(0, m_class.getName().lastIndexOf('.'));
        m_subPackageName = m_packageName+'.'+m_lastQual;
        try
        {
            collectClassNames();
        }
        catch (Exception e)
        {
            MExceptionHandler.handleException(e);
        }
    } // end of ClassCollector(Class, String)

    protected void collectClassNames() throws Exception
    {
        Vector classFileNames = new Vector();

        if (m_class.getResource("").getProtocol().equalsIgnoreCase("jar"))
        {
            URLConnection urlConn = m_class.getResource("").openConnection();
            if (!(urlConn instanceof JarURLConnection))
            {
                throw new Exception("Is jar file but has no JarURLConnection");
            }
            JarURLConnection jarConn = (JarURLConnection)urlConn;
            JarFile jarFile = jarConn.getJarFile();
            for (Enumeration e = jarFile.entries(); e.hasMoreElements(); )
            {
                JarEntry currentEntry = (JarEntry)e.nextElement();
                if (currentEntry.getName().startsWith(m_path)
                    &&!currentEntry.isDirectory())
                {
                    classFileNames.add(currentEntry.getName());
                } // end of if
            } // end of for e
        } // end of if(Classe in einer .jar Datei)
        else
        {
            URL url = m_class.getResource(m_lastQual);
            if (url==null)
            {
                throw new Exception("Kann "+m_lastQual+" Verzeichnis nicht finden"+
                                    "\nres="+m_class.getResource(""));
            }
            File demosDir = new File(url.getFile());

            if (demosDir==null)
            {
                throw new Exception("Kann "+m_lastQual+" Verzeichnis nicht finden"+
                                    "\n url="+url);
            }

            if (!demosDir.isDirectory())
            {
                throw new Exception(m_lastQual+" ist kein Verzeichnis"+
                                    "\n url="+url+
                                    "\n file="+demosDir);
            }
            String[] list = demosDir.list();

            for (int i = 0; i<list.length; i++)
            {
                String fullName = m_packageName+"."+m_lastQual+"."+list[i];
                classFileNames.add(fullName);
            }
        } // end of if else (Classe in einer .jar Datei)

        for (int i = 0; i<classFileNames.size(); i++)
        {
            String currentName = (String)classFileNames.get(i);
            if (currentName.indexOf("$")==-1 && currentName.endsWith(".class"))
            {
                // remove trailing ".class"
                currentName = currentName.substring(0, currentName.length()-6);
                StringBuffer tmp = new StringBuffer(currentName);
                for (int j = 0; j<tmp.length(); j++)
                {
                    if (tmp.charAt(j)=='/'||tmp.charAt(j)=='\\')
                        tmp.setCharAt(j, '.');
                }
                m_classNames.add(tmp.toString());
            }
        }

    } // end of collectClassNames()

    public Vector loadClasses(JProgressBar progressBar)
    {
        Vector loadedClasses = new Vector();
        int count = progressBar.getValue();

        for (int i = 0; i<m_classNames.size(); i++)
        {
            String className = (String)m_classNames.get(i);
            String progressName = className.substring(m_subPackageName.length()+1,
                className.length());
            progressBar.setValue(count++);
            progressBar.setString("Lade "+progressName);
            try
            {
                Class currentClass = Class.forName(className);
                Object obj = currentClass.newInstance();

                if (m_class.isInstance(obj))
                {
                    loadedClasses.add(obj);
                }

            }
            catch (Exception e)
            {
                MExceptionHandler.handleException(e);
            }
        }
        return loadedClasses;
    } // end of loadClasses(JProgressBar)

    public Vector loadClasses()
    {
        Vector loadedClasses = new Vector();

        for (int i = 0; i<m_classNames.size(); i++)
        {
            try
            {
                Class currentClass = Class.forName((String)m_classNames.get(i));
                Object obj = currentClass.newInstance();
                if (m_class.isInstance(obj))
                {
                    loadedClasses.add(obj);
                }
            }
            catch (Exception e)
            {
                MExceptionHandler.handleException(e);
            }
        }
        return loadedClasses;
    } // end of loadClasses()

    public String[] getClassNames()
    {
        return (String[])m_classNames.toArray((Object[])new String[0]);
    }

    public String getClassName(int i)
    {
        return (String)m_classNames.get(i);
    }

} // end of ClassCollector

Sinn des ganzen ist, eine Klasse anzugeben, sollte auch mit einem Interface gehen und den Namen des Unterpaketes was untersucht werden soll. Wenn alles (noch) funktioniert -ich habe einige blöde continues in einer Schleife entfernt und daraus strukturierten Code zu haben - kann man dann die Namen der Klassen des selben Typs abfragen. Sinn des ganzen ist eine Art PlugIn-Light zu haben, in der man nichts mehr konfigurieren braucht sondern seine neu zu verwendenden Klassen in ein Unterverzeichnis packt.

Naja mal schauen ob das noch (de Morgan lässt grüßen).

Takidoso
 
Zurück