Added feature about annotation for KissDispatcher.

This commit is contained in:
Christian P. MOMON 2024-08-12 03:35:46 +02:00
parent d872a7528b
commit 40fa91feb4
8 changed files with 384 additions and 0 deletions

View file

@ -21,6 +21,8 @@ package fr.devinsy.kiss4web.dispatcher;
import org.slf4j.Logger;
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.Hook;
import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister;
@ -49,6 +51,7 @@ public class KissDispatcher
// Pathinfo -> Servlet.
private ServletCache cache;
private AnnotationHooks annotationHooks;
/**
* Instantiates a new kiss dispatcher.
@ -57,6 +60,17 @@ public class KissDispatcher
{
this.cache = new ServletCache();
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;
}
/**

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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
}
}

View file

@ -18,6 +18,7 @@
*/
package fr.devinsy.kiss4web.dispatcher.hooks;
import java.util.Collection;
import java.util.Iterator;
import jakarta.servlet.ServletContext;
@ -119,6 +120,25 @@ public class HookRegister
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.
*

View file

@ -95,4 +95,20 @@ public class RewriteHook extends HookCore
//
return result;
}
/**
* To string.
*
* @return the string
*/
@Override
public String toString()
{
String result;
result = this.pattern.toString() + " -> " + this.targetClassName;
//
return result;
}
}