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.math.BigDecimal;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  import java.util.Locale;
26  import java.util.stream.Collectors;
27  
28  import org.jdom2.Element;
29  import org.mycore.common.MCRException;
30  
31  import com.google.gson.JsonArray;
32  import com.google.gson.JsonObject;
33  
34  /**
35   * Stores spatial information for geographic references. The latitude longitude values are stored in an array list,
36   * where two BigDecimal build a point.
37   *
38   * @author Matthias Eichner
39   * @author Jens Kupferschmidt
40   */
41  public class MCRMetaSpatial extends MCRMetaDefault {
42  
43      private List<BigDecimal> data;
44  
45      /**
46       * initializes with empty values.
47       */
48      public MCRMetaSpatial() {
49          super();
50          this.data = new ArrayList<>();
51      }
52  
53      @Deprecated
54      public MCRMetaSpatial(String subtag, String defaultLanguage, String type, Integer inherited) throws MCRException {
55          super(subtag, defaultLanguage, type, inherited);
56          this.data = new ArrayList<>();
57      }
58  
59      /**
60       * The constructor for a MCRMetaSpatial instance with an empty data container.
61       * @param subtag the name of the subtag
62       * @param type an optional type or an empty string
63       * @param inherited a value &gt;= 0
64       * 
65       * @throws MCRException if the set_subtag value is null or empty
66       */
67      public MCRMetaSpatial(String subtag, String type, Integer inherited) throws MCRException {
68          super(subtag, null, type, inherited);
69          this.data = new ArrayList<>();
70      }
71  
72      /**
73       * Returns the spatial data. Two entries build a point. The first is always the latitude and the second one
74       * is always the longitude value.
75       *
76       * @return list of the spatial data
77       */
78      public List<BigDecimal> getData() {
79          return this.data;
80      }
81  
82      public void setData(List<BigDecimal> data) {
83          this.data = data;
84      }
85  
86      /**
87       * Adds a new point to the data.
88       *
89       * @param lat the latitude value
90       * @param lng the longitude value
91       */
92      public void add(BigDecimal lat, BigDecimal lng) {
93          this.data.add(lat);
94          this.data.add(lng);
95      }
96  
97      @Override
98      public void setFromDOM(Element element) throws MCRException {
99          super.setFromDOM(element);
100         String textData = element.getText();
101         String[] splitData = textData.split(",");
102         if (splitData.length % 2 != 0) {
103             throw new MCRException(String.format(Locale.ROOT,
104                 "Unable to parse MCRMetaSpatial cause text data '%s' contains invalid content", textData));
105         }
106         try {
107             Arrays.stream(splitData).map(BigDecimal::new).forEach(this.data::add);
108         } catch (NumberFormatException nfe) {
109             throw new MCRException(String.format(Locale.ROOT,
110                 "Unable to parse MCRMetaSpatial cause text data '%s' contains invalid content", textData), nfe);
111         }
112     }
113 
114     @Override
115     public Element createXML() throws MCRException {
116         Element element = super.createXML();
117         return element.setText(this.data.stream().map(BigDecimal::toPlainString).collect(Collectors.joining(",")));
118     }
119 
120     /**
121      * Creates the JSON representation. Extends the {@link MCRMetaDefault#createJSON()} method
122      * with the following data.
123      *
124      * <pre>
125      *   {
126      *     data: [50.92878, 11.5899]
127      *   }
128      * </pre>
129      *
130      */
131     @Override
132     public JsonObject createJSON() {
133         JsonObject json = super.createJSON();
134         JsonArray dataArray = new JsonArray();
135         this.data.forEach(dataArray::add);
136         json.add("data", dataArray);
137         return json;
138     }
139 
140     @Override
141     public void validate() throws MCRException {
142         super.validate();
143         if (this.data.isEmpty()) {
144             throw new MCRException("spatial list should contain content");
145         }
146         if (this.data.size() % 2 != 0) {
147             throw new MCRException(
148                 String.format(Locale.ROOT, "spatial list content '%s' is uneven", this.data.toString()));
149         }
150     }
151 
152     /**
153      * clone of this instance
154      * 
155      * you will get a (deep) clone of this element
156      * 
157      * @see java.lang.Object#clone()
158      */
159     @Override
160     public MCRMetaSpatial clone() {
161         MCRMetaSpatial clone = (MCRMetaSpatial) super.clone();
162 
163         clone.data = new ArrayList<>(this.data); // Big Integer is immutable
164 
165         return clone;
166     }
167 
168 }