001/*
002 * PlotSquared, a land and world management plugin for Minecraft.
003 * Copyright (C) IntellectualSites <https://intellectualsites.com>
004 * Copyright (C) IntellectualSites team and contributors
005 *
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
018 */
019package com.plotsquared.core.configuration;
020
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025/**
026 * Represents a section of a {@link Configuration}.
027 */
028public interface ConfigurationSection {
029
030    /**
031     * Gets a set containing all keys in this section.
032     *
033     * <p>If deep is set to true, then this will contain all the keys within any
034     * child {@link ConfigurationSection}s (and their children, etc). These
035     * will be in a valid path notation for you to use.
036     *
037     * <p>If deep is set to false, then this will contain only the keys of any
038     * direct children, and not their own children.
039     *
040     * @param deep Whether or not to get a deep list, as opposed to a shallow
041     *             list.
042     * @return Set of keys contained within this ConfigurationSection.
043     */
044    Set<String> getKeys(boolean deep);
045
046    /**
047     * Gets a Map containing all keys and their values for this section.
048     *
049     * <p>If deep is set to true, then this will contain all the keys and values
050     * within any child {@link ConfigurationSection}s (and their children,
051     * etc). These keys will be in a valid path notation for you to use.
052     *
053     * <p>If deep is set to false, then this will contain only the keys and
054     * values of any direct children, and not their own children.
055     *
056     * @param deep Whether or not to get a deep list, as opposed to a shallow
057     *             list.
058     * @return Map of keys and values of this section.
059     */
060    Map<String, Object> getValues(boolean deep);
061
062    /**
063     * Checks if this {@link ConfigurationSection} contains the given path.
064     *
065     * <p>If the value for the requested path does not exist but a default value
066     * has been specified, this will return true.
067     *
068     * @param path Path to check for existence.
069     * @return {@code true} if this section contains the requested path, either via
070     *         default or being set.
071     * @throws IllegalArgumentException Thrown when path is {@code null}.
072     */
073    boolean contains(String path);
074
075    /**
076     * Checks if this {@link ConfigurationSection} has a value set for the
077     * given path.
078     *
079     * <p>If the value for the requested path does not exist but a default value
080     * has been specified, this will still return false.
081     *
082     * @param path Path to check for existence.
083     * @return {@code true} if this section contains the requested path, regardless of
084     *         having a default.
085     * @throws IllegalArgumentException Thrown when path is {@code null}.
086     */
087    boolean isSet(String path);
088
089    /**
090     * Gets the path of this {@link ConfigurationSection} from its root {@link
091     * Configuration}.
092     *
093     * <p>For any {@link Configuration} themselves, this will return an empty
094     * string.
095     *
096     * <p>If the section is no longer contained within its root for any reason,
097     * such as being replaced with a different value,
098     * this may return {@code null}.
099     *
100     * <p>To retrieve the single name of this section, that is, the final part
101     * of the path returned by this method, you may use {@link #getName()}.
102     *
103     * @return Path of this section relative to its root
104     */
105    String getCurrentPath();
106
107    /**
108     * Gets the name of this individual {@link ConfigurationSection}, in the
109     * path.
110     *
111     * <p>This will always be the final part of {@link #getCurrentPath()}, unless
112     * the section is orphaned.
113     *
114     * @return Name of this section
115     */
116    String getName();
117
118    /**
119     * Gets the root {@link Configuration} that contains this {@link
120     * ConfigurationSection}
121     *
122     * <p>For any {@link Configuration} themselves, this will return its own
123     * object.
124     *
125     * <p>If the section is no longer contained within its root for any reason,
126     * such as being replaced with a different value,
127     * this may return {@code null}.
128     *
129     * @return Root configuration containing this section.
130     */
131    Configuration getRoot();
132
133    /**
134     * Gets the parent {@link ConfigurationSection} that directly contains
135     * this {@link ConfigurationSection}.
136     *
137     * <p>For any {@link Configuration} themselves, this will return
138     * {@code null}.
139     *
140     * <p>If the section is no longer contained within its parent for any
141     * reason, such as being replaced with a different value, this may
142     * return {@code null}.
143     *
144     * @return Parent section containing this section.
145     */
146    ConfigurationSection getParent();
147
148    /**
149     * Gets the requested Object by path.
150     *
151     * <p>If the Object does not exist but a default value has been specified,
152     * this will return the default value. If the Object does not exist and no
153     * default value was specified, this will return {@code null}.
154     *
155     * @param path Path of the Object to get.
156     * @return Requested Object.
157     */
158    Object get(String path);
159
160    /**
161     * Gets the requested Object by path, returning a default value if not
162     * found.
163     *
164     * <p>If the Object does not exist then the specified default value will
165     * returned regardless of if a default has been identified in the root
166     * {@link Configuration}.
167     *
168     * @param path         Path of the Object to get.
169     * @param defaultValue The default value to return if the path is not found.
170     * @return Requested Object.
171     */
172    Object get(String path, Object defaultValue);
173
174    /**
175     * Sets the specified path to the given value.
176     *
177     * <p>If value is {@code null}, the entry will be removed. Any
178     * existing entry will be replaced, regardless of what the new value is.
179     *
180     * <p>Some implementations may have limitations on what you may store. See
181     * their individual javadoc for details. No implementations should allow
182     * you to store {@link Configuration}s or {@link ConfigurationSection}s,
183     * please use {@link #createSection(String)} for that.
184     *
185     * @param path  Path of the object to set.
186     * @param value New value to set the path to.
187     */
188    void set(String path, Object value);
189
190    /**
191     * Creates an empty {@link ConfigurationSection} at the specified path.
192     *
193     * <p>Any value that was previously set at this path will be overwritten. If
194     * the previous value was itself a {@link ConfigurationSection}, it will
195     * be orphaned.
196     *
197     * @param path Path to create the section at.
198     * @return Newly created section
199     */
200    ConfigurationSection createSection(String path);
201
202    /**
203     * Creates a {@link ConfigurationSection} at the specified path, with
204     * specified values.
205     *
206     * <p>Any value that was previously set at this path will be overwritten. If
207     * the previous value was itself a {@link ConfigurationSection}, it will
208     * be orphaned.
209     *
210     * @param path Path to create the section at.
211     * @param map  The values to used.
212     * @return Newly created section
213     */
214    ConfigurationSection createSection(String path, Map<?, ?> map);
215
216    // Primitives
217
218    /**
219     * Gets the requested String by path.
220     *
221     * <p>If the String does not exist but a default value has been specified,
222     * this will return the default value. If the String does not exist and no
223     * default value was specified, this will return {@code null}.
224     *
225     * @param path Path of the String to get.
226     * @return Requested String.
227     */
228    String getString(String path);
229
230    /**
231     * Gets the requested String by path, returning a default value if not
232     * found.
233     *
234     * <p>If the String does not exist then the specified default value will
235     * returned regardless of if a default has been identified in the root
236     * {@link Configuration}.
237     *
238     * @param path Path of the String to get.
239     * @param def  The default value to return if the path is not found or is
240     *             not a String.
241     * @return Requested String.
242     */
243    String getString(String path, String def);
244
245    /**
246     * Checks if the specified path is a String.
247     *
248     * <p>If the path exists but is not a String, this will return false. If
249     * the path does not exist, this will return false. If the path does not
250     * exist but a default value has been specified, this will check if that
251     * default value is a String and return appropriately.
252     *
253     * @param path Path of the String to check.
254     * @return Whether or not the specified path is a String.
255     */
256    boolean isString(String path);
257
258    /**
259     * Gets the requested int by path.
260     *
261     * <p>If the int does not exist but a default value has been specified, this
262     * will return the default value. If the int does not exist and no default
263     * value was specified, this will return 0.
264     *
265     * @param path Path of the int to get.
266     * @return Requested int.
267     */
268    int getInt(String path);
269
270    /**
271     * Gets the requested int by path, returning a default value if not found.
272     *
273     * <p>If the int does not exist then the specified default value will
274     * returned regardless of if a default has been identified in the root
275     * {@link Configuration}.
276     *
277     * @param path Path of the int to get.
278     * @param def  The default value to return if the path is not found or is
279     *             not an int.
280     * @return Requested int.
281     */
282    int getInt(String path, int def);
283
284    /**
285     * Checks if the specified path is an int.
286     *
287     * <p>If the path exists but is not a int, this will return false. If the
288     * path does not exist, this will return false. If the path does not exist
289     * but a default value has been specified, this will check if that default
290     * value is a int and return appropriately.
291     *
292     * @param path Path of the int to check.
293     * @return Whether or not the specified path is an int.
294     */
295    boolean isInt(String path);
296
297    /**
298     * Gets the requested boolean by path.
299     *
300     * <p>If the boolean does not exist but a default value has been specified,
301     * this will return the default value. If the boolean does not exist and
302     * no default value was specified, this will return false.
303     *
304     * @param path Path of the boolean to get.
305     * @return Requested boolean.
306     */
307    boolean getBoolean(String path);
308
309    /**
310     * Gets the requested boolean by path, returning a default value if not
311     * found.
312     *
313     * <p>If the boolean does not exist then the specified default value will
314     * returned regardless of if a default has been identified in the root
315     * {@link Configuration}.
316     *
317     * @param path         Path of the boolean to get.
318     * @param defaultValue The default value to return if the path is not found or is
319     *                     not a boolean.
320     * @return Requested boolean.
321     */
322    boolean getBoolean(String path, boolean defaultValue);
323
324    /**
325     * Checks if the specified path is a boolean.
326     *
327     * <p>If the path exists but is not a boolean, this will return false. If the
328     * path does not exist, this will return false. If the path does not exist
329     * but a default value has been specified, this will check if that default
330     * value is a boolean and return appropriately.
331     *
332     * @param path Path of the boolean to check.
333     * @return Whether or not the specified path is a boolean.
334     */
335    boolean isBoolean(String path);
336
337    /**
338     * Gets the requested double by path.
339     *
340     * <p>If the double does not exist but a default value has been specified,
341     * this will return the default value. If the double does not exist and no
342     * default value was specified, this will return 0.
343     *
344     * @param path Path of the double to get.
345     * @return Requested double.
346     */
347    double getDouble(String path);
348
349    /**
350     * Gets the requested double by path, returning a default value if not
351     * found.
352     *
353     * <p>If the double does not exist then the specified default value will
354     * returned regardless of if a default has been identified in the root
355     * {@link Configuration}.
356     *
357     * @param path         Path of the double to get.
358     * @param defaultValue The default value to return if the path is not found or is
359     *                     not a double.
360     * @return Requested double.
361     */
362    double getDouble(String path, double defaultValue);
363
364    /**
365     * Checks if the specified path is a double.
366     *
367     * <p>If the path exists but is not a double, this will return false. If the
368     * path does not exist, this will return false. If the path does not exist
369     * but a default value has been specified, this will check if that default
370     * value is a double and return appropriately.
371     *
372     * @param path Path of the double to check.
373     * @return Whether or not the specified path is a double.
374     */
375    boolean isDouble(String path);
376
377    /**
378     * Gets the requested long by path.
379     *
380     * <p>If the long does not exist but a default value has been specified, this
381     * will return the default value. If the long does not exist and no
382     * default value was specified, this will return 0.
383     *
384     * @param path Path of the long to get.
385     * @return Requested long.
386     */
387    long getLong(String path);
388
389    /**
390     * Gets the requested long by path, returning a default value if not
391     * found.
392     *
393     * <p>If the long does not exist then the specified default value will
394     * returned regardless of if a default has been identified in the root
395     * {@link Configuration}.
396     *
397     * @param path Path of the long to get.
398     * @param def  The default value to return if the path is not found or is
399     *             not a long.
400     * @return Requested long.
401     */
402    long getLong(String path, long def);
403
404    /**
405     * Checks if the specified path is a long.
406     *
407     * <p>If the path exists but is not a long, this will return false. If the
408     * path does not exist, this will return false. If the path does not exist
409     * but a default value has been specified, this will check if that default
410     * value is a long and return appropriately.
411     *
412     * @param path Path of the long to check.
413     * @return Whether or not the specified path is a long.
414     */
415    boolean isLong(String path);
416
417    // Java
418
419    /**
420     * Gets the requested List by path.
421     *
422     * <p>If the List does not exist but a default value has been specified, this
423     * will return the default value. If the List does not exist and no
424     * default value was specified, this will return null.
425     *
426     * @param path Path of the List to get.
427     * @return Requested List.
428     */
429    List<?> getList(String path);
430
431    /**
432     * Gets the requested List by path, returning a default value if not
433     * found.
434     *
435     * <p>If the List does not exist then the specified default value will
436     * returned regardless of if a default has been identified in the root
437     * {@link Configuration}.
438     *
439     * @param path Path of the List to get.
440     * @param def  The default value to return if the path is not found or is
441     *             not a List.
442     * @return Requested List.
443     */
444    List<?> getList(String path, List<?> def);
445
446    /**
447     * Checks if the specified path is a List.
448     *
449     * <p>If the path exists but is not a List, this will return false. If the
450     * path does not exist, this will return false. If the path does not exist
451     * but a default value has been specified, this will check if that default
452     * value is a List and return appropriately.
453     *
454     * @param path Path of the List to check.
455     * @return Whether or not the specified path is a List.
456     */
457    boolean isList(String path);
458
459    /**
460     * Gets the requested List of String by path.
461     *
462     * <p>If the List does not exist but a default value has been specified,
463     * this will return the default value. If the List does not exist and no
464     * default value was specified, this will return an empty List.
465     *
466     * <p>This method will attempt to cast any values into a String if possible,
467     * but may miss any values out if they are not compatible.
468     *
469     * @param path Path of the List to get.
470     * @return Requested List of String.
471     */
472    List<String> getStringList(String path);
473
474    /**
475     * Gets the requested List of Integer by path.
476     *
477     * <p>If the List does not exist but a default value has been specified,
478     * this will return the default value. If the List does not exist and no
479     * default value was specified, this will return an empty List.
480     *
481     * <p>This method will attempt to cast any values into a Integer if
482     * possible, but may miss any values out if they are not compatible.
483     *
484     * @param path Path of the List to get.
485     * @return Requested List of Integer.
486     */
487    List<Integer> getIntegerList(String path);
488
489    /**
490     * Gets the requested List of Boolean by path.
491     *
492     * <p>If the List does not exist but a default value has been specified,
493     * this will return the default value. If the List does not exist and no
494     * default value was specified, this will return an empty List.
495     *
496     * <p>This method will attempt to cast any values into a Boolean if
497     * possible, but may miss any values out if they are not compatible.
498     *
499     * @param path Path of the List to get.
500     * @return Requested List of Boolean.
501     */
502    List<Boolean> getBooleanList(String path);
503
504    /**
505     * Gets the requested List of Double by path.
506     *
507     * <p>If the List does not exist but a default value has been specified,
508     * this will return the default value. If the List does not exist and no
509     * default value was specified, this will return an empty List.
510     *
511     * <p>This method will attempt to cast any values into a Double if possible,
512     * but may miss any values out if they are not compatible.
513     *
514     * @param path Path of the List to get.
515     * @return Requested List of Double.
516     */
517    List<Double> getDoubleList(String path);
518
519    /**
520     * Gets the requested List of Float by path.
521     *
522     * <p>If the List does not exist but a default value has been specified,
523     * this will return the default value. If the List does not exist and no
524     * default value was specified, this will return an empty List.
525     *
526     * <p>This method will attempt to cast any values into a Float if possible,
527     * but may miss any values out if they are not compatible.
528     *
529     * @param path Path of the List to get.
530     * @return Requested List of Float.
531     */
532    List<Float> getFloatList(String path);
533
534    /**
535     * Gets the requested List of Long by path.
536     *
537     * <p>If the List does not exist but a default value has been specified,
538     * this will return the default value. If the List does not exist and no
539     * default value was specified, this will return an empty List.
540     *
541     * <p>This method will attempt to cast any values into a Long if possible,
542     * but may miss any values out if they are not compatible.
543     *
544     * @param path Path of the List to get.
545     * @return Requested List of Long.
546     */
547    List<Long> getLongList(String path);
548
549    /**
550     * Gets the requested List of Byte by path.
551     *
552     * <p>If the List does not exist but a default value has been specified,
553     * this will return the default value. If the List does not exist and no
554     * default value was specified, this will return an empty List.
555     *
556     * <p>This method will attempt to cast any values into a Byte if possible,
557     * but may miss any values out if they are not compatible.
558     *
559     * @param path Path of the List to get.
560     * @return Requested List of Byte.
561     */
562    List<Byte> getByteList(String path);
563
564    /**
565     * Gets the requested List of Character by path.
566     *
567     * <p>If the List does not exist but a default value has been specified,
568     * this will return the default value. If the List does not exist and no
569     * default value was specified, this will return an empty List.
570     *
571     * <p>This method will attempt to cast any values into a Character if
572     * possible, but may miss any values out if they are not compatible.
573     *
574     * @param path Path of the List to get.
575     * @return Requested List of Character.
576     */
577    List<Character> getCharacterList(String path);
578
579    /**
580     * Gets the requested List of Short by path.
581     *
582     * <p>If the List does not exist but a default value has been specified,
583     * this will return the default value. If the List does not exist and no
584     * default value was specified, this will return an empty List.
585     *
586     * <p>This method will attempt to cast any values into a Short if
587     * possible, but may miss any values out if they are not compatible.
588     *
589     * @param path Path of the List to get.
590     * @return Requested List of Short.
591     */
592    List<Short> getShortList(String path);
593
594    /**
595     * Gets the requested List of Maps by path.
596     *
597     * <p>If the List does not exist but a default value has been specified,
598     * this will return the default value. If the List does not exist and no
599     * default value was specified, this will return an empty List.
600     * <p>This method will attempt to cast any values into a Map if possible,
601     * but may miss any values out if they are not compatible.
602     *
603     * @param path Path of the List to get.
604     * @return Requested List of Maps.
605     */
606    List<Map<?, ?>> getMapList(String path);
607
608    /**
609     * Gets the requested ConfigurationSection by path.
610     *
611     * <p>If the ConfigurationSection does not exist but a default value has
612     * been specified, this will return the default value. If the
613     * ConfigurationSection does not exist and no default value was specified,
614     * this will return {@code null}.
615     *
616     * @param path Path of the ConfigurationSection to get.
617     * @return Requested ConfigurationSection.
618     */
619    ConfigurationSection getConfigurationSection(String path);
620
621    /**
622     * Checks if the specified path is a ConfigurationSection.
623     *
624     * <p>If the path exists but is not a ConfigurationSection, this will return
625     * false. If the path does not exist, this will return false. If the path
626     * does not exist but a default value has been specified, this will check
627     * if that default value is a ConfigurationSection and return
628     * appropriately.
629     *
630     * @param path Path of the ConfigurationSection to check.
631     * @return Whether or not the specified path is a ConfigurationSection.
632     */
633    boolean isConfigurationSection(String path);
634
635    /**
636     * Gets the equivalent {@link ConfigurationSection} from the default
637     * {@link Configuration} defined in {@link #getRoot()}.
638     *
639     * <p>If the root contains no defaults, or the defaults doesn't contain a
640     * value for this path, or the value at this path is not a {@link
641     * ConfigurationSection} then this will return {@code null}.
642     *
643     * @return Equivalent section in root configuration
644     */
645    ConfigurationSection getDefaultSection();
646
647    /**
648     * Sets the default value in the root at the given path as provided.
649     *
650     * <p>If no source {@link Configuration} was provided as a default
651     * collection, then a new {@link MemoryConfiguration} will be created to
652     * hold the new default value.
653     *
654     * <p>If value is {@code null}, the value will be removed from the
655     * default Configuration source.
656     *
657     * <p>If the value as returned by {@link #getDefaultSection()} is
658     * {@code null}, then this will create a new section at the path,
659     * replacing anything that may have existed there previously.
660     *
661     * @param path  Path of the value to set
662     * @param value Value to set the default to
663     * @throws IllegalArgumentException Thrown if path is {@code null}
664     */
665    void addDefault(String path, Object value);
666
667}