├── LICENSE ├── README.md ├── pom.xml └── src └── main └── java └── xyz └── mkotb └── configapi ├── Coloured.java ├── ConfigFactory.java ├── RequiredField.java ├── comment ├── Comment.java ├── CommentHelper.java ├── Comments.java ├── HeaderComment.java ├── HeaderComments.java └── Self.java ├── ex ├── ClassStructureException.java ├── InternalProcessingException.java └── InvalidConfigurationException.java └── internal ├── InternalsHelper.java ├── SerializableMemorySection.java ├── adapt ├── AdapterHandler.java ├── ObjectAdapter.java └── impl │ ├── ArrayAdapter.java │ ├── CollectionAdapter.java │ ├── DateAdapter.java │ ├── MapAdapter.java │ ├── SQLDateAdapter.java │ ├── UUIDAdapter.java │ ├── atomic │ ├── AtomicBooleanAdapter.java │ ├── AtomicIntegerAdapter.java │ ├── AtomicIntegerArrayAdapter.java │ ├── AtomicLongAdapter.java │ └── AtomicLongArrayAdapter.java │ └── bukkit │ ├── ConfigurationSectionAdapter.java │ ├── ConfigurationSerializableHelper.java │ ├── EnchantmentAdapter.java │ └── OfflinePlayerAdapter.java ├── dummy └── CentralDummyHolder.java └── naming ├── CamelCaseNamingStrategy.java ├── DummyNamingStrategy.java ├── NamingStrategies.java ├── NamingStrategy.java └── UnderscoreNamingStrategy.java /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ConfigAPI 2 | This project is a GSON-like project for Bukkit's YML Config API. This project is on maven central! You can add it to your project using the following: 3 | 4 | ```xml 5 | 6 | xyz.mkotb 7 | config-api 8 | 1.0.1 9 | 10 | ``` 11 | 12 | If you're not familiar with GSON, let me show you a quick example of what you can do with this API: 13 | 14 | ```java 15 | public class MyPlugin extends JavaPlugin { 16 | private MyConfig myConfig; 17 | private ConfigFactory configFactory = ConfigFactory.newFactory(this); 18 | 19 | @Override 20 | public void onEnable() { 21 | myConfig = configFactory.fromFile("config", MyConfig.class); 22 | getLogger().info(myConfig.getStartMessage()); 23 | 24 | if (myConfig.myFavouriteNumbers != null) { 25 | getLogger().info(myConfig.myFavouriteNumbers.toString()); 26 | } 27 | } 28 | 29 | @Override 30 | public void onDisable() { 31 | // if we changed values in my config while the server is up 32 | // we should save it 33 | configFactory.save("config", myConfig); 34 | } 35 | } 36 | 37 | @Comment("This is my header comment") 38 | public class MyConfig { 39 | // init values will be saved as part of the "default config" 40 | private String startMessage = "This awesome bukkit plugin has started!"; 41 | @Comment("Put in your favourite number here!") 42 | @RequiredField // if this field is not set in the config file due to user error 43 | // an exception will be thrown 44 | private int myFavouriteNumber = 3; 45 | // lists, sets, queues, maps, and arrays are supported! 46 | List myFavouriteNumbers; 47 | // supports concurrency classes! 48 | private AtomicInteger myFavouriteAtomicNumber = new AtomicInteger(4); 49 | // myWeapon will be set if it's in the config but won't exist 50 | // by default 51 | private ItemStack myWeapon; 52 | // additionally objects within the config are allowed 53 | private PartOfConfig part; 54 | 55 | public String getStartMessage() { 56 | return startMessage; 57 | } 58 | } 59 | 60 | public class PartOfConfig { 61 | private String hi = "my name is billy"; 62 | } 63 | ``` 64 | 65 | In the following example, we displayed majority of the features available in the API. The `fromFile()` method takes care of all the initial processes you may need, such as creating the new file and placing default values. Many additional classes such as color, offline players, and vectors are supported to be saved. In the future, extensibility to the Adapter API will be added to where you can use your own data types which can be converted. 66 | 67 | ## Interaction with the File 68 | 69 | As of currently, if you were to setup and run this plugin, it would write the following to `config.yml` using the default values: 70 | 71 | ```yml 72 | # This is my header comment 73 | start-message: This awesome bukkit plugin has started! 74 | # Put in your favourite number here! 75 | my-favourite-number: 3 76 | my-favourite-atomic-number: 4 77 | ``` 78 | 79 | As you can see, it only saved the fields which were already set as defaults. If you haven't noticed already, the API changed the naming conventions from Java lower camel case (`likeThis`) to the conventional YAML namespace (`like-this`). You can modify which naming convention the API uses. There will be more information you can refer to on this on [the wiki]( Wiki). 80 | 81 | If we were to add a list of our favourite numbers to the config manually, we will be able to see the API being able to load them up without a problem: 82 | 83 | ```yml 84 | my-favourite-numbers: 85 | - 2 86 | - 6 87 | - 8 88 | ``` 89 | 90 | And if we start up our server with the new config, we'll see the following printed in console: 91 | 92 | ``` 93 | [01:09:42 INFO]: [ConfigTestPlugin] Enabling ConfigTestPlugin v1.0 94 | [01:09:42 INFO]: [ConfigTestPlugin] This super cool awesome bukkit plugin has started! 95 | [01:09:42 INFO]: [ConfigTestPlugin] [2, 6, 8] 96 | ``` 97 | 98 | Well, that was easy. 99 | 100 | ConfigAPI is still in early development and will soon be for release for developers to use in their projects. Contributions are more than welcome! 101 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | xyz.mkotb 8 | config-api 9 | 1.0.1 10 | 11 | ConfigAPI 12 | GSON-like ORM for the Bukkit Config API 13 | http://github.com/mkotb/ConfigAPI 14 | 15 | 16 | UTF-8 17 | 18 | 19 | 20 | scm:git:git@github.com:mkotb/ConfigAPI.git 21 | scm:git:git@github.com:mkotb/ConfigAPI.git 22 | git@github.com:mkotb/ConfigAPI.git 23 | 24 | 25 | 26 | 27 | ISC License 28 | http://choosealicense.com/licenses/isc/ 29 | 30 | 31 | 32 | 33 | 34 | spigot-repo 35 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 36 | 37 | 38 | 39 | 40 | 41 | ossrh 42 | https://oss.sonatype.org/content/repositories/snapshots 43 | 44 | 45 | ossrh 46 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 47 | 48 | 49 | 50 | 51 | 52 | mkotb 53 | Mazen Kotb 54 | mazenkotb@gmail.com 55 | PST 56 | https://github.com/mkotb 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.spigotmc 64 | spigot-api 65 | 1.10.2-R0.1-SNAPSHOT 66 | provided 67 | 68 | 69 | 70 | 71 | org.bukkit 72 | bukkit 73 | 1.10.2-R0.1-SNAPSHOT 74 | provided 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | org.apache.maven.plugins 83 | maven-shade-plugin 84 | 2.4.3 85 | 86 | 87 | package 88 | 89 | shade 90 | 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-compiler-plugin 97 | 3.3 98 | 99 | 1.8 100 | 1.8 101 | true 102 | true 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-jar-plugin 112 | 2.4 113 | 114 | 115 | 116 | com.mycila.maven-license-plugin 117 | maven-license-plugin 118 | 119 | 120 | 121 | true 122 | UTF-8 123 | true 124 |
./LICENSE
125 | 126 | SLASHSTAR_STYLE 127 | 128 | 129 | license 130 | 131 | 132 | src/main/java/** 133 | src/test/java/** 134 | 135 |
136 | clean 137 | 138 | format 139 | 140 |
141 |
142 |
143 |
144 |
145 | 146 | 147 | 148 | ossrh 149 | 150 | 151 | 152 | maven-gpg-plugin 153 | 1.6 154 | 155 | 156 | sign-artifacts 157 | verify 158 | 159 | sign 160 | 161 | 162 | 163 | 164 | true 165 | 166 | 167 | 168 | org.apache.maven.plugins 169 | maven-source-plugin 170 | 2.4 171 | 172 | 173 | attach-sources 174 | 175 | jar-no-fork 176 | 177 | 178 | 179 | 180 | 181 | org.apache.maven.plugins 182 | maven-javadoc-plugin 183 | 2.10.3 184 | 185 | 186 | attach-javadocs 187 | 188 | jar 189 | 190 | 191 | 192 | 193 | 194 | org.sonatype.plugins 195 | nexus-staging-maven-plugin 196 | 1.6.6 197 | true 198 | 199 | ossrh 200 | https://oss.sonatype.org/ 201 | true 202 | 203 | 204 | 205 | 206 | 207 | 208 |
-------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/Coloured.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.FIELD) 25 | public @interface Coloured { 26 | char value() default '&'; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/ConfigFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi; 17 | 18 | import org.bukkit.ChatColor; 19 | import org.bukkit.configuration.MemorySection; 20 | import org.bukkit.configuration.file.FileConfiguration; 21 | import org.bukkit.configuration.file.YamlConfiguration; 22 | import org.bukkit.plugin.java.JavaPlugin; 23 | import xyz.mkotb.configapi.comment.CommentHelper; 24 | import xyz.mkotb.configapi.ex.ClassStructureException; 25 | import xyz.mkotb.configapi.ex.InternalProcessingException; 26 | import xyz.mkotb.configapi.internal.InternalsHelper; 27 | import xyz.mkotb.configapi.internal.SerializableMemorySection; 28 | import xyz.mkotb.configapi.internal.adapt.AdapterHandler; 29 | import xyz.mkotb.configapi.internal.dummy.CentralDummyHolder; 30 | import xyz.mkotb.configapi.internal.naming.CamelCaseNamingStrategy; 31 | import xyz.mkotb.configapi.internal.naming.NamingStrategy; 32 | 33 | import java.io.File; 34 | import java.io.IOException; 35 | import java.io.PrintWriter; 36 | import java.lang.reflect.Field; 37 | import java.util.Map; 38 | 39 | public final class ConfigFactory { 40 | private volatile NamingStrategy namingStrategy = new CamelCaseNamingStrategy(); 41 | private final JavaPlugin plugin; 42 | 43 | private ConfigFactory(JavaPlugin plugin) { 44 | this.plugin = plugin; 45 | File directory = plugin.getDataFolder(); 46 | 47 | if (directory.exists()) { 48 | directory.mkdirs(); 49 | } 50 | } 51 | 52 | public static ConfigFactory newFactory(JavaPlugin plugin) { 53 | return new ConfigFactory(plugin); 54 | } 55 | 56 | public T fromFile(String name, Class classOf) { 57 | return fromFile(new File(configDirectory(), name + ".yml"), classOf); 58 | } 59 | 60 | public T fromFile(File config, Class classOf) { 61 | if (!config.exists()) { 62 | CentralDummyHolder dummyHolder = CentralDummyHolder.instance(); 63 | T dummy; 64 | 65 | if ((dummy = dummyHolder.dummyFrom(classOf)) == null) { 66 | dummy = InternalsHelper.newInstance(classOf); 67 | 68 | if (dummy == null) { 69 | throw new ClassStructureException("An accessible no-args constructor could not " + 70 | "be found in " + classOf.getName()); 71 | } 72 | } 73 | 74 | colourizeFields(dummy); 75 | save(config, dummy); 76 | dummyHolder.insertDummy(classOf, dummy); 77 | return dummy; 78 | } 79 | 80 | AdapterHandler handler = AdapterHandler.create(namingStrategy); 81 | FileConfiguration data = YamlConfiguration.loadConfiguration(config); 82 | return colourizeFields(handler.adaptIn(data, null, classOf)); 83 | } 84 | 85 | public void save(String name, T object) { 86 | save(new File(configDirectory(), name + ".yml"), object); 87 | } 88 | 89 | public void save(File config, T object) { 90 | if (!config.exists()) { 91 | try { 92 | config.getParentFile().mkdirs(); 93 | config.createNewFile(); 94 | } catch (IOException ex) { 95 | throw new InternalProcessingException("Could not create file!", ex); 96 | } 97 | } 98 | 99 | StringBuilder sb = new StringBuilder(); 100 | Map comments = CommentHelper.extractComments(object, namingStrategy); 101 | String[] header = CommentHelper.extractHeader(object.getClass()); 102 | AdapterHandler handler = AdapterHandler.create(namingStrategy); 103 | MemorySection section = handler.adaptOut(object, MemorySection.class); 104 | 105 | if (header != null) { 106 | CommentHelper.encodeComments(header, sb); 107 | } 108 | 109 | ((SerializableMemorySection) section).map().forEach((k, v) -> { 110 | FileConfiguration fieldData = new YamlConfiguration(); 111 | 112 | if (comments.containsKey(k)) { 113 | CommentHelper.encodeComments(comments.get(k), sb); 114 | } 115 | 116 | fieldData.set(k, v); 117 | sb.append(fieldData.saveToString()); 118 | }); 119 | 120 | try (PrintWriter out = new PrintWriter(config)){ 121 | out.print(sb.toString()); 122 | } catch (IOException ex) { 123 | throw new InternalProcessingException("Unable to save config to file!", ex); 124 | } 125 | } 126 | 127 | private T colourizeFields(T object) { 128 | for (Field field : object.getClass().getDeclaredFields()) { 129 | if (!field.isAnnotationPresent(Coloured.class)) { 130 | continue; 131 | } 132 | 133 | if (field.getType() != String.class) { 134 | continue; 135 | } 136 | 137 | Coloured annotation = field.getDeclaredAnnotation(Coloured.class); 138 | String value = InternalsHelper.getField(field, object); 139 | 140 | if (value != null) { 141 | InternalsHelper.setField(field, object, AdapterHandler.translateAlternateColorCodes( 142 | ChatColor.COLOR_CHAR, annotation.value(), value)); 143 | } 144 | } 145 | 146 | return object; 147 | } 148 | 149 | private File configDirectory() { 150 | return plugin.getDataFolder(); 151 | } 152 | 153 | public NamingStrategy namingStrategy() { 154 | return namingStrategy; 155 | } 156 | 157 | public void setPreferredStrategy(NamingStrategy preferredStrategy) { 158 | this.namingStrategy = preferredStrategy; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/RequiredField.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(value = RetentionPolicy.RUNTIME) 24 | @Target(value = ElementType.FIELD) 25 | public @interface RequiredField { 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/Comment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target({ElementType.FIELD, ElementType.TYPE}) 25 | public @interface Comment { 26 | String[] value(); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/CommentHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import xyz.mkotb.configapi.internal.naming.NamingStrategy; 19 | 20 | import java.lang.annotation.Annotation; 21 | import java.lang.reflect.Field; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | public final class CommentHelper { 26 | private CommentHelper() { 27 | } 28 | 29 | public static void encodeComments(String[] comments, StringBuilder builder) { 30 | for (String comment : comments) { 31 | builder.append("# ").append(comment).append(System.lineSeparator()); 32 | } 33 | } 34 | 35 | public static Map extractComments(Object object, NamingStrategy namingStrat) { 36 | Map comments = new HashMap<>(); 37 | 38 | for(Field field : object.getClass().getDeclaredFields()) { 39 | for (Annotation annotation : field.getDeclaredAnnotations()) { 40 | String[] value = valueFrom(annotation); 41 | 42 | if (value != null) { 43 | comments.put(namingStrat.rename(field.getName()), value); 44 | break; 45 | } 46 | } 47 | } 48 | 49 | return comments; 50 | } 51 | 52 | public static String[] extractHeader(Class cls) { 53 | for (Annotation annotation : cls.getAnnotations()) { 54 | String[] value = valueFrom(annotation); 55 | 56 | if (value != null) { 57 | return value; 58 | } 59 | } 60 | 61 | return null; 62 | } 63 | 64 | public static String[] valueFrom(Annotation annotation) { 65 | if (annotation instanceof Comment) { 66 | return ((Comment) annotation).value(); 67 | } 68 | 69 | if (annotation instanceof HeaderComment) { 70 | return new String[] {((HeaderComment) annotation).value()}; 71 | } 72 | 73 | if (annotation instanceof Comments) { 74 | return ((Comments) annotation).value(); 75 | } 76 | 77 | if (annotation instanceof HeaderComments) { 78 | return ((HeaderComments) annotation).value(); 79 | } 80 | 81 | return null; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/Comments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.FIELD) 25 | @Deprecated 26 | public @interface Comments { 27 | String[] value(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/HeaderComment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.TYPE) 25 | @Deprecated 26 | public @interface HeaderComment { 27 | String value(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/HeaderComments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.TYPE) 25 | @Deprecated 26 | public @interface HeaderComments { 27 | String[] value(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/comment/Self.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.comment; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.FIELD) 25 | public @interface Self { 26 | String value() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/ex/ClassStructureException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.ex; 17 | 18 | public class ClassStructureException extends RuntimeException { 19 | public ClassStructureException() { 20 | } 21 | 22 | public ClassStructureException(String message) { 23 | super(message); 24 | } 25 | 26 | public ClassStructureException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | 30 | public ClassStructureException(Throwable cause) { 31 | super(cause); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/ex/InternalProcessingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.ex; 17 | 18 | public class InternalProcessingException extends RuntimeException { 19 | public InternalProcessingException() { 20 | } 21 | 22 | public InternalProcessingException(String message) { 23 | super(message); 24 | } 25 | 26 | public InternalProcessingException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/ex/InvalidConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.ex; 17 | 18 | public class InvalidConfigurationException extends RuntimeException { 19 | public InvalidConfigurationException() { 20 | } 21 | 22 | public InvalidConfigurationException(String message) { 23 | super(message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/InternalsHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal; 17 | 18 | import sun.reflect.ReflectionFactory; 19 | import xyz.mkotb.configapi.internal.naming.NamingStrategies; 20 | import xyz.mkotb.configapi.internal.naming.NamingStrategy; 21 | 22 | import java.lang.reflect.Constructor; 23 | import java.lang.reflect.Field; 24 | import java.lang.reflect.ParameterizedType; 25 | import java.lang.reflect.Type; 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | import java.util.concurrent.ConcurrentHashMap; 29 | 30 | public final class InternalsHelper { 31 | private static final Map FIELD_CACHE = new ConcurrentHashMap<>(); 32 | 33 | private InternalsHelper() { 34 | } 35 | 36 | public static Class typeOf(Field field, int index) { 37 | Type genericType = field.getGenericType(); 38 | 39 | if (genericType instanceof ParameterizedType) { 40 | return (Class) ((ParameterizedType) genericType).getActualTypeArguments()[index]; 41 | } 42 | 43 | return Object.class; 44 | } 45 | 46 | /* 47 | * Creates an instance of the class without calling it's constructor. 48 | * clazz must implement java.io.Serializable 49 | */ 50 | public static T newInstanceWithoutInit(Class clazz) { 51 | try { 52 | ReflectionFactory rf = 53 | ReflectionFactory.getReflectionFactory(); 54 | Constructor objDef = Object.class.getDeclaredConstructor(); 55 | Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef); 56 | 57 | return clazz.cast(intConstr.newInstance()); 58 | } catch (RuntimeException e) { 59 | throw e; 60 | } catch (Exception e) { 61 | throw new IllegalStateException("Cannot create object", e); 62 | } 63 | } 64 | 65 | public static T newInstance(Class classOf) { 66 | try { 67 | return classOf.newInstance(); 68 | } catch (InstantiationException | IllegalAccessException ex) { 69 | return null; 70 | } 71 | } 72 | 73 | public static Map mapFieldsOf(T obj) { 74 | return mapFieldsOf(obj, NamingStrategies.from("dummy")); 75 | } 76 | 77 | public static Map mapFieldsOf(T obj, NamingStrategy strategy) { 78 | Map fieldMap = new HashMap<>(); 79 | Field[] fields = obj.getClass().getFields(); 80 | 81 | for (Field field : fields) { 82 | fieldMap.put(strategy.rename(field.getName()), getField(field, obj)); 83 | } 84 | 85 | return fieldMap; 86 | } 87 | 88 | public static Field staticFieldFor(Class clazz, String name) { 89 | try { 90 | String id = fieldIdentifier(clazz, name); 91 | 92 | if (FIELD_CACHE.containsKey(id)) { 93 | return FIELD_CACHE.get(id); 94 | } 95 | 96 | Field field = clazz.getDeclaredField(name); 97 | 98 | FIELD_CACHE.put(id, field); 99 | return field; 100 | } catch (NoSuchFieldException ex) { 101 | return null; 102 | } 103 | } 104 | 105 | public static Field fieldFor(Object object, String name) { 106 | try { 107 | String id = fieldIdentifier(object.getClass(), name); 108 | 109 | if (FIELD_CACHE.containsKey(id)) { 110 | return FIELD_CACHE.get(id); 111 | } 112 | Field field = object.getClass().getDeclaredField(name); 113 | 114 | FIELD_CACHE.put(id, field); 115 | return field; 116 | } catch (NoSuchFieldException ignored) { 117 | return null; 118 | } 119 | } 120 | 121 | public static T getField(Field field, Object instance) { 122 | try { 123 | field.setAccessible(true); 124 | return (T) field.get(instance); 125 | } catch (IllegalAccessException ex) { 126 | return null; 127 | } 128 | } 129 | 130 | public static boolean setField(String fieldName, Object instance, Object value) { 131 | Field field = fieldFor(instance, fieldName); 132 | return field != null && setField(field, instance, value); 133 | } 134 | 135 | public static boolean setField(Field field, Object instance, Object value) { 136 | try { 137 | field.setAccessible(true); 138 | field.set(instance, value); 139 | return true; 140 | } catch (IllegalAccessException ex) { 141 | return false; 142 | } 143 | } 144 | 145 | private static String fieldIdentifier(Class cls, String fieldName) { 146 | return cls.getName() + "||" + fieldName; 147 | } 148 | 149 | private static String fieldIdentifier(Field field) { 150 | return field.getDeclaringClass().getName() + "||" + field.getName(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/SerializableMemorySection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal; 17 | 18 | import org.bukkit.configuration.MemorySection; 19 | 20 | import java.io.Serializable; 21 | import java.util.LinkedHashMap; 22 | import java.util.Map; 23 | import java.util.Set; 24 | 25 | public class SerializableMemorySection extends MemorySection implements Serializable { 26 | private Map map; 27 | 28 | @Override 29 | public Object get(String path, Object def) { 30 | Object value = map().get(path); 31 | return value == null ? def : value; 32 | } 33 | 34 | @Override 35 | public void set(String path, Object value) { 36 | map().put(path, value); 37 | } 38 | 39 | @Override 40 | public Set getKeys(boolean deep) { 41 | return map().keySet(); 42 | } 43 | 44 | @Override 45 | public Map getValues(boolean deep) { 46 | return map(); 47 | } 48 | 49 | @Override 50 | protected Object getDefault(String path) { 51 | return null; 52 | } 53 | 54 | public Map map() { 55 | if (map == null) { 56 | map = new LinkedHashMap<>(); 57 | } 58 | 59 | return map; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/AdapterHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt; 17 | 18 | import org.bukkit.ChatColor; 19 | import org.bukkit.OfflinePlayer; 20 | import org.bukkit.enchantment.Enchantment; 21 | import org.bukkit.configuration.ConfigurationSection; 22 | import org.bukkit.configuration.MemorySection; 23 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 24 | import xyz.mkotb.configapi.Coloured; 25 | import xyz.mkotb.configapi.RequiredField; 26 | import xyz.mkotb.configapi.comment.Self; 27 | import xyz.mkotb.configapi.ex.ClassStructureException; 28 | import xyz.mkotb.configapi.ex.InvalidConfigurationException; 29 | import xyz.mkotb.configapi.internal.InternalsHelper; 30 | import xyz.mkotb.configapi.internal.SerializableMemorySection; 31 | import xyz.mkotb.configapi.internal.adapt.impl.*; 32 | import xyz.mkotb.configapi.internal.adapt.impl.atomic.*; 33 | import xyz.mkotb.configapi.internal.adapt.impl.bukkit.*; 34 | import xyz.mkotb.configapi.internal.naming.NamingStrategy; 35 | 36 | import java.lang.reflect.Field; 37 | import java.lang.reflect.Modifier; 38 | import java.util.*; 39 | import java.util.concurrent.ConcurrentHashMap; 40 | import java.util.concurrent.atomic.*; 41 | 42 | public final class AdapterHandler { 43 | private static final Map, Class> PRIMITIVE_BOXES = new ConcurrentHashMap<>(); 44 | private static final Set> FILTER_CLASSES = new HashSet<>(); 45 | private static final Map, ObjectAdapter> ADAPTERS = new ConcurrentHashMap<>(); 46 | 47 | static { 48 | PRIMITIVE_BOXES.put(boolean.class, Boolean.class); 49 | PRIMITIVE_BOXES.put(char.class, Character.class); 50 | PRIMITIVE_BOXES.put(byte.class, Byte.class); 51 | PRIMITIVE_BOXES.put(short.class, Short.class); 52 | PRIMITIVE_BOXES.put(int.class, Integer.class); 53 | PRIMITIVE_BOXES.put(long.class, Long.class); 54 | PRIMITIVE_BOXES.put(float.class, Float.class); 55 | PRIMITIVE_BOXES.put(double.class, Double.class); 56 | PRIMITIVE_BOXES.put(void.class, Void.class); 57 | 58 | ADAPTERS.put(Date.class, new DateAdapter()); 59 | ADAPTERS.put(java.sql.Date.class, new SQLDateAdapter()); 60 | ADAPTERS.put(UUID.class, new UUIDAdapter()); 61 | 62 | ADAPTERS.put(ConfigurationSection.class, new ConfigurationSectionAdapter()); 63 | ADAPTERS.put(Enchantment.class, new EnchantmentAdapter()); 64 | ADAPTERS.put(OfflinePlayer.class, new OfflinePlayerAdapter()); 65 | 66 | ADAPTERS.put(AtomicBoolean.class, new AtomicBooleanAdapter()); 67 | ADAPTERS.put(AtomicInteger.class, new AtomicIntegerAdapter()); 68 | ADAPTERS.put(AtomicIntegerArray.class, new AtomicIntegerArrayAdapter()); 69 | ADAPTERS.put(AtomicLong.class, new AtomicLongAdapter()); 70 | ADAPTERS.put(AtomicLongArray.class, new AtomicLongArrayAdapter()); 71 | 72 | FILTER_CLASSES.addAll(ADAPTERS.keySet()); 73 | FILTER_CLASSES.addAll(PRIMITIVE_BOXES.values()); 74 | FILTER_CLASSES.add(String.class); 75 | FILTER_CLASSES.add(Map.class); 76 | FILTER_CLASSES.add(Collection.class); 77 | } 78 | 79 | private final NamingStrategy namingStrategy; 80 | 81 | private AdapterHandler(NamingStrategy strategy) { 82 | this.namingStrategy = strategy; 83 | } 84 | 85 | public static AdapterHandler create(NamingStrategy strategy) { 86 | return new AdapterHandler(strategy); 87 | } 88 | 89 | public static void registerAdapter(Class clazz, ObjectAdapter adapter) { 90 | ADAPTERS.replace(clazz, adapter); 91 | } 92 | 93 | public static boolean isSerializable(Class clazz) { 94 | return (ConfigurationSerializable.class.isAssignableFrom(clazz) && 95 | ConfigurationSerializableHelper.isRegistered(clazz)) || 96 | ((FILTER_CLASSES.stream().anyMatch((e) -> e.isAssignableFrom(clazz) || clazz.equals(e)))); 97 | } 98 | 99 | public static Class outClass(Class clazz) { 100 | if (!isSerializable(clazz)) { 101 | return MemorySection.class; 102 | } 103 | 104 | return clazz; 105 | } 106 | 107 | public O adaptOut(I input, Class outClass) { 108 | return adaptOut(input, outClass, null); 109 | } 110 | 111 | public O adaptOut(I input, Class outClass, Class type) { 112 | if (Collection.class.isAssignableFrom(input.getClass())) { 113 | CollectionAdapter adapter = CollectionAdapter.create(type, 114 | (Class) outClass, this); 115 | return outClass.cast(adapter.write((Collection) input)); 116 | } 117 | 118 | if (Map.class.isAssignableFrom(input.getClass())) { 119 | MapAdapter adapter = MapAdapter.create(type, 120 | this); 121 | return outClass.cast(adapter.write((Map) input)); 122 | } 123 | 124 | if (input.getClass().isArray()) { 125 | Class cls = input.getClass(); 126 | ArrayAdapter adapter = ArrayAdapter.create(cls.getComponentType(), this); 127 | return outClass.cast(adapter.write(input)); 128 | } 129 | 130 | if (PRIMITIVE_BOXES.values().contains(outClass) || input.getClass().isPrimitive()) { 131 | return outClass.cast(input); 132 | } 133 | 134 | if (outClass == String.class) { 135 | return outClass.cast(input); 136 | } 137 | 138 | ObjectAdapter oldAdapter = ADAPTERS.get(input.getClass()); 139 | 140 | if (oldAdapter == null) { 141 | if (ConfigurationSerializableHelper.isRegistered(input.getClass()) && // ensure registration for deserialization purposes 142 | input instanceof ConfigurationSerializable) { 143 | MemorySection memorySection = InternalsHelper.newInstanceWithoutInit(SerializableMemorySection.class); 144 | ((ConfigurationSerializable) input).serialize().forEach(memorySection::set); 145 | return outClass.cast(memorySection); 146 | } 147 | 148 | MemorySection section = InternalsHelper.newInstanceWithoutInit(SerializableMemorySection.class); 149 | InternalsHelper.setField("map", section, new LinkedHashMap()); 150 | Field[] fields = input.getClass().getDeclaredFields(); 151 | Field selfField = null; 152 | 153 | for (Field field : fields) { 154 | if (Modifier.isTransient(field.getModifiers())) { 155 | continue; 156 | } 157 | 158 | Object value = InternalsHelper.getField(field, input); 159 | 160 | if (value != null) { 161 | Class fieldType = null; 162 | Class fieldClass = field.getType(); 163 | Class beforeFieldClass = fieldClass; 164 | 165 | if (field.getDeclaredAnnotation(Self.class) != null) { 166 | if (!ConfigurationSection.class.isAssignableFrom(beforeFieldClass)) { 167 | throw new ClassStructureException("Field " + field.getName() + " with @Self annotation is not a " + 168 | "configuration section, is " + beforeFieldClass.getName()); 169 | } 170 | 171 | selfField = field; 172 | continue; 173 | } 174 | 175 | if (!FILTER_CLASSES.stream().anyMatch((e) -> e.isAssignableFrom(beforeFieldClass)) 176 | && !fieldClass.isArray()) { 177 | fieldClass = MemorySection.class; 178 | } 179 | 180 | if (beforeFieldClass.isPrimitive()) { 181 | fieldClass = PRIMITIVE_BOXES.get(beforeFieldClass); 182 | } 183 | 184 | if (Map.class.isAssignableFrom(fieldClass)) { 185 | fieldType = InternalsHelper.typeOf(field, 1); 186 | fieldClass = ConfigurationSection.class; 187 | } else if (Collection.class.isAssignableFrom(fieldClass)) { 188 | fieldType = InternalsHelper.typeOf(field, 0); 189 | fieldClass = Object.class; 190 | } else if (fieldClass.isArray()) { 191 | fieldClass = Object.class; 192 | } 193 | 194 | Object obj = adaptOut(value, fieldClass, fieldType); 195 | 196 | if (obj instanceof String && field.isAnnotationPresent(Coloured.class)) { 197 | Coloured annotation = field.getDeclaredAnnotation(Coloured.class); 198 | obj = translateAlternateColorCodes(annotation.value(), ChatColor.COLOR_CHAR, (String) obj); 199 | } 200 | 201 | section.set(namingStrategy.rename(field.getName()), obj); 202 | } 203 | } 204 | 205 | if (selfField != null) { 206 | ConfigurationSection selfSec = InternalsHelper.getField(selfField, input); 207 | 208 | if (selfSec != null) { 209 | selfSec.getValues(false).forEach((key, value) -> { 210 | if (!section.contains(key)) { 211 | section.set(key, value); 212 | } 213 | }); 214 | } 215 | } 216 | 217 | return outClass.cast(section); 218 | } 219 | 220 | ObjectAdapter adapter; 221 | 222 | try { 223 | adapter = (ObjectAdapter) oldAdapter; 224 | } catch (ClassCastException ex) { 225 | throw new ClassStructureException(outClass.getName() + " does not match registered adapter" + 226 | " for " + input.getClass().getName() + "!"); 227 | } 228 | 229 | return adapter.write(input); 230 | } 231 | 232 | public I adaptIn(ConfigurationSection section, String key, Class inClass) { 233 | return adaptIn(section, key, inClass, null); 234 | } 235 | 236 | public I adaptIn(ConfigurationSection section, String key, Class inClass, Class type) { 237 | if (inClass.isArray()) { 238 | ArrayAdapter adapter = ArrayAdapter.create(inClass.getComponentType(), this); 239 | return inClass.cast(adapter.read(key, section)); 240 | } 241 | 242 | if (Collection.class.isAssignableFrom(inClass)) { 243 | CollectionAdapter adapter = CollectionAdapter.create(type, 244 | (Class) inClass, this); 245 | return inClass.cast(adapter.read(key, section)); 246 | } 247 | 248 | if (Map.class.isAssignableFrom(inClass)) { 249 | MapAdapter adapter = MapAdapter.create(type, 250 | this); 251 | return inClass.cast(adapter.read(key, section)); 252 | } 253 | 254 | if (inClass.isPrimitive() || inClass == String.class || PRIMITIVE_BOXES.values().contains(inClass)) { 255 | return inClass.cast(section.get(key)); 256 | } 257 | 258 | ObjectAdapter oldAdapter = ADAPTERS.get(inClass); 259 | 260 | if (oldAdapter == null) { 261 | if (ConfigurationSerializableHelper.isRegistered(inClass) && 262 | ConfigurationSerializable.class.isAssignableFrom(inClass)) { 263 | return ConfigurationSerializableHelper.deserialize(ConfigurationSerializableHelper.toMap(section.getConfigurationSection(key)), 264 | inClass); 265 | } 266 | 267 | ConfigurationSection readingSection = (key == null) ? section : section.getConfigurationSection(key); 268 | I instance = InternalsHelper.newInstance(inClass); 269 | Field[] fields = inClass.getDeclaredFields(); 270 | Field selfField = null; 271 | 272 | for (Field field : fields) { 273 | if (Modifier.isTransient(field.getModifiers())) { 274 | continue; 275 | } 276 | 277 | String name = namingStrategy.rename(field.getName()); 278 | 279 | if (field.getDeclaredAnnotation(Self.class) != null) { 280 | if (!ConfigurationSection.class.isAssignableFrom(field.getType())) { 281 | throw new ClassStructureException("Field " + field.getName() + " with @Self annotation is not a " + 282 | "configuration section, is " + field.getType().getName()); 283 | } 284 | 285 | selfField = field; 286 | continue; 287 | } 288 | 289 | if (!readingSection.contains(name)) { 290 | if (field.getAnnotation(RequiredField.class) != null) { 291 | String message = "Could not find the required field, " + name; 292 | 293 | if (key != null) { 294 | message += ", in section " + key; 295 | } 296 | 297 | throw new InvalidConfigurationException(message); 298 | } 299 | 300 | continue; 301 | } 302 | 303 | Class fieldType = null; 304 | Class fieldClass = field.getType(); 305 | 306 | if (fieldClass.isPrimitive()) { 307 | fieldClass = PRIMITIVE_BOXES.get(fieldClass); 308 | } 309 | 310 | if (Map.class.isAssignableFrom(fieldClass)) { 311 | fieldType = InternalsHelper.typeOf(field, 1); 312 | } else if (Collection.class.isAssignableFrom(fieldClass)) { 313 | fieldType = InternalsHelper.typeOf(field, 0); 314 | } 315 | 316 | InternalsHelper.setField(field, instance, adaptIn(readingSection, name, fieldClass, fieldType)); 317 | } 318 | 319 | if (selfField != null) { 320 | InternalsHelper.setField(selfField, instance, readingSection); 321 | } 322 | 323 | return instance; 324 | } 325 | 326 | ObjectAdapter adapter; 327 | 328 | try { 329 | adapter = (ObjectAdapter) oldAdapter; 330 | } catch (ClassCastException ex) { 331 | throw new ClassStructureException(ex); 332 | } 333 | 334 | return adapter.read(key, section); 335 | } 336 | 337 | public static String translateAlternateColorCodes(char colorChar, char altColorChar, String textToTranslate) { 338 | char[] b = textToTranslate.toCharArray(); 339 | for (int i = 0; i < b.length - 1; i++) { 340 | if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) { 341 | b[i] = colorChar; 342 | b[i+1] = Character.toLowerCase(b[i+1]); 343 | } 344 | } 345 | return new String(b); 346 | } 347 | } 348 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/ObjectAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | 20 | public interface ObjectAdapter { 21 | I read(String key, ConfigurationSection section); 22 | O write(I obj); 23 | } -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/ArrayAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import org.bukkit.configuration.MemoryConfiguration; 20 | import org.bukkit.configuration.MemorySection; 21 | import xyz.mkotb.configapi.internal.InternalsHelper; 22 | import xyz.mkotb.configapi.internal.SerializableMemorySection; 23 | import xyz.mkotb.configapi.internal.adapt.AdapterHandler; 24 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 25 | 26 | import java.lang.reflect.Array; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class ArrayAdapter implements ObjectAdapter { 31 | private final Class type; 32 | private final AdapterHandler handler; 33 | 34 | private ArrayAdapter(Class type, AdapterHandler handler) { 35 | this.type = type; 36 | this.handler = handler; 37 | } 38 | 39 | public static ArrayAdapter create(Class type, AdapterHandler handler) { 40 | return new ArrayAdapter(type, handler); 41 | } 42 | 43 | @Override 44 | public Object read(String key, ConfigurationSection section) { 45 | List list; 46 | 47 | if (section.isConfigurationSection(key)) { 48 | list = new ArrayList<>(section.getConfigurationSection(key).getValues(false).values()); 49 | } else { 50 | list = section.getList(key); 51 | } 52 | 53 | Object array = Array.newInstance(type, list.size()); 54 | 55 | for (int i = 0; i < list.size(); i++) { 56 | Object obj = list.get(i); 57 | ConfigurationSection dummySection = new MemoryConfiguration(); 58 | 59 | dummySection.set("dummy", obj); 60 | Array.set(array, i, handler.adaptIn(dummySection, "dummy", obj.getClass())); 61 | } 62 | 63 | return array; 64 | } 65 | 66 | @Override 67 | public Object write(Object obj) { 68 | int length = Array.getLength(obj); 69 | 70 | if (!AdapterHandler.isSerializable(type) && !type.isPrimitive()) { 71 | MemorySection section = InternalsHelper.newInstanceWithoutInit(SerializableMemorySection.class); 72 | 73 | for (int i = 0; i < length; i++) { 74 | section.set(String.valueOf(i + 1), handler.adaptOut(Array.get(obj, i), AdapterHandler.outClass(type))); 75 | } 76 | 77 | return section; 78 | } 79 | 80 | List list = new ArrayList<>(length); 81 | 82 | for (int i = 0; i < length; i++) { 83 | Object object = Array.get(obj, i); 84 | 85 | if (type.isPrimitive() || type == String.class) { 86 | list.add(object); 87 | continue; 88 | } 89 | 90 | list.add(handler.adaptOut(object, AdapterHandler.outClass(type))); 91 | } 92 | 93 | return list; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/CollectionAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import org.bukkit.configuration.MemoryConfiguration; 20 | import org.bukkit.configuration.MemorySection; 21 | import xyz.mkotb.configapi.ex.InternalProcessingException; 22 | import xyz.mkotb.configapi.internal.InternalsHelper; 23 | import xyz.mkotb.configapi.internal.SerializableMemorySection; 24 | import xyz.mkotb.configapi.internal.adapt.AdapterHandler; 25 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 26 | 27 | import java.lang.reflect.InvocationTargetException; 28 | import java.util.*; 29 | import java.util.concurrent.ConcurrentHashMap; 30 | 31 | public class CollectionAdapter implements ObjectAdapter { 32 | private final Class type; 33 | private final Class implementationClass; 34 | private final AdapterHandler handler; 35 | 36 | private CollectionAdapter(Class type, Class collectionClass, AdapterHandler handler) { 37 | this.type = type; 38 | this.implementationClass = findImplementation(collectionClass); 39 | this.handler = handler; 40 | } 41 | 42 | public static CollectionAdapter create(Class type, Class collectionClass, AdapterHandler handler) { 43 | return new CollectionAdapter<>(type, collectionClass, handler); 44 | } 45 | 46 | private static Class findImplementation(Class cls) { 47 | if (List.class.isAssignableFrom(cls)) { 48 | return ArrayList.class; 49 | } else if (Set.class.isAssignableFrom(cls)) { 50 | return HashSet.class; 51 | } else if (Queue.class.isAssignableFrom(cls)) { 52 | return PriorityQueue.class; 53 | } 54 | 55 | return cls; 56 | } 57 | 58 | @Override 59 | public Collection read(String key, ConfigurationSection section) { 60 | Collection collection; 61 | List originalList; 62 | 63 | if (section.isConfigurationSection(key)) { 64 | originalList = new ArrayList<>(section.getConfigurationSection(key).getValues(false).values()); 65 | } else { 66 | originalList = section.getList(key); 67 | } 68 | 69 | try { 70 | collection = implementationClass.getDeclaredConstructor(int.class).newInstance(originalList.size()); 71 | } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { 72 | throw new InternalProcessingException("Could not create new instance of " + implementationClass.getName(), e); 73 | } 74 | 75 | for (Object obj: originalList) { 76 | ConfigurationSection dummySection = new MemoryConfiguration(); 77 | 78 | dummySection.set("dummy", obj); 79 | collection.add(handler.adaptIn(dummySection, "dummy", type)); 80 | } 81 | 82 | return collection; 83 | } 84 | 85 | @Override // can't use streams due to abstraction 86 | public Object write(Collection collection) { 87 | if (!AdapterHandler.isSerializable(type) && !type.isPrimitive()) { 88 | MemorySection section = InternalsHelper.newInstanceWithoutInit(SerializableMemorySection.class); 89 | int i = 0; 90 | 91 | for (Object o : collection) { 92 | section.set(String.valueOf(++i), handler.adaptOut(o, AdapterHandler.outClass(type))); 93 | } 94 | 95 | return section; 96 | } 97 | 98 | List list = new ArrayList<>(collection.size()); 99 | 100 | for (Object o : collection) { 101 | list.add(handler.adaptOut(o, AdapterHandler.outClass(type))); 102 | } 103 | 104 | return list; 105 | } 106 | } -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/DateAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.text.DateFormat; 22 | import java.text.ParseException; 23 | import java.util.Date; 24 | import java.util.Locale; 25 | 26 | public class DateAdapter implements ObjectAdapter { 27 | private final DateFormat enUsFormat 28 | = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US); 29 | 30 | @Override 31 | public synchronized Date read(String key, ConfigurationSection section) { 32 | try { 33 | return enUsFormat.parse(section.getString(key)); 34 | } catch (ParseException ignored) { 35 | return new Date(); 36 | } 37 | } 38 | 39 | @Override 40 | public synchronized String write(Date obj) { 41 | return enUsFormat.format(obj); 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/MapAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import org.bukkit.configuration.MemoryConfiguration; 20 | import org.bukkit.configuration.MemorySection; 21 | import xyz.mkotb.configapi.internal.InternalsHelper; 22 | import xyz.mkotb.configapi.internal.SerializableMemorySection; 23 | import xyz.mkotb.configapi.internal.adapt.AdapterHandler; 24 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 25 | 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | 29 | public class MapAdapter implements ObjectAdapter { 30 | private final Class valueClass; 31 | private final AdapterHandler handler; 32 | 33 | private MapAdapter(Class valueClass, AdapterHandler handler) { 34 | this.valueClass = valueClass; 35 | this.handler = handler; 36 | } 37 | 38 | public static MapAdapter create(Class valueClass, AdapterHandler handler) { 39 | return new MapAdapter<>(valueClass, handler); 40 | } 41 | 42 | @Override 43 | public Map read(String key, ConfigurationSection section) { 44 | ConfigurationSection originalMap = section.getConfigurationSection(key); 45 | Map map = new HashMap(); 46 | 47 | originalMap.getValues(false).forEach((k, v) -> { 48 | ConfigurationSection dummySection = new MemoryConfiguration(); 49 | 50 | dummySection.set("dummy", v); 51 | map.put(k, handler.adaptIn(dummySection, "dummy", valueClass)); 52 | }); 53 | 54 | return map; 55 | } 56 | 57 | @Override 58 | public ConfigurationSection write(Map obj) { 59 | MemorySection memorySection = InternalsHelper.newInstanceWithoutInit(SerializableMemorySection.class); 60 | obj.forEach((k, v) -> memorySection.set(k.toString(), handler.adaptOut(v, AdapterHandler.outClass(valueClass)))); 61 | return memorySection; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/SQLDateAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.sql.Date; 22 | import java.text.DateFormat; 23 | import java.text.ParseException; 24 | import java.text.SimpleDateFormat; 25 | 26 | public class SQLDateAdapter implements ObjectAdapter { 27 | private final DateFormat format = new SimpleDateFormat("MMM d, yyyy"); 28 | 29 | @Override 30 | public Date read(String key, ConfigurationSection section) { 31 | try { 32 | return new Date(format.parse(section.getString(key)).getTime()); 33 | } catch (ParseException ex) { 34 | return new Date(System.currentTimeMillis()); 35 | } 36 | } 37 | 38 | @Override 39 | public synchronized String write(Date obj) { 40 | return format.format(obj); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/UUIDAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.UUID; 22 | 23 | public class UUIDAdapter implements ObjectAdapter { 24 | @Override 25 | public UUID read(String key, ConfigurationSection section) { 26 | return UUID.fromString(section.getString(key)); 27 | } 28 | 29 | @Override 30 | public String write(UUID obj) { 31 | return obj.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/atomic/AtomicBooleanAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.atomic; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.concurrent.atomic.AtomicBoolean; 22 | 23 | // TODO AtomicReference 24 | public class AtomicBooleanAdapter implements ObjectAdapter { 25 | @Override 26 | public AtomicBoolean read(String key, ConfigurationSection section) { 27 | return new AtomicBoolean(section.getBoolean(key)); 28 | } 29 | 30 | @Override 31 | public Boolean write(AtomicBoolean obj) { 32 | return obj.get(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/atomic/AtomicIntegerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.atomic; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | 23 | public class AtomicIntegerAdapter implements ObjectAdapter { 24 | @Override 25 | public AtomicInteger read(String key, ConfigurationSection section) { 26 | return new AtomicInteger(section.getInt(key)); 27 | } 28 | 29 | @Override 30 | public Integer write(AtomicInteger obj) { 31 | return obj.get(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/atomic/AtomicIntegerArrayAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.atomic; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.concurrent.atomic.AtomicIntegerArray; 24 | 25 | public class AtomicIntegerArrayAdapter implements ObjectAdapter> { 26 | @Override 27 | public AtomicIntegerArray read(String key, ConfigurationSection section) { 28 | return new AtomicIntegerArray(section.getIntegerList(key).stream().mapToInt((e) -> e).toArray()); 29 | } 30 | 31 | @Override 32 | public List write(AtomicIntegerArray obj) { 33 | List list = new ArrayList<>(); 34 | 35 | for (int i = 0; i < obj.length(); i++) { 36 | list.add(obj.get(i)); 37 | } 38 | 39 | return list; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/atomic/AtomicLongAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.atomic; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.concurrent.atomic.AtomicLong; 22 | 23 | public class AtomicLongAdapter implements ObjectAdapter { 24 | @Override 25 | public AtomicLong read(String key, ConfigurationSection section) { 26 | return new AtomicLong(section.getLong(key)); 27 | } 28 | 29 | @Override 30 | public Long write(AtomicLong obj) { 31 | return obj.get(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/atomic/AtomicLongArrayAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.atomic; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.concurrent.atomic.AtomicLongArray; 24 | 25 | public class AtomicLongArrayAdapter implements ObjectAdapter> { 26 | @Override 27 | public AtomicLongArray read(String key, ConfigurationSection section) { 28 | return new AtomicLongArray(section.getLongList(key).stream().mapToLong((e) -> e).toArray()); 29 | } 30 | 31 | @Override 32 | public List write(AtomicLongArray obj) { 33 | List list = new ArrayList<>(); 34 | 35 | for (int i = 0; i < obj.length(); i++) { 36 | list.add(obj.get(i)); 37 | } 38 | 39 | return list; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/bukkit/ConfigurationSectionAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.bukkit; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 20 | 21 | public class ConfigurationSectionAdapter implements ObjectAdapter { 22 | @Override 23 | public ConfigurationSection read(String key, ConfigurationSection section) { 24 | return section.getConfigurationSection(key); 25 | } 26 | 27 | @Override 28 | public ConfigurationSection write(ConfigurationSection obj) { 29 | return obj; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/bukkit/ConfigurationSerializableHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.bukkit; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import org.bukkit.configuration.serialization.ConfigurationSerializable; 20 | import org.bukkit.configuration.serialization.ConfigurationSerialization; 21 | import xyz.mkotb.configapi.internal.InternalsHelper; 22 | 23 | import java.util.Collection; 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | 27 | public class ConfigurationSerializableHelper { 28 | private ConfigurationSerializableHelper() { 29 | } 30 | 31 | public static Collection> registeredClasses() { 32 | Map> aliases = InternalsHelper.getField( 33 | InternalsHelper.staticFieldFor(ConfigurationSerialization.class, "aliases"), null 34 | ); 35 | return aliases.values(); 36 | } 37 | 38 | public static boolean isRegistered(Class cls) { 39 | return registeredClasses().contains(cls); 40 | } 41 | 42 | public static T deserialize(Map map, Class cls) { 43 | return cls.cast(ConfigurationSerialization.deserializeObject(map, cls.asSubclass(ConfigurationSerializable.class))); 44 | } 45 | 46 | public static Map toMap(ConfigurationSection section) { 47 | Map map = new HashMap<>(); 48 | 49 | section.getKeys(false).forEach(key -> map.put(key, section.get(key))); 50 | 51 | return map; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/bukkit/EnchantmentAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.bukkit; 17 | 18 | import org.bukkit.configuration.ConfigurationSection; 19 | import org.bukkit.enchantments.Enchantment; 20 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 21 | 22 | public class EnchantmentAdapter implements ObjectAdapter { 23 | @Override 24 | public Enchantment read(String key, ConfigurationSection section) { 25 | return Enchantment.getByName(section.getString(key)); 26 | } 27 | 28 | @Override 29 | public String write(Enchantment obj) { 30 | return obj.getName(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/adapt/impl/bukkit/OfflinePlayerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.adapt.impl.bukkit; 17 | 18 | import org.bukkit.OfflinePlayer; 19 | import org.bukkit.configuration.ConfigurationSection; 20 | import xyz.mkotb.configapi.internal.adapt.ObjectAdapter; 21 | 22 | public class OfflinePlayerAdapter implements ObjectAdapter { 23 | @Override 24 | public OfflinePlayer read(String key, ConfigurationSection section) { 25 | return section.getOfflinePlayer(key); 26 | } 27 | 28 | @Override 29 | public OfflinePlayer write(OfflinePlayer obj) { 30 | return obj; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/dummy/CentralDummyHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.dummy; 17 | 18 | import java.util.Map; 19 | import java.util.concurrent.ConcurrentHashMap; 20 | 21 | public final class CentralDummyHolder { 22 | private static final CentralDummyHolder INSTANCE = new CentralDummyHolder(); 23 | private final Map, Object> dummySet = new ConcurrentHashMap<>(); 24 | 25 | private CentralDummyHolder() { 26 | } 27 | 28 | public static CentralDummyHolder instance() { 29 | return INSTANCE; 30 | } 31 | 32 | public T dummyFrom(Class classOf) { 33 | return (T) dummySet.get(classOf); 34 | } 35 | 36 | public void insertDummy(Class classOf, T dummy) { 37 | dummySet.put(classOf, dummy); 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/naming/CamelCaseNamingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.naming; 17 | 18 | import java.util.regex.Pattern; 19 | import java.util.stream.Collectors; 20 | import java.util.stream.Stream; 21 | 22 | public class CamelCaseNamingStrategy implements NamingStrategy { 23 | private static final Pattern CAMEL_PATTERN = Pattern.compile("(?<=[^_\\r\\n])(?:(?>_+)|(?=[A-Z])(?:(?(?=\\d))(? strategies = new ConcurrentHashMap<>(); 23 | 24 | private NamingStrategies() { 25 | insert("underscore", new UnderscoreNamingStrategy()); 26 | insert("camelcase", new CamelCaseNamingStrategy()); 27 | insert("dummy", new DummyNamingStrategy()); 28 | insert("null", from("dummy")); 29 | } 30 | 31 | public static NamingStrategy from(String name) { 32 | return strategies.get(name.toLowerCase()); 33 | } 34 | 35 | public static void insert(String name, NamingStrategy strategy) { 36 | strategies.replace(name.toLowerCase(), strategy); // guaranteed atomicy 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/naming/NamingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.naming; 17 | 18 | public interface NamingStrategy { 19 | String rename(String input); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/xyz/mkotb/configapi/internal/naming/UnderscoreNamingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, Mazen Kotb, mazenkotb@gmail.com 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | package xyz.mkotb.configapi.internal.naming; 17 | 18 | public class UnderscoreNamingStrategy implements NamingStrategy { 19 | @Override 20 | public String rename(String input) { 21 | return input.replaceAll("_", "-").toLowerCase(); 22 | } 23 | } --------------------------------------------------------------------------------