001package com.github.theholywaffle.teamspeak3.api.wrapper;
002
003/*
004 * #%L
005 * TeamSpeak 3 Java API
006 * %%
007 * Copyright (C) 2014 Bert De Geyter
008 * %%
009 * Permission is hereby granted, free of charge, to any person obtaining a copy
010 * of this software and associated documentation files (the "Software"), to deal
011 * in the Software without restriction, including without limitation the rights
012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
013 * copies of the Software, and to permit persons to whom the Software is
014 * furnished to do so, subject to the following conditions:
015 * 
016 * The above copyright notice and this permission notice shall be included in
017 * all copies or substantial portions of the Software.
018 * 
019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
025 * THE SOFTWARE.
026 * #L%
027 */
028
029import com.github.theholywaffle.teamspeak3.api.Property;
030
031import java.util.Collections;
032import java.util.Map;
033
034/**
035 * A wrapper class around a {@link Map}.
036 * <p>
037 * We use wrapper classes instead of just passing around plain Maps because
038 * </p><ul>
039 * <li>it's more descriptive</li>
040 * <li>there's no confusion between types (e.g. {@code Client} and {@code Channel})</li>
041 * <li>we can create getters for the specific use-cases</li>
042 * <li>we don't have to check for {@code null} each time</li>
043 * </ul>
044 */
045public class Wrapper {
046
047        /**
048         * An empty wrapper whose getters will always return the default values
049         * ({@code -1}, {@code false}, or {@code ""}).
050         */
051        public static final Wrapper EMPTY = new Wrapper(Collections.emptyMap());
052
053        private final Map<String, String> map;
054
055        /**
056         * Creates a new wrapper around the given map.
057         *
058         * @param map
059         *              the Map to abstract, cannot be {@code null}
060         */
061        public Wrapper(Map<String, String> map) {
062                this.map = map;
063        }
064
065        /**
066         * Gets the map underlying this {@code Wrapper}.
067         *
068         * @return the underlying map
069         */
070        public Map<String, String> getMap() {
071                return map;
072        }
073
074        /**
075         * Gets a property as a boolean from the underlying map.
076         * Returns {@code true} if the property exists in the map and its value is {@code "1"}.
077         *
078         * @param propertyName
079         *              the name of the property
080         *
081         * @return the boolean value of the property or {@code false} if the property doesn't exist
082         */
083        public boolean getBoolean(String propertyName) {
084                return getInt(propertyName) == 1;
085        }
086
087        /**
088         * Gets a property as a boolean from the underlying map.
089         * Returns {@code true} if the property exists in the map and its value is {@code "1"}.
090         *
091         * @param property
092         *              the property
093         *
094         * @return the boolean value of the property or {@code false} if the property doesn't exist
095         */
096        public boolean getBoolean(Property property) {
097                return getBoolean(property.getName());
098        }
099
100        /**
101         * Gets a property as a double from the underlying map.
102         * If the property doesn't exist in the underlying map, {@code -1.0} is returned.
103         *
104         * @param propertyName
105         *              the name of the property
106         *
107         * @return the double value of the property or {@code -1.0} if the property doesn't exist
108         */
109        public double getDouble(String propertyName) {
110                String value = get(propertyName);
111                return value.isEmpty() ? -1D : Double.parseDouble(value);
112        }
113
114        /**
115         * Gets a property as a double from the underlying map.
116         * If the property doesn't exist in the underlying map, {@code -1.0} is returned.
117         *
118         * @param property
119         *              the property
120         *
121         * @return the double value of the property or {@code -1.0} if the property doesn't exist
122         */
123        public double getDouble(Property property) {
124                return getDouble(property.getName());
125        }
126
127        /**
128         * Gets a property as a long from the underlying map.
129         * If the property doesn't exist in the underlying map, {@code -1} is returned.
130         *
131         * @param propertyName
132         *              the name of the property
133         *
134         * @return the long value of the property or {@code -1} if the property doesn't exist
135         */
136        public long getLong(String propertyName) {
137                String value = get(propertyName);
138                return value.isEmpty() ? -1L : Long.parseLong(value);
139        }
140
141        /**
142         * Gets a property as a long from the underlying map.
143         * If the property doesn't exist in the underlying map, {@code -1} is returned.
144         *
145         * @param property
146         *              the property
147         *
148         * @return the long value of the property or {@code -1} if the property doesn't exist
149         */
150        public long getLong(Property property) {
151                return getLong(property.getName());
152        }
153
154        /**
155         * Gets a property as an integer from the underlying map.
156         * If the property doesn't exist in the underlying map, {@code -1} is returned.
157         *
158         * @param propertyName
159         *              the name of the property
160         *
161         * @return the integer value of the property or {@code -1} if the property doesn't exist
162         */
163        public int getInt(String propertyName) {
164                String value = get(propertyName);
165                return value.isEmpty() ? -1 : Integer.parseInt(value);
166        }
167
168        /**
169         * Gets a property as an integer from the underlying map.
170         * If the property doesn't exist in the underlying map, {@code -1} is returned.
171         *
172         * @param property
173         *              the property
174         *
175         * @return the integer value of the property or {@code -1} if the property doesn't exist
176         */
177        public int getInt(Property property) {
178                return getInt(property.getName());
179        }
180
181        /**
182         * Gets a property as a String from the underlying map.
183         * If the property doesn't exist in the underlying map, an empty String is returned.
184         *
185         * @param propertyName
186         *              the name of the property
187         *
188         * @return the String value of the property or an empty String if the property doesn't exist
189         */
190        public String get(String propertyName) {
191                final String result = map.get(propertyName);
192                return result != null ? result : "";
193        }
194
195        /**
196         * Gets a property as a {@code String} from the underlying map.
197         * If the property doesn't exist in the underlying map, an empty String is returned.
198         *
199         * @param property
200         *              the property
201         *
202         * @return the String value of the property or an empty String if the property doesn't exist
203         */
204        public String get(Property property) {
205                return get(property.getName());
206        }
207
208        @Override
209        public String toString() {
210                return map.toString();
211        }
212}