Eniripsa96/EnchantmentAPI — pull request #6 by Di3mex (2013-06-15 16:54:35+00:00)
Title: Restructuring

What new?
------------------
- Added useful service classes, such as:
- Modules
- Command Handlers
- Modular Configuration (YAML) handlers
- Moved classes into appropriate packages.
- Updated CustomEnchantment with setters, uses Materials for storage

Packages
--------------
Before, all the source files were under a [single package](https://github.com/Eniripsa96/EnchantmentAPI/tree/master/src/main/com/rit/sucy). After adding utility classes it made sense to move all classes into separate packages.

Configuration
------------------
I added the [ModularConfig](https://github.com/Di3mex/EnchantmentAPI/blob/master/src/main/com/rit/sucy/service/ModularConfig.java) class to handle configuration files and [ConfigNode](https://github.com/Di3mex/EnchantmentAPI/blob/master/src/main/com/rit/sucy/service/ConfigNode.java) to represent all possible configuration node paths, what type of variable to expect from the path, and the default value it should be set to.

Also, should the configuration's internal structure change, it means minimal / reduced changes to references in the code.

The best example of using it would be in the [RootConfig](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/config/RootConfig.java) class, which handles the default config.yml file. Associated with this class are the nodes from the [RootNode](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/config/RootNode.java) enumeration. For each entry, you can easily see the path in the config, the type, and the default value that it will set to if the entry is missing.

The defaults and current configuration are loaded by simply [iterating over the enumeration](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/config/RootConfig.java#L59-L73).

Using the config is easy. Simply get the variable you want by giving it the enumeration value you want:

````java
//Retrieving an instance of the config.
RootConfig config = plugin.getModuleForClass(RootConfig.class);
//Using the config
boolean enabled = config.getBoolean(RootNode.VANILLA_ENABLE);
````

All configuration code has been moved out of CustomEnchantment and moved into [RootConfig](https://github.com/Di3mex/EnchantmentAPI/blob/master/src/main/com/rit/sucy/config/RootConfig.java#L95-L208)
First the Enchantments will be loaded and afterwards values from the config will be loaded and will overwrite the values in memory. Therefore setters had to be added to CustomEnchantment. This setup also allows us to easily add customization to enchantments or let the user decide how much customisability he wishes to have. I demonstrated this by adding configuration options to hide some configuration options and let the admin decide what he needs. This has the advantage that the config doesn't become too long if the admin only wants to disable some custom enchantments. To increase readability I separated custom/vanilla enchantments and sort the enchantments by name before writing them to the config.

Added [MaterialsParser](https://github.com/Di3mex/EnchantmentAPI/blob/master/src/main/com/rit/sucy/service/MaterialsParser.java)
This class is able to parse strings/itemids from stringlists. It is robust and can deal well with misformated input as you can see in the [JUnit Tests](https://github.com/Di3mex/EnchantmentAPI/blob/master/src/test/com/rit/sucy/service/MaterialsParserTest.java)

The following text has been copied from a Pull Request from Mitsugaru I have gotten for EHM a few months ago. Mitsugaru explains how to use his utility classes. I adapted them to work with EnchantmentAPI, but I think he explains it better than me.

Modules
------------
Modules are basically a way to separate the logic and storage methods that need to be accessed by other parts of the plugin.

For example, some of the methods in the old EntityEventHandler were used in other parts of the code. Specifically, ```markLootLess(LivingEntity entity)``` is used in both the [EntityEventHandler](https://github.com/Di3mex/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/EntityEventHandler.java#L191) and was statically called in the [RespawnZombieTask](https://github.com/Di3mex/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/RespawnZombieTask.java#L46). By moving reusable code into Module classes, anything that has a reference to the original plugin instance can access a module class and use its methods. This removes messy static methods.

Getting an existing module instance is really easy:
```java
EntityModule module = plugin.getModuleForClass(EntityModule.class);
```
No casting necessary, its automatically done for you via Generics. Whatever Module class you ask for, you receive the registered instance of it, if it has been registered. If it hasn't been, then the returned module would be null... however, you're guaranteed the current existing modules in the code will be registered since they're the first thing to happen on the plugin enable.

Now, you might be thinking that Modules are overkill. I mean, this could easily be accomplished by just having the plugin have a reference to the instance:
```java
public class ExtraHardMode extends JavaPlugin {
private final EntityModule entityModule= new EntityModule ();

public EntityModule getEntityModule() {
return entityModule;
}
}
```
Except, modules allows us to easily expand available classes without having to require that method. Instead of having a method per module, we have a single unified method that lets you get the module instance you ask for. It makes the main plugin class look really clean in comparison.

Plus, it also allows for people to extend ExtraHardMode by having secondary plugins register their own modules. AKA, maybe a plugin called EHMExtensions?

Registering a module is easy:
```java
registerModule(MessageConfig.class, new MessageConfig(this));
```
On register, the starting() method of the module is called. Examples that make use of that method are the configuration handlers (which are also modules now) [RootConfig](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/config/RootConfig.java) and [MessageConfig](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/config/messages/MessageConfig.java), where they load their defaults, if any are missing, and load the actual data of the config to memory. As well as [BlockModule](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/module/BlockModule.java#L145) where it gets the block materials that have physics enabled.

Creating a Module class is as simple as either extending [EHMModule](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/EHMModule.java) or implementing the [IModule](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/IModule.java) interface. The abstract class EHMModule is there only to insure that the module always has a reference to the original plugin instance.

Commands & Command Handlers
-------------------------------------------------
I've also added two more files, [CommandHandler](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/CommandHandler.java) and [ICommand](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/ICommand.java). These have been immensely helpful in creating modular command trees.

Essentially, think of a CommandHandler as a menu with various options and ICommand classes are those terminating commands.

CommandHandlers implement [CommandExecutor](http://jd.bukkit.org/rb/apidocs/org/bukkit/command/CommandExecutor.html), so you can [attach them to commands](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/ExtraHardMode.java#L87) _or_ [chain them to existing](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/CommandHandler.java#L83) CommandHandlers to make menus within menus (Menu-ception).

Classes that implement the ICommand interface, such as the [ReloadCommand](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/command/ReloadCommand.java), are the terminating commands.

For instance, I added a few basic commands under the [root command](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/command/Commander.java#L15-L20) ```/ehm```.

Permissions
------------------
Enter [PermissionNode](https://github.com/Mitsugaru/ExtraHardMode/blob/master/src/me/ryanhamshire/ExtraHardMode/service/PermissionNode.java) enumeration. A central place to store and reference registered permission nodes. This way, there is no question to what permission nodes exist. Also, should a permission node path change, the code does not have to change.

Other minor cleanup
-----------------------------
### Public static reference to plugin instance
```java
/**
* Singleton instance of the API
*/
private static EnchantmentAPI instance;
```
It may appear to be convienent, but it is **FAR** from it.
If there is one programming habit of some Bukkit developers that should be broken, its **THIS**.
This should **never** be done. **Ever**. Please... just no.

If a part of your plugin needs a reference to the main plugin instance... it isn't so much extra to pass that reference to its constructor and have the object hold onto it.

Credits:
-----------
- Mitsugaru, for his easily adaptable utility classes