Added feature about annotation for KissDispatcher.
This commit is contained in:
parent
d872a7528b
commit
40fa91feb4
8 changed files with 384 additions and 0 deletions
|
@ -21,6 +21,8 @@ package fr.devinsy.kiss4web.dispatcher;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.kiss4web.dispatcher.annotation.AnnotationHooks;
|
||||||
|
import fr.devinsy.kiss4web.dispatcher.annotation.AnnotationUtils;
|
||||||
import fr.devinsy.kiss4web.dispatcher.hooks.ErrorServlet;
|
import fr.devinsy.kiss4web.dispatcher.hooks.ErrorServlet;
|
||||||
import fr.devinsy.kiss4web.dispatcher.hooks.Hook;
|
import fr.devinsy.kiss4web.dispatcher.hooks.Hook;
|
||||||
import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister;
|
import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister;
|
||||||
|
@ -49,6 +51,7 @@ public class KissDispatcher
|
||||||
|
|
||||||
// Pathinfo -> Servlet.
|
// Pathinfo -> Servlet.
|
||||||
private ServletCache cache;
|
private ServletCache cache;
|
||||||
|
private AnnotationHooks annotationHooks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new kiss dispatcher.
|
* Instantiates a new kiss dispatcher.
|
||||||
|
@ -57,6 +60,17 @@ public class KissDispatcher
|
||||||
{
|
{
|
||||||
this.cache = new ServletCache();
|
this.cache = new ServletCache();
|
||||||
this.hookRegister = new HookRegister("Init").register(new InitHook());
|
this.hookRegister = new HookRegister("Init").register(new InitHook());
|
||||||
|
this.annotationHooks = AnnotationUtils.getAnnotationHooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the annotation hooks.
|
||||||
|
*
|
||||||
|
* @return the annotation hooks
|
||||||
|
*/
|
||||||
|
public AnnotationHooks getAnnotationHooks()
|
||||||
|
{
|
||||||
|
return this.annotationHooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* This file is part of Kiss4web.
|
||||||
|
*
|
||||||
|
* Kiss4web is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Kiss4web is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package fr.devinsy.kiss4web.dispatcher.annotation;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.kiss4web.dispatcher.hooks.RewriteHook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class AnnotationHook.
|
||||||
|
*/
|
||||||
|
public class AnnotationHook extends RewriteHook
|
||||||
|
{
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(AnnotationHook.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new annotation hook.
|
||||||
|
*
|
||||||
|
* @param regex
|
||||||
|
* the regex
|
||||||
|
* @param targetClassName
|
||||||
|
* the target class name
|
||||||
|
*/
|
||||||
|
public AnnotationHook(final String regex, final String targetClassName)
|
||||||
|
{
|
||||||
|
super(regex, targetClassName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2024 Christian Pierre MOMON
|
||||||
|
*
|
||||||
|
* This file is part of Kiss4web.
|
||||||
|
*
|
||||||
|
* Kiss4web is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Kiss4web is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package fr.devinsy.kiss4web.dispatcher.annotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class AnnotationHooks.
|
||||||
|
*/
|
||||||
|
public class AnnotationHooks extends ArrayList<AnnotationHook>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1979896054785066359L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new hook list.
|
||||||
|
*/
|
||||||
|
public AnnotationHooks()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2024 Christian Pierre MOMON <christian@momon.org>
|
||||||
|
*
|
||||||
|
* This file is part of Kiss4web.
|
||||||
|
*
|
||||||
|
* Kiss4web is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Kiss4web is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package fr.devinsy.kiss4web.dispatcher.annotation;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import fr.devinsy.kiss4web.Kiss4webException;
|
||||||
|
import jakarta.servlet.http.HttpServlet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class AnnotationUtils.
|
||||||
|
*/
|
||||||
|
public class AnnotationUtils
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(AnnotationUtils.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive method used to find all classes in a given directory and
|
||||||
|
* subdirs.
|
||||||
|
*
|
||||||
|
* @param directory
|
||||||
|
* The base directory
|
||||||
|
* @param packageName
|
||||||
|
* The package name for classes found inside the base directory
|
||||||
|
* @return The classes
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
private static List<Class> findClasses(final File directory, final String packageName) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
List<Class> result;
|
||||||
|
|
||||||
|
result = new ArrayList<Class>();
|
||||||
|
if (directory.exists())
|
||||||
|
{
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
for (File file : files)
|
||||||
|
{
|
||||||
|
if (file.isDirectory())
|
||||||
|
{
|
||||||
|
assert !file.getName().contains(".");
|
||||||
|
result.addAll(findClasses(file, packageName + "." + file.getName()));
|
||||||
|
}
|
||||||
|
else if (file.getName().endsWith(".class"))
|
||||||
|
{
|
||||||
|
result.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the annotation hooks.
|
||||||
|
*
|
||||||
|
* @return the annotation hooks
|
||||||
|
* @throws Kiss4webException
|
||||||
|
*/
|
||||||
|
public static AnnotationHooks getAnnotationHooks()
|
||||||
|
{
|
||||||
|
AnnotationHooks result;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = new AnnotationHooks();
|
||||||
|
Class[] classes = getClasses("website");
|
||||||
|
for (Class clazz : classes)
|
||||||
|
{
|
||||||
|
if (clazz.isAnnotationPresent(KissServlet.class))
|
||||||
|
{
|
||||||
|
// System.out.println("==> " + clazz.getName() + " " +
|
||||||
|
// clazz.getCanonicalName());
|
||||||
|
// System.out.println("==> " + ((Class<HttpServlet>)
|
||||||
|
// clazz).getAnnotation(KissServlet.class).value());
|
||||||
|
|
||||||
|
String className = clazz.getCanonicalName();
|
||||||
|
String regexPathInfo = ((Class<HttpServlet>) clazz).getAnnotation(KissServlet.class).value();
|
||||||
|
|
||||||
|
AnnotationHook hook = new AnnotationHook(regexPathInfo, className);
|
||||||
|
result.add(hook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException | IOException exception)
|
||||||
|
{
|
||||||
|
logger.error("Package website undefined, KissServlet annotations ignored.", exception);
|
||||||
|
result = new AnnotationHooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the classes.
|
||||||
|
*
|
||||||
|
* @param packageName
|
||||||
|
* the package name
|
||||||
|
* @return the classes
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* the class not found exception
|
||||||
|
* @throws IOException
|
||||||
|
* Signals that an I/O exception has occurred.
|
||||||
|
*/
|
||||||
|
private static Class[] getClasses(final String packageName) throws ClassNotFoundException, IOException
|
||||||
|
{
|
||||||
|
Class[] result;
|
||||||
|
|
||||||
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
assert classLoader != null;
|
||||||
|
String path = packageName.replace('.', '/');
|
||||||
|
Enumeration<URL> resources = classLoader.getResources(path);
|
||||||
|
List<File> dirs = new ArrayList<File>();
|
||||||
|
while (resources.hasMoreElements())
|
||||||
|
{
|
||||||
|
URL resource = resources.nextElement();
|
||||||
|
dirs.add(new File(resource.getFile()));
|
||||||
|
}
|
||||||
|
ArrayList<Class> classes = new ArrayList<Class>();
|
||||||
|
for (File directory : dirs)
|
||||||
|
{
|
||||||
|
classes.addAll(findClasses(directory, packageName));
|
||||||
|
}
|
||||||
|
result = classes.toArray(new Class[classes.size()]);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Christian Pierre MOMON
|
||||||
|
*
|
||||||
|
* This file is part of Kiss4web.
|
||||||
|
*
|
||||||
|
* Kiss4web is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Kiss4web is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package fr.devinsy.kiss4web.dispatcher.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface KissServlet
|
||||||
|
{
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Christian Pierre MOMON
|
||||||
|
*
|
||||||
|
* This file is part of Kiss4web.
|
||||||
|
*
|
||||||
|
* Kiss4web is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Kiss4web is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
package fr.devinsy.kiss4web.dispatcher.annotation;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
|
import javax.annotation.processing.RoundEnvironment;
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
@javax.annotation.processing.SupportedAnnotationTypes("fr.devinsy.kiss4web.dispatcher.annotation.KissServlet")
|
||||||
|
@javax.annotation.processing.SupportedSourceVersion(javax.lang.model.SourceVersion.RELEASE_17)
|
||||||
|
public class KissServletProcessor extends AbstractProcessor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void init(final ProcessingEnvironment processingEnv)
|
||||||
|
{
|
||||||
|
super.init(processingEnv);
|
||||||
|
// Initialization code, if needed
|
||||||
|
System.out.println("=============== @INIT");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv)
|
||||||
|
{
|
||||||
|
for (TypeElement annotation : annotations)
|
||||||
|
{
|
||||||
|
// Find elements annotated with MyCustomAnnotation
|
||||||
|
for (Element element : roundEnv.getElementsAnnotatedWith(annotation))
|
||||||
|
{
|
||||||
|
// Process each element
|
||||||
|
this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Processing: " + element.getSimpleName());
|
||||||
|
|
||||||
|
// Your processing logic here
|
||||||
|
System.out.println("=============== YOOOOOOOOOOP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return true; // No further processing of this annotation type
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package fr.devinsy.kiss4web.dispatcher.hooks;
|
package fr.devinsy.kiss4web.dispatcher.hooks;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
@ -119,6 +120,25 @@ public class HookRegister
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register.
|
||||||
|
*
|
||||||
|
* @param hook
|
||||||
|
* the hook
|
||||||
|
* @return the hook register
|
||||||
|
*/
|
||||||
|
public HookRegister register(final Collection<? extends Hook> hooks)
|
||||||
|
{
|
||||||
|
HookRegister result;
|
||||||
|
|
||||||
|
this.hooks.addAll(hooks);
|
||||||
|
|
||||||
|
result = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register.
|
* Register.
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,4 +95,20 @@ public class RewriteHook extends HookCore
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To string.
|
||||||
|
*
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
|
||||||
|
result = this.pattern.toString() + " -> " + this.targetClassName;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue