Update plugin-annotations to 1.12 and Java 8.

This commit is contained in:
Senmori 2018-02-27 21:42:48 -05:00
parent be009c1cc6
commit b0b94aee56
31 changed files with 566 additions and 302 deletions

18
pom.xml
View file

@ -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>
</project>

View file

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

View file

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

View file

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

View file

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

View file

@ -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;
if(hasMainBeenFound){
raiseError("More than one class with @Main found, aborting!");
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("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);
// website
processAndPut(yml, "website", mainType, null, Website.class, String.class, "url");
if(mainType.getAnnotation(UsesDatabase.class) != null) yml.put("database", true);
// prefix
processAndPut(yml, "prefix", mainType, null, LogPrefix.class, String.class, "prefix");
processAndPut(yml, "depend", mainType, null, DependsOn.class, String[].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);
processAndPut(yml, "softdepend", mainType, null, SoftDependsOn.class, String[].class);
// 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);
processAndPut(yml, "prefix", mainType, null, LogPrefix.class, String.class);
// 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);
processAndPut(yml, "loadbefore", mainType, null, LoadBefore.class, String[].class);
Commands.Cmd[] commands = process(mainType, new Commands.Cmd[0], Commands.class, Commands.Cmd[].class);
Map<String, Object> commandMap = new HashMap<String, Object>();
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());
// 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.putIfAbsent("commands", commandMap);
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>();
// 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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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