Ultrakompakter HTTP Server
ulrich
2024-12-01 675190608e81f38a713c965071c36b49b0ef8027
commit | author | age
f4025a 1 /*
c2e8cf 2   neon - Embeddable HTTP Server based on jdk.httpserver
U 3   Copyright (C) 2024  Ulrich Hilger
f4025a 4
c2e8cf 5   This program is free software: you can redistribute it and/or modify
U 6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
f4025a 18 package de.uhilger.neon;
U 19
20 import java.io.File;
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.net.URL;
26 import java.net.URLClassLoader;
27 import java.util.Enumeration;
28 import java.util.logging.Level;
29 import java.util.logging.Logger;
30 import java.util.zip.ZipEntry;
31 import java.util.zip.ZipFile;
32
33 /**
34  * Die Klasse JarScanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, in 
35  * welcher JAR-Datei sie liegt und diese JAR-Datei nach Klassen zu durchsuchen.
36  * 
37  * @author Ulrich Hilger
38  * @version 0.1, 30.11.2024
39  */
40 public class JarScanner {
41   
42   
43   public void processZipContent(ClassLoader urlCL, File archive, String packageName, JarScannerListener l, Handler h, String contextName) {
44     try {
45       ZipFile zipfile = new ZipFile(archive);
46       Enumeration en = zipfile.entries();
47       while (en.hasMoreElements()) {
48         ZipEntry zipentry = (ZipEntry) en.nextElement();
49         if (!zipentry.isDirectory()) {
50           processZipEntry(urlCL, zipentry, packageName, l, h, contextName);
51         } else {
52           // ZIP-Dir muss nicht bearbeitet werden
53         }
54       }
55       zipfile.close();
56     } catch (IOException ex) {
57       log(Level.SEVERE, ex.getLocalizedMessage());
58     }
59   }
60
61   private void processZipEntry(ClassLoader urlCL, ZipEntry zipentry, String packageName, JarScannerListener l, Handler h, String contextName) {
62     log(Level.FINEST, zipentry.getName());
63     String zName = zipentry.getName();
64     if (zName.toLowerCase().endsWith(".class")) {
65       int pos = zName.indexOf(".class");
66       String fullClassName = zName.substring(0, pos);
67       log(Level.FINEST, "full class name: " + zName);
68       String fullClassNameDots = fullClassName.replace('/', '.');
69       log(Level.FINEST, "full class name dots: " + fullClassNameDots);
70       String pkgName = getPackageName(fullClassNameDots);
71       log(Level.FINEST, " -- package name: " + pkgName);
72       if (null != urlCL && pkgName.toLowerCase().startsWith(packageName)) {
73         Class c = null;
74         try {
75           c = urlCL.loadClass(fullClassNameDots);
76           if (c != null) {
77             if (c.isAnnotationPresent(Actor.class)) {
78               log(Level.FINER, " ---- ACTOR ---- " + fullClassNameDots);
79               l.actorFound(c, h, contextName);
80             } else {
81               log(Level.FINER, "kein Actor " + fullClassNameDots);
82             }
83           } else {
84             log(Level.FINER, "class NOT loaded: " + zName);
85           }
86         } catch (ClassNotFoundException ex) {
87           log(Level.FINER, " +++++ Class not found: " + ex.getMessage());
88         }
89       }
90     }
91   }
92   
93   private String getPackageName(String fullClassName) {
94     String packageName;
95     int pos = fullClassName.lastIndexOf(".");
96     if (pos > 0) {
97       packageName = fullClassName.substring(0, pos);
98     } else {
99       packageName = fullClassName;
100     }
101     return packageName;
102   }
103   
104   public ClassLoader getUrlClassLoader(Class c) {
105     URL url;
106     ClassLoader urlCL = null;
107     try {
108       url = getPath(c).toURL();
109       log(Level.FINER, "url: " + url.getPath());
110       urlCL = new URLClassLoader(new URL[]{url});
111     } catch (URISyntaxException ex) {
112       log(Level.SEVERE, ex.getMessage());
113     } catch (MalformedURLException ex) {
114       log(Level.SEVERE, ex.getMessage());
115     } finally {
116       return urlCL;
117     }
118   }
119   
120   public URI getPath(Class c) throws URISyntaxException {
121     //Class c = this.getClass();
122     String className = c.getName();
123     finer("this name: " + className);
124     
125     int pos = className.indexOf(".class");
126     if(pos > -1) {
127       String classNameWoExt = className.substring(0, pos);
128     }
129     String classNameWoPkg = className.substring(className.lastIndexOf(".") + 1);
130     finer("Class name: " + classNameWoPkg);
131     String classPath = c.getResource(classNameWoPkg + ".class").getPath();
132     pos = classPath.indexOf("!");
133     String jarPath;
134     if(pos > -1) {
135       jarPath = /*"jar:" + */ classPath.substring(0, pos);
136     } else {
137       jarPath = classPath;
138     }
139     finer("path: " + jarPath);
140     return new URI(jarPath);
141   }
142   
143   private void finer(String msg) {
144     log(Level.FINER, msg);
145   }
146   
147   private void log(Level l, String msg) {
148     Logger.getLogger(JarScanner.class.getName()).log(l, msg);
149   }
150   
151   
152   public interface JarScannerListener {
153     public void actorFound(Class actorClass, Handler h, String contextName);
154   }
155   
156 }