Bukkit  1.4.7-R1.0
 All Classes Namespaces Files Functions Variables Enumerator Pages
PluginDescriptionFile.java
Go to the documentation of this file.
1 package org.bukkit.plugin;
2 
3 import java.io.InputStream;
4 import java.io.Reader;
5 import java.io.Writer;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 
10 import org.bukkit.permissions.Permission;
11 import org.bukkit.permissions.PermissionDefault;
12 import org.yaml.snakeyaml.Yaml;
13 import org.yaml.snakeyaml.constructor.SafeConstructor;
14 
15 import com.google.common.collect.ImmutableList;
16 import com.google.common.collect.ImmutableMap;
17 
21 public final class PluginDescriptionFile {
22  private static final Yaml yaml = new Yaml(new SafeConstructor());
23  private String name = null;
24  private String main = null;
25  private String classLoaderOf = null;
26  private List<String> depend = null;
27  private List<String> softDepend = null;
28  private List<String> loadBefore = null;
29  private String version = null;
30  private Map<String, Map<String, Object>> commands = null;
31  private String description = null;
32  private List<String> authors = null;
33  private String website = null;
34  private String prefix = null;
35  private boolean database = false;
37  private List<Permission> permissions = null;
38  private Map<?, ?> lazyPermissions = null;
39  private PermissionDefault defaultPerm = PermissionDefault.OP;
40 
41  public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
42  loadMap((Map<?, ?>) yaml.load(stream));
43  }
44 
51  public PluginDescriptionFile(final Reader reader) throws InvalidDescriptionException {
52  loadMap((Map<?, ?>) yaml.load(reader));
53  }
54 
62  public PluginDescriptionFile(final String pluginName, final String pluginVersion, final String mainClass) {
63  name = pluginName;
64  version = pluginVersion;
65  main = mainClass;
66  }
67 
73  public void save(Writer writer) {
74  yaml.dump(saveMap(), writer);
75  }
76 
82  public String getName() {
83  return name;
84  }
85 
91  public String getVersion() {
92  return version;
93  }
94 
100  public String getFullName() {
101  return name + " v" + version;
102  }
103 
109  public String getMain() {
110  return main;
111  }
112 
113  public Map<String, Map<String, Object>> getCommands() {
114  return commands;
115  }
116 
117  public List<String> getDepend() {
118  return depend;
119  }
120 
121  public List<String> getSoftDepend() {
122  return softDepend;
123  }
124 
129  public List<String> getLoadBefore() {
130  return loadBefore;
131  }
132 
134  return order;
135  }
136 
142  public String getDescription() {
143  return description;
144  }
145 
146  public List<String> getAuthors() {
147  return authors;
148  }
149 
150  public String getWebsite() {
151  return website;
152  }
153 
154  public boolean isDatabaseEnabled() {
155  return database;
156  }
157 
158  public void setDatabaseEnabled(boolean database) {
159  this.database = database;
160  }
161 
162  public List<Permission> getPermissions() {
163  if (permissions == null) {
164  if (lazyPermissions == null) {
165  permissions = ImmutableList.<Permission>of();
166  } else {
167  permissions = ImmutableList.copyOf(Permission.loadPermissions(lazyPermissions, "Permission node '%s' in plugin description file for " + getFullName() + " is invalid", defaultPerm));
168  lazyPermissions = null;
169  }
170  }
171  return permissions;
172  }
173 
175  return defaultPerm;
176  }
177 
178  public String getClassLoaderOf() {
179  return classLoaderOf;
180  }
181 
182  public String getPrefix() {
183  return prefix;
184  }
185 
186  private void loadMap(Map<?, ?> map) throws InvalidDescriptionException {
187  try {
188  name = map.get("name").toString();
189 
190  if (!name.matches("^[A-Za-z0-9 _.-]+$")) {
191  throw new InvalidDescriptionException("name '" + name + "' contains invalid characters.");
192  }
193  } catch (NullPointerException ex) {
194  throw new InvalidDescriptionException(ex, "name is not defined");
195  } catch (ClassCastException ex) {
196  throw new InvalidDescriptionException(ex, "name is of wrong type");
197  }
198 
199  try {
200  version = map.get("version").toString();
201  } catch (NullPointerException ex) {
202  throw new InvalidDescriptionException(ex, "version is not defined");
203  } catch (ClassCastException ex) {
204  throw new InvalidDescriptionException(ex, "version is of wrong type");
205  }
206 
207  try {
208  main = map.get("main").toString();
209  if (main.startsWith("org.bukkit.")) {
210  throw new InvalidDescriptionException("main may not be within the org.bukkit namespace");
211  }
212  } catch (NullPointerException ex) {
213  throw new InvalidDescriptionException(ex, "main is not defined");
214  } catch (ClassCastException ex) {
215  throw new InvalidDescriptionException(ex, "main is of wrong type");
216  }
217 
218  if (map.get("commands") != null) {
219  ImmutableMap.Builder<String, Map<String, Object>> commandsBuilder = ImmutableMap.<String, Map<String, Object>>builder();
220  try {
221  for (Map.Entry<?, ?> command : ((Map<?, ?>) map.get("commands")).entrySet()) {
222  ImmutableMap.Builder<String, Object> commandBuilder = ImmutableMap.<String, Object>builder();
223  if (command.getValue() != null) {
224  for (Map.Entry<?, ?> commandEntry : ((Map<?, ?>) command.getValue()).entrySet()) {
225  if (commandEntry.getValue() instanceof Iterable) {
226  // This prevents internal alias list changes
227  ImmutableList.Builder<Object> commandSubList = ImmutableList.<Object>builder();
228  for (Object commandSubListItem : (Iterable<?>) commandEntry.getValue()) {
229  if (commandSubListItem != null) {
230  commandSubList.add(commandSubListItem);
231  }
232  }
233  commandBuilder.put(commandEntry.getKey().toString(), commandSubList.build());
234  } else if (commandEntry.getValue() != null) {
235  commandBuilder.put(commandEntry.getKey().toString(), commandEntry.getValue());
236  }
237  }
238  }
239  commandsBuilder.put(command.getKey().toString(), commandBuilder.build());
240  }
241  } catch (ClassCastException ex) {
242  throw new InvalidDescriptionException(ex, "commands are of wrong type");
243  }
244  commands = commandsBuilder.build();
245  }
246 
247  if (map.get("class-loader-of") != null) {
248  classLoaderOf = map.get("class-loader-of").toString();
249  }
250 
251  if (map.get("depend") != null) {
252  ImmutableList.Builder<String> dependBuilder = ImmutableList.<String>builder();
253  try {
254  for (Object dependency : (Iterable<?>) map.get("depend")) {
255  dependBuilder.add(dependency.toString());
256  }
257  } catch (ClassCastException ex) {
258  throw new InvalidDescriptionException(ex, "depend is of wrong type");
259  } catch (NullPointerException e) {
260  throw new InvalidDescriptionException(e, "invalid dependency format");
261  }
262  depend = dependBuilder.build();
263  }
264 
265  if (map.get("softdepend") != null) {
266  ImmutableList.Builder<String> softDependBuilder = ImmutableList.<String>builder();
267  try {
268  for (Object dependency : (Iterable<?>) map.get("softdepend")) {
269  softDependBuilder.add(dependency.toString());
270  }
271  } catch (ClassCastException ex) {
272  throw new InvalidDescriptionException(ex, "softdepend is of wrong type");
273  } catch (NullPointerException ex) {
274  throw new InvalidDescriptionException(ex, "invalid soft-dependency format");
275  }
276  softDepend = softDependBuilder.build();
277  }
278 
279  if (map.get("loadbefore") != null) {
280  ImmutableList.Builder<String> loadBeforeBuilder = ImmutableList.<String>builder();
281  try {
282  for (Object predependency : (Iterable<?>) map.get("loadbefore")) {
283  loadBeforeBuilder.add(predependency.toString());
284  }
285  } catch (ClassCastException ex) {
286  throw new InvalidDescriptionException(ex, "loadbefore is of wrong type");
287  } catch (NullPointerException ex) {
288  throw new InvalidDescriptionException(ex, "invalid load-before format");
289  }
290  loadBefore = loadBeforeBuilder.build();
291  }
292 
293  if (map.get("database") != null) {
294  try {
295  database = (Boolean) map.get("database");
296  } catch (ClassCastException ex) {
297  throw new InvalidDescriptionException(ex, "database is of wrong type");
298  }
299  }
300 
301  if (map.get("website") != null) {
302  website = map.get("website").toString();
303  }
304 
305  if (map.get("description") != null) {
306  description = map.get("description").toString();
307  }
308 
309  if (map.get("load") != null) {
310  try {
311  order = PluginLoadOrder.valueOf(((String) map.get("load")).toUpperCase().replaceAll("\\W", ""));
312  } catch (ClassCastException ex) {
313  throw new InvalidDescriptionException(ex, "load is of wrong type");
314  } catch (IllegalArgumentException ex) {
315  throw new InvalidDescriptionException(ex, "load is not a valid choice");
316  }
317  }
318 
319  if (map.get("authors") != null) {
320  ImmutableList.Builder<String> authorsBuilder = ImmutableList.<String>builder();
321  if (map.get("author") != null) {
322  authorsBuilder.add(map.get("author").toString());
323  }
324  try {
325  for (Object o : (Iterable<?>) map.get("authors")) {
326  authorsBuilder.add(o.toString());
327  }
328  } catch (ClassCastException ex) {
329  throw new InvalidDescriptionException(ex, "authors are of wrong type");
330  } catch (NullPointerException ex) {
331  throw new InvalidDescriptionException(ex, "authors are improperly defined");
332  }
333  authors = authorsBuilder.build();
334  } else if (map.get("author") != null) {
335  authors = ImmutableList.of(map.get("author").toString());
336  } else {
337  authors = ImmutableList.<String>of();
338  }
339 
340  if (map.get("default-permission") != null) {
341  try {
342  defaultPerm = PermissionDefault.getByName(map.get("default-permission").toString());
343  } catch (ClassCastException ex) {
344  throw new InvalidDescriptionException(ex, "default-permission is of wrong type");
345  } catch (IllegalArgumentException ex) {
346  throw new InvalidDescriptionException(ex, "default-permission is not a valid choice");
347  }
348  }
349 
350  try {
351  lazyPermissions = (Map<?, ?>) map.get("permissions");
352  } catch (ClassCastException ex) {
353  throw new InvalidDescriptionException(ex, "permissions are of the wrong type");
354  }
355 
356  if (map.get("prefix") != null) {
357  prefix = map.get("prefix").toString();
358  }
359  }
360 
361  private Map<String, Object> saveMap() {
362  Map<String, Object> map = new HashMap<String, Object>();
363 
364  map.put("name", name);
365  map.put("main", main);
366  map.put("version", version);
367  map.put("database", database);
368  map.put("order", order.toString());
369  map.put("default-permission", defaultPerm.toString());
370 
371  if (commands != null) {
372  map.put("command", commands);
373  }
374  if (depend != null) {
375  map.put("depend", depend);
376  }
377  if (softDepend != null) {
378  map.put("softdepend", softDepend);
379  }
380  if (website != null) {
381  map.put("website", website);
382  }
383  if (description != null) {
384  map.put("description", description);
385  }
386 
387  if (authors.size() == 1) {
388  map.put("author", authors.get(0));
389  } else if (authors.size() > 1) {
390  map.put("authors", authors);
391  }
392 
393  if (classLoaderOf != null) {
394  map.put("class-loader-of", classLoaderOf);
395  }
396 
397  if (prefix != null) {
398  map.put("prefix", prefix);
399  }
400 
401  return map;
402  }
403 }