2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.api
.service
.geo
;
11 import static org
.junit
.Assert
.assertTrue
;
13 import java
.awt
.Color
;
14 import java
.io
.FileNotFoundException
;
15 import java
.io
.IOException
;
16 import java
.io
.InputStream
;
17 import java
.io
.InputStreamReader
;
18 import java
.net
.HttpURLConnection
;
19 import java
.net
.MalformedURLException
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Collection
;
23 import java
.util
.HashMap
;
24 import java
.util
.HashSet
;
25 import java
.util
.List
;
28 import java
.util
.UUID
;
30 import org
.apache
.commons
.lang3
.StringUtils
;
31 import org
.apache
.http
.client
.ClientProtocolException
;
32 import org
.apache
.logging
.log4j
.LogManager
;
33 import org
.apache
.logging
.log4j
.Logger
;
34 import org
.junit
.Assert
;
35 import org
.junit
.Before
;
36 import org
.junit
.Test
;
37 import org
.unitils
.dbunit
.annotation
.DataSet
;
38 import org
.unitils
.spring
.annotation
.SpringBeanByType
;
40 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
41 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
43 import eu
.etaxonomy
.cdm
.common
.StreamUtils
;
44 import eu
.etaxonomy
.cdm
.common
.URI
;
45 import eu
.etaxonomy
.cdm
.common
.UriUtils
;
46 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
47 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
48 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
49 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
50 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
51 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
52 import eu
.etaxonomy
.cdm
.model
.description
.PresenceAbsenceTerm
;
53 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
54 import eu
.etaxonomy
.cdm
.model
.location
.Country
;
55 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
56 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
57 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaType
;
58 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
59 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTermBase
;
60 import eu
.etaxonomy
.cdm
.model
.term
.TermTree
;
61 import eu
.etaxonomy
.cdm
.model
.term
.TermType
;
62 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
63 import eu
.etaxonomy
.cdm
.test
.integration
.CdmTransactionalIntegrationTest
;
69 public class DistributionServiceImplTest
extends CdmTransactionalIntegrationTest
{
71 private static final Logger logger
= LogManager
.getLogger();
73 private static final String EDIT_MAPSERVICE_URI_STRING
= "https://edit.africamuseum.be/edit_wp5/v1.2/rest_gen.php";
74 private static URI editMapServiceUri
;
77 private ITermService termService
;
80 private IVocabularyService vocabService
;
83 private GeoServiceAreaAnnotatedMapping mapping
;
86 private IDistributionService distributionService
;
89 private ITaxonService taxonService
;
92 public void setUp() throws Exception
{
93 System
.setProperty("ONLY-A-TEST", "TRUE"); // allows EditGeoServiceUtilities to skip some line of code
94 editMapServiceUri
= new URI(EDIT_MAPSERVICE_URI_STRING
);
97 //******************************************** TESTS**************
100 public void testGetWebServiceUrlCountry() {
101 Set
<Distribution
> distributions
= new HashSet
<>();
102 Country germany
= termService
.findByIdInVocabulary("DEU", Country
.uuidCountryVocabulary
, Country
.class);
104 distributions
.add(Distribution
.NewInstance(germany
, PresenceAbsenceTerm
.PRESENT()));
105 distributions
.add(Distribution
.NewInstance(termService
.findByIdInVocabulary("DE", Country
.uuidCountryVocabulary
, Country
.class), PresenceAbsenceTerm
.INTRODUCED()));
106 Map
<PresenceAbsenceTerm
, Color
> presenceAbsenceColorMap
= new HashMap
<>();
107 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.PRESENT(), Color
.BLUE
);
108 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.INTRODUCED(), Color
.BLACK
);
109 List
<Language
> languages
= new ArrayList
<>();
111 boolean subAreaPreference
= false;
112 boolean statusOrderPreference
= false;
113 TermTree
<NamedArea
> areaTree
= null;
114 TermTree
<PresenceAbsenceTerm
> statusTree
= null;
115 Set
<MarkerType
> fallbackAreaMarkerTypes
= null;
117 Collection
<Distribution
> filteredDistributions
= DistributionServiceUtilities
.filterDistributions(
118 distributions
, areaTree
, statusTree
, fallbackAreaMarkerTypes
, false,
119 statusOrderPreference
, subAreaPreference
, true);
121 String result
= DistributionServiceUtilities
.getDistributionServiceRequestParameterString(filteredDistributions
,
122 mapping
, null, null, languages
);
124 Assert
.assertTrue("WebServiceUrl must contain country part for Germany", result
.matches(".*ad=country_earth(%3A|:)gmi_cntry:.:DEU.*"));
128 public void testGetWebServiceUrlTdwg() throws MalformedURLException
, IOException
{
129 //String webServiceUrl = "http://www.test.de/webservice";
130 Set
<Distribution
> distributions
= new HashSet
<>();
131 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("SPA"), PresenceAbsenceTerm
.PRESENT()));
132 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("GER"), PresenceAbsenceTerm
.INTRODUCED()));
133 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("14"), PresenceAbsenceTerm
.CULTIVATED()));
134 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("BGM"), PresenceAbsenceTerm
.ABSENT()));
135 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("FRA"), PresenceAbsenceTerm
.ABSENT()));
136 distributions
.add(Distribution
.NewInstance(termService
.getAreaByTdwgAbbreviation("IND-AP"), PresenceAbsenceTerm
.PRESENT()));
138 Map
<PresenceAbsenceTerm
, Color
> presenceAbsenceColorMap
= new HashMap
<>();
139 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.PRESENT(), Color
.BLUE
);
140 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.INTRODUCED(), Color
.BLACK
);
141 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.CULTIVATED(), Color
.YELLOW
);
142 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.ABSENT(), Color
.DARK_GRAY
);
143 // String backLayer ="";
144 presenceAbsenceColorMap
= null;
145 // String bbox="-20,0,120,70";
146 List
<Language
> languages
= new ArrayList
<>();
148 // boolean subAreaPreference = false;
149 // boolean statusOrderPreference = false;
150 String result
= DistributionServiceUtilities
.getDistributionServiceRequestParameterString(
153 null, // presenceAbsenceTermColors
154 null, // projectToLayer
156 //TODO Set semantics is not determined
157 //String expected = "http://www.test.de/webservice?l=tdwg3&ad=tdwg3:a:GER|b:OKL|c:BGM|b:SPA|d:FRA&as=a:005500|b:00FF00|c:FFFFFF|d:001100&bbox=-20,40,40,40&ms=400x300";
158 logger
.debug(result
);
159 assertTrue(result
.matches(".*ad=tdwg[1-4].*"));
160 assertTrue(result
.matches(".*tdwg2:[a-d]:14[\\|&].*") );
161 assertTrue(result
.matches(".*[a-d]:FRA,BGM[\\|&].*") || result
.matches(".*[a-d]:BGM,FRA[\\|&].*") );
162 assertTrue(result
.matches(".*[a-d]:GER[\\|&].*") );
163 assertTrue(result
.matches(".*[a-d]:SPA[\\|&].*") );
164 assertTrue(result
.matches(".*tdwg4:[a-d]:INDAP[\\|&].*") );
165 //assertTrue(result.matches("0000ff"));
168 // request map image from webservice
169 subTestWithEditMapService(result
);
173 public void testGetWebServiceUrlCyprus() throws ClientProtocolException
, IOException
{
175 Set
<Distribution
> distributions
= new HashSet
<>();
176 distributions
.add(Distribution
.NewInstance(divisions
.get("1"), PresenceAbsenceTerm
.PRESENT()));
177 distributions
.add(Distribution
.NewInstance(divisions
.get("2"), PresenceAbsenceTerm
.INTRODUCED()));
178 distributions
.add(Distribution
.NewInstance(divisions
.get("3"), PresenceAbsenceTerm
.CULTIVATED()));
179 distributions
.add(Distribution
.NewInstance(divisions
.get("4"), PresenceAbsenceTerm
.ABSENT()));
180 distributions
.add(Distribution
.NewInstance(divisions
.get("5"), PresenceAbsenceTerm
.ABSENT()));
181 distributions
.add(Distribution
.NewInstance(divisions
.get("6"), PresenceAbsenceTerm
.PRESENT()));
183 Map
<PresenceAbsenceTerm
, Color
> presenceAbsenceColorMap
= new HashMap
<>();
184 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.PRESENT(), Color
.BLUE
);
185 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.INTRODUCED(), Color
.BLACK
);
186 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.CULTIVATED(), Color
.YELLOW
);
187 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.ABSENT(), Color
.DARK_GRAY
);
188 presenceAbsenceColorMap
= null;
189 List
<Language
> languages
= new ArrayList
<>();
191 String result
= DistributionServiceUtilities
.getDistributionServiceRequestParameterString(
194 null, null, languages
);
195 //TODO Set semantics is not determined
196 //String expected = "http://www.test.de/webservice?l=tdwg3&ad=tdwg3:a:GER|b:OKL|c:BGM|b:SPA|d:FRA&as=a:005500|b:00FF00|c:FFFFFF|d:001100&bbox=-20,40,40,40&ms=400x300";
197 assertTrue(result
.matches(".*ad=cyprusdivs%3Abdcode:.*"));
198 assertTrue(result
.matches(".*[a-d]:5,4[\\|&].*") || result
.matches(".*[a-d]:4,5[\\|&].*") );
199 assertTrue(result
.matches(".*[a-d]:1,6[\\|&].*") || result
.matches(".*[a-d]:6,1[\\|&].*") );
200 assertTrue(result
.matches(".*[a-d]:2[\\|&].*") );
201 assertTrue(result
.matches(".*[a-d]:3[\\|&].*") );
203 // request map image from webservice
204 subTestWithEditMapService(result
);
207 private void subTestWithEditMapService(String queryString
)throws MalformedURLException
, IOException
{
208 if(UriUtils
.isServiceAvailable(editMapServiceUri
)){
209 URL requestUrl
= new URL(editMapServiceUri
.toString() + "?img=false&bbox=-180,-90,180,90&ms=1000&" + queryString
);
210 logger
.debug("editMapServiceUri: " + requestUrl
);
211 HttpURLConnection connection
= (HttpURLConnection
) requestUrl
.openConnection();
212 connection
.connect();
213 // connection.setReadTimeout(10000); //timeout after 10 sec, does not seem to work
214 assertTrue(connection
.getResponseCode() == 200);
215 InputStream contentStream
= connection
.getInputStream();
216 String content
= StreamUtils
.readToString(contentStream
);
217 logger
.debug("EditMapService response body:\n" + content
);
218 assertTrue(content
.startsWith("[{"));
219 assertTrue(content
.endsWith("}]"));
220 assertTrue(content
.matches(".*\"bbox\":.*"));
221 assertTrue(content
.matches(".*\"legend\":.*"));
222 assertTrue(content
.matches(".*\"layers\":.*"));
223 assertTrue(content
.matches(".*\"sld\":.*"));
224 assertTrue(content
.matches(".*\"geoserver\":.*"));
228 public static final UUID uuidCyprusDivisionsVocabulary
= UUID
.fromString("2119f610-1f93-4d87-af28-40aeefaca100");
229 private final Map
<String
, NamedArea
> divisions
= new HashMap
<>();
231 private boolean makeCyprusAreas() throws IOException
{
234 NamedAreaType areaType
= NamedAreaType
.NATURAL_AREA();
235 NamedAreaLevel areaLevel
= NamedAreaLevel
.NewInstance("Cyprus Division", "Cyprus Division", null);
237 termService
.saveOrUpdate(areaLevel
);
239 TermVocabulary
<NamedArea
> areaVocabulary
= TermVocabulary
.NewInstance(TermType
.NamedArea
,
240 NamedArea
.class, "Cyprus devisions", "Cyprus divisions", null, null);
241 areaVocabulary
.setUuid(uuidCyprusDivisionsVocabulary
);
243 for(int i
= 1; i
<= 8; i
++){
244 UUID divisionUuid
= getNamedAreaUuid(String
.valueOf(i
));
245 NamedArea division
= this.newNamedArea(
248 "Cyprus: Division " + i
,
249 String
.valueOf(i
), // id in vocab
253 divisions
.put(String
.valueOf(i
), division
);
256 vocabService
.saveOrUpdate(areaVocabulary
);
257 commitAndStartNewTransaction(null);
259 // import and map shapefile attributes from csv
260 InputStream is
= getClass().getClassLoader().getResourceAsStream("eu/etaxonomy/cdm/api/service/geo/cyprusdivs.csv");
261 List
<String
> idSearchFields
= new ArrayList
<String
>();
262 idSearchFields
.add("bdcode");
263 String wmsLayerName
= "cyprusdivs";
264 distributionService
.mapShapeFileToNamedAreas(new InputStreamReader(is
), idSearchFields
, wmsLayerName
, uuidCyprusDivisionsVocabulary
, null);
267 @SuppressWarnings("unchecked")
268 Set
<DefinedTermBase
> terms
= vocabService
.load(uuidCyprusDivisionsVocabulary
).getTerms();
269 for(DefinedTermBase
<?
> dtb
: terms
){
270 divisions
.put(dtb
.getIdInVocabulary(), (NamedArea
) dtb
);
273 // indigenousStatus = (PresenceTerm)getTermService().find(CyprusTransformer.indigenousUuid);
274 // casualStatus = (PresenceTerm)getTermService().find(CyprusTransformer.casualUuid);
275 // nonInvasiveStatus = (PresenceTerm)getTermService().find(CyprusTransformer.nonInvasiveUuid);
276 // invasiveStatus = (PresenceTerm)getTermService().find(CyprusTransformer.invasiveUuid);
277 // questionableStatus = (PresenceTerm)getTermService().find(CyprusTransformer.questionableUuid);
282 public static final UUID uuidDivision1
= UUID
.fromString("ab17eee9-1abb-4ce9-a9a2-563f840cdbfc");
283 public static final UUID uuidDivision2
= UUID
.fromString("c3606165-efb7-4224-a168-63e009eb4aa5");
284 public static final UUID uuidDivision3
= UUID
.fromString("750d4e07-e34b-491f-a7b7-09723afdc960");
285 public static final UUID uuidDivision4
= UUID
.fromString("8a858922-e8e5-4791-ad53-906e50633ec7");
286 public static final UUID uuidDivision5
= UUID
.fromString("16057133-d541-4ebd-81d4-cb92265ec54c");
287 public static final UUID uuidDivision6
= UUID
.fromString("fbf21230-4a42-4f4c-9af8-5da52123c264");
288 public static final UUID uuidDivision7
= UUID
.fromString("d31dd96a-36ea-4428-871c-d8552a9565ca");
289 public static final UUID uuidDivision8
= UUID
.fromString("236ea447-c3ab-486d-9e06-cc5907861acc");
291 public UUID
getNamedAreaUuid(String key
) {
292 if (StringUtils
.isBlank(key
)){return null;
293 }else if (key
.equalsIgnoreCase("1")){return uuidDivision1
;
294 }else if (key
.equalsIgnoreCase("2")){return uuidDivision2
;
295 }else if (key
.equalsIgnoreCase("3")){return uuidDivision3
;
296 }else if (key
.equalsIgnoreCase("4")){return uuidDivision4
;
297 }else if (key
.equalsIgnoreCase("5")){return uuidDivision5
;
298 }else if (key
.equalsIgnoreCase("6")){return uuidDivision6
;
299 }else if (key
.equalsIgnoreCase("7")){return uuidDivision7
;
300 }else if (key
.equalsIgnoreCase("8")){return uuidDivision8
;
306 protected NamedArea
newNamedArea(UUID uuid
, String label
, String text
, String IdInVocabulary
, NamedAreaType areaType
, NamedAreaLevel level
, TermVocabulary
<NamedArea
> voc
){
307 NamedArea namedArea
= NamedArea
.NewInstance(text
, label
, null);
308 voc
.addTerm(namedArea
);
309 namedArea
.setType(areaType
);
310 namedArea
.setLevel(level
);
311 namedArea
.setUuid(uuid
);
312 namedArea
.setIdInVocabulary(IdInVocabulary
);
317 public void testGetWebServiceUrlBangka() throws ClientProtocolException
, IOException
{
318 NamedArea areaBangka
= NamedArea
.NewInstance("Bangka", "Bangka", null);
319 TermVocabulary
<NamedArea
> voc
= TermVocabulary
.NewInstance(TermType
.NamedArea
,
320 NamedArea
.class, "test Voc", "test voc", null, null);
321 voc
.addTerm(areaBangka
);
323 GeoServiceArea geoServiceArea
= new GeoServiceArea();
324 String geoServiceLayer
="vmap0_as_bnd_political_boundary_a";
325 String layerFieldName
="nam";
326 String areaValue
= "PULAU BANGKA#SUMATERA SELATAN";
327 geoServiceArea
.add(geoServiceLayer
, layerFieldName
, areaValue
);
328 geoServiceArea
.add(geoServiceLayer
, layerFieldName
, "BALI");
330 mapping
.set(areaBangka
, geoServiceArea
);
331 Set
<Distribution
> distributions
= new HashSet
<>();
332 distributions
.add(Distribution
.NewInstance(areaBangka
, PresenceAbsenceTerm
.PRESENT()));
334 Map
<PresenceAbsenceTerm
, Color
> presenceAbsenceColorMap
= new HashMap
<>();
335 presenceAbsenceColorMap
.put(PresenceAbsenceTerm
.PRESENT(), Color
.BLUE
);
337 presenceAbsenceColorMap
= null;
338 List
<Language
> languages
= new ArrayList
<>();
340 String result
= DistributionServiceUtilities
.getDistributionServiceRequestParameterString(distributions
,
342 null, null, languages
);
343 //TODO Set semantics is not determined
344 //String expected = "http://www.test.de/webservice?l=tdwg3&ad=tdwg3:a:GER|b:OKL|c:BGM|b:SPA|d:FRA&as=a:005500|b:00FF00|c:FFFFFF|d:001100&bbox=-20,40,40,40&ms=400x300";
346 logger
.debug(result
);
347 assertTrue(result
.matches(".*ad=vmap0_as_bnd_political_boundary_a%3Anam:.*"));
348 assertTrue(result
.matches(".*(PULAU\\+BANGKA%23SUMATERA\\+SELATAN).*") );
349 assertTrue(result
.matches(".*(BALI).*") );
351 // request map image from webservice
352 subTestWithEditMapService(result
);
356 @DataSet( value
="EditGeoServiceTest.getDistributionServiceRequestParameterString.xml")
358 // @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
359 // @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
360 // @DataSet( value="EditGeoServiceTest.getDistributionServiceRequestParameterString.xml")
362 public void getDistributionServiceRequestParameterString(){
363 boolean subAreaPreference
= false;
364 boolean statusOrderPreference
= false;
365 Set
<MarkerType
> hideMarkedAreas
= null;
366 Map
<PresenceAbsenceTerm
, Color
> presenceAbsenceTermColors
= null;
367 List
<Language
> langs
= null;
369 List
<TaxonDescription
> taxonDescriptions
= new ArrayList
<>();
370 TaxonDescription description1
= TaxonDescription
.NewInstance();
371 taxonDescriptions
.add(description1
);
372 Distribution distribution1
= Distribution
.NewInstance(Country
.GERMANY(), null);
373 description1
.addElement(distribution1
);
374 Distribution distribution2
= Distribution
.NewInstance(Country
.FRANCE(), null);
375 distribution2
.setFeature(Feature
.COMMON_NAME());
376 description1
.addElement(distribution2
);
378 Taxon taxon
= (Taxon
)taxonService
.find(UUID
.fromString("7598f5d4-1cf2-4269-ae99-2adb79ae167c"));
379 TaxonDescription taxDesc
= taxon
.getDescriptions().iterator().next();
380 for (DescriptionElementBase deb
: taxDesc
.getElements()){
381 Distribution distribution
= CdmBase
.deproxy(deb
, Distribution
.class);
382 NamedArea area
= distribution
.getArea();
383 System
.out
.println(area
.getTitleCache());
385 taxonDescriptions
.addAll(taxon
.getDescriptions());
387 String distributions
= distributionService
.getDistributionServiceRequestParameterString(taxonDescriptions
,
388 subAreaPreference
, statusOrderPreference
, hideMarkedAreas
, presenceAbsenceTermColors
, langs
);
389 // System.out.println(distributions);
390 Assert
.assertTrue("Distribution string should contain the non-persisted distribution Germany", distributions
.contains("DEU"));
391 Assert
.assertFalse("Distribution string should contain France as it has a non-distribution feature", distributions
.contains("FRA"));
397 public void createTestDataSet() throws FileNotFoundException
{
399 List
<TaxonDescription
> taxonDescriptions
= new ArrayList
<>();
400 TaxonDescription description1
= TaxonDescription
.NewInstance();
401 taxonDescriptions
.add(description1
);
402 Distribution distribution1
= Distribution
.NewInstance(Country
.POLANDPOLISHPEOPLESREPUBLIC(), null);
403 description1
.addElement(distribution1
);
404 Distribution distribution2
= Distribution
.NewInstance(Country
.SWITZERLANDSWISSCONFEDERATION(), null);
405 // distribution2.setFeature(Feature.COMMON_NAME());
406 description1
.addElement(distribution2
);
407 Taxon taxon
= Taxon
.NewInstance(null, null);
408 taxon
.setTitleCache("Dummy taxon", true);
409 taxon
.addDescription(description1
);
410 taxon
.setUuid(UUID
.fromString("7598f5d4-1cf2-4269-ae99-2adb79ae167c"));
412 taxonService
.save(taxon
);
417 writeDbUnitDataSetFile(new String
[] {
419 "DESCRIPTIONBASE", "DESCRIPTIONELEMENTBASE",
420 "HIBERNATE_SEQUENCES" // IMPORTANT!!!
422 "getDistributionServiceRequestParameterString", true );