Changeset 6366
- Timestamp:
- 07/08/15 12:02:38 (9 years ago)
- Location:
- vlo/branches/vlo-3.3-oeaw/vlo-importer/src
- Files:
-
- 3 added
- 7 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/AvailabilityPostProcessor.java
r6149 r6366 1 1 package eu.clarin.cmdi.vlo.importer; 2 2 3 import java.io.IOException;4 import java.io.InputStream;5 import java.net.MalformedURLException;6 3 import java.util.ArrayList; 7 import java.util.HashMap;8 4 import java.util.List; 9 import java.util.Map;10 import java.util.regex.Matcher;11 import java.util.regex.Pattern;12 import javax.xml.parsers.DocumentBuilder;13 import javax.xml.parsers.DocumentBuilderFactory;14 import javax.xml.parsers.ParserConfigurationException;15 import javax.xml.xpath.XPath;16 import javax.xml.xpath.XPathConstants;17 import javax.xml.xpath.XPathExpressionException;18 import javax.xml.xpath.XPathFactory;19 import org.w3c.dom.Document;20 import org.w3c.dom.Node;21 import org.w3c.dom.NodeList;22 import org.xml.sax.SAXException;23 5 24 6 /** … … 26 8 * @author teckart 27 9 */ 28 public class AvailabilityPostProcessor implements PostProcessor{10 public class AvailabilityPostProcessor extends PostProcessorsWithVocabularyMap { 29 11 30 private static Map<String, String> availabilityMap;31 12 private static final Integer MAX_LENGTH = 20; 32 13 private static final String OTHER_VALUE = "Other"; … … 37 18 List<String> resultList = new ArrayList<String>(); 38 19 39 if (get LicenseAvailabilityMap().containsKey(value.toLowerCase())) {40 resultList.add(get LicenseAvailabilityMap().get(value.toLowerCase()));20 if (getVocabularyMap().containsKey(value)) { 21 resultList.add(getVocabularyMap().get(value)); 41 22 } else { 42 23 if (result.length() > MAX_LENGTH) { … … 49 30 return resultList; 50 31 } 51 52 private Map<String, String> getLicenseAvailabilityMap() { 53 if (availabilityMap == null) { 54 try { 55 // load records from file 56 availabilityMap = createControlledVocabularyMap(MetadataImporter.config.getLicenseAvailabilityMapUrl()); 57 } catch (Exception e) { 58 throw new RuntimeException("Cannot instantiate postProcessor:", e); 59 } 60 } 61 return availabilityMap; 62 } 63 64 private Map<String, String> createControlledVocabularyMap(String languageNamesUrl) throws ParserConfigurationException, MalformedURLException, SAXException, XPathExpressionException, IOException { 65 Map<String, String> result = new HashMap<String, String>(); 66 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 67 domFactory.setNamespaceAware(true); 68 69 InputStream mappingFileAsStream; 70 mappingFileAsStream = NationalProjectPostProcessor.class.getResourceAsStream(languageNamesUrl); 71 72 DocumentBuilder builder = domFactory.newDocumentBuilder(); 73 Document doc = builder.parse(mappingFileAsStream); 74 XPath xpath = XPathFactory.newInstance().newXPath(); 75 NodeList nodeList = (NodeList) xpath.evaluate("//Availability", doc, XPathConstants.NODESET); 76 for (int i = 0; i < nodeList.getLength(); i++) { 77 Node node = nodeList.item(i); 78 String availabilityName = node.getAttributes().getNamedItem("name").getTextContent(); 79 NodeList childNodeList = node.getChildNodes(); 80 for (int j = 0; j < childNodeList.getLength(); j++) { 81 String license = childNodeList.item(j).getTextContent().toLowerCase(); 82 result.put(license, availabilityName); 83 } 84 } 85 return result; 32 33 @Override 34 protected String getMappingFileUrl() { 35 return MetadataImporter.config.getLicenseAvailabilityMapUrl(); 86 36 } 87 37 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/LanguageCodePostProcessor.java
r6351 r6366 1 1 package eu.clarin.cmdi.vlo.importer; 2 2 3 import java.io.IOException;4 import java.io.InputStream;5 import java.net.MalformedURLException;6 3 import java.util.ArrayList; 7 import java.util.HashMap;8 4 import java.util.List; 9 import java.util.Map;10 import java.util.Map.Entry;11 5 import java.util.regex.Matcher; 12 6 import java.util.regex.Pattern; 13 7 14 import javax.xml.bind.JAXBException;15 import javax.xml.parsers.DocumentBuilder;16 import javax.xml.parsers.DocumentBuilderFactory;17 import javax.xml.parsers.ParserConfigurationException;18 import javax.xml.xpath.XPath;19 import javax.xml.xpath.XPathConstants;20 import javax.xml.xpath.XPathExpressionException;21 import javax.xml.xpath.XPathFactory;22 23 8 import org.slf4j.Logger; 24 9 import org.slf4j.LoggerFactory; 25 import org.w3c.dom.Document;26 import org.w3c.dom.Node;27 import org.w3c.dom.NodeList;28 import org.xml.sax.SAXException;29 10 30 11 import eu.clarin.cmdi.vlo.LanguageCodeUtils; 31 12 32 public class LanguageCodePostProcessor implements PostProcessor{13 public class LanguageCodePostProcessor extends PostProcessorsWithVocabularyMap{ 33 14 34 15 private final static Logger LOG = LoggerFactory.getLogger(LanguageCodePostProcessor.class); 35 16 36 private static Map<String, String> languageNameVariantsMap = null;37 38 17 protected static final String CODE_PREFIX = "code:"; 39 18 protected static final String LANG_NAME_PREFIX = "name:"; … … 61 40 return resultList; 62 41 } 42 43 @Override 44 protected String getMappingFileUrl() { 45 return MetadataImporter.config.getLanguageNameVariantsUrl(); 46 } 47 63 48 64 49 protected String extractLanguageCode(String value) { … … 69 54 70 55 // map known language name variants to their offical name 71 if(get LanguageNamesVariantsMap().containsKey(result))72 result = get LanguageNamesVariantsMap().get(result);56 if(getVocabularyMap().containsKey(result)) 57 result = getVocabularyMap().get(result); 73 58 74 59 // input is already ISO 639-3? … … 100 85 return result; 101 86 } 102 103 private Map<String, String> getLanguageNamesVariantsMap() {104 if (languageNameVariantsMap == null) {105 try {106 // load records from file, in the future this should be loaded from CLAVAS directly and the file only used as fallback107 languageNameVariantsMap = createControlledVocabularyMap(MetadataImporter.config.getLanguageNameVariantsUrl());108 } catch (Exception e) {109 throw new RuntimeException("Cannot instantiate postProcessor:", e);110 }111 }112 return languageNameVariantsMap;113 }114 115 116 private Map<String, String> createControlledVocabularyMap(String languageNamesUrl) throws JAXBException{117 Map<String, String> result = new HashMap<String, String>();118 InputStream is = NationalProjectPostProcessor.class.getResourceAsStream(languageNamesUrl);119 VariantsMapping languageMap = (VariantsMapping) VLOMarshaller.unmarshal(is, VariantsMapping.class);120 for(Entry<String, List<String>> map: languageMap.getMap().entrySet()){121 String officalLangName = (String) map.getKey();122 List<String> variants = map.getValue();123 for(String variant: variants){124 result.put(variant, officalLangName);125 }126 }127 return result;128 }129 87 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/NationalProjectPostProcessor.java
r5754 r6366 1 1 package eu.clarin.cmdi.vlo.importer; 2 2 3 import java.io.File;4 import java.io.IOException;5 3 import java.io.InputStream; 6 4 import java.util.ArrayList; 7 import java.util.HashMap;8 5 import java.util.List; 9 6 import java.util.Map; 7 import java.util.Map.Entry; 8 import java.util.TreeMap; 10 9 import java.util.regex.Matcher; 11 10 import java.util.regex.Pattern; 12 import javax.xml.parsers.DocumentBuilder; 13 import javax.xml.parsers.DocumentBuilderFactory; 14 import javax.xml.xpath.XPath; 15 import javax.xml.xpath.XPathConstants; 16 import javax.xml.xpath.XPathExpressionException; 17 import javax.xml.xpath.XPathFactory; 18 import org.apache.commons.io.FileUtils; 11 19 12 import org.slf4j.Logger; 20 13 import org.slf4j.LoggerFactory; 21 import org.w3c.dom.Document; 22 import org.w3c.dom.NodeList;14 15 import eu.clarin.cmdi.vlo.importer.VariantsMap.Variant; 23 16 24 17 /** … … 29 22 * 30 23 */ 31 public class NationalProjectPostProcessor extends LanguageCodePostProcessor{24 public class NationalProjectPostProcessor extends PostProcessorsWithVocabularyMap { 32 25 33 26 private final static Logger LOG = LoggerFactory.getLogger(NationalProjectPostProcessor.class); 34 27 35 private static Map<String, String> nationalProjectMap = null;36 28 private static Map<Pattern, String> nationalProjectRegExpMap = null; 37 29 … … 48 40 List<String> resultList = new ArrayList<String>(); 49 41 50 if (input != null && get Mapping().containsKey(input)) {51 resultList.add(get Mapping().get(input));42 if (input != null && getVocabularyMap().containsKey(input)) { 43 resultList.add(getVocabularyMap().get(input)); 52 44 return resultList; 53 45 } … … 64 56 return resultList; 65 57 } 66 67 private Map<String, String> getMapping() { 68 if (nationalProjectMap == null) { 69 getNationalProjectMapping(); 70 } 71 return nationalProjectMap; 72 } 73 58 74 59 private Map<Pattern, String> getRegExpMapping() { 75 76 getNationalProjectMapping();60 if (nationalProjectRegExpMap == null) { 61 createControlledVocabularyMap(); 77 62 } 78 63 return nationalProjectRegExpMap; 79 64 } 80 81 private void getNationalProjectMapping() { 82 String projectsMappingFile = MetadataImporter.config.getNationalProjectMapping(); 65 66 @Override 67 protected String getMappingFileUrl() { 68 String projectsMappingFile = MetadataImporter.config.getNationalProjectMapping(); 83 69 84 70 if (projectsMappingFile.length() == 0) { … … 86 72 projectsMappingFile = "/nationalProjectsMapping.xml"; 87 73 } 88 74 75 return projectsMappingFile; 76 } 77 78 @Override 79 protected void createControlledVocabularyMap() { 80 if(variantsMap == null){ 81 variantsMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); 82 } 83 84 if(nationalProjectRegExpMap == null){ 85 nationalProjectRegExpMap = new TreeMap<Pattern, String>(); 86 } 87 89 88 try { 90 nationalProjectMap = new HashMap<String, String>(); 91 nationalProjectRegExpMap = new HashMap<Pattern, String>(); 92 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 93 domFactory.setNamespaceAware(true); 94 95 DocumentBuilder builder = domFactory.newDocumentBuilder(); 96 Document doc; 97 98 // first, try to open the packaged mapping file 99 InputStream mappingFileAsStream; 100 mappingFileAsStream = NationalProjectPostProcessor.class.getResourceAsStream(projectsMappingFile); 101 102 if (mappingFileAsStream != null) { 103 doc = builder.parse(mappingFileAsStream); 104 } else { 105 // the resource cannot be found inside the package, try outside 106 File mappingAsFile; 107 108 mappingAsFile = new File(projectsMappingFile); 109 110 if (!mappingAsFile.exists()) { 111 LOG.info("National project mapping file does not exist - using minimal test file."); 112 mappingAsFile = createMinimalMappingFile(); 113 } 114 doc = builder.parse(mappingAsFile); 115 } 116 117 XPath xpath = XPathFactory.newInstance().newXPath(); 118 NodeList nodeList = (NodeList) xpath.evaluate("//nationalProjectMapping", doc, XPathConstants.NODESET); 119 for (int i = 1; i <= nodeList.getLength(); i++) { 120 String mdCollectionDisplayName = xpath.evaluate("//nationalProjectMapping[" + i + "]/MdCollectionDisplayName", doc).trim(); 121 String nationalProject = xpath.evaluate("//nationalProjectMapping[" + i + "]/NationalProject", doc).trim(); 122 Boolean isRegExp; 123 try { 124 isRegExp = Boolean.parseBoolean(xpath.evaluate("//nationalProjectMapping[" + i + "]/MdCollectionDisplayName/@isRegExp", doc)); 125 } catch (XPathExpressionException xee) { 126 isRegExp = false; 127 } 128 if (isRegExp == true) { 129 nationalProjectRegExpMap.put(Pattern.compile(mdCollectionDisplayName), nationalProject); 130 } else { 131 nationalProjectMap.put(mdCollectionDisplayName, nationalProject); 132 } 133 } 89 // load records from file 90 // in the future this should be loaded from CLAVAS directly and the file only used as fallback 91 InputStream is = PostProcessorsWithVocabularyMap.class.getResourceAsStream(getMappingFileUrl()); 92 VariantsMap map = (VariantsMap) VLOMarshaller.unmarshal(is, VariantsMap.class); 93 94 for(Entry<String, List<Variant>> entry: map.getMap().entrySet()){ 95 for(Variant variant: entry.getValue()){ 96 if(variant.isRegExp()){ 97 nationalProjectRegExpMap.put(Pattern.compile(variant.getValue()), entry.getKey()); 98 }else{ 99 variantsMap.put(variant.getValue(), entry.getKey()); 100 } 101 } 102 } 134 103 } catch (Exception e) { 135 104 throw new RuntimeException("Cannot instantiate postProcessor:", e); … … 137 106 } 138 107 139 /**140 * Create temporary and minimal mapping file for testing purposes and as141 * backup solution142 *143 * @return minimal file for national projects mapping (e.g. TLA: ANDES ->144 * CLARIN-EU)145 */146 private File createMinimalMappingFile() {147 String content = "";148 content += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";149 content += "<nationalProjects>\n";150 content += " <nationalProjectMapping><MdCollectionDisplayName>TLA: ANDES</MdCollectionDisplayName><NationalProject>CLARIN-EU</NationalProject></nationalProjectMapping>\n";151 content += " <nationalProjectMapping><MdCollectionDisplayName isRegExp=\"true\">Meertens.*</MdCollectionDisplayName><NationalProject>CLARIN-NL</NationalProject></nationalProjectMapping>\n";152 content += "</nationalProjects>\n";153 154 File file = null;155 try {156 file = File.createTempFile("vlo.nationalTestMapping", ".map");157 FileUtils.writeStringToFile(file, content, "UTF-8");158 } catch (IOException ioe) {159 LOG.error("Could not create temporary national project mapping file");160 }161 162 return file;163 }164 108 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/OrganisationPostProcessor.java
r6020 r6366 1 1 package eu.clarin.cmdi.vlo.importer; 2 2 3 import java.io.IOException;4 import java.io.InputStream;5 import java.net.MalformedURLException;6 3 import java.util.Arrays; 7 import java.util.HashMap;8 4 import java.util.List; 9 import java.util.Map;10 import javax.xml.parsers.DocumentBuilder;11 import javax.xml.parsers.DocumentBuilderFactory;12 import javax.xml.parsers.ParserConfigurationException;13 import javax.xml.xpath.XPath;14 import javax.xml.xpath.XPathConstants;15 import javax.xml.xpath.XPathExpressionException;16 import javax.xml.xpath.XPathFactory;17 import org.w3c.dom.Document;18 import org.w3c.dom.Node;19 import org.w3c.dom.NodeList;20 import org.xml.sax.SAXException;21 5 22 public class OrganisationPostProcessor implements PostProcessor{6 public class OrganisationPostProcessor extends PostProcessorsWithVocabularyMap{ 23 7 24 private static Map<String, String> organisationNamesMap = null;25 8 26 9 /** … … 38 21 for (int i = 0; i < splitArray.length; i++) { 39 22 String orgaName = splitArray[i]; 40 if (get NormalizedOrganisationNamesMap().containsKey(normalizeVariant(orgaName))) {41 splitArray[i] = get NormalizedOrganisationNamesMap().get(normalizeVariant(orgaName));23 if (getVocabularyMap().containsKey(normalizeVariant(orgaName))) { 24 splitArray[i] = getVocabularyMap().get(normalizeVariant(orgaName)); 42 25 } 43 26 } 44 27 45 28 return Arrays.asList(splitArray); 29 } 30 31 @Override 32 protected String getMappingFileUrl() { 33 return MetadataImporter.config.getOrganisationNamesUrl(); 46 34 } 47 35 … … 53 41 return key.toLowerCase().replaceAll("-", " "); 54 42 } 55 56 private Map<String, String> getNormalizedOrganisationNamesMap() { 57 if (organisationNamesMap == null) { 58 try { 59 // load records from file, in the future this should be loaded from CLAVAS directly and the file only used as fallback 60 organisationNamesMap = createControlledVocabularyMap(MetadataImporter.config.getOrganisationNamesUrl()); 61 } catch (Exception e) { 62 throw new RuntimeException("Cannot instantiate postProcessor:", e); 63 } 64 } 65 return organisationNamesMap; 66 } 67 68 private Map<String, String> createControlledVocabularyMap(String urlToVocabularyFile) throws ParserConfigurationException, MalformedURLException, SAXException, XPathExpressionException, IOException { 69 Map<String, String> result = new HashMap<String, String>(); 70 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 71 domFactory.setNamespaceAware(true); 72 73 InputStream mappingFileAsStream; 74 mappingFileAsStream = NationalProjectPostProcessor.class.getResourceAsStream(urlToVocabularyFile); 75 76 DocumentBuilder builder = domFactory.newDocumentBuilder(); 77 Document doc = builder.parse(mappingFileAsStream); 78 XPath xpath = XPathFactory.newInstance().newXPath(); 79 NodeList nodeList = (NodeList) xpath.evaluate("//Organisation", doc, XPathConstants.NODESET); 80 for (int i = 0; i < nodeList.getLength(); i++) { 81 Node node = nodeList.item(i); 82 String organisationName = node.getAttributes().getNamedItem("name").getTextContent(); 83 NodeList childNodeList = node.getChildNodes(); 84 for (int j = 0; j < childNodeList.getLength(); j++) { 85 String variation = normalizeVariant(childNodeList.item(j).getTextContent()); 86 result.put(variation, organisationName); 87 } 88 } 89 return result; 90 } 43 44 91 45 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/VLOMarshaller.java
r6351 r6366 26 26 * @return the facet concept mapping 27 27 */ 28 public static FacetConceptMapping getFacetConceptMapping( 29 String facetConcepts) { 28 public static FacetConceptMapping getFacetConceptMapping(String facetConcepts) { 29 30 FacetConceptMapping result; 31 InputStream is = null; 30 32 31 if (facetConcepts == null || "".equals(facetConcepts)) { 32 return unmarshal(VLOMarshaller.class.getResourceAsStream(VloConfig.DEFAULT_FACET_CONCEPTS_RESOURCE_FILE)); 33 } else { 34 try { 35 return unmarshal(new FileInputStream(facetConcepts)); 36 } catch (FileNotFoundException ex) { 33 try { 34 is = (facetConcepts == null || "".equals(facetConcepts))? 35 VLOMarshaller.class.getResourceAsStream(VloConfig.DEFAULT_FACET_CONCEPTS_RESOURCE_FILE) : 36 new FileInputStream(facetConcepts); 37 } catch (FileNotFoundException e) { 37 38 logger.error("Could not find facets file: {}", facetConcepts); 38 39 return null; 39 }40 40 } 41 42 return unmarshal(is); 41 43 } 44 42 45 43 46 /** … … 67 70 * @return 68 71 */ 69 public static Object unmarshal(InputStream inputStream, Classclazz)throws JAXBException{72 static Object unmarshal(InputStream inputStream, Class<?> clazz)throws JAXBException{ 70 73 JAXBContext jc = JAXBContext.newInstance(clazz); 71 74 Unmarshaller u = jc.createUnmarshaller(); … … 91 94 } 92 95 } 93 94 96 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/main/java/eu/clarin/cmdi/vlo/importer/VariantsMap.java
r6356 r6366 5 5 import java.util.List; 6 6 import java.util.Map; 7 import java.util.TreeMap; 7 8 8 9 import javax.xml.bind.annotation.XmlAccessType; … … 11 12 import javax.xml.bind.annotation.XmlElement; 12 13 import javax.xml.bind.annotation.XmlRootElement; 14 import javax.xml.bind.annotation.XmlValue; 13 15 14 import org.apache.solr.common.util.Hash;15 16 import org.slf4j.Logger; 16 17 import org.slf4j.LoggerFactory; … … 18 19 @XmlAccessorType(XmlAccessType.FIELD) 19 20 @XmlRootElement(name = "mappings") 20 public class VariantsMap ping{21 public class VariantsMap { 21 22 22 private final static Logger LOG = LoggerFactory.getLogger(VariantsMap ping.class);23 private final static Logger LOG = LoggerFactory.getLogger(VariantsMap.class); 23 24 24 25 @XmlAttribute … … 44 45 } 45 46 46 public Map<String, List<String>> getMap(){ 47 Map<String, List<String>> map = new HashMap<String, List<String>>(); 47 48 /** 49 * returns inverted map variant-normalizedVal 50 * 51 */ 52 53 public Map<String, String> getInvertedMap(){ 54 Map<String, String> invMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); 55 for(Mapping m: mappings) 56 for(Variant variant: m.getVariants()) 57 if(!variant.isRegExp()) 58 invMap.put(variant.getValue(), m.getValue()); 59 60 return invMap; 61 } 62 63 64 65 public Map<String, List<Variant>> getMap(){ 66 Map<String, List<Variant>> map = new HashMap<String, List<Variant>>(); 48 67 for(Mapping m: mappings) 49 68 map.put(m.value, m.variants); … … 53 72 54 73 55 56 74 @XmlAccessorType(XmlAccessType.FIELD) 57 75 @XmlRootElement(name = "mapping") 58 76 public static class Mapping{ 77 78 private String value; 79 80 @XmlElement(name = "variant") 81 List<Variant> variants = new ArrayList<Variant>(); 82 83 public String getValue() { 84 return value; 85 } 86 87 public void setValue(String value) { 88 this.value = value; 89 } 90 91 public List<Variant> getVariants() { 92 return variants; 93 } 94 95 public void setVariants(List<Variant> variants) { 96 this.variants = variants; 97 } 98 99 } 100 101 @XmlAccessorType(XmlAccessType.FIELD) 102 @XmlRootElement(name = "variant") 103 public static class Variant{ 104 105 @XmlValue 106 private String value; 59 107 60 108 @XmlAttribute 61 109 private boolean isRegExp = false; 62 110 63 private String value;64 65 @XmlElement(name = "variant")66 List<String> variants = new ArrayList<String>();67 68 111 public boolean isRegExp() { 69 112 return isRegExp; … … 81 124 this.value = value; 82 125 } 83 84 public List<String> getVariants() {85 return variants;86 }87 88 public void setVariants(List<String> variants) {89 this.variants = variants;90 }91 126 92 127 } -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/test/java/eu/clarin/cmdi/vlo/importer/LanguageCodePostProcessorTest.java
r6142 r6366 15 15 16 16 // optionally, modify the configuration here 17 config.setLanguageNameVariantsUrl("/uniform_maps" + config.getLanguageNameVariantsUrl()); 18 17 19 } 18 20 -
vlo/branches/vlo-3.3-oeaw/vlo-importer/src/test/java/eu/clarin/cmdi/vlo/importer/NationalProjectPostProcessorTest.java
r5754 r6366 11 11 public void setUp() throws Exception { 12 12 new DefaultVloConfigFactory().newConfig(); 13 14 //use uniform maps in uniform_maps folder 15 config.setNationalProjectMapping("/uniform_maps" + config.getNationalProjectMapping()); 13 16 } 14 17
Note: See TracChangeset
for help on using the changeset viewer.