| /******************************************************************************** |
| * Copyright (c) 2015-2021 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.businessobjects.boundary; |
| |
| import static org.eclipse.mdm.businessobjects.boundary.ResourceConstants.REQUESTPARAM_SOURCENAME; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Stack; |
| |
| import javax.ejb.EJB; |
| import javax.ws.rs.GET; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.PathParam; |
| import javax.ws.rs.Produces; |
| import javax.ws.rs.core.MediaType; |
| import javax.ws.rs.core.Response; |
| |
| import org.eclipse.mdm.api.base.model.MDMLocalization; |
| import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse; |
| import org.eclipse.mdm.businessobjects.utils.ServiceUtils; |
| |
| import io.swagger.v3.oas.annotations.Operation; |
| import io.swagger.v3.oas.annotations.Parameter; |
| import io.swagger.v3.oas.annotations.media.Content; |
| import io.swagger.v3.oas.annotations.media.Schema; |
| import io.swagger.v3.oas.annotations.responses.ApiResponse; |
| import io.swagger.v3.oas.annotations.tags.Tag; |
| |
| /** |
| * |
| * @author jst |
| * |
| */ |
| |
| @Tag(name = "Localization") |
| @Path("/environments/{" + REQUESTPARAM_SOURCENAME + "}/mdmlocalizations") |
| public class LocalizationResource { |
| |
| private static final String LOCALIZATION_PREFIX = "mdm://i18n/"; |
| |
| @EJB |
| private LocalizationService localizationService; |
| |
| @GET |
| @Operation(summary = "Get all localizations", description = "Returns all localizations as hierarchical map", responses = { |
| @ApiResponse(description = "All localizations as map", content = @Content(schema = @Schema(implementation = Map.class))), |
| @ApiResponse(responseCode = "400", description = "Error") }) |
| @Produces(MediaType.APPLICATION_JSON + "+packed") |
| public Response read( |
| @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) { |
| return ServiceUtils.toResponse(groupByKey(localizationService.localize(sourceName))); |
| } |
| |
| @GET |
| @Operation(summary = "Get all localizations as entities", description = "Returns all localizations as list of MDMLocalization entities.", responses = { |
| @ApiResponse(description = "All localizations", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))), |
| @ApiResponse(responseCode = "400", description = "Error") }) |
| @Produces(MediaType.APPLICATION_JSON) |
| public Response readEntities( |
| @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) { |
| return ServiceUtils |
| .toResponse(new MDMEntityResponse(MDMLocalization.class, localizationService.localize(sourceName))); |
| |
| } |
| |
| @GET |
| @Operation(summary = "Get default mimetypes", description = "Returns all default mimetypes.", responses = { |
| @ApiResponse(description = "All default mimetypes", content = @Content(schema = @Schema(implementation = Map.class))), |
| @ApiResponse(responseCode = "400", description = "Error") }) |
| @Produces(MediaType.APPLICATION_JSON) |
| @Path("mimetypes") |
| public Response getDefaultMimeTypes( |
| @Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName) { |
| return ServiceUtils.toResponse(localizationService.getDefaultMimeTypes(sourceName)); |
| |
| } |
| |
| /** |
| * Pack localization information, by organizing translations in a hierarchical |
| * map. |
| * |
| * Names of {@link MDMLocalization} are used as keys. The keys are split on |
| * slashes (not the escaped ones) and the prefix is omitted. The actual |
| * translation values are held as array of the AliasNames. |
| * |
| * @param localizations the flat list of {@link MDMLocalization} entities. |
| * @return hierarchical translation map |
| */ |
| private Map<String, Object> groupByKey(List<MDMLocalization> localizations) { |
| Map<String, Object> result = new HashMap<>(); |
| for (MDMLocalization localization : localizations) { |
| // remove prefix since it contains no information |
| String key = localization.getName(); |
| if (key.contains(LOCALIZATION_PREFIX)) { |
| key = key.substring(LOCALIZATION_PREFIX.length()); |
| } |
| // create stack with key fragments in backward order |
| String[] keyFragments = key.split("/"); |
| Stack<String> stack = new Stack<>(); |
| for (int i = keyFragments.length - 1; i >= 0; --i) { |
| stack.push(keyFragments[i]); |
| } |
| // add to result map |
| addToMap(result, stack, localization.getTranslations()); |
| } |
| return result; |
| } |
| |
| /** |
| * Adds translations recursively to a hierarchical map. |
| * |
| * @param current current submap |
| * @param keyStack remaining key fragements |
| * @param translations array with translations |
| * @return |
| */ |
| @SuppressWarnings("unchecked") |
| private void addToMap(Map<String, Object> current, Stack<String> keyStack, List<String> translations) { |
| String key = keyStack.pop().replace("%2F", "/"); |
| // key chain contains more fragments |
| if (!keyStack.isEmpty()) { |
| // find existing sub-map or create and add new |
| Map<String, Object> next; |
| if (current.containsKey(key)) { |
| next = (Map<String, Object>) current.get(key); |
| } else { |
| next = new HashMap<String, Object>(); |
| current.put(key, next); |
| } |
| // process next fragment in sub-map |
| addToMap(next, keyStack, translations); |
| // last key fragment reached, thus translations are inserted now. |
| } else { |
| // last wins |
| current.put(key, translations); |
| } |
| } |
| } |