import java.lang.annotation.ElementType ;
import java.lang.annotation.Retention ;
import java.lang.annotation.RetentionPolicy ;
import java.lang.annotation.Target ;
import java.lang.reflect.Method ;
import java.lang.reflect.Modifier ;
import java.util.HashMap ;
import java.util.Map ;
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )
@interface PatternHandler {
}
interface TownyChatReplacerCallable {
}
class AnnotationRegistry {
private static final Map
< String , TownyChatReplacerCallable
> MAP
= new HashMap
< String , TownyChatReplacerCallable
> ( ) ;
public static void register
( String pattern, TownyChatReplacerCallable handler
) { System .
out .
println ( "Registering pattern:" + pattern
+ " handler:" + handler
) ; MAP.put ( pattern, handler) ;
}
TownyChatReplacerCallable handler = MAP.get ( pattern) ;
if ( handler != null ) {
String result
= handler.
call ( pattern, event
) ; System .
out .
println ( "Handler returned:" + result
) ; } else {
System .
out .
println ( "No Handler for:" + pattern
) ; }
}
public static void register( Class<?> clazz) {
Method [ ] methods
= clazz.
getDeclaredMethods ( ) ; method_loop
: for ( Method method
: methods
) { PatternHandler annotation = method.getAnnotation ( PatternHandler.class ) ;
if ( annotation != null ) {
if ( ! Modifier .
isStatic ( method.
getModifiers ( ) ) ) { System .
out .
println ( "Method must be static: " + method.
getName ( ) ) ; continue ;
}
if ( ! ( method.
getReturnType ( ) == String .
class ) ) { System .
out .
println ( "Method must return String: " + method.
getName ( ) + " returns:" + method.getReturnType ( ) .getName ( ) ) ;
continue ;
}
Class<?> [ ] parameterTypes = method.getParameterTypes ( ) ;
if ( parameterTypes.length != 2 ) {
System .
out .
println ( "Method must take 2 parameters: String, String" ) ; continue ;
}
// this would need to be different for different types
for ( Class<?> paramType : parameterTypes) {
if ( ! paramType.
isAssignableFrom ( String .
class ) ) { System .
out .
println ( "Method parameter does not take String: " + method.getName ( ) + " param:" + paramType.getName ( ) ) ;
continue method_loop;
}
}
// could check even more... not public etc
register( annotation.value ( ) , new MethodAdapter( method) ) ;
}
}
}
}
class Callables {
@PatternHandler( "foo" )
return "This is foo handler called with " + match + "," + event;
}
@PatternHandler( "bar" )
return "This is bar handler called with " + match + "," + event;
}
@PatternHandler( "bad" )
return "broken" ;
}
@PatternHandler( "bad" )
return 42 ;
}
@PatternHandler( "bad" )
return "broken" ;
}
@PatternHandler( "bad" )
return "broken" ;
}
}
class MethodAdapter implements TownyChatReplacerCallable {
public MethodAdapter
( Method m
) { method = m;
}
@Override
try {
return ( String ) method.
invoke ( null , match, event
) ; e.printStackTrace ( ) ;
return "OMGZ" ;
}
}
}
public class Main {
public static void main
( String [ ] args
) { AnnotationRegistry.register ( Callables.class ) ;
System .
out .
println ( "\n -- Done with registration --\n " ) ;
AnnotationRegistry.handle ( "foo" , "event1" ) ;
AnnotationRegistry.handle ( "bar" , "event2" ) ;
AnnotationRegistry.handle ( "zoom" , "event3" ) ;
}
}
aW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgpAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQpAVGFyZ2V0KEVsZW1lbnRUeXBlLk1FVEhPRCkKQGludGVyZmFjZSBQYXR0ZXJuSGFuZGxlciB7CiAgICBTdHJpbmcgdmFsdWUoKTsKfQoKaW50ZXJmYWNlIFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGUgewogICAgU3RyaW5nIGNhbGwoU3RyaW5nIG1hdGNoLCBTdHJpbmcgZXZlbnQpOwp9CgpjbGFzcyBBbm5vdGF0aW9uUmVnaXN0cnkgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZywgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZT4gTUFQID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlPigpOwoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlcihTdHJpbmcgcGF0dGVybiwgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZSBoYW5kbGVyKSB7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZWdpc3RlcmluZyBwYXR0ZXJuOiIgKyBwYXR0ZXJuICsgIiBoYW5kbGVyOiIgKyBoYW5kbGVyKTsKICAgICAgICBNQVAucHV0KHBhdHRlcm4sIGhhbmRsZXIpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBoYW5kbGUoU3RyaW5nIHBhdHRlcm4sIFN0cmluZyBldmVudCkgewogICAgICAgIFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGUgaGFuZGxlciA9IE1BUC5nZXQocGF0dGVybik7CiAgICAgICAgaWYgKGhhbmRsZXIgIT0gbnVsbCkgewogICAgICAgICAgICBTdHJpbmcgcmVzdWx0ID0gaGFuZGxlci5jYWxsKHBhdHRlcm4sIGV2ZW50KTsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJIYW5kbGVyIHJldHVybmVkOiIgKyByZXN1bHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gSGFuZGxlciBmb3I6IiArIHBhdHRlcm4pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXIoQ2xhc3M8Pz4gY2xhenopIHsKICAgICAgICBNZXRob2RbXSBtZXRob2RzID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2RzKCk7CiAgICAgICAgbWV0aG9kX2xvb3A6IGZvciAoTWV0aG9kIG1ldGhvZCA6IG1ldGhvZHMpIHsKICAgICAgICAgICAgUGF0dGVybkhhbmRsZXIgYW5ub3RhdGlvbiA9IG1ldGhvZC5nZXRBbm5vdGF0aW9uKFBhdHRlcm5IYW5kbGVyLmNsYXNzKTsKICAgICAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1N0YXRpYyhtZXRob2QuZ2V0TW9kaWZpZXJzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJNZXRob2QgbXVzdCBiZSBzdGF0aWM6ICIgKyBtZXRob2QuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghKG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkgPT0gU3RyaW5nLmNsYXNzKSkgewogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTWV0aG9kIG11c3QgcmV0dXJuIFN0cmluZzogIiArIG1ldGhvZC5nZXROYW1lKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiByZXR1cm5zOiIgKyBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBDbGFzczw/PltdIHBhcmFtZXRlclR5cGVzID0gbWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICAgICAgICAgICBpZiAocGFyYW1ldGVyVHlwZXMubGVuZ3RoICE9IDIpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk1ldGhvZCBtdXN0IHRha2UgMiBwYXJhbWV0ZXJzOiBTdHJpbmcsIFN0cmluZyIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gdGhpcyB3b3VsZCBuZWVkIHRvIGJlIGRpZmZlcmVudCBmb3IgZGlmZmVyZW50IHR5cGVzCiAgICAgICAgICAgICAgICBmb3IgKENsYXNzPD8+IHBhcmFtVHlwZSA6IHBhcmFtZXRlclR5cGVzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXJhbVR5cGUuaXNBc3NpZ25hYmxlRnJvbShTdHJpbmcuY2xhc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTWV0aG9kIHBhcmFtZXRlciBkb2VzIG5vdCB0YWtlIFN0cmluZzogIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbWV0aG9kLmdldE5hbWUoKSArICIgcGFyYW06IiArIHBhcmFtVHlwZS5nZXROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBtZXRob2RfbG9vcDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBjb3VsZCBjaGVjayBldmVuIG1vcmUuLi4gbm90IHB1YmxpYyBldGMKICAgICAgICAgICAgICAgIHJlZ2lzdGVyKGFubm90YXRpb24udmFsdWUoKSwgbmV3IE1ldGhvZEFkYXB0ZXIobWV0aG9kKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCmNsYXNzIENhbGxhYmxlcyB7CgogICAgQFBhdHRlcm5IYW5kbGVyKCJmb28iKQogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9vTWV0aG9kKFN0cmluZyBtYXRjaCwgU3RyaW5nIGV2ZW50KSB7CiAgICAgICAgcmV0dXJuICJUaGlzIGlzIGZvbyBoYW5kbGVyIGNhbGxlZCB3aXRoICIgKyBtYXRjaCArICIsIiArIGV2ZW50OwogICAgfQoKICAgIEBQYXR0ZXJuSGFuZGxlcigiYmFyIikKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGJhck1ldGhvZChTdHJpbmcgbWF0Y2gsIFN0cmluZyBldmVudCkgewogICAgICAgIHJldHVybiAiVGhpcyBpcyBiYXIgaGFuZGxlciBjYWxsZWQgd2l0aCAiICsgbWF0Y2ggKyAiLCIgKyBldmVudDsKICAgIH0KCiAgICBAUGF0dGVybkhhbmRsZXIoImJhZCIpCiAgICBwdWJsaWMgU3RyaW5nIG5vblN0YXRpY01ldGhvZChTdHJpbmcgbWF0Y2gsIFN0cmluZyBldmVudCkgewogICAgICAgIHJldHVybiAiYnJva2VuIjsKICAgIH0KCiAgICBAUGF0dGVybkhhbmRsZXIoImJhZCIpCiAgICBwdWJsaWMgc3RhdGljIEludGVnZXIgd3JvbmdSZXR1cm5UeXBlTWV0aG9kKFN0cmluZyBtYXRjaCwgU3RyaW5nIGV2ZW50KSB7CiAgICAgICAgcmV0dXJuIDQyOwogICAgfQoKICAgIEBQYXR0ZXJuSGFuZGxlcigiYmFkIikKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHdyb25nUGFyYW1ldGVyVHlwZU1ldGhvZChTdHJpbmcgbWF0Y2gsIEludGVnZXIgZXZlbnQpIHsKICAgICAgICByZXR1cm4gImJyb2tlbiI7CiAgICB9CgogICAgQFBhdHRlcm5IYW5kbGVyKCJiYWQiKQogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgd3JvbmdQYXJhbWV0ZXJDb3VudE1ldGhvZChTdHJpbmcgbWF0Y2gsIFN0cmluZyBldmVudCwgU3RyaW5nIGZvbykgewogICAgICAgIHJldHVybiAiYnJva2VuIjsKICAgIH0KCn0KCmNsYXNzIE1ldGhvZEFkYXB0ZXIgaW1wbGVtZW50cyBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlIHsKICAgIHByaXZhdGUgZmluYWwgTWV0aG9kIG1ldGhvZDsKCiAgICBwdWJsaWMgTWV0aG9kQWRhcHRlcihNZXRob2QgbSkgewogICAgICAgIG1ldGhvZCA9IG07CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIGNhbGwoU3RyaW5nIG1hdGNoLCBTdHJpbmcgZXZlbnQpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gKFN0cmluZykgbWV0aG9kLmludm9rZShudWxsLCBtYXRjaCwgZXZlbnQpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CiAgICAgICAgICAgIHJldHVybiAiT01HWiI7CiAgICAgICAgfQogICAgfQp9CgpwdWJsaWMgY2xhc3MgTWFpbiB7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgQW5ub3RhdGlvblJlZ2lzdHJ5LnJlZ2lzdGVyKENhbGxhYmxlcy5jbGFzcyk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbi0tIERvbmUgd2l0aCByZWdpc3RyYXRpb24gLS1cbiIpOwoKICAgICAgICBBbm5vdGF0aW9uUmVnaXN0cnkuaGFuZGxlKCJmb28iLCAiZXZlbnQxIik7CiAgICAgICAgQW5ub3RhdGlvblJlZ2lzdHJ5LmhhbmRsZSgiYmFyIiwgImV2ZW50MiIpOwogICAgICAgIEFubm90YXRpb25SZWdpc3RyeS5oYW5kbGUoInpvb20iLCAiZXZlbnQzIik7CiAgICB9Cn0K