View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.datamodel.metadata;
20  
21  import java.util.ArrayList;
22  import java.util.Comparator;
23  import java.util.List;
24  import java.util.Objects;
25  import java.util.stream.Collectors;
26  import java.util.stream.Stream;
27  
28  import org.jdom2.Content;
29  import org.jdom2.Element;
30  import org.mycore.common.MCRException;
31  import org.mycore.common.xml.MCRXMLHelper;
32  import org.mycore.datamodel.classifications2.MCRCategoryID;
33  
34  import com.fasterxml.jackson.annotation.JsonClassDescription;
35  import com.fasterxml.jackson.annotation.JsonIgnore;
36  import com.google.gson.JsonArray;
37  import com.google.gson.JsonObject;
38  
39  /**
40   * A Link to a {@link MCRDerivate}. In addition to {@link MCRMetaLink} this class contains information about the
41   * linked {@link MCRBase} like mainDoc, titles and classifications in {@link MCRDerivate}.
42   * See also {@link MCREditableMetaEnrichedLinkID}
43   */
44  @JsonClassDescription("Links to derivates")
45  public class MCRMetaEnrichedLinkID extends MCRMetaLinkID {
46  
47      protected static final String ORDER_ELEMENT_NAME = "order";
48  
49      protected static final String MAIN_DOC_ELEMENT_NAME = "maindoc";
50  
51      protected static final String CLASSIFICATION_ELEMENT_NAME = "classification";
52  
53      protected static final String CLASSID_ATTRIBUTE_NAME = "classid";
54  
55      protected static final String CATEGID_ATTRIBUTE_NAME = "categid";
56  
57      protected static final String TITLE_ELEMENT_NAME = "title";
58  
59      protected static final String LANG_ATTRIBUTE_NAME = "lang";
60  
61      private static final List<String> ORDER = List.of(ORDER_ELEMENT_NAME, MAIN_DOC_ELEMENT_NAME, TITLE_ELEMENT_NAME,
62          CLASSIFICATION_ELEMENT_NAME);
63  
64      private List<Content> contentList;
65  
66      public MCRMetaEnrichedLinkID() {
67          setContentList(new ArrayList<>());
68      }
69  
70      public static MCRMetaEnrichedLinkID fromDom(Element element) {
71          final MCRMetaEnrichedLinkID mcrMetaEnrichedLinkID = new MCRMetaEnrichedLinkID();
72          mcrMetaEnrichedLinkID.setFromDOM(element);
73          return mcrMetaEnrichedLinkID;
74      }
75  
76      private static int getElementPosition(Element e) {
77          final int index = ORDER.indexOf(e.getName());
78          return index < 0 ? ORDER.size() : index;
79      }
80  
81      @Override
82      public void setFromDOM(Element element) {
83          super.setFromDOM(element);
84  
85          contentList = element.getContent().stream().map(Content::clone).collect(Collectors.toList());
86      }
87  
88      @Override
89      public Element createXML() throws MCRException {
90          final Element xml = super.createXML();
91  
92          contentList.stream().map(Content::clone).forEach(xml::addContent);
93  
94          xml.sortChildren(
95              Comparator.comparingInt(MCRMetaEnrichedLinkID::getElementPosition)
96                  .thenComparing(contentList::indexOf));
97  
98          return xml;
99      }
100 
101     @JsonIgnore
102     public List<Content> getContentList() {
103         return contentList;
104     }
105 
106     public void setContentList(List<Content> contentList) {
107         this.contentList = Objects.requireNonNull(contentList);
108     }
109 
110     public int getOrder() {
111         return elementsWithNameFromContentList(ORDER_ELEMENT_NAME)
112             .findFirst()
113             .map(Element::getTextNormalize)
114             .map(Integer::valueOf)
115             .orElse(1);
116     }
117 
118     public String getMainDoc() {
119         return elementsWithNameFromContentList(MAIN_DOC_ELEMENT_NAME)
120             .findFirst()
121             .map(Element::getTextTrim)
122             .orElse(null);
123     }
124 
125     public List<MCRCategoryID> getClassifications() {
126         return elementsWithNameFromContentList(CLASSIFICATION_ELEMENT_NAME)
127             .map(el -> new MCRCategoryID(el.getAttributeValue(CLASSID_ATTRIBUTE_NAME),
128                 el.getAttributeValue(CATEGID_ATTRIBUTE_NAME)))
129             .collect(Collectors.toList());
130     }
131 
132     public List<MCRMetaLangText> getTitle() {
133         return elementsWithNameFromContentList(TITLE_ELEMENT_NAME)
134             .map(el -> {
135                 MCRMetaLangText mlt = new MCRMetaLangText();
136                 mlt.setFromDOM(el);
137                 return mlt;
138             })
139             .collect(Collectors.toList());
140     }
141 
142     protected Stream<Element> elementsWithNameFromContentList(String name) {
143         return getContentList().stream()
144             .filter(Element.class::isInstance)
145             .map(Element.class::cast)
146             .filter(el -> el.getName().equals(name));
147     }
148 
149     @Override
150     public JsonObject createJSON() {
151         final JsonObject json = super.createJSON();
152         json.addProperty(ORDER_ELEMENT_NAME, getOrder());
153         json.addProperty(MAIN_DOC_ELEMENT_NAME, getMainDoc());
154         final List<MCRMetaLangText> title = getTitle();
155         JsonArray titles = new JsonArray(title.size());
156         title.stream().forEach(t -> titles.add(t.createJSON()));
157         json.add("titles", titles);
158         final List<MCRCategoryID> categories = getClassifications();
159         JsonArray classifications = new JsonArray(categories.size());
160         categories.stream().map(MCRCategoryID::toString).forEach(classifications::add);
161         json.add("classifications", classifications);
162         return json;
163     }
164 
165     @Override
166     public boolean equals(Object o) {
167         if (!super.equals(o)) {
168             return false;
169         }
170 
171         MCRMetaEnrichedLinkID that = (MCRMetaEnrichedLinkID) o;
172         final List<Content> myContentList = getContentList();
173         final List<Content> theirContentList = that.getContentList();
174         final int listSize = myContentList.size();
175         if (listSize != theirContentList.size()) {
176             return false;
177         }
178         for (int i = 0; i < listSize; i++) {
179             Content myContent = myContentList.get(i);
180             Content theirContent = theirContentList.get(i);
181             if (!myContent.equals(theirContent) || (myContent instanceof Element && theirContent instanceof Element
182                 && !MCRXMLHelper.deepEqual((Element) myContent, (Element) theirContent))) {
183                 return false;
184             }
185         }
186         return true;
187     }
188 
189     @Override
190     public int hashCode() {
191         return Objects.hash(super.hashCode(), getContentList());
192     }
193 }