import java.lang.annotation.ElementType ;
import java.lang.annotation.Retention ;
import java.lang.annotation.RetentionPolicy ;
import java.lang.annotation.Target ;
import java.lang.reflect.Field ;
import java.lang.reflect.Modifier ;
import java.util.HashMap ;
import java.util.Map ;
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.FIELD )
@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) {
Field [ ] fields
= clazz.
getDeclaredFields ( ) ; for ( Field field
: fields
) { PatternHandler annotation = field.getAnnotation ( PatternHandler.class ) ;
if ( annotation != null ) {
if ( ! Modifier .
isStatic ( field.
getModifiers ( ) ) ) { System .
out .
println ( "Field must be static:" + field.
getName ( ) ) ; continue ;
}
try {
Object object
= field.
get ( null ) ; if ( object instanceof TownyChatReplacerCallable) {
register( annotation.value ( ) , ( TownyChatReplacerCallable) object) ;
} else {
System .
out .
println ( "Field must be instanceof TownyChatReplacerCallable:" + field.
getName ( ) ) ; }
e.printStackTrace ( ) ;
e.printStackTrace ( ) ;
}
}
}
}
}
class Callables {
@PatternHandler( "foo" )
public static final TownyChatReplacerCallable FOO = new TownyChatReplacerCallable( ) {
@Override
return "This is foo handler called with " + match + "," + event;
}
} ;
@PatternHandler( "bar" )
public static final TownyChatReplacerCallable BAR = new TownyChatReplacerCallable( ) {
@Override
return "This is foo handler called with " + match + "," + event;
}
} ;
@PatternHandler( "lala" )
public static final String WRONG_CLASS
= "" ;
@PatternHandler( "lulu" )
public final TownyChatReplacerCallable notStatic = new TownyChatReplacerCallable( ) {
@Override
return "This is foo handler called with " + match + "," + event;
}
} ;
}
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" ) ;
}
}
aW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQ7CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKCkBSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCkBUYXJnZXQoRWxlbWVudFR5cGUuRklFTEQpCkBpbnRlcmZhY2UgUGF0dGVybkhhbmRsZXIgewogICAgU3RyaW5nIHZhbHVlKCk7Cn0KCmludGVyZmFjZSBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlIHsKICAgIFN0cmluZyBjYWxsKFN0cmluZyBtYXRjaCwgU3RyaW5nIGV2ZW50KTsKfQoKY2xhc3MgQW5ub3RhdGlvblJlZ2lzdHJ5IHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGU+IE1BUCA9IG5ldyBIYXNoTWFwPFN0cmluZywgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZT4oKTsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlcihTdHJpbmcgcGF0dGVybiwgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZSBoYW5kbGVyKSB7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZWdpc3RlcmluZyBwYXR0ZXJuOiIgKyBwYXR0ZXJuICsgIiBoYW5kbGVyOiIgKyBoYW5kbGVyKTsKICAgICAgICBNQVAucHV0KHBhdHRlcm4sIGhhbmRsZXIpOwogICAgfQogICAgcHVibGljIHN0YXRpYyB2b2lkIGhhbmRsZShTdHJpbmcgcGF0dGVybiwgU3RyaW5nIGV2ZW50KSB7CiAgICAgICAgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZSBoYW5kbGVyID0gTUFQLmdldChwYXR0ZXJuKTsKICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsKSB7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBoYW5kbGVyLmNhbGwocGF0dGVybiwgZXZlbnQpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkhhbmRsZXIgcmV0dXJuZWQ6IiArIHJlc3VsdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJObyBIYW5kbGVyIGZvcjoiICsgcGF0dGVybik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlcihDbGFzczw/PiBjbGF6eikgewogICAgICAgIEZpZWxkW10gZmllbGRzID0gY2xhenouZ2V0RGVjbGFyZWRGaWVsZHMoKTsKICAgICAgICBmb3IgKEZpZWxkIGZpZWxkIDogZmllbGRzKSB7CiAgICAgICAgICAgIFBhdHRlcm5IYW5kbGVyIGFubm90YXRpb24gPSBmaWVsZC5nZXRBbm5vdGF0aW9uKFBhdHRlcm5IYW5kbGVyLmNsYXNzKTsKICAgICAgICAgICAgaWYgKGFubm90YXRpb24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKCFNb2RpZmllci5pc1N0YXRpYyhmaWVsZC5nZXRNb2RpZmllcnMoKSkpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZpZWxkIG11c3QgYmUgc3RhdGljOiIgKyBmaWVsZC5nZXROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBPYmplY3Qgb2JqZWN0ID0gZmllbGQuZ2V0KG51bGwpOwogICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyKGFubm90YXRpb24udmFsdWUoKSwgKFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGUpIG9iamVjdCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGaWVsZCBtdXN0IGJlIGluc3RhbmNlb2YgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZToiICArIGZpZWxkLmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKY2xhc3MgQ2FsbGFibGVzIHsKCiAgICBAUGF0dGVybkhhbmRsZXIoImZvbyIpCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGUgRk9PID0gbmV3IFRvd255Q2hhdFJlcGxhY2VyQ2FsbGFibGUoKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBjYWxsKFN0cmluZyBtYXRjaCwgU3RyaW5nIGV2ZW50KSB7CiAgICAgICAgICAgIHJldHVybiAiVGhpcyBpcyBmb28gaGFuZGxlciBjYWxsZWQgd2l0aCAiICsgbWF0Y2ggKyAiLCIgKyBldmVudDsKICAgICAgICB9CiAgICB9OwoKICAgIEBQYXR0ZXJuSGFuZGxlcigiYmFyIikKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZSBCQVIgPSBuZXcgVG93bnlDaGF0UmVwbGFjZXJDYWxsYWJsZSgpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIGNhbGwoU3RyaW5nIG1hdGNoLCBTdHJpbmcgZXZlbnQpIHsKICAgICAgICAgICAgcmV0dXJuICJUaGlzIGlzIGZvbyBoYW5kbGVyIGNhbGxlZCB3aXRoICIgKyBtYXRjaCArICIsIiArIGV2ZW50OwogICAgICAgIH0KICAgIH07CgogICAgQFBhdHRlcm5IYW5kbGVyKCJsYWxhIikKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdST05HX0NMQVNTID0gIiI7CgogICAgQFBhdHRlcm5IYW5kbGVyKCJsdWx1IikKICAgIHB1YmxpYyBmaW5hbCBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlIG5vdFN0YXRpYyA9IG5ldyBUb3dueUNoYXRSZXBsYWNlckNhbGxhYmxlKCkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgY2FsbChTdHJpbmcgbWF0Y2gsIFN0cmluZyBldmVudCkgewogICAgICAgICAgICByZXR1cm4gIlRoaXMgaXMgZm9vIGhhbmRsZXIgY2FsbGVkIHdpdGggIiArIG1hdGNoICsgIiwiICsgZXZlbnQ7CiAgICAgICAgfQogICAgfTsKfQoKcHVibGljIGNsYXNzIE1haW4gewogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIEFubm90YXRpb25SZWdpc3RyeS5yZWdpc3RlcihDYWxsYWJsZXMuY2xhc3MpOwoKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuLS0gRG9uZSB3aXRoIHJlZ2lzdHJhdGlvbiAtLVxuIik7CgogICAgICAgIEFubm90YXRpb25SZWdpc3RyeS5oYW5kbGUoImZvbyIsICJldmVudDEiKTsKICAgICAgICBBbm5vdGF0aW9uUmVnaXN0cnkuaGFuZGxlKCJiYXIiLCAiZXZlbnQyIik7CiAgICAgICAgQW5ub3RhdGlvblJlZ2lzdHJ5LmhhbmRsZSgiem9vbSIsICJldmVudDMiKTsKICAgIH0KfQo=