Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.plugin;
2
3import org.bukkit.Bukkit;
4import org.bukkit.permissions.Permission;
5import org.yaml.snakeyaml.Yaml;
6import org.yaml.snakeyaml.constructor.SafeConstructor;
7
8import java.io.InputStream;
9import java.io.Reader;
10import java.io.Writer;
11import java.util.ArrayList;
12import java.util.HashMap;
13import java.util.Map;
14import java.util.Set;
15import java.util.logging.Level;
16
17/**
18 * Provides access to a Plugins description file, plugin.yaml
19 */
20public final class PluginDescriptionFile {
21 private static final Yaml yaml = new Yaml(new SafeConstructor());
22 private String name = null;
23 private String main = null;
24 private String classLoaderOf = null;
25 private ArrayList<String> depend = null;
26 private ArrayList<String> softDepend = null;
27 private ArrayList<String> dependencies = null;
28 private String version = null;
29 private Object commands = null;
30 private String description = null;
31 private ArrayList<String> authors = new ArrayList<String>();
32 private String website = null;
33 private boolean database = false;
34 private boolean visible = true;
35 private PluginLoadOrder order = PluginLoadOrder.POSTWORLD;
36 private ArrayList<Permission> permissions = new ArrayList<Permission>();
37
38 @SuppressWarnings("unchecked")
39 public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
40 loadMap((Map<String, Object>) yaml.load(stream));
41 }
42
43 /**
44 * Loads a PluginDescriptionFile from the specified reader
45 *
46 * @param reader
47 */
48 @SuppressWarnings("unchecked")
49 public PluginDescriptionFile(final Reader reader) throws InvalidDescriptionException {
50 loadMap((Map<String, Object>) yaml.load(reader));
51 }
52
53 /**
54 * Creates a new PluginDescriptionFile with the given detailed
55 *
56 * @param pluginName Name of this plugin
57 * @param mainClass Full location of the main class of this plugin
58 */
59 public PluginDescriptionFile(final String pluginName, final String pluginVersion, final String mainClass) {
60 name = pluginName;
61 version = pluginVersion;
62 main = mainClass;
63 }
64
65 /**
66 * Saves this PluginDescriptionFile to the given writer
67 *
68 * @param writer Writer to output this file to
69 */
70 public void save(Writer writer) {
71 yaml.dump(saveMap(), writer);
72 }
73
74 /**
75 * Returns the name of a plugin
76 *
77 * @return String name
78 */
79 public String getName() {
80 return name;
81 }
82
83 /**
84 * Returns the version of a plugin
85 *
86 * @return String name
87 */
88 public String getVersion() {
89 return version;
90 }
91
92 /**
93 * Returns the name of a plugin including the version
94 *
95 * @return String name
96 */
97 public String getFullName() {
98 return name + " v" + version;
99 }
100
101 /**
102 * Returns the main class for a plugin
103 *
104 * @return Java classpath
105 */
106 public String getMain() {
107 return main;
108 }
109
110 public Object getCommands() {
111 return commands;
112 }
113
114 public Object getDepend() {
115 return depend;
116 }
117
118 public ArrayList<String> getDependencies() {
119 return dependencies;
120 }
121
122 public Object getSoftDepend() {
123 return softDepend;
124 }
125
126 public PluginLoadOrder getLoad() {
127 return order;
128 }
129
130 /**
131 * Gets the description of this plugin
132 * <p>
133 * return Description of this plugin
134 */
135 public String getDescription() {
136 return description;
137 }
138
139 public ArrayList<String> getAuthors() {
140 return authors;
141 }
142
143 public String getWebsite() {
144 return website;
145 }
146
147 public boolean isDatabaseEnabled() {
148 return database;
149 }
150
151 public boolean isVisible() {
152 return visible;
153 }
154
155 public void setDatabaseEnabled(boolean database) {
156 this.database = database;
157 }
158
159 public ArrayList<Permission> getPermissions() {
160 return permissions;
161 }
162
163 public String getClassLoaderOf() {
164 return classLoaderOf;
165 }
166
167 private void loadMap(Map<String, Object> map) throws InvalidDescriptionException {
168 try {
169 name = map.get("name").toString();
170
171 if (!name.matches("^[A-Za-z0-9 _.-]+$")) {
172 throw new InvalidDescriptionException("name '" + name + "' contains invalid characters.");
173 }
174 } catch (NullPointerException ex) {
175 throw new InvalidDescriptionException(ex, "name is not defined");
176 } catch (ClassCastException ex) {
177 throw new InvalidDescriptionException(ex, "name is of wrong type");
178 }
179
180 try {
181 version = map.get("version").toString();
182 } catch (NullPointerException ex) {
183 throw new InvalidDescriptionException(ex, "version is not defined");
184 } catch (ClassCastException ex) {
185 throw new InvalidDescriptionException(ex, "version is of wrong type");
186 }
187
188 try {
189 main = map.get("main").toString();
190 if (main.startsWith("org.bukkit.")) {
191 throw new InvalidDescriptionException("main may not be within the org.bukkit namespace");
192 }
193 } catch (NullPointerException ex) {
194 throw new InvalidDescriptionException(ex, "main is not defined");
195 } catch (ClassCastException ex) {
196 throw new InvalidDescriptionException(ex, "main is of wrong type");
197 }
198
199 if (map.containsKey("commands")) {
200 try {
201 commands = map.get("commands");
202 } catch (ClassCastException ex) {
203 throw new InvalidDescriptionException(ex, "commands are of wrong type");
204 }
205 }
206
207 if (map.containsKey("class-loader-of")) {
208 classLoaderOf = map.get("class-loader-of").toString();
209 }
210
211 if (map.containsKey("depend")) {
212 try {
213 depend = (ArrayList<String>) map.get("depend");
214 } catch (ClassCastException ex) {
215 throw new InvalidDescriptionException(ex, "depend is of wrong type");
216 }
217 }
218
219 if (map.containsKey("dependencies")) {
220 try {
221 dependencies = (ArrayList<String>) map.get("dependencies");
222 } catch (ClassCastException ex) {
223 throw new InvalidDescriptionException(ex, "dependencies is of wrong type");
224 }
225 }
226
227 if (map.containsKey("softdepend")) {
228 try {
229 softDepend = (ArrayList<String>) map.get("softdepend");
230 } catch (ClassCastException ex) {
231 throw new InvalidDescriptionException(ex, "softdepend is of wrong type");
232 }
233 }
234
235 if (map.containsKey("database")) {
236 try {
237 database = (Boolean) map.get("database");
238 } catch (ClassCastException ex) {
239 throw new InvalidDescriptionException(ex, "database is of wrong type");
240 }
241 }
242
243 if (map.containsKey("website")) {
244 try {
245 website = (String) map.get("website");
246 } catch (ClassCastException ex) {
247 throw new InvalidDescriptionException(ex, "website is of wrong type");
248 }
249 }
250
251 if (map.containsKey("description")) {
252 try {
253 description = (String) map.get("description");
254 } catch (ClassCastException ex) {
255 throw new InvalidDescriptionException(ex, "description is of wrong type");
256 }
257 }
258
259 if (map.containsKey("load")) {
260 try {
261 order = PluginLoadOrder.valueOf(((String) map.get("load")).toUpperCase().replaceAll("\\W", ""));
262 } catch (ClassCastException ex) {
263 throw new InvalidDescriptionException(ex, "load is of wrong type");
264 } catch (IllegalArgumentException ex) {
265 throw new InvalidDescriptionException(ex, "load is not a valid choice");
266 }
267 }
268
269 if (map.containsKey("author")) {
270 try {
271 String extra = (String) map.get("author");
272
273 authors.add(extra);
274 } catch (ClassCastException ex) {
275 throw new InvalidDescriptionException(ex, "author is of wrong type");
276 }
277 }
278
279 if (map.containsKey("authors")) {
280 try {
281 ArrayList<String> extra = (ArrayList<String>) map.get("authors");
282
283 authors.addAll(extra);
284 } catch (ClassCastException ex) {
285 throw new InvalidDescriptionException(ex, "authors are of wrong type");
286 }
287 }
288
289 if (map.containsKey("permissions")) {
290 try {
291 Map<String, Map<String, Object>> perms = (Map<String, Map<String, Object>>) map.get("permissions");
292
293 loadPermissions(perms);
294 } catch (ClassCastException ex) {
295 throw new InvalidDescriptionException(ex, "permissions are of wrong type");
296 }
297 }
298
299 if (map.containsKey("visible")) {
300 try {
301 visible = (Boolean) map.get("visible");
302 } catch (ClassCastException ex) {
303 throw new InvalidDescriptionException(ex, "visible is of wrong type");
304 }
305 }
306 }
307
308 private Map<String, Object> saveMap() {
309 Map<String, Object> map = new HashMap<String, Object>();
310
311 map.put("name", name);
312 map.put("main", main);
313 map.put("version", version);
314 map.put("database", database);
315 map.put("order", order.toString());
316 map.put("visible", visible);
317
318 if (commands != null) {
319 map.put("command", commands);
320 }
321 if (depend != null) {
322 map.put("depend", depend);
323 }
324 if (dependencies != null) {
325 map.put("dependencies", dependencies);
326 }
327 if (softDepend != null) {
328 map.put("softdepend", softDepend);
329 }
330 if (website != null) {
331 map.put("website", website);
332 }
333 if (description != null) {
334 map.put("description", description);
335 }
336
337 if (authors.size() == 1) {
338 map.put("author", authors.get(0));
339 } else if (authors.size() > 1) {
340 map.put("authors", authors);
341 }
342
343 if (classLoaderOf != null) {
344 map.put("class-loader-of", classLoaderOf);
345 }
346
347 return map;
348 }
349
350 private void loadPermissions(Map<String, Map<String, Object>> perms) {
351 Set<String> keys = perms.keySet();
352
353 for (String name : keys) {
354 try {
355 permissions.add(Permission.loadPermission(name, perms.get(name)));
356 } catch (Throwable ex) {
357 Bukkit.getServer().getLogger().log(Level.SEVERE, "Permission node '" + name + "' in plugin description file for " + getFullName() + " is invalid", ex);
358 }
359 }
360 }
361}