Merge branch 'release/5.6.0'
[cdmlib.git] / cdmlib-ext / src / test / java / eu / etaxonomy / cdm / ext / geo / EditGeoServiceTest.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.cdm.ext.geo;
11
12 import static org.junit.Assert.assertTrue;
13
14 import java.awt.Color;
15 import java.io.FileNotFoundException;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
19 import java.net.HttpURLConnection;
20 import java.net.MalformedURLException;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.UUID;
32
33 import org.apache.commons.lang.StringUtils;
34 import org.apache.http.client.ClientProtocolException;
35 import org.apache.log4j.Logger;
36 import org.junit.Assert;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.unitils.dbunit.annotation.DataSet;
40 import org.unitils.spring.annotation.SpringBeanByType;
41
42 import eu.etaxonomy.cdm.api.service.ITaxonService;
43 import eu.etaxonomy.cdm.api.service.ITermService;
44 import eu.etaxonomy.cdm.api.service.IVocabularyService;
45 import eu.etaxonomy.cdm.api.utility.DescriptionUtility;
46 import eu.etaxonomy.cdm.common.StreamUtils;
47 import eu.etaxonomy.cdm.common.UriUtils;
48 import eu.etaxonomy.cdm.model.common.CdmBase;
49 import eu.etaxonomy.cdm.model.common.Language;
50 import eu.etaxonomy.cdm.model.common.MarkerType;
51 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
52 import eu.etaxonomy.cdm.model.description.Distribution;
53 import eu.etaxonomy.cdm.model.description.Feature;
54 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
55 import eu.etaxonomy.cdm.model.description.TaxonDescription;
56 import eu.etaxonomy.cdm.model.location.Country;
57 import eu.etaxonomy.cdm.model.location.NamedArea;
58 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
59 import eu.etaxonomy.cdm.model.location.NamedAreaType;
60 import eu.etaxonomy.cdm.model.taxon.Taxon;
61 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
62 import eu.etaxonomy.cdm.model.term.TermType;
63 import eu.etaxonomy.cdm.model.term.TermVocabulary;
64 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
65
66 /**
67 * @author a.mueller
68 * @since 08.10.2008
69 */
70 public class EditGeoServiceTest extends CdmTransactionalIntegrationTest {
71 private static final Logger logger = Logger.getLogger(EditGeoServiceTest.class);
72
73 private static final String EDIT_MAPSERVICE_URI_STING = "http://edit.africamuseum.be/edit_wp5/v1.2/rest_gen.php";
74 private static URI editMapServiceUri;
75
76 @SpringBeanByType
77 private ITermService termService;
78
79 @SpringBeanByType
80 private IVocabularyService vocabService;
81
82 @SpringBeanByType
83 private GeoServiceAreaAnnotatedMapping mapping;
84
85 @SpringBeanByType
86 private IEditGeoService editGeoService;
87
88 @SpringBeanByType
89 private ITaxonService taxonService ;
90
91
92 /**
93 * @throws java.lang.Exception
94 */
95 @Before
96 public void setUp() throws Exception {
97 System.setProperty("ONLY-A-TEST", "TRUE"); // allows EditGeoServiceUtilities to skip some line of code
98 editMapServiceUri = new URI(EDIT_MAPSERVICE_URI_STING);
99 }
100
101
102 //******************************************** TESTS**************
103
104 @Test
105 public void testGetWebServiceUrlCountry() {
106 Set<Distribution> distributions = new HashSet<>();
107 Country germany = termService.findByIdInVocabulary("DEU", Country.uuidCountryVocabulary, Country.class);
108 // germany = (Country)termService.find(665);
109 // germany = (Country)termService.find(UUID.fromString("cbe7ce69-2952-4309-85dd-0d7d4a4830a1"));
110
111 // germany = Country.GERMANY();
112
113 distributions.add(Distribution.NewInstance(germany, PresenceAbsenceTerm.PRESENT()));
114 distributions.add(Distribution.NewInstance(termService.findByIdInVocabulary("DE", Country.uuidCountryVocabulary, Country.class), PresenceAbsenceTerm.INTRODUCED()));
115 Map<PresenceAbsenceTerm, Color> presenceAbsenceColorMap = new HashMap<PresenceAbsenceTerm, Color>();
116 presenceAbsenceColorMap.put(PresenceAbsenceTerm.PRESENT(), Color.BLUE);
117 presenceAbsenceColorMap.put(PresenceAbsenceTerm.INTRODUCED(), Color.BLACK);
118 List<Language> languages = new ArrayList<Language>();
119
120 boolean subAreaPreference = false;
121 boolean statusOrderPreference = false;
122
123
124 Collection<Distribution> filteredDistributions = DescriptionUtility.filterDistributions(
125 distributions, null, true, statusOrderPreference, subAreaPreference);
126
127 String result = EditGeoServiceUtilities.getDistributionServiceRequestParameterString(filteredDistributions,
128 mapping, null, null, languages );
129 logger.warn(result);
130 Assert.assertTrue("WebServiceUrl must contain country part for Germany", result.matches(".*ad=country_earth(%3A|:)gmi_cntry:.:DEU.*"));
131 }
132
133 @Test
134 public void testGetWebServiceUrlTdwg() throws MalformedURLException, IOException {
135 //String webServiceUrl = "http://www.test.de/webservice";
136 Set<Distribution> distributions = new HashSet<Distribution>();
137 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("SPA"), PresenceAbsenceTerm.PRESENT()));
138 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("GER"), PresenceAbsenceTerm.INTRODUCED()));
139 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("14"), PresenceAbsenceTerm.CULTIVATED()));
140 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("BGM"), PresenceAbsenceTerm.ABSENT()));
141 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("FRA"), PresenceAbsenceTerm.ABSENT()));
142 distributions.add(Distribution.NewInstance(termService.getAreaByTdwgAbbreviation("IND-AP"), PresenceAbsenceTerm.PRESENT()));
143
144 Map<PresenceAbsenceTerm, Color> presenceAbsenceColorMap = new HashMap<PresenceAbsenceTerm, Color>();
145 presenceAbsenceColorMap.put(PresenceAbsenceTerm.PRESENT(), Color.BLUE);
146 presenceAbsenceColorMap.put(PresenceAbsenceTerm.INTRODUCED(), Color.BLACK);
147 presenceAbsenceColorMap.put(PresenceAbsenceTerm.CULTIVATED(), Color.YELLOW);
148 presenceAbsenceColorMap.put(PresenceAbsenceTerm.ABSENT(), Color.DARK_GRAY);
149 String backLayer ="";
150 presenceAbsenceColorMap = null;
151 String bbox="-20,0,120,70";
152 List<Language> languages = new ArrayList<Language>();
153
154 boolean subAreaPreference = false;
155 boolean statusOrderPreference = false;
156 String result = EditGeoServiceUtilities.getDistributionServiceRequestParameterString(
157 distributions,
158 mapping,
159 null, // presenceAbsenceTermColors
160 null, // projectToLayer
161 languages );
162 //TODO Set semantics is not determined
163 //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";
164 logger.debug(result);
165 assertTrue(result.matches(".*ad=tdwg[1-4].*"));
166 assertTrue(result.matches(".*tdwg2:[a-d]:14[\\|&].*") );
167 assertTrue(result.matches(".*[a-d]:FRA,BGM[\\|&].*") || result.matches(".*[a-d]:BGM,FRA[\\|&].*") );
168 assertTrue(result.matches(".*[a-d]:GER[\\|&].*") );
169 assertTrue(result.matches(".*[a-d]:SPA[\\|&].*") );
170 assertTrue(result.matches(".*tdwg4:[a-d]:INDAP[\\|&].*") );
171 //assertTrue(result.matches("0000ff"));
172 //TODO continue
173
174 // request map image from webservice
175 subTestWithEditMapService(result);
176 }
177
178 @Test
179 public void testGetWebServiceUrlCyprus() throws ClientProtocolException, IOException, URISyntaxException {
180 makeCyprusAreas();
181 Set<Distribution> distributions = new HashSet<Distribution>();
182 distributions.add(Distribution.NewInstance(divisions.get("1"), PresenceAbsenceTerm.PRESENT()));
183 distributions.add(Distribution.NewInstance(divisions.get("2"), PresenceAbsenceTerm.INTRODUCED()));
184 distributions.add(Distribution.NewInstance(divisions.get("3"), PresenceAbsenceTerm.CULTIVATED()));
185 distributions.add(Distribution.NewInstance(divisions.get("4"), PresenceAbsenceTerm.ABSENT()));
186 distributions.add(Distribution.NewInstance(divisions.get("5"), PresenceAbsenceTerm.ABSENT()));
187 distributions.add(Distribution.NewInstance(divisions.get("6"), PresenceAbsenceTerm.PRESENT()));
188
189 Map<PresenceAbsenceTerm, Color> presenceAbsenceColorMap = new HashMap<PresenceAbsenceTerm, Color>();
190 presenceAbsenceColorMap.put(PresenceAbsenceTerm.PRESENT(), Color.BLUE);
191 presenceAbsenceColorMap.put(PresenceAbsenceTerm.INTRODUCED(), Color.BLACK);
192 presenceAbsenceColorMap.put(PresenceAbsenceTerm.CULTIVATED(), Color.YELLOW);
193 presenceAbsenceColorMap.put(PresenceAbsenceTerm.ABSENT(), Color.DARK_GRAY);
194 String backLayer ="";
195 presenceAbsenceColorMap = null;
196 String bbox="-20,0,120,70";
197 List<Language> languages = new ArrayList<Language>();
198
199 boolean subAreaPreference = false;
200 boolean statusOrderPreference = false;
201 String result = EditGeoServiceUtilities.getDistributionServiceRequestParameterString(
202 distributions,
203 mapping,
204 null, null, languages );
205 //TODO Set semantics is not determined
206 //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";
207 assertTrue(result.matches(".*ad=cyprusdivs%3Abdcode:.*"));
208 assertTrue(result.matches(".*[a-d]:5,4[\\|&].*") || result.matches(".*[a-d]:4,5[\\|&].*") );
209 assertTrue(result.matches(".*[a-d]:1,6[\\|&].*") || result.matches(".*[a-d]:6,1[\\|&].*") );
210 assertTrue(result.matches(".*[a-d]:2[\\|&].*") );
211 assertTrue(result.matches(".*[a-d]:3[\\|&].*") );
212
213 // request map image from webservice
214 subTestWithEditMapService(result);
215 }
216
217 private void subTestWithEditMapService(String queryString)throws MalformedURLException, IOException {
218 if(UriUtils.isServiceAvailable(editMapServiceUri)){
219 URL requestUrl = new URL(editMapServiceUri.toString() + "?img=false&bbox=-180,-90,180,90&ms=1000&" + queryString);
220 logger.debug("editMapServiceUri: " + requestUrl);
221 HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
222 connection.connect();
223 // connection.setReadTimeout(10000); //timeout after 10 sec, does not seem to work
224 assertTrue(connection.getResponseCode() == 200);
225 InputStream contentStream = connection.getInputStream();
226 String content = StreamUtils.readToString(contentStream);
227 logger.debug("EditMapService response body:\n" + content);
228 assertTrue(content.startsWith("[{"));
229 assertTrue(content.endsWith("}]"));
230 assertTrue(content.matches(".*\"bbox\":.*"));
231 assertTrue(content.matches(".*\"legend\":.*"));
232 assertTrue(content.matches(".*\"layers\":.*"));
233 assertTrue(content.matches(".*\"sld\":.*"));
234 assertTrue(content.matches(".*\"geoserver\":.*"));
235 }
236 }
237
238 public static final UUID uuidCyprusDivisionsVocabulary = UUID.fromString("2119f610-1f93-4d87-af28-40aeefaca100");
239 private final Map<String, NamedArea> divisions = new HashMap<String, NamedArea>();
240
241 private boolean makeCyprusAreas() throws IOException {
242 //divisions
243
244
245 NamedAreaType areaType = NamedAreaType.NATURAL_AREA();
246 NamedAreaLevel areaLevel = NamedAreaLevel.NewInstance("Cyprus Division", "Cyprus Division", null);
247
248 termService.saveOrUpdate(areaLevel);
249
250 TermVocabulary<NamedArea> areaVocabulary = TermVocabulary.NewInstance(TermType.NamedArea, "Cyprus devisions", "Cyprus divisions", null, null);
251 areaVocabulary.setUuid(uuidCyprusDivisionsVocabulary);
252
253
254 for(int i = 1; i <= 8; i++){
255 UUID divisionUuid = getNamedAreaUuid(String.valueOf(i));
256 NamedArea division = this.newNamedArea(
257 divisionUuid,
258 "Division " + i,
259 "Cyprus: Division " + i,
260 String.valueOf(i), // id in vocab
261 areaType,
262 areaLevel,
263 areaVocabulary);
264 divisions.put(String.valueOf(i), division);
265 }
266
267 vocabService.saveOrUpdate(areaVocabulary);
268 commitAndStartNewTransaction(null);
269
270
271 // import and map shapefile attributes from csv
272 InputStream is = getClass().getClassLoader().getResourceAsStream("eu/etaxonomy/cdm/ext/geo/cyprusdivs.csv");
273 List<String> idSearchFields = new ArrayList<String>();
274 idSearchFields.add("bdcode");
275 String wmsLayerName = "cyprusdivs";
276 editGeoService.mapShapeFileToNamedAreas(new InputStreamReader(is), idSearchFields, wmsLayerName, uuidCyprusDivisionsVocabulary, null);
277
278 divisions.clear();
279 Set<DefinedTermBase> terms = vocabService.load(uuidCyprusDivisionsVocabulary).getTerms();
280 for(DefinedTermBase dtb : terms){
281 divisions.put(dtb.getIdInVocabulary(), (NamedArea) dtb);
282 }
283
284
285 // indigenousStatus = (PresenceTerm)getTermService().find(CyprusTransformer.indigenousUuid);
286 // casualStatus = (PresenceTerm)getTermService().find(CyprusTransformer.casualUuid);
287 // nonInvasiveStatus = (PresenceTerm)getTermService().find(CyprusTransformer.nonInvasiveUuid);
288 // invasiveStatus = (PresenceTerm)getTermService().find(CyprusTransformer.invasiveUuid);
289 // questionableStatus = (PresenceTerm)getTermService().find(CyprusTransformer.questionableUuid);
290
291 return true;
292
293
294 }
295
296 public static final UUID uuidDivision1 = UUID.fromString("ab17eee9-1abb-4ce9-a9a2-563f840cdbfc");
297 public static final UUID uuidDivision2 = UUID.fromString("c3606165-efb7-4224-a168-63e009eb4aa5");
298 public static final UUID uuidDivision3 = UUID.fromString("750d4e07-e34b-491f-a7b7-09723afdc960");
299 public static final UUID uuidDivision4 = UUID.fromString("8a858922-e8e5-4791-ad53-906e50633ec7");
300 public static final UUID uuidDivision5 = UUID.fromString("16057133-d541-4ebd-81d4-cb92265ec54c");
301 public static final UUID uuidDivision6 = UUID.fromString("fbf21230-4a42-4f4c-9af8-5da52123c264");
302 public static final UUID uuidDivision7 = UUID.fromString("d31dd96a-36ea-4428-871c-d8552a9565ca");
303 public static final UUID uuidDivision8 = UUID.fromString("236ea447-c3ab-486d-9e06-cc5907861acc");
304
305
306 public UUID getNamedAreaUuid(String key) {
307 if (StringUtils.isBlank(key)){return null;
308 }else if (key.equalsIgnoreCase("1")){return uuidDivision1;
309 }else if (key.equalsIgnoreCase("2")){return uuidDivision2;
310 }else if (key.equalsIgnoreCase("3")){return uuidDivision3;
311 }else if (key.equalsIgnoreCase("4")){return uuidDivision4;
312 }else if (key.equalsIgnoreCase("5")){return uuidDivision5;
313 }else if (key.equalsIgnoreCase("6")){return uuidDivision6;
314 }else if (key.equalsIgnoreCase("7")){return uuidDivision7;
315 }else if (key.equalsIgnoreCase("8")){return uuidDivision8;
316 }else{
317 return null;
318 }
319 }
320
321 protected NamedArea newNamedArea(UUID uuid, String label, String text, String IdInVocabulary, NamedAreaType areaType, NamedAreaLevel level, TermVocabulary<NamedArea> voc){
322 NamedArea namedArea = NamedArea.NewInstance(text, label, null);
323 voc.addTerm(namedArea);
324 namedArea.setType(areaType);
325 namedArea.setLevel(level);
326 namedArea.setUuid(uuid);
327 namedArea.setIdInVocabulary(IdInVocabulary);
328 return namedArea;
329 }
330
331 @Test
332 public void testGetWebServiceUrlBangka() throws ClientProtocolException, IOException, URISyntaxException {
333 NamedArea areaBangka = NamedArea.NewInstance("Bangka", "Bangka", null);
334 TermVocabulary<NamedArea> voc = TermVocabulary.NewInstance(TermType.NamedArea, "test Voc", "test voc", null, null);
335 voc.addTerm(areaBangka);
336
337 GeoServiceArea geoServiceArea = new GeoServiceArea();
338 String geoServiceLayer="vmap0_as_bnd_political_boundary_a";
339 String layerFieldName ="nam";
340 String areaValue = "PULAU BANGKA#SUMATERA SELATAN";
341 geoServiceArea.add(geoServiceLayer, layerFieldName, areaValue);
342 geoServiceArea.add(geoServiceLayer, layerFieldName, "BALI");
343
344 mapping.set(areaBangka, geoServiceArea);
345 Set<Distribution> distributions = new HashSet<Distribution>();
346 distributions.add(Distribution.NewInstance(areaBangka, PresenceAbsenceTerm.PRESENT()));
347
348 Map<PresenceAbsenceTerm, Color> presenceAbsenceColorMap = new HashMap<PresenceAbsenceTerm, Color>();
349 presenceAbsenceColorMap.put(PresenceAbsenceTerm.PRESENT(), Color.BLUE);
350
351 presenceAbsenceColorMap = null;
352 List<Language> languages = new ArrayList<Language>();
353
354 boolean subAreaPreference = false;
355 boolean statusOrderPreference = false;
356 String result = EditGeoServiceUtilities.getDistributionServiceRequestParameterString(distributions,
357 mapping,
358 null, null, languages );
359 //TODO Set semantics is not determined
360 //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";
361
362 logger.debug(result);
363 assertTrue(result.matches(".*ad=vmap0_as_bnd_political_boundary_a%3Anam:.*"));
364 assertTrue(result.matches(".*(PULAU\\+BANGKA%23SUMATERA\\+SELATAN).*") );
365 assertTrue(result.matches(".*(BALI).*") );
366
367 // request map image from webservice
368 subTestWithEditMapService(result);
369 }
370
371
372 @SuppressWarnings("deprecation")
373 // @Test
374 @DataSet( value="EditGeoServiceTest.getDistributionServiceRequestParameterString.xml")
375 // @DataSets({
376 // @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
377 // @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
378 // @DataSet( value="EditGeoServiceTest.getDistributionServiceRequestParameterString.xml")
379 // })
380 public void getDistributionServiceRequestParameterString(){
381 boolean subAreaPreference = false;
382 boolean statusOrderPreference = false;
383 Set<MarkerType> hideMarkedAreas = null;
384 Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors = null;
385 List<Language> langs = null;
386
387 List<TaxonDescription> taxonDescriptions = new ArrayList<TaxonDescription>();
388 TaxonDescription description1 = TaxonDescription.NewInstance();
389 taxonDescriptions.add(description1);
390 Distribution distribution1 = Distribution.NewInstance(Country.GERMANY(), null);
391 description1.addElement(distribution1);
392 Distribution distribution2 = Distribution.NewInstance(Country.FRANCEFRENCHREPUBLIC(), null);
393 distribution2.setFeature(Feature.COMMON_NAME());
394 description1.addElement(distribution2);
395
396 Taxon taxon = (Taxon)taxonService.find(UUID.fromString("7598f5d4-1cf2-4269-ae99-2adb79ae167c"));
397 TaxonDescription taxDesc = taxon.getDescriptions().iterator().next();
398 for (DescriptionElementBase deb : taxDesc.getElements()){
399 Distribution distribution = CdmBase.deproxy(deb, Distribution.class);
400 NamedArea area = distribution.getArea();
401 System.out.println(area.getTitleCache());
402 }
403 taxonDescriptions.addAll(taxon.getDescriptions());
404
405 String distributions = editGeoService.getDistributionServiceRequestParameterString(taxonDescriptions,
406 subAreaPreference, statusOrderPreference, hideMarkedAreas, presenceAbsenceTermColors, langs);
407 System.out.println(distributions);
408 Assert.assertTrue("Distribution string should contain the non-persited distribution Germany", distributions.contains("DEU"));
409 Assert.assertFalse("Distribution string should contain France as it has a non-distribution feature", distributions.contains("FRA"));
410
411 // CHE,POL
412 }
413
414 @Override
415 // @Test
416 public void createTestDataSet() throws FileNotFoundException {
417
418 List<TaxonDescription> taxonDescriptions = new ArrayList<TaxonDescription>();
419 TaxonDescription description1 = TaxonDescription.NewInstance();
420 taxonDescriptions.add(description1);
421 Distribution distribution1 = Distribution.NewInstance(Country.POLANDPOLISHPEOPLESREPUBLIC(), null);
422 description1.addElement(distribution1);
423 Distribution distribution2 = Distribution.NewInstance(Country.SWITZERLANDSWISSCONFEDERATION(), null);
424 // distribution2.setFeature(Feature.COMMON_NAME());
425 description1.addElement(distribution2);
426 Taxon taxon = Taxon.NewInstance(null, null);
427 taxon.setTitleCache("Dummy taxon", true);
428 taxon.addDescription(description1);
429 taxon.setUuid(UUID.fromString("7598f5d4-1cf2-4269-ae99-2adb79ae167c"));
430
431 taxonService.save(taxon);
432
433
434 setComplete();
435 endTransaction();
436
437 writeDbUnitDataSetFile(new String[] {
438 "TAXONBASE",
439 "DESCRIPTIONBASE", "DESCRIPTIONELEMENTBASE",
440 "HIBERNATE_SEQUENCES" // IMPORTANT!!!
441 },
442 "getDistributionServiceRequestParameterString", true );
443
444 }
445
446
447 }