1 /*
2 * Copyright 2015 Data Archiving and Networked Services (an institute of
3 * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4 * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5 *
6 * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7 * the European Commission - subsequent versions of the EUPL (the "Licence");
8 * You may not use this work except in compliance with the Licence.
9 * You may obtain a copy of the Licence at:
10 *
11 * https://joinup.ec.europa.eu/software/page/eupl
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the Licence is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the Licence for the specific language governing
17 * permissions and limitations under the Licence.
18 */
19
20 package eu.ehri.project.models.idgen;
21
22 import com.google.common.base.Joiner;
23 import com.google.common.collect.ListMultimap;
24 import eu.ehri.project.persistence.Bundle;
25 import eu.ehri.project.utils.Slugify;
26
27 import java.util.Collection;
28 import static eu.ehri.project.definitions.Ontology.IDENTIFIER_KEY;
29 import static eu.ehri.project.definitions.Ontology.LANGUAGE_OF_DESCRIPTION;
30
31 /**
32 * Generates an ID for nodes which represent Descriptions, where
33 * the graph id is a combination of the parent scopes, plus the description
34 * language code, plus an optional description identifier (say, 'alt').
35 */
36 public enum DescriptionIdGenerator implements IdGenerator {
37
38 INSTANCE;
39
40 public static final String DESCRIPTION_SEPARATOR = ".";
41
42 private static final Joiner idJoiner = Joiner
43 .on(IdGeneratorUtils.HIERARCHY_SEPARATOR).skipNulls();
44
45 public static final Joiner descriptionJoiner = Joiner.on(DESCRIPTION_SEPARATOR);
46
47 public ListMultimap<String,String> handleIdCollision(Collection<String> scopeIds, Bundle bundle) {
48 return IdGeneratorUtils.handleIdCollision(scopeIds, LANGUAGE_OF_DESCRIPTION,
49 getIdBase(bundle));
50 }
51
52 /**
53 * Use an array of scope IDs and the bundle data to generate a unique
54 * id within a given scope.
55 *
56 * @param scopeIds An array of scope ids
57 * @param bundle The bundle
58 * @return The calculated identifier
59 */
60 public String generateId(Collection<String> scopeIds, Bundle bundle) {
61 return descriptionJoiner.join(IdGeneratorUtils.joinPath(scopeIds), getIdBase(bundle));
62 }
63
64 /**
65 * Return the base data for the id, sans scoping.
66 * If the bundle contains a language of description, it comes first.
67 * If the bundle has a non-empty identifier, it is used too.
68 * @param bundle The entity's bundle.
69 * @return The base id string, consisting of language code and/or identifier.
70 */
71 public String getIdBase(Bundle bundle) {
72 String lang = bundle.getDataValue(LANGUAGE_OF_DESCRIPTION);
73 String ident = bundle.getDataValue(IDENTIFIER_KEY);
74 String identSlug = ident != null
75 ? Slugify.slugify(ident, IdGeneratorUtils.SLUG_REPLACE)
76 : null;
77 if (identSlug != null && identSlug.trim().isEmpty()) {
78 identSlug = null;
79 }
80 return idJoiner.join(lang, identSlug);
81 }
82 }