Add Warning API and settings for Deprecated events

By: Wesley Wolfe <weswolf@aol.com>
This commit is contained in:
Bukkit/Spigot 2012-08-07 00:16:57 -05:00
parent 32052e63e2
commit cef9873c0c
6 changed files with 126 additions and 6 deletions

View File

@ -8,6 +8,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import org.bukkit.Warning.WarningState;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
@ -373,4 +374,8 @@ public final class Bukkit {
public static String getMotd() {
return server.getMotd();
}
public static WarningState getWarningState() {
return server.getWarningState();
}
}

View File

@ -8,6 +8,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import org.bukkit.Warning.WarningState;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
@ -651,4 +652,11 @@ public interface Server extends PluginMessageRecipient {
* @returns the servers MOTD
*/
String getMotd();
/**
* Gets the current warning state for the server
*
* @return The configured WarningState
*/
public WarningState getWarningState();
}

View File

@ -0,0 +1,93 @@
package org.bukkit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
/**
* This designates the warning state for a specific item.
* When the server settings dictate 'default' warnings, warnings are printed if the {@link #value()} is true.
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Warning {
/**
* This represents the states that server verbose for warnings may be.
*/
public enum WarningState {
/**
* Indicates all warnings should be printed for deprecated items.
*/
ON,
/**
* Indicates no warnings should be printed for deprecated items.
*/
OFF,
/**
* Indicates each warning would default to the configured {@link Warning} annotation, or always if annotation not found.
*/
DEFAULT;
private static final Map<String, WarningState> values = ImmutableMap.<String,WarningState>builder()
.put("off", OFF)
.put("false", OFF)
.put("f", OFF)
.put("no", OFF)
.put("n", OFF)
.put("on", ON)
.put("true", ON)
.put("t", ON)
.put("yes", ON)
.put("y", ON)
.put("", DEFAULT)
.put("d", DEFAULT)
.put("default", DEFAULT)
.build();
/**
* This method checks the provided warning should be printed for this state
* @param warning The warning annotation added to a deprecated item
* @return ON is always True<br>
* OFF is always false<br>
* DEFAULT is false if and only if annotation is not null and specifies false for {@link Warning#value()}, true otherwise.
*/
public boolean printFor(Warning warning) {
if (this == DEFAULT) {
return warning == null || warning.value();
}
return this == ON;
}
/**
* This method returns the corresponding warning state for the given string value.
* @param value The string value to check
* @return {@link #DEFAULT} if not found, or the respective WarningState
*/
public static WarningState value(final String value) {
if (value == null) {
return DEFAULT;
}
WarningState state = values.get(value.toLowerCase());
if (state == null) {
return DEFAULT;
}
return state;
}
}
/**
* This sets if the deprecation warnings when registering events gets printed when the setting is in the default state.
* @return false normally, or true to encourage warning printout
*/
boolean value() default false;
/**
* This can provide detailed information on why the event is deprecated.
* @return The reason an event is deprecated
*/
String reason() default "";
}

View File

@ -10,7 +10,10 @@ import org.bukkit.event.HandlerList;
/**
* This event will sometimes fire synchronously, depending on how it was triggered.
* The constructor provides a boolean to indicate if the event was fired synchronously or asynchronously.
* If a plugin causes a Player to chat with {@link Player#chat(String)} or by other general means, this event will be synchronous.<br>
* When asynchronous, this event can be called from any thread, but the main thread, and has limited access to the API.<br>
* <br>
* If a player is the direct cause of this event by incoming packet, this event will be asynchronous.
* If a plugin triggers this event by compelling a player to chat, this event will be synchronous.<br>
* <br>
* <b>Care should be taken to check {@link #isAsynchronous()} and treat the event appropriately.</b>
*/

View File

@ -5,17 +5,20 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.Warning;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
/**
* Holds information for player chat and commands
* @deprecated This event was broken in 1.3, where chat should be asynchronous.
* It is deprecated because listening for it is detrimental to server performance.
* {@link AsyncPlayerChatEvent} is the encouraged alternative.
* @deprecated This event will fire from the main thread and allows the use of all of the Bukkit API, unlike the {@link AsyncPlayerChatEvent}.<br>
* <br>
* Listening to this event forces chat to wait for the main thread which causes delays for chat.<br>
* {@link AsyncPlayerChatEvent} is the encouraged alternative for thread safe implementations.
*/
@Deprecated
@Warning(reason="Listening to this event forces chat to wait for the main thread, delaying chat messages.")
public class PlayerChatEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;

View File

@ -23,6 +23,8 @@ import java.util.regex.Pattern;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.Warning;
import org.bukkit.Warning.WarningState;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.event.Event;
@ -299,16 +301,22 @@ public class JavaPluginLoader implements PluginLoader {
for (Class<?> clazz = eventClass; Event.class.isAssignableFrom(clazz); clazz = clazz.getSuperclass()) {
// This loop checks for extending deprecated events
if (clazz.getAnnotation(Deprecated.class) != null) {
Warning warning = clazz.getAnnotation(Warning.class);
WarningState warningState = server.getWarningState();
if (!warningState.printFor(warning)) {
break;
}
plugin.getLogger().log(
Level.WARNING,
String.format(
"\"%s\" has registered a listener for %s on method \"%s\", but the event is Deprecated." +
" Server performance will be affected; please notify the authors %s.",
" \"%s\"; please notify the authors %s.",
plugin.getDescription().getFullName(),
clazz.getName(),
method.toGenericString(),
(warning != null && warning.reason().length() != 0) ? warning.reason() : "Server performance will be affected",
Arrays.toString(plugin.getDescription().getAuthors().toArray())),
new AuthorNagException(null));
warningState == WarningState.ON ? new AuthorNagException(null) : null);
break;
}
}