summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorSenmori <thesenmori@gmail.com>2018-07-13 00:28:40 -0400
committermd_5 <git@md-5.net>2018-07-13 15:50:41 +1000
commit3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba (patch)
tree91404cc6b63abe03d441226e04da85f3f642249a /src/main
parente677cffa5de059d623c03705f9568b57447f5b05 (diff)
downloadplugin-annotations-3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba.tar
plugin-annotations-3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba.tar.gz
plugin-annotations-3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba.tar.lz
plugin-annotations-3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba.tar.xz
plugin-annotations-3d4b0c8a117a5ffc54e90b6b3b41f6f24e000cba.zip
Misc changes for v1.2
* Add @ApiVersion and appropriate targets * Add ability to have @Command and @Permission annotations on classes that implement CommandExecutor. Thanks Hex for the suggestion. * Remove last reference to @Main. * Update README. * Bump version. * Remove deprecated annotations.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java358
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java9
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java9
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java9
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java5
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java3
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java5
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java11
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java4
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java8
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java9
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/ApiVersion.java62
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java2
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOrder.java (renamed from src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOn.java)4
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java2
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java62
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java23
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/UsesDatabase.java20
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java26
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java2
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java2
-rw-r--r--src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java3
22 files changed, 364 insertions, 274 deletions
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java b/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java
index 9557b79..2f0f8d7 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java
@@ -2,25 +2,28 @@ package org.bukkit.plugin.java.annotation;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.annotation.command.Command;
+import org.bukkit.plugin.java.annotation.command.Commands;
import org.bukkit.plugin.java.annotation.dependency.Dependency;
import org.bukkit.plugin.java.annotation.dependency.LoadBefore;
import org.bukkit.plugin.java.annotation.dependency.SoftDependency;
import org.bukkit.plugin.java.annotation.permission.ChildPermission;
import org.bukkit.plugin.java.annotation.permission.Permission;
+import org.bukkit.plugin.java.annotation.permission.Permissions;
+import org.bukkit.plugin.java.annotation.plugin.ApiVersion;
import org.bukkit.plugin.java.annotation.plugin.Description;
-import org.bukkit.plugin.java.annotation.plugin.LoadOn;
+import org.bukkit.plugin.java.annotation.plugin.LoadOrder;
import org.bukkit.plugin.java.annotation.plugin.LogPrefix;
import org.bukkit.plugin.java.annotation.plugin.Plugin;
-import org.bukkit.plugin.java.annotation.plugin.UsesDatabase;
import org.bukkit.plugin.java.annotation.plugin.Website;
import org.bukkit.plugin.java.annotation.plugin.author.Author;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
-
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
@@ -31,231 +34,358 @@ import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
-import javax.swing.text.DateFormatter;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-@SupportedAnnotationTypes("org.bukkit.plugin.java.annotation.*")
-@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@SupportedAnnotationTypes( "org.bukkit.plugin.java.annotation.*" )
+@SupportedSourceVersion( SourceVersion.RELEASE_8 )
public class PluginAnnotationProcessor extends AbstractProcessor {
private boolean hasMainBeenFound = false;
- private static final DateTimeFormatter dFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss", Locale.ENGLISH);
+ private static final DateTimeFormatter dFormat = DateTimeFormatter.ofPattern( "yyyy/MM/dd HH:mm:ss", Locale.ENGLISH );
@Override
public boolean process(Set<? extends TypeElement> annots, RoundEnvironment rEnv) {
- Element main = null;
+ Element mainPluginElement = null;
hasMainBeenFound = false;
- Set<? extends Element> elements = rEnv.getElementsAnnotatedWith(Plugin.class);
- if(elements.size() > 1) {
- raiseError("Found more than one plugin main class");
+ Set<? extends Element> elements = rEnv.getElementsAnnotatedWith( Plugin.class );
+ if ( elements.size() > 1 ) {
+ raiseError( "Found more than one plugin main class" );
return false;
}
- if(elements.isEmpty()) {
+ if ( elements.isEmpty() ) {
return false;
}
- if(hasMainBeenFound){
- raiseError("The plugin class has already been located, aborting!");
+ if ( hasMainBeenFound ) {
+ raiseError( "The plugin class has already been located, aborting!" );
return false;
}
- main = elements.iterator().next();
+ mainPluginElement = elements.iterator().next();
hasMainBeenFound = true;
- TypeElement mainType;
- if(main instanceof TypeElement){
- mainType = (TypeElement) main;
+ TypeElement mainPluginType;
+ if ( mainPluginElement instanceof TypeElement ) {
+ mainPluginType = ( TypeElement ) mainPluginElement;
} else {
- raiseError("Element annotated with @Main is not a type!", main);
+ raiseError( "Element annotated with @Plugin is not a type!", mainPluginElement );
return false;
}
- if(!(mainType.getEnclosingElement() instanceof PackageElement) && !mainType.getModifiers().contains(Modifier.STATIC)){
- raiseError("Element annotated with @Main is not top-level or static nested!", mainType);
+ if ( !( mainPluginType.getEnclosingElement() instanceof PackageElement ) && !mainPluginType.getModifiers().contains( Modifier.STATIC ) ) {
+ raiseError( "Element annotated with @Plugin is not top-level or static nested!", mainPluginType );
return false;
}
- if(!processingEnv.getTypeUtils().isSubtype(mainType.asType(), fromClass(JavaPlugin.class))){
- raiseError("Class annotated with @Main is not an subclass of JavaPlugin!", mainType);
+ if ( !processingEnv.getTypeUtils().isSubtype( mainPluginType.asType(), fromClass( JavaPlugin.class ) ) ) {
+ raiseError( "Class annotated with @Plugin is not an subclass of JavaPlugin!", mainPluginType );
}
Map<String, Object> yml = Maps.newLinkedHashMap(); // linked so we can maintain the same output into file for sanity
// populate mainName
- final String mainName = mainType.getQualifiedName().toString();
- yml.put("main", mainName); // always override this so we make sure the main class name is correct
+ final String mainName = mainPluginType.getQualifiedName().toString();
+ yml.put( "main", mainName ); // always override this so we make sure the main class name is correct
// populate plugin name
- processAndPut(yml, "name", mainType, mainName.substring(mainName.lastIndexOf('.') + 1), Plugin.class, String.class, "name");
+ processAndPut( yml, "name", mainPluginType, mainName.substring( mainName.lastIndexOf( '.' ) + 1 ), Plugin.class, String.class, "name" );
// populate version
- processAndPut(yml, "version", mainType, Plugin.DEFAULT_VERSION, Plugin.class, String.class, "version");
+ processAndPut( yml, "version", mainPluginType, Plugin.DEFAULT_VERSION, Plugin.class, String.class, "version" );
// populate plugin description
- processAndPut(yml, "description", mainType, null, Description.class, String.class, "desc");
+ processAndPut( yml, "description", mainPluginType, null, Description.class, String.class );
// populate plugin load order
- processAndPut(yml, "load", mainType, null, LoadOn.class, String.class,"loadOn");
+ processAndPut( yml, "load", mainPluginType, null, LoadOrder.class, String.class );
// authors
- Author[] authors = mainType.getAnnotationsByType(Author.class);
+ Author[] authors = mainPluginType.getAnnotationsByType( Author.class );
List<String> authorMap = Lists.newArrayList();
- for(Author auth : authors) {
- authorMap.add(auth.name());
+ for ( Author auth : authors ) {
+ authorMap.add( auth.value() );
}
- if(authorMap.size() > 1) {
- yml.put("authors", authorMap);
- } else if(authorMap.size() == 1) {
- yml.put("author", authorMap.iterator().next());
+ if ( authorMap.size() > 1 ) {
+ yml.put( "authors", authorMap );
+ } else if ( authorMap.size() == 1 ) {
+ yml.put( "author", authorMap.iterator().next() );
}
// website
- processAndPut(yml, "website", mainType, null, Website.class, String.class, "url");
+ processAndPut( yml, "website", mainPluginType, null, Website.class, String.class );
// prefix
- processAndPut(yml, "prefix", mainType, null, LogPrefix.class, String.class, "prefix");
+ processAndPut( yml, "prefix", mainPluginType, null, LogPrefix.class, String.class );
// dependencies
- Dependency[] dependencies = mainType.getAnnotationsByType(Dependency.class);
+ Dependency[] dependencies = mainPluginType.getAnnotationsByType( Dependency.class );
List<String> hardDependencies = Lists.newArrayList();
- for(Dependency dep : dependencies) {
- hardDependencies.add(dep.plugin());
+ for ( Dependency dep : dependencies ) {
+ hardDependencies.add( dep.value() );
}
- if(!hardDependencies.isEmpty()) yml.putIfAbsent("depend", hardDependencies);
+ if ( !hardDependencies.isEmpty() ) yml.put( "depend", hardDependencies );
// soft-dependencies
- SoftDependency[] softDependencies = mainType.getAnnotationsByType(SoftDependency.class);
- String[] softDepArr = new String[softDependencies.length];
- for(int i = 0; i < softDependencies.length; i++) {
- softDepArr[i] = softDependencies[i].plugin();
+ SoftDependency[] softDependencies = mainPluginType.getAnnotationsByType( SoftDependency.class );
+ String[] softDepArr = new String[ softDependencies.length ];
+ for ( int i = 0; i < softDependencies.length; i++ ) {
+ softDepArr[ i ] = softDependencies[ i ].value();
}
- if(softDepArr.length > 0) yml.putIfAbsent("softdepend", softDepArr);
+ if ( softDepArr.length > 0 ) yml.put( "softdepend", softDepArr );
// load-before
- LoadBefore[] loadBefore = mainType.getAnnotationsByType(LoadBefore.class);
- String[] loadBeforeArr = new String[loadBefore.length];
- for(int i = 0; i < loadBefore.length; i++) {
- loadBeforeArr[i] = loadBefore[i].plugin();
+ LoadBefore[] loadBefore = mainPluginType.getAnnotationsByType( LoadBefore.class );
+ String[] loadBeforeArr = new String[ loadBefore.length ];
+ for ( int i = 0; i < loadBefore.length; i++ ) {
+ loadBeforeArr[ i ] = loadBefore[ i ].value();
}
- if(loadBeforeArr.length > 0) yml.putIfAbsent("loadbefore", loadBeforeArr);
+ if ( loadBeforeArr.length > 0 ) yml.put( "loadbefore", loadBeforeArr );
// commands
- Command[] commands = mainType.getAnnotationsByType(Command.class);
- Map<String, Object> commandMap = Maps.newLinkedHashMap();
- for(Command command : commands) {
- Map<String, Object> desc = Maps.newLinkedHashMap();
- String name = command.name();
- if(!command.desc().isEmpty()) desc.put("description", command.desc());
- if(command.aliases().length != 0) desc.put("aliases", command.aliases());
- if(!command.permission().isEmpty()) desc.put("permission", command.permission());
- if(!command.permissionMessage().isEmpty()) desc.put("permission-message", command.permissionMessage());
- if(!command.usage().isEmpty()) desc.put("usage", command.usage());
- commandMap.put(name, desc);
+ // Begin processing external command annotations
+ Map<String, Map<String, Object>> commandMap = Maps.newLinkedHashMap();
+ boolean result = processExternalCommands( rEnv.getElementsAnnotatedWith( Command.class ), mainPluginType, commandMap );
+ if ( !result ) {
+ // #processExternalCommand already raised the errors
+ return false;
+ }
+
+ Commands commands = mainPluginType.getAnnotation( Commands.class );
+
+ // Check main class for any command annotations
+ if ( commands != null ) {
+ Map<String, Map<String, Object>> merged = Maps.newLinkedHashMap();
+ merged.putAll( commandMap );
+ merged.putAll( this.processCommands( commands ) );
+ commandMap = merged;
}
- if(!commandMap.isEmpty()) yml.putIfAbsent("commands", commandMap);
-
- // permissions
- Permission[] permissions = mainType.getAnnotationsByType(Permission.class);
- Map<String, Object> permMap = Maps.newLinkedHashMap();
- for(Permission perm : permissions) {
- Map<String, Object> desc = Maps.newLinkedHashMap();
- String name = perm.name();
- if(!perm.desc().isEmpty()) desc.put("description", perm.desc());
- desc.put("default", perm.defaultValue().toString());
- Map<String, Object> children = Maps.newLinkedHashMap();
- for(ChildPermission child : perm.children()) {
- children.put(child.name(), child.inherit());
+
+ yml.put( "commands", commandMap );
+
+ // Permissions
+ Map<String, Map<String, Object>> permissionMetadata = Maps.newLinkedHashMap();
+
+ Set<? extends Element> permissionAnnotations = rEnv.getElementsAnnotatedWith( Command.class );
+ if ( permissionAnnotations.size() > 0 ) {
+ for ( Element element : permissionAnnotations ) {
+ if ( element.equals( mainPluginElement ) ) {
+ continue;
+ }
+ if ( element.getAnnotation( Permission.class ) != null ) {
+ Permission permissionAnnotation = element.getAnnotation( Permission.class );
+ permissionMetadata.put( permissionAnnotation.name(), this.processPermission( permissionAnnotation ) );
+ }
}
- if(!children.isEmpty()) desc.put("children", children);
- permMap.put(name, desc);
}
- if(!permMap.isEmpty()) yml.putIfAbsent("permissions", permMap);
- // database D: //TODO: Remove me!
- if(mainType.getAnnotation(UsesDatabase.class) != null) {
- yml.put("database", true);
- processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING, "Database support was dropped in Bukkit in version 1.12.", mainType);
+ Permissions permissions = mainPluginType.getAnnotation( Permissions.class );
+ if ( permissions != null ) {
+ Map<String, Map<String, Object>> joined = Maps.newLinkedHashMap();
+ joined.putAll( permissionMetadata );
+ joined.putAll( this.processPermissions( permissions ) );
+ permissionMetadata = joined;
+ }
+ yml.put( "permissions", permissionMetadata );
+
+ // api-version
+ if ( mainPluginType.getAnnotation( ApiVersion.class ) != null ) {
+ ApiVersion apiVersion = mainPluginType.getAnnotation( ApiVersion.class );
+ if ( apiVersion.value() != ApiVersion.Target.DEFAULT ) {
+ yml.put( "api-version", apiVersion.value().getVersion() );
+ }
}
- Yaml yaml = new Yaml();
try {
- FileObject file = this.processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "plugin.yml");
- try(Writer w = file.openWriter()) {
- w.append("# Auto-generated plugin.yml, generated at ")
- .append(LocalDateTime.now().format(dFormat))
- .append(" by ")
- .append(this.getClass().getName())
- .append("\n\n");
+ Yaml yaml = new Yaml();
+ FileObject file = this.processingEnv.getFiler().createResource( StandardLocation.CLASS_OUTPUT, "", "plugin.yml" );
+ try ( Writer w = file.openWriter() ) {
+ w.append( "# Auto-generated plugin.yml, generated at " )
+ .append( LocalDateTime.now().format( dFormat ) )
+ .append( " by " )
+ .append( this.getClass().getName() )
+ .append( "\n\n" );
// have to format the yaml explicitly because otherwise it dumps child nodes as maps within braces.
- String raw = yaml.dumpAs(yml, Tag.MAP, DumperOptions.FlowStyle.BLOCK);
- w.write(raw);
+ String raw = yaml.dumpAs( yml, Tag.MAP, DumperOptions.FlowStyle.BLOCK );
+ w.write( raw );
w.flush();
w.close();
}
// try with resources will close the Writer since it implements Closeable
- } catch (IOException e) {
- throw new RuntimeException(e);
+ } catch ( IOException e ) {
+ throw new RuntimeException( e );
}
- processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "NOTE: You are using org.bukkit.plugin.java.annotation, an experimental API!");
+ processingEnv.getMessager().printMessage( Diagnostic.Kind.WARNING, "NOTE: You are using org.bukkit.plugin.java.annotation, an experimental API!" );
return true;
}
private void raiseError(String message) {
- this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
+ this.processingEnv.getMessager().printMessage( Diagnostic.Kind.ERROR, message );
}
private void raiseError(String message, Element element) {
- this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
+ this.processingEnv.getMessager().printMessage( Diagnostic.Kind.ERROR, message, element );
}
private TypeMirror fromClass(Class<?> clazz) {
- return processingEnv.getElementUtils().getTypeElement(clazz.getName()).asType();
+ return processingEnv.getElementUtils().getTypeElement( clazz.getName() ).asType();
}
private <A extends Annotation, R> R processAndPut(
Map<String, Object> map, String name, Element el, R defaultVal, Class<A> annotationType, Class<R> returnType) {
- return processAndPut(map, name, el, defaultVal, annotationType, returnType, "value");
+ return processAndPut( map, name, el, defaultVal, annotationType, returnType, "value" );
}
private <A extends Annotation, R> R processAndPut(
Map<String, Object> map, String name, Element el, R defaultVal, Class<A> annotationType, Class<R> returnType, String methodName) {
- R result = process(el, defaultVal, annotationType, returnType, methodName);
- if(result != null)
- map.putIfAbsent(name, result);
+ R result = process( el, defaultVal, annotationType, returnType, methodName );
+ if ( result != null )
+ map.put( name, result );
return result;
}
private <A extends Annotation, R> R process(Element el, R defaultVal, Class<A> annotationType, Class<R> returnType, String methodName) {
R result;
- A ann = el.getAnnotation(annotationType);
- if(ann == null) result = defaultVal;
+ A ann = el.getAnnotation( annotationType );
+ if ( ann == null ) result = defaultVal;
else {
try {
- Method value = annotationType.getMethod(methodName);
- Object res = value.invoke(ann);
- result = (R) (returnType == String.class ? res.toString() : returnType.cast(res));
- } catch (Exception e) {
- throw new RuntimeException(e); // shouldn't happen in theory (blame Choco if it does)
+ Method value = annotationType.getMethod( methodName );
+ Object res = value.invoke( ann );
+ result = ( R ) ( returnType == String.class ? res.toString() : returnType.cast( res ) );
+ } catch ( Exception e ) {
+ throw new RuntimeException( e ); // shouldn't happen in theory (blame Choco if it does)
}
}
return result;
}
+
+ private boolean processExternalCommands(Set<? extends Element> commandExecutors, TypeElement mainPluginType, Map<String, Map<String, Object>> commandMetadata) {
+ for ( Element element : commandExecutors ) {
+ // Check to see if someone annotated a non-class with this
+ if ( !( element instanceof TypeElement ) ) {
+ this.raiseError( "Specified Command Executor class is not a class." );
+ return false;
+ }
+
+ TypeElement typeElement = ( TypeElement ) element;
+ if ( typeElement.equals( mainPluginType ) ) {
+ continue;
+ }
+
+ // Check to see if annotated class is actuall a command executor
+ TypeMirror mirror = this.processingEnv.getElementUtils().getTypeElement( CommandExecutor.class.getName() ).asType();
+ if ( !( this.processingEnv.getTypeUtils().isAssignable( typeElement.asType(), mirror ) ) ) {
+ this.raiseError( "Specified Command Executor class is not assignable from CommandExecutor " );
+ return false;
+ }
+
+ Command annotation = typeElement.getAnnotation( Command.class );
+ commandMetadata.put( annotation.name(), this.processCommand( annotation ) );
+ }
+ return true;
+ }
+
+ /**
+ * Processes a set of commands.
+ *
+ * @param commands The annotation.
+ *
+ * @return The generated command metadata.
+ */
+ protected Map<String, Map<String, Object>> processCommands(Commands commands) {
+ Map<String, Map<String, Object>> commandList = Maps.newLinkedHashMap();
+ for ( Command command : commands.value() ) {
+ commandList.put( command.name(), this.processCommand( command ) );
+ }
+ return commandList;
+ }
+
+ /**
+ * Processes a single command.
+ *
+ * @param commandAnnotation The annotation.
+ *
+ * @return The generated command metadata.
+ */
+ protected Map<String, Object> processCommand(Command commandAnnotation) {
+ Map<String, Object> command = Maps.newLinkedHashMap();
+
+ if ( commandAnnotation.aliases().length == 1 ) {
+ command.put( "aliases", commandAnnotation.aliases()[ 0 ] );
+ } else if ( commandAnnotation.aliases().length > 1 ) {
+ command.put( "aliases", commandAnnotation.aliases() );
+ }
+
+ if ( !"".equals( commandAnnotation.desc() ) ) {
+ command.put( "description", commandAnnotation.desc() );
+ }
+ if ( !"".equals( commandAnnotation.permission() ) ) {
+ command.put( "permission", commandAnnotation.permission() );
+ }
+ if ( !"".equals( commandAnnotation.permissionMessage() ) ) {
+ command.put( "permission-message", commandAnnotation.permissionMessage() );
+ }
+ if ( !"".equals( commandAnnotation.usage() ) ) {
+ command.put( "usage", commandAnnotation.usage() );
+ }
+
+ return command;
+ }
+
+ /**
+ * Processes a command.
+ *
+ * @param permissionAnnotation The annotation.
+ *
+ * @return The generated permission metadata.
+ */
+ protected Map<String, Object> processPermission(Permission permissionAnnotation) {
+ Map<String, Object> permission = Maps.newLinkedHashMap();
+
+ if ( !"".equals( permissionAnnotation.desc() ) ) {
+ permission.put( "description", permissionAnnotation.desc() );
+ }
+ if ( PermissionDefault.OP != permissionAnnotation.defaultValue() ) {
+ permission.put( "default", permissionAnnotation.defaultValue().toString().toLowerCase() );
+ }
+
+ if ( permissionAnnotation.children().length > 0 ) {
+ Map<String, Boolean> childrenList = Maps.newLinkedHashMap(); // maintain order
+ for ( ChildPermission childPermission : permissionAnnotation.children() ) {
+ childrenList.put( childPermission.name(), childPermission.inherit() );
+ }
+ permission.put( "children", childrenList );
+ }
+
+ return permission;
+ }
+
+ /**
+ * Processes a set of permissions.
+ *
+ * @param permissions The annotation.
+ *
+ * @return The generated permission metadata.
+ */
+ protected Map<String, Map<String, Object>> processPermissions(Permissions permissions) {
+ Map<String, Map<String, Object>> permissionList = Maps.newLinkedHashMap();
+ for ( Permission permission : permissions.value() ) {
+ permissionList.put( permission.name(), this.processPermission( permission ) );
+ }
+ return permissionList;
+ }
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java b/src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java
index 6ba1211..df66cc6 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java
@@ -7,9 +7,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents a list of this plugin's registered command(s).
+ * Part of the plugin annotations framework.
+ * <p>
+ * Represents a list of this plugin's registered command(s).
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
@Target(ElementType.TYPE)
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java
index ac6e942..28b045b 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java
@@ -8,7 +8,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Defines a plugin dependency
+ * Defines a plugin dependency.
+ * <br>
+ * The plugin's <b>name</b> attribute is required in order to load the dependency.<br>
+ * If any plugin listed is not found the plugin will fail to load. <br>
+ * If multiple plugins list each other as a dependency, so that there are no plugins with an unloadable dependency,
+ * all plugins will fail to load.
*/
@Documented
@Target(ElementType.TYPE)
@@ -18,5 +23,5 @@ public @interface Dependency {
/**
* A plugin that is required to be present in order for this plugin to load.
*/
- String plugin();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java
index 8d59aaa..54e9e5d 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java
@@ -7,9 +7,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents the plugins a plugin depends on in order to be loaded
+ * Part of the plugin annotations framework.
+ * <p>
+ * Represents the plugins a plugin depends on in order to be loaded
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
@Target(ElementType.TYPE)
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java
index d5ba086..06e3f5b 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java
@@ -11,6 +11,9 @@ import java.lang.annotation.Target;
* Part of the plugin annotations framework.
* <p>
* Represents the plugin this plugin should be loaded before
+ * <br>
+ * The plugin's <b>name</b> attribute is required in order to specify the target. <br>
+ * The plugin listed will be treated as a {@link SoftDependency}. <br>
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@@ -20,5 +23,5 @@ public @interface LoadBefore {
/**
* A plugin that should be loaded after your plugin
*/
- String plugin();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java
index 67991e9..7061622 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java
@@ -8,6 +8,9 @@ import java.lang.annotation.Target;
/**
* Defines a list of plugin to load after this plugin
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java
index a53e16b..9f3c379 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java
@@ -11,6 +11,9 @@ import java.lang.annotation.Target;
/**
* Represents a soft (optional) dependency for this plugin.
* If this dependency is not present, the plugin will still load.
+ * <br>
+ * The <b>name</b> attribute of the plugin is required in order to specify the target. <br>
+ * Circular soft-dependencies are loaded arbitrarily.
*/
@Documented
@@ -21,5 +24,5 @@ public @interface SoftDependency {
/**
* A plugin that is required in order for this plugin to have full functionality.
*/
- String plugin();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java
index 038831d..fb53a10 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java
@@ -7,10 +7,13 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents the plugins this plugin should try to load before this plugin will attempt to load.
- * A plugin will still load if a soft dependency is not present.
+ * Part of the plugin annotations framework.
+ * <p>
+ * Represents the plugins this plugin should try to load before this plugin will attempt to load.
+ * A plugin will still load if a soft dependency is not present.
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java b/src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java
index 7fe1a3d..53b6ccf 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java
@@ -7,7 +7,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Defines a child permission for {@link Permission}
+ * Defines a child permission for a {@link Permission}
*/
@Documented
@Target(ElementType.TYPE)
@@ -15,7 +15,7 @@ import java.lang.annotation.Target;
public @interface ChildPermission {
/**
* If true, this child node will inherit the parent {@link Permission}'s permission.
- * If false, this child node inherits the inverse parent permission.
+ * If false, this child node inherits the inverse of the parent permission.
*/
boolean inherit() default true;
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java
index 58770e2..a00c0f9 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java
@@ -19,22 +19,22 @@ import java.lang.annotation.Target;
@Repeatable(Permissions.class)
public @interface Permission {
/**
- * This perm's name.
+ * This permission's name.
*/
String name();
/**
- * This perm's description.
+ * This permission's description.
*/
String desc() default "";
/**
- * This perm's default {@link PermissionDefault}
+ * This permission's default {@link PermissionDefault}
*/
PermissionDefault defaultValue() default PermissionDefault.OP;
/**
- * This permission's child nodes ({@link ChildPermission})
+ * This permission's child nodes ( {@link ChildPermission} )
*/
ChildPermission[] children() default {};
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java
index 8dd8581..644b152 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java
@@ -7,9 +7,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents a list of this plugin's registered name.
+ * Part of the plugin annotations framework.
+ * <p>
+ * Represents a list of this plugin's registered name.
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/ApiVersion.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/ApiVersion.java
new file mode 100644
index 0000000..b7f1e24
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/ApiVersion.java
@@ -0,0 +1,62 @@
+package org.bukkit.plugin.java.annotation.plugin;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+
+/**
+ * This annotation specifies the api version of the plugin.
+ * <br>
+ * Defaults to {@link ApiVersion.Target#DEFAULT}.
+ * <br>
+ * Pre-1.13 plugins do not need to use this annotation.
+ */
+@Documented
+@Retention( RetentionPolicy.SOURCE )
+@Target( ElementType.TYPE )
+public @interface ApiVersion {
+
+ Target value() default Target.DEFAULT;
+
+ /**
+ * Specifies the target api-version for this plugin.
+ *
+ * All pre-1.13 plugins must use {@link #DEFAULT}.
+ */
+ public static enum Target {
+ /**
+ * This target version specifies that the plugin was made for pre-1.13 Spigot versions.
+ */
+ DEFAULT( null ),
+
+ /**
+ * This target version specifies that the plugin was made with 1.13+ versions in mind.
+ */
+ v1_13( "1.13", DEFAULT );
+
+
+ private final String version;
+ private final Collection<Target> conflictsWith = Sets.newLinkedHashSet();
+
+ private Target(String version, Target... conflictsWith) {
+ this.version = version;
+ this.conflictsWith.addAll( Lists.newArrayList( conflictsWith ) );
+ }
+
+
+ public String getVersion() {
+ return version;
+ }
+
+ public boolean conflictsWith(Target target) {
+ return this.conflictsWith.contains( target );
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java
index 137249d..69abeca 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java
@@ -19,6 +19,6 @@ public @interface Description {
/**
* A human friendly description of the functionality this plugin provides.
*/
- String desc();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOn.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOrder.java
index 23716f7..528ad1a 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOn.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOrder.java
@@ -17,11 +17,11 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
-public @interface LoadOn {
+public @interface LoadOrder {
/**
* Explicitly state when the plugin should be loaded.
* If not defined, will default to {@link PluginLoadOrder#POSTWORLD}.
* See {@link PluginLoadOrder}
*/
- PluginLoadOrder loadOn();
+ PluginLoadOrder value() default PluginLoadOrder.POSTWORLD;
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java
index baefbff..cdf0838 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java
@@ -19,5 +19,5 @@ public @interface LogPrefix {
/**
* The name to use when logging to console instead of the plugin's name.
*/
- String prefix();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java
deleted file mode 100644
index 3a21c6c..0000000
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.bukkit.plugin.java.annotation.plugin;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * DEPRECATED: Use {@link Plugin} instead.
- * Marks this class (which <i>must</i> subclass JavaPlugin) as this plugin's main class.
- * <p>
- * This class is part of the plugin annotation framework that automates plugin.yml.
- * <p>
- * Example:
- * <pre>
- * <code>{@literal @}Main
- * {@literal @}Name("Test")
- * {@literal @}Version("v1.0")
- * {@literal @}Description("A test plugin.")
- * {@literal @}LoadOn(PluginLoadOrder.POSTWORLD)
- * {@literal @}Author("md_5")
- * {@literal @}Website("spigotmc.org")
- * {@literal @}UsesDatabase
- * {@literal @}DependsOn({"WorldEdit", "Towny"})
- * {@literal @}SoftDependsOn("Vault")
- * {@literal @}LogPrefix("Testing")
- * {@literal @}LoadBefore("Essentials")
- * {@literal @}Commands({
- * {@literal @}Command(
- * name = "foo",
- * name = "Foo command",
- * aliases = {"foobar", "fubar"},
- * permission = "test.foo",
- * permissionMessage = "You do not have permission!",
- * usage = "/<command> [test|stop]"
- * ),
- * {@literal @}Command("bar")
- * })
- * {@literal @}Permissions({
- * {@literal @}Perm(
- * name = "test.foo",
- * name = "Allows foo command",
- * defaultValue = PermissionDefault.OP,
- * ),
- * {@literal @}Perm(
- * name = "test.*",
- * name = "Wildcard perm",
- * defaultValue = PermissionDefault.OP,
- * children = {"test.foo"}
- * )
- * })
- * public class Test extends JavaPlugin { ... }
- * </code>
- * </pre>
- * @deprecated use {@link Plugin} instead.
- */
-@Deprecated
-@Documented
-@Retention(RetentionPolicy.SOURCE)
-@Target(ElementType.TYPE)
-public @interface Main {}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java
deleted file mode 100644
index 9a11752..0000000
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.bukkit.plugin.java.annotation.plugin;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents the name of the plugin.
- * <p>
- * If not present in a class annotated with {@link Main} the name defaults to Class.getSimpleName() and will emmit a warning.
- * @deprecated use {@link Plugin#name()} instead.
- */
-@Deprecated
-@Documented
-@Retention(RetentionPolicy.SOURCE)
-@Target(ElementType.TYPE)
-public @interface Name {
- String name();
-}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/UsesDatabase.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/UsesDatabase.java
deleted file mode 100644
index aedb9e4..0000000
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/UsesDatabase.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.bukkit.plugin.java.annotation.plugin;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Part of the plugin annotations framework.
- * <p>
- * Denotes this plugin as using Bukkit's bundled database system.
- * @deprecated Bukkit no longer supports database(s) in the plugin.yml
- */
-
-@Deprecated
-@Documented
-@Retention(RetentionPolicy.SOURCE)
-@Target(ElementType.TYPE)
-public @interface UsesDatabase {}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java
deleted file mode 100644
index ba8c25e..0000000
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.bukkit.plugin.java.annotation.plugin;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Part of the plugin annotations framework.
- * <p>
- * Represents the version of the plugin.
- * <p>
- * If not present in a class annotated with {@link Main} the name defaults to "v0.0" and will emmit a warning.
- * @deprecated use {@link Plugin#version()} instead
- */
-
-@Deprecated
-@Documented
-@Retention(RetentionPolicy.SOURCE)
-@Target(ElementType.TYPE)
-public @interface Version {
- String version();
-
- String DEFAULT_VERSION = "v0.0";
-}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java
index aa28475..9937138 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java
@@ -19,5 +19,5 @@ public @interface Website {
/**
* The url to the website where a user can download this plugin.
*/
- String url();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java
index e8172a2..d652259 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java
@@ -21,5 +21,5 @@ public @interface Author {
/**
* The name of the person who developed this plugin.
*/
- String name();
+ String value();
}
diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java
index 08ba1a3..b58e7cb 100644
--- a/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java
+++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java
@@ -8,6 +8,9 @@ import java.lang.annotation.Target;
/**
* Represents a list of author(s) for this plugin.
+ * <br>
+ * This specific annotation should not be used by people who do not know
+ * how repeating annotations work.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)