1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.datamodel.classifications2.impl;
20
21 import java.net.URI;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Locale;
26 import java.util.Optional;
27 import java.util.SortedSet;
28 import java.util.TreeSet;
29 import java.util.stream.Collectors;
30
31 import org.mycore.common.MCRConstants;
32 import org.mycore.common.MCRSessionMgr;
33 import org.mycore.common.config.MCRConfiguration2;
34 import org.mycore.datamodel.classifications2.MCRCategory;
35 import org.mycore.datamodel.classifications2.MCRCategoryDAOFactory;
36 import org.mycore.datamodel.classifications2.MCRCategoryID;
37 import org.mycore.datamodel.classifications2.MCRLabel;
38 import org.mycore.util.concurrent.MCRReadWriteGuard;
39
40
41
42
43
44
45
46 public abstract class MCRAbstractCategoryImpl implements MCRCategory {
47
48 protected final MCRReadWriteGuard childGuard = new MCRReadWriteGuard();
49
50 protected MCRCategory root;
51
52 protected MCRCategory parent;
53
54 protected SortedSet<MCRLabel> labels;
55
56 protected List<MCRCategory> children;
57
58 private MCRCategoryID id;
59
60 private URI uri;
61
62 private String defaultLang;
63
64 private static HashSet<String> LANGUAGES;
65
66 static {
67 LANGUAGES = new HashSet<>(MCRConfiguration2.getString("MCR.Metadata.Languages")
68 .map(MCRConfiguration2::splitValue)
69 .map(s -> s.collect(Collectors.toList()))
70 .orElseGet(Collections::emptyList));
71 }
72
73 public MCRAbstractCategoryImpl() {
74 super();
75 if (defaultLang == null) {
76 defaultLang = MCRConfiguration2.getString("MCR.Metadata.DefaultLang").orElse(MCRConstants.DEFAULT_LANG);
77 }
78 labels = new TreeSet<>();
79 }
80
81 public List<MCRCategory> getChildren() {
82 return childGuard.lazyLoad(this::childrenNotHere, this::initChildren, () -> children);
83 }
84
85 private boolean childrenNotHere() {
86 return children == null;
87 }
88
89 private void initChildren() {
90 setChildrenUnlocked(MCRCategoryDAOFactory.getInstance().getChildren(id));
91 }
92
93 protected abstract void setChildrenUnlocked(List<MCRCategory> children);
94
95 public MCRCategoryID getId() {
96 return id;
97 }
98
99 public void setId(MCRCategoryID id) {
100 this.id = id;
101 }
102
103 public SortedSet<MCRLabel> getLabels() {
104 return labels;
105 }
106
107 public MCRCategory getRoot() {
108 if (getId().isRootID()) {
109 return this;
110 }
111 if (root == null && getParent() != null) {
112 root = getParent().getRoot();
113 }
114 return root;
115 }
116
117 public URI getURI() {
118 return uri;
119 }
120
121 public void setURI(URI uri) {
122 this.uri = uri;
123 }
124
125 public boolean hasChildren() {
126 return childGuard
127 .read(() -> Optional.ofNullable(children).map(c -> !c.isEmpty()))
128 .orElse(MCRCategoryDAOFactory.getInstance().hasChildren(id));
129 }
130
131 public final boolean isCategory() {
132 return !isClassification();
133 }
134
135 public final boolean isClassification() {
136 return getId().isRootID();
137 }
138
139 public MCRCategory getParent() {
140 return parent;
141 }
142
143 public void setParent(MCRCategory parent) {
144 if (this.parent == parent) {
145 return;
146 }
147 detachFromParent();
148 this.parent = parent;
149 if (parent != null) {
150 parent.getChildren().add(this);
151 }
152 }
153
154
155
156
157 void detachFromParent() {
158 if (parent != null) {
159
160 parent.getChildren().remove(this);
161 parent = null;
162 }
163 }
164
165 public Optional<MCRLabel> getCurrentLabel() {
166 if (labels.isEmpty()) {
167 return Optional.empty();
168 }
169
170 return Optional.of(
171 getLabel(MCRSessionMgr.getCurrentSession().getCurrentLanguage())
172 .orElseGet(() -> getLabel(defaultLang)
173 .orElseGet(() -> labels.stream().filter(l -> LANGUAGES.contains(l.getLang())).findFirst()
174 .orElseGet(() -> labels.stream().filter(l -> !l.getLang().startsWith("x-")).findFirst()
175 .orElseGet(() -> labels.iterator().next())))));
176 }
177
178 public Optional<MCRLabel> getLabel(String lang) {
179 String languageTag = Locale.forLanguageTag(lang).toLanguageTag();
180 for (MCRLabel label : labels) {
181 if (label.getLang().equals(languageTag)) {
182 return Optional.of(label);
183 }
184 }
185 return Optional.empty();
186 }
187
188 public String toString() {
189 return Optional.ofNullable(id).map(MCRCategoryID::toString).orElse(null);
190 }
191 }