diff options
31 files changed, 566 insertions, 302 deletions
@@ -10,16 +10,16 @@ <groupId>org.spigotmc</groupId> <artifactId>plugin-annotations</artifactId> - <version>1.0.0-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Plugin Annotations</name> <url>http://www.spigotmc.org/</url> - <description>A annotaion-based compiletime plugin.yml generator.</description> + <description>A annotation-based compile time plugin.yml generator.</description> <properties> - <maven.compiler.source>1.6</maven.compiler.source> - <maven.compiler.target>1.6</maven.compiler.target> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> @@ -47,7 +47,7 @@ <dependency> <groupId>org.bukkit</groupId> <artifactId>bukkit</artifactId> - <version>1.8-R0.1-SNAPSHOT</version> + <version>1.12.2-R0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> <!-- we don't currently have tests @@ -91,7 +91,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>animal-sniffer-maven-plugin</artifactId> - <version>1.13</version> + <version>1.16</version> <executions> <execution> <phase>process-classes</phase> @@ -103,8 +103,8 @@ <configuration> <signature> <groupId>org.codehaus.mojo.signature</groupId> - <artifactId>java16</artifactId> - <version>1.1</version> + <artifactId>java18</artifactId> + <version>1.0</version> </signature> </configuration> </plugin> @@ -116,4 +116,4 @@ </resource> </resources> </build> -</project>
\ No newline at end of file +</project> diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Commands.java b/src/main/java/org/bukkit/plugin/java/annotation/Commands.java deleted file mode 100644 index c730b59..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/Commands.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents a list of this plugin's registered commands. - */ - -@Target(ElementType.TYPE) -public @interface Commands { // TODO: in java 8, make repeatable. - - public Cmd[] value(); - - @Target({}) - public static @interface Cmd { - - /** - * This command's name. - */ - public String value(); - - /** - * This command's description. - */ - - public String desc() default ""; - - /** - * This command's aliases. - */ - public String[] aliases() default {}; - - /** - * This command's permission node. - */ - public String permission() default ""; - - /** - * This command's permission-check-fail message. - */ - public String permissionMessage() default ""; - - /** - * This command's usage message. - */ - public String usage() default ""; - } - -} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/DependsOn.java b/src/main/java/org/bukkit/plugin/java/annotation/DependsOn.java deleted file mode 100644 index 892a267..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/DependsOn.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents the plugin's hard dependencies. - */ - -@Target(ElementType.TYPE) -public @interface DependsOn { - - public String[] value(); - -} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/LoadBefore.java b/src/main/java/org/bukkit/plugin/java/annotation/LoadBefore.java deleted file mode 100644 index d0802f4..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/LoadBefore.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents the plugins this plugin should be loaded before - */ - -@Target(ElementType.TYPE) -public @interface LoadBefore { - - public String[] value(); - -} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Permissions.java b/src/main/java/org/bukkit/plugin/java/annotation/Permissions.java deleted file mode 100644 index c6097c3..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/Permissions.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import org.bukkit.permissions.PermissionDefault; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents a list of this plugin's registered permissions. - */ - -@Target(ElementType.TYPE) -public @interface Permissions { // TODO: in java 8, make repeatable. - - public Perm[] value(); - - @Target({}) - public static @interface Perm { - - /** - * This perm's name. - */ - public String value(); - - /** - * This perm's description. - */ - - public String desc() default ""; - - /** - * This perm's default. - */ - public PermissionDefault defaultValue() default PermissionDefault.OP; - - /** - * This perm's child nodes - */ - public String[] children() default {}; - - /** - * This perms's negated child nodes - */ - public String[] antichildren() default {}; - - } - -} 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 9266c97..9557b79 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/PluginAnnotationProcessor.java @@ -1,163 +1,220 @@ package org.bukkit.plugin.java.annotation; -import org.bukkit.plugin.PluginLoadOrder; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.annotation.command.Command; +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.plugin.Description; +import org.bukkit.plugin.java.annotation.plugin.LoadOn; +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.*; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; 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.StringWriter; +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.HashMap; +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_6) +@SupportedSourceVersion(SourceVersion.RELEASE_8) public class PluginAnnotationProcessor extends AbstractProcessor { private boolean hasMainBeenFound = false; - private static final DateFormat dFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + 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; - for(Element el : rEnv.getElementsAnnotatedWith(Main.class)) { - if(main != null){ - raiseError("More than one class with @Main found, aborting!"); - return false; - } - main = el; - } + hasMainBeenFound = false; - if(main == null) return false; + 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()) { + return false; + } if(hasMainBeenFound){ - raiseError("More than one class with @Main found, aborting!"); + raiseError("The plugin class has already been located, aborting!"); return false; } + main = elements.iterator().next(); hasMainBeenFound = true; TypeElement mainType; if(main instanceof TypeElement){ mainType = (TypeElement) main; } else { - raiseError("Element annotated with @Main is not a type!"); + raiseError("Element annotated with @Main is not a type!", main); return false; } if(!(mainType.getEnclosingElement() instanceof PackageElement) && !mainType.getModifiers().contains(Modifier.STATIC)){ - raiseError("Element annotated with @Main is not top-level or static nested!"); + raiseError("Element annotated with @Main is not top-level or static nested!", mainType); return false; } if(!processingEnv.getTypeUtils().isSubtype(mainType.asType(), fromClass(JavaPlugin.class))){ - raiseError("Class annotated with @Main is not an subclass of JavaPlugin!"); + raiseError("Class annotated with @Main is not an subclass of JavaPlugin!", mainType); } - Map<String, Object> yml = new HashMap<String, Object>(); + 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); + yml.put("main", mainName); // always override this so we make sure the main class name is correct - processAndPut(yml, "name", mainType, mainName.substring(mainName.lastIndexOf('.') + 1), Name.class, String.class); + // populate plugin name + processAndPut(yml, "name", mainType, mainName.substring(mainName.lastIndexOf('.') + 1), Plugin.class, String.class, "name"); - processAndPut(yml, "version", mainType, Version.DEFAULT_VERSION, Version.class, String.class); + // populate version + processAndPut(yml, "version", mainType, Plugin.DEFAULT_VERSION, Plugin.class, String.class, "version"); - processAndPut(yml, "description", mainType, null, Description.class, String.class); + // populate plugin description + processAndPut(yml, "description", mainType, null, Description.class, String.class, "desc"); - processAndPut(yml, "load", mainType, null, LoadOn.class, String.class); + // populate plugin load order + processAndPut(yml, "load", mainType, null, LoadOn.class, String.class,"loadOn"); - { - String[] authors = process(mainType, new String[0], Author.class, String[].class); - switch(authors.length) { - case 0: break; - case 1: yml.put("author", authors[0]); break; - default: yml.put("authors", authors); break; - } + // authors + Author[] authors = mainType.getAnnotationsByType(Author.class); + List<String> authorMap = Lists.newArrayList(); + for(Author auth : authors) { + authorMap.add(auth.name()); + } + if(authorMap.size() > 1) { + yml.put("authors", authorMap); + } else if(authorMap.size() == 1) { + yml.put("author", authorMap.iterator().next()); } - processAndPut(yml, "website", mainType, null, Website.class, String.class); - - if(mainType.getAnnotation(UsesDatabase.class) != null) yml.put("database", true); - - processAndPut(yml, "depend", mainType, null, DependsOn.class, String[].class); - - processAndPut(yml, "softdepend", mainType, null, SoftDependsOn.class, String[].class); - - processAndPut(yml, "prefix", mainType, null, LogPrefix.class, String.class); + // website + processAndPut(yml, "website", mainType, null, Website.class, String.class, "url"); - processAndPut(yml, "loadbefore", mainType, null, LoadBefore.class, String[].class); + // prefix + processAndPut(yml, "prefix", mainType, null, LogPrefix.class, String.class, "prefix"); - Commands.Cmd[] commands = process(mainType, new Commands.Cmd[0], Commands.class, Commands.Cmd[].class); + // dependencies + Dependency[] dependencies = mainType.getAnnotationsByType(Dependency.class); + List<String> hardDependencies = Lists.newArrayList(); + for(Dependency dep : dependencies) { + hardDependencies.add(dep.plugin()); + } + if(!hardDependencies.isEmpty()) yml.putIfAbsent("depend", hardDependencies); - Map<String, Object> commandMap = new HashMap<String, Object>(); + // 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(); + } + if(softDepArr.length > 0) yml.putIfAbsent("softdepend", softDepArr); - for(Commands.Cmd cmd : commands) { - String name = cmd.value(); - Map<String, Object> desc = new HashMap<String, Object>(); - if(!cmd.desc().isEmpty()) desc.put("description", cmd.desc()); - if(cmd.aliases().length != 0) desc.put("aliases", cmd.aliases()); - if(!cmd.permission().isEmpty()) desc.put("permission", cmd.permission()); - if(!cmd.permissionMessage().isEmpty()) desc.put("permission-message", cmd.permissionMessage()); - if(!cmd.usage().isEmpty()) desc.put("usage", cmd.usage()); + // 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(); + } + if(loadBeforeArr.length > 0) yml.putIfAbsent("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); } - - if(!commandMap.isEmpty()) yml.put("commands", commandMap); - - Permissions.Perm[] perms = process(mainType, new Permissions.Perm[0], Permissions.class, Permissions.Perm[].class); - - Map<String, Object> permMap = new HashMap<String, Object>(); - - for(Permissions.Perm perm : perms) { - String name = perm.value(); - Map<String, Object> desc = new HashMap<String, Object>(); + 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 = new HashMap<String, Object>(); - for(String p : perm.children()) children.put(p, true); - for(String p : perm.antichildren()) children.put(p, false); + Map<String, Object> children = Maps.newLinkedHashMap(); + for(ChildPermission child : perm.children()) { + children.put(child.name(), child.inherit()); + } if(!children.isEmpty()) desc.put("children", children); permMap.put(name, desc); } + if(!permMap.isEmpty()) yml.putIfAbsent("permissions", permMap); - if(!permMap.isEmpty()) yml.put("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); + } Yaml yaml = new Yaml(); - try { FileObject file = this.processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "plugin.yml"); - Writer w = file.openWriter(); - try{ - w.append("# Auto-generated plugin.yml, generated at ").append(dFormat.format(new Date())).append(" by ").append(this.getClass().getName()).append("\n\n"); - yaml.dump(yml, w); - } finally { + 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); w.flush(); w.close(); } - + // try with resources will close the Writer since it implements Closeable } 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!"); - return true; } @@ -165,28 +222,38 @@ public class PluginAnnotationProcessor extends AbstractProcessor { this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message); } + private void raiseError(String message, Element element) { + this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element); + } + private TypeMirror fromClass(Class<?> clazz) { 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) { - R result = process(el, defaultVal, annotationType, returnType); + 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.put(name, result); + map.putIfAbsent(name, result); return result; } - private <A extends Annotation, R> R process(Element el, R defaultVal, Class<A> annotationType, Class<R> returnType) { + + 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; else { try { - Method value = annotationType.getMethod("value"); + 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 + throw new RuntimeException(e); // shouldn't happen in theory (blame Choco if it does) } } return result; diff --git a/src/main/java/org/bukkit/plugin/java/annotation/SoftDependsOn.java b/src/main/java/org/bukkit/plugin/java/annotation/SoftDependsOn.java deleted file mode 100644 index 81e8662..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/SoftDependsOn.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents the plugin's soft dependencies. - */ - -@Target(ElementType.TYPE) -public @interface SoftDependsOn { - - public String[] value(); - -} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/UsesDatabase.java b/src/main/java/org/bukkit/plugin/java/annotation/UsesDatabase.java deleted file mode 100644 index e73ebfc..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/UsesDatabase.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Denotes this plugin as using Bukkit's bundled database system. - */ - -@Target(ElementType.TYPE) -public @interface UsesDatabase {} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Website.java b/src/main/java/org/bukkit/plugin/java/annotation/Website.java deleted file mode 100644 index 385483f..0000000 --- a/src/main/java/org/bukkit/plugin/java/annotation/Website.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bukkit.plugin.java.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Part of the plugin annotations framework. - * <p> - * Represents the website of the plugin. - */ - -@Target(ElementType.TYPE) -public @interface Website { - - public String value(); - -}
\ No newline at end of file diff --git a/src/main/java/org/bukkit/plugin/java/annotation/command/Command.java b/src/main/java/org/bukkit/plugin/java/annotation/command/Command.java new file mode 100644 index 0000000..9d54dee --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/command/Command.java @@ -0,0 +1,48 @@ +package org.bukkit.plugin.java.annotation.command; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines a plugin command + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Repeatable(Commands.class) +public @interface Command { + + /** + * This command's name. + */ + String name(); + + /** + * This command's description. + */ + String desc() default ""; + + /** + * This command's aliases. + */ + String[] aliases() default {}; + + /** + * This command's permission node. + */ + String permission() default ""; + + /** + * This command's permission-check-fail message. + */ + String permissionMessage() default ""; + + /** + * This command's usage message. + */ + String usage() default ""; +} 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 new file mode 100644 index 0000000..c98a77b --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/command/Commands.java @@ -0,0 +1,20 @@ +package org.bukkit.plugin.java.annotation.command; + +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 a list of this plugin's registered command(s). + */ + +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Commands { + Command[] value() default {}; +} 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 new file mode 100644 index 0000000..42872f0 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/Dependency.java @@ -0,0 +1,19 @@ +package org.bukkit.plugin.java.annotation.dependency; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines a plugin dependency + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +@Repeatable(DependsOn.class) +public @interface Dependency { + String plugin(); +} 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 new file mode 100644 index 0000000..e94d612 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/DependsOn.java @@ -0,0 +1,20 @@ +package org.bukkit.plugin.java.annotation.dependency; + +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 plugins a plugin depends on in order to be loaded + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface DependsOn { + Dependency[] value() default {}; + +} 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 new file mode 100644 index 0000000..25388ea --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBefore.java @@ -0,0 +1,21 @@ +package org.bukkit.plugin.java.annotation.dependency; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Part of the plugin annotations framework. + * <p> + * Represents the plugin this plugin should be loaded before + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +@Repeatable(LoadBeforePlugins.class) +public @interface LoadBefore { + String plugin(); +} 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 new file mode 100644 index 0000000..400d1d7 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/LoadBeforePlugins.java @@ -0,0 +1,17 @@ +package org.bukkit.plugin.java.annotation.dependency; + +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; + +/** + * Defines a list of plugin to load before this plugin + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface LoadBeforePlugins { + LoadBefore[] value() default {}; +} 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 new file mode 100644 index 0000000..cc36edc --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependency.java @@ -0,0 +1,22 @@ +package org.bukkit.plugin.java.annotation.dependency; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Represents a soft (optional) dependency for this plugin. + * If this dependency is not present, the plugin will still load. + */ + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +@Repeatable(SoftDependsOn.class) +public @interface SoftDependency { + String plugin(); +} 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 new file mode 100644 index 0000000..6be9631 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/dependency/SoftDependsOn.java @@ -0,0 +1,23 @@ +package org.bukkit.plugin.java.annotation.dependency; + +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 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. + */ + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface SoftDependsOn { + + SoftDependency[] value() default {}; + +} 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 new file mode 100644 index 0000000..e22789e --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/ChildPermission.java @@ -0,0 +1,18 @@ +package org.bukkit.plugin.java.annotation.permission; + +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; + +/** + * Defines a child permission for {@link Permission} + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface ChildPermission { + boolean inherit() default true; + String name(); +} 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 new file mode 100644 index 0000000..35a72ab --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permission.java @@ -0,0 +1,40 @@ +package org.bukkit.plugin.java.annotation.permission; + +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.java.annotation.plugin.author.Authors; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines a plugin permission + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +@Repeatable(Permissions.class) +public @interface Permission { + /** + * This perm's name. + */ + String name(); + + /** + * This perm's description. + */ + String desc() default ""; + + /** + * This perm's default {@link PermissionDefault} + */ + PermissionDefault defaultValue() default PermissionDefault.OP; + + /** + * This permission's child nodes + */ + 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 new file mode 100644 index 0000000..9557769 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/permission/Permissions.java @@ -0,0 +1,20 @@ +package org.bukkit.plugin.java.annotation.permission; + +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 a list of this plugin's registered name. + */ + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Permissions { + Permission[] value() default {}; +} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Description.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java index 4595d06..4fd72ae 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/Description.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Description.java @@ -1,6 +1,9 @@ -package org.bukkit.plugin.java.annotation; +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; /** @@ -9,9 +12,10 @@ import java.lang.annotation.Target; * Represents a short description for the plugin. */ +@Documented +@Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Description { - - public String value(); + String desc(); } diff --git a/src/main/java/org/bukkit/plugin/java/annotation/LoadOn.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOn.java index 9e5372d..3a63325 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/LoadOn.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LoadOn.java @@ -1,8 +1,11 @@ -package org.bukkit.plugin.java.annotation; +package org.bukkit.plugin.java.annotation.plugin; import org.bukkit.plugin.PluginLoadOrder; +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; /** @@ -11,8 +14,9 @@ import java.lang.annotation.Target; * Represents the optional load order of the plugin. */ +@Documented +@Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface LoadOn { - - public PluginLoadOrder value(); + PluginLoadOrder loadOn(); } diff --git a/src/main/java/org/bukkit/plugin/java/annotation/LogPrefix.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java index e8d6ed4..52bd424 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/LogPrefix.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/LogPrefix.java @@ -1,6 +1,9 @@ -package org.bukkit.plugin.java.annotation; +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; /** @@ -9,8 +12,9 @@ import java.lang.annotation.Target; * Represents the prefix used for the plugin's log entries, defaults to plugin name. */ +@Documented +@Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface LogPrefix { - - public String value(); + String prefix(); } diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Main.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java index ebef467..3a21c6c 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/Main.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Main.java @@ -1,9 +1,13 @@ -package org.bukkit.plugin.java.annotation; +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. @@ -23,25 +27,25 @@ import java.lang.annotation.Target; * {@literal @}LogPrefix("Testing") * {@literal @}LoadBefore("Essentials") * {@literal @}Commands({ - * {@literal @}Cmd( - * value = "foo", - * desc = "Foo command", + * {@literal @}Command( + * name = "foo", + * name = "Foo command", * aliases = {"foobar", "fubar"}, * permission = "test.foo", * permissionMessage = "You do not have permission!", * usage = "/<command> [test|stop]" * ), - * {@literal @}Cmd("bar") + * {@literal @}Command("bar") * }) * {@literal @}Permissions({ * {@literal @}Perm( - * value = "test.foo", - * desc = "Allows foo command", + * name = "test.foo", + * name = "Allows foo command", * defaultValue = PermissionDefault.OP, * ), * {@literal @}Perm( - * value = "test.*", - * desc = "Wildcard perm", + * name = "test.*", + * name = "Wildcard perm", * defaultValue = PermissionDefault.OP, * children = {"test.foo"} * ) @@ -49,7 +53,10 @@ import java.lang.annotation.Target; * 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/Name.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java index 2ef196b..9a11752 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/Name.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Name.java @@ -1,6 +1,9 @@ -package org.bukkit.plugin.java.annotation; +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; /** @@ -9,10 +12,12 @@ import java.lang.annotation.Target; * 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 { - - public String value(); + String name(); } diff --git a/src/main/java/org/bukkit/plugin/java/annotation/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Plugin.java new file mode 100644 index 0000000..bd0a78f --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Plugin.java @@ -0,0 +1,24 @@ +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; + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Plugin { + /** + * The name of this plugin + */ + String name(); + + /** + * This version of this plugin + */ + String version(); + + String DEFAULT_VERSION = "v0.0"; +} 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 new file mode 100644 index 0000000..aedb9e4 --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/UsesDatabase.java @@ -0,0 +1,20 @@ +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/Version.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java index 2d7ab66..ba8c25e 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/Version.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Version.java @@ -1,6 +1,9 @@ -package org.bukkit.plugin.java.annotation; +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; /** @@ -9,12 +12,15 @@ import java.lang.annotation.Target; * 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(); - public String value(); - - public static final String DEFAULT_VERSION = "v0.0"; + 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 new file mode 100644 index 0000000..add83cf --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/Website.java @@ -0,0 +1,20 @@ +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 website of the plugin. + */ + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Website { + String url(); +} diff --git a/src/main/java/org/bukkit/plugin/java/annotation/Author.java b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java index d226d7d..ef63a56 100644 --- a/src/main/java/org/bukkit/plugin/java/annotation/Author.java +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Author.java @@ -1,6 +1,10 @@ -package org.bukkit.plugin.java.annotation; +package org.bukkit.plugin.java.annotation.plugin.author; +import java.lang.annotation.Documented; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** @@ -9,10 +13,10 @@ import java.lang.annotation.Target; * Represents the author(s) of the plugin. Translates to {@code author} * in plugin.yml if a single author, otherwise {@code authors} */ - +@Documented +@Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) +@Repeatable(Authors.class) public @interface Author { - - public String[] value(); - + String name(); } 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 new file mode 100644 index 0000000..7e2673c --- /dev/null +++ b/src/main/java/org/bukkit/plugin/java/annotation/plugin/author/Authors.java @@ -0,0 +1,14 @@ +package org.bukkit.plugin.java.annotation.plugin.author; + +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; + +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Authors { + Author[] value(); +} |