1 /* 2 * Copyright 2020-2022 Foreseeti AB <https://foreseeti.com> 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.mal_lang.langspec.builders; 18 19 import static java.util.Objects.requireNonNull; 20 import static org.mal_lang.langspec.Utils.requireIdentifier; 21 22 import jakarta.json.JsonObject; 23 import java.util.ArrayList; 24 import java.util.LinkedHashMap; 25 import java.util.List; 26 import java.util.Map; 27 28 /** 29 * A builder for creating {@link org.mal_lang.langspec.Lang} objects. 30 * 31 * @since 1.0.0 32 */ 33 public final class LangBuilder { 34 private final Map<String, String> defines = new LinkedHashMap<>(); 35 private final Map<String, CategoryBuilder> categories = new LinkedHashMap<>(); 36 private final Map<String, AssetBuilder> assets = new LinkedHashMap<>(); 37 private final List<AssociationBuilder> associations = new ArrayList<>(); 38 private String license = null; 39 private String notice = null; 40 41 /** 42 * Constructs a new {@code LangBuilder} object. 43 * 44 * @since 1.0.0 45 */ 46 public LangBuilder() {} 47 48 /** 49 * Returns all defines in this {@code LangBuilder} object. 50 * 51 * @return all defines in this {@code LangBuilder} object 52 * @since 1.0.0 53 */ 54 public Map<String, String> getDefines() { 55 return Map.copyOf(this.defines); 56 } 57 58 /** 59 * Adds a define to this {@code LangBuilder} object. 60 * 61 * @param key the key of the define 62 * @param value the value of the define 63 * @return this {@code LangBuilder} object 64 * @throws java.lang.NullPointerException if {@code key} or {@code value} is {@code null} 65 * @throws java.lang.IllegalArgumentException if {@code key} is not a valid identifier 66 * @since 1.0.0 67 */ 68 public LangBuilder addDefine(String key, String value) { 69 this.defines.put(requireIdentifier(key), requireNonNull(value)); 70 return this; 71 } 72 73 /** 74 * Returns a list of all categories in this {@code LangBuilder} object. 75 * 76 * @return a list of all categories in this {@code LangBuilder} object 77 * @since 1.0.0 78 */ 79 public List<CategoryBuilder> getCategories() { 80 return List.copyOf(this.categories.values()); 81 } 82 83 /** 84 * Adds a category to this {@code LangBuilder} object. 85 * 86 * @param category the category to add 87 * @return this {@code LangBuilder} object 88 * @throws java.lang.NullPointerException if {@code category} is {@code null} 89 * @since 1.0.0 90 */ 91 public LangBuilder addCategory(CategoryBuilder category) { 92 requireNonNull(category); 93 this.categories.put(category.getName(), category); 94 return this; 95 } 96 97 /** 98 * Returns a list of all assets in this {@code LangBuilder} object. 99 * 100 * @return a list of all assets in this {@code LangBuilder} object 101 * @since 1.0.0 102 */ 103 public List<AssetBuilder> getAssets() { 104 return List.copyOf(this.assets.values()); 105 } 106 107 /** 108 * Adds an asset to this {@code LangBuilder} object. 109 * 110 * @param asset the asset to add 111 * @return this {@code LangBuilder} object 112 * @throws java.lang.NullPointerException if {@code asset} is {@code null} 113 * @since 1.0.0 114 */ 115 public LangBuilder addAsset(AssetBuilder asset) { 116 requireNonNull(asset); 117 this.assets.put(asset.getName(), asset); 118 return this; 119 } 120 121 /** 122 * Returns a list of all associations in this {@code LangBuilder} object. 123 * 124 * @return a list of all associations in this {@code LangBuilder} object 125 * @since 1.0.0 126 */ 127 public List<AssociationBuilder> getAssociations() { 128 return List.copyOf(this.associations); 129 } 130 131 /** 132 * Adds an association to this {@code LangBuilder} object. 133 * 134 * @param association the association to add 135 * @return this {@code LangBuilder} object 136 * @throws java.lang.NullPointerException if {@code association} is {@code null} 137 * @since 1.0.0 138 */ 139 public LangBuilder addAssociation(AssociationBuilder association) { 140 this.associations.add(requireNonNull(association)); 141 return this; 142 } 143 144 /** 145 * Returns the license of this {@code LangBuilder} object, or {@code null} if no license has been 146 * set. 147 * 148 * @return the license of this {@code LangBuilder} object, or {@code null} if no license has been 149 * set 150 * @since 1.0.0 151 */ 152 public String getLicense() { 153 return this.license; 154 } 155 156 /** 157 * Sets the license of this {@code LangBuilder} object. 158 * 159 * @param license the license to set 160 * @return this {@code LangBuilder} object 161 * @throws java.lang.NullPointerException if {@code license} is {@code null} 162 * @since 1.0.0 163 */ 164 public LangBuilder setLicense(String license) { 165 this.license = requireNonNull(license); 166 return this; 167 } 168 169 /** 170 * Returns the notice of this {@code LangBuilder} object, or {@code null} if no notice has been 171 * set. 172 * 173 * @return the notice of this {@code LangBuilder} object, or {@code null} if no notice has been 174 * set 175 * @since 1.0.0 176 */ 177 public String getNotice() { 178 return this.notice; 179 } 180 181 /** 182 * Sets the notice of this {@code LangBuilder} object. 183 * 184 * @param notice the notice to set 185 * @return this {@code LangBuilder} object 186 * @throws java.lang.NullPointerException if {@code notice} is {@code null} 187 * @since 1.0.0 188 */ 189 public LangBuilder setNotice(String notice) { 190 this.notice = requireNonNull(notice); 191 return this; 192 } 193 194 /** 195 * Creates a new {@code LangBuilder} from a {@link jakarta.json.JsonObject}. 196 * 197 * @param jsonLang the {@link jakarta.json.JsonObject} 198 * @return a new {@code LangBuilder} 199 * @throws java.lang.NullPointerException if {@code jsonLang} is {@code null} 200 * @since 1.0.0 201 */ 202 public static LangBuilder fromJson(JsonObject jsonLang) { 203 return LangBuilder.fromJson(jsonLang, Map.of(), Map.of(), null, null); 204 } 205 206 /** 207 * Creates a new {@code LangBuilder} from a {@link jakarta.json.JsonObject}. 208 * 209 * @param jsonLang the {@link jakarta.json.JsonObject} 210 * @param svgIcons the SVG icons of the language 211 * @param pngIcons the PNG icons of the language 212 * @return a new {@code LangBuilder} 213 * @throws java.lang.NullPointerException if {@code jsonLang}, {@code svgIcons}, or {@code 214 * pngIcons} is {@code null} 215 * @since 1.0.0 216 */ 217 public static LangBuilder fromJson( 218 JsonObject jsonLang, Map<String, byte[]> svgIcons, Map<String, byte[]> pngIcons) { 219 return LangBuilder.fromJson(jsonLang, svgIcons, pngIcons, null, null); 220 } 221 222 /** 223 * Creates a new {@code LangBuilder} from a {@link jakarta.json.JsonObject}. 224 * 225 * @param jsonLang the {@link jakarta.json.JsonObject} 226 * @param license the license of the language, or {@code null} 227 * @param notice the notice of the language, or {@code null} 228 * @return a new {@code LangBuilder} 229 * @throws java.lang.NullPointerException if {@code jsonLang} is {@code null} 230 * @since 1.0.0 231 */ 232 public static LangBuilder fromJson(JsonObject jsonLang, String license, String notice) { 233 return LangBuilder.fromJson(jsonLang, Map.of(), Map.of(), license, notice); 234 } 235 236 /** 237 * Creates a new {@code LangBuilder} from a {@link jakarta.json.JsonObject}. 238 * 239 * @param jsonLang the {@link jakarta.json.JsonObject} 240 * @param svgIcons the SVG icons of the language 241 * @param pngIcons the PNG icons of the language 242 * @param license the license of the language, or {@code null} 243 * @param notice the notice of the language, or {@code null} 244 * @return a new {@code LangBuilder} 245 * @throws java.lang.NullPointerException if {@code jsonLang}, {@code svgIcons}, or {@code 246 * pngIcons} is {@code null} 247 * @since 1.0.0 248 */ 249 public static LangBuilder fromJson( 250 JsonObject jsonLang, 251 Map<String, byte[]> svgIcons, 252 Map<String, byte[]> pngIcons, 253 String license, 254 String notice) { 255 requireNonNull(jsonLang); 256 requireNonNull(svgIcons); 257 requireNonNull(pngIcons); 258 var builder = new LangBuilder(); 259 var jsonDefines = jsonLang.getJsonObject("defines"); 260 for (var key : jsonDefines.keySet()) { 261 builder.addDefine(key, jsonDefines.getString(key)); 262 } 263 for (var jsonCategory : jsonLang.getJsonArray("categories")) { 264 builder.addCategory(CategoryBuilder.fromJson(jsonCategory.asJsonObject())); 265 } 266 for (var jsonAsset : jsonLang.getJsonArray("assets")) { 267 builder.addAsset(AssetBuilder.fromJson(jsonAsset.asJsonObject(), svgIcons, pngIcons)); 268 } 269 for (var jsonAssociation : jsonLang.getJsonArray("associations")) { 270 builder.addAssociation(AssociationBuilder.fromJson(jsonAssociation.asJsonObject())); 271 } 272 if (license != null) { 273 builder.setLicense(license); 274 } 275 if (notice != null) { 276 builder.setNotice(notice); 277 } 278 return builder; 279 } 280 }