diff --git a/fim-adapter/pom.xml b/fim-adapter/pom.xml index b689f1c70031ac3c2eef2d5ec97131dce5e75ac3..3f238ee3b4d1a481ba465908a15a815f62374aa5 100644 --- a/fim-adapter/pom.xml +++ b/fim-adapter/pom.xml @@ -16,6 +16,11 @@ <artifactId>common</artifactId> </dependency> + <dependency> + <groupId>de.ozgcloud.eingang</groupId> + <artifactId>semantik-adapter</artifactId> + </dependency> + <!--spring--> <dependency> <groupId>org.springframework.boot</groupId> @@ -26,6 +31,7 @@ <artifactId>spring-boot-starter-actuator</artifactId> </dependency> + <!--test --> <dependency> <groupId>de.ozgcloud.eingang</groupId> @@ -33,6 +39,10 @@ <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>de.ozgcloud.eingang</groupId> + <artifactId>semantik-adapter</artifactId> + </dependency> </dependencies> <build> diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimAdapterApplication.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimAdapterApplication.java deleted file mode 100644 index 7c3ad3b214b076f41c1cedec7292df37d7019c95..0000000000000000000000000000000000000000 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimAdapterApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.ozgcloud.eingang.fim; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -import java.util.TimeZone; - -@SpringBootApplication(scanBasePackages = { "de.ozgcloud" }) -public class FimAdapterApplication { - - public static void main(String[] args) { - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - SpringApplication.run(FimAdapterApplication.class, args); - } -} diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedMapper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..d6bc3225122a6fd73f5f9449b79a32ecc2ea837e --- /dev/null +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedMapper.java @@ -0,0 +1,76 @@ +package de.ozgcloud.eingang.fim; + +import de.ozgcloud.eingang.common.formdata.FormData; +import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; +import de.ozgcloud.eingang.semantik.enginebased.EngineBasedMapper; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +@Log4j2 +public class FimBasedMapper implements EngineBasedMapper { + + @Autowired + private FimService fimService = null; + + public boolean isResponsible(final FormData formData) { + return true; + } + @Override + public FormData parseFormData(final FormData initialFormData) { + final List<IncomingFileGroup> attachments = initialFormData.getAttachments(); + final Optional<IncomingFile> metadataFileOpt = findFile(attachments, "fim_xtaMetadata.xml"); + if (metadataFileOpt.isEmpty()) { + LOG.error("Metadata File not found for fim data mapping", initialFormData); + return initialFormData; + } + final Optional<String> entryPointOpt = getEntryPoint(metadataFileOpt.get()); + if (entryPointOpt.isEmpty()) { + LOG.error("No entry point found in metadata file for fim data mapping", initialFormData); + return initialFormData; + } + final Optional<IncomingFile> fileOpt = findFile(attachments, entryPointOpt.get()); + if (fileOpt.isEmpty()) { + LOG.error("Entry point file not found for fim data mapping", initialFormData); + return initialFormData; + } + try { + final Document document = loadDocument(fileOpt.get()); + return fimService.transformDocument(document, initialFormData); + } catch (ParserConfigurationException | SAXException | IOException | FimException e) { + LOG.error("Can't transform document into fim formdata", initialFormData); + return initialFormData; + } + } + + private Optional<IncomingFile> findFile(final Collection<IncomingFileGroup> attachments, final String name) { + for (IncomingFileGroup group : attachments) { + for (IncomingFile file : group.getFiles()) { + if (name.equals(file.getName())) { + return Optional.of(file); + } + } + } + return Optional.empty(); + } + + private Optional<String> getEntryPoint(final IncomingFile incomingFile) { + // TODO sollte über formdata metadaten kommen statt aus dem meta file geparsed zu werden + return Optional.of("antrag.xml"); + } + + private Document loadDocument(final IncomingFile incomingFile) throws ParserConfigurationException, IOException, SAXException { + final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + return builder.parse(incomingFile.getContentStream()); + } +} diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataController.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataController.java deleted file mode 100644 index f3ed708b4080fe03670cff7a83316c0d877d5cfb..0000000000000000000000000000000000000000 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataController.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.ozgcloud.eingang.fim; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -@Controller -@ResponseBody -@RequestMapping("formData") -@RequiredArgsConstructor -public class FimDataController { -} diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java index 291f820bab4855cff880fc4c264b425c5e956252..642d3bb6f9e86c326cd5d4469df11e1e6efb94b5 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java @@ -1,7 +1,9 @@ package de.ozgcloud.eingang.fim; import de.ozgcloud.eingang.common.formdata.FormData; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.function.TriFunction; import org.springframework.stereotype.Service; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -9,20 +11,26 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Optional; import java.util.function.BiFunction; @Service @Log4j2 -public class FimDataMapper implements BiFunction<Document, FimScheme, FormData.FormDataBuilder> { +public class FimDataMapper implements TriFunction<Document, FimScheme, Collection<IncomingFileGroup>, FormData.FormDataBuilder> { + + private static final String LABEL_KEY = "label"; + private static final String VALUE_KEY = "value"; @Override - public FormData.FormDataBuilder apply(final Document document, final FimScheme fimScheme) { + public FormData.FormDataBuilder apply(final Document document, final FimScheme fimScheme, final Collection<IncomingFileGroup> attachments) { final FormData.FormDataBuilder formDataBuilder = FormData.builder(); Map<String, Object> data = new LinkedHashMap<>(); process(document.getDocumentElement(), fimScheme, data, 0); formDataBuilder.formData(data); + formDataBuilder.attachments(attachments); return formDataBuilder; } @@ -37,12 +45,17 @@ public class FimDataMapper implements BiFunction<Document, FimScheme, FormData.F continue; } if (child.getChildNodes().getLength() == 1 && child.getChildNodes().item(0) instanceof Text textNode) { - data.put(fimScheme.getFieldName(child.getNodeName()), textNode.getTextContent()); + insertValueIntoFormData(data, fimScheme.getFieldName(child.getNodeName()), child.getNodeName(), textNode.getTextContent()); } else { final Map<String, Object> childMap = new LinkedHashMap<>(); - data.put(fimScheme.getFieldName(child.getNodeName()), childMap); + insertValueIntoFormData(data, fimScheme.getFieldName(child.getNodeName()), child.getNodeName(), childMap); process((Element) child, fimScheme, childMap, level + 1); } } } + + private void insertValueIntoFormData(final Map<String, Object> data, final Optional<String> fieldName, final String nodeName, final Object obj) { + final Map<String, Object> labelMap = Map.of(LABEL_KEY, fieldName.orElse(nodeName), VALUE_KEY, obj); + data.put(nodeName, labelMap); + } } diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimException.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimException.java index 5d2cf83c9efd7ebbbb35640fe2d61dba5da8d27b..9ead23ce4135e337eaa05494cde15b14c9c09184 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimException.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimException.java @@ -4,4 +4,7 @@ public class FimException extends RuntimeException { public FimException(final String ex) { super(ex); } + public FimException(final String e, final Throwable th) { + super(e, th); + } } diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimScheme.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimScheme.java index 71bd6e9ac2a0f737cc309a04ce2825e3b11164fe..49591924c9a0371f804b756ec79fa53f0308a287 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimScheme.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimScheme.java @@ -9,6 +9,7 @@ import org.w3c.dom.NodeList; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Optional; public class FimScheme { @@ -36,7 +37,7 @@ public class FimScheme { } } - public String getFieldName(final String fieldName) { + public Optional<String> getFieldName(final String fieldName) { return schemeAdapter.getFieldName(fieldIndex, fieldName); } } diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java index c780a14d3898ec2380c193924156dc403d3f160c..0e07fa99bef94e2c90b3c5b62ca8a9655b1ab357 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java @@ -1,6 +1,7 @@ package de.ozgcloud.eingang.fim; import de.ozgcloud.eingang.common.formdata.FormData; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import de.ozgcloud.eingang.fim.adapter.FimSchemeAdapter; import io.micrometer.common.util.StringUtils; import org.springframework.beans.factory.InitializingBean; @@ -17,6 +18,7 @@ import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; @Service @@ -55,16 +57,18 @@ public class FimService implements InitializingBean { return new FimScheme(doc, fimSchemeIdentifier, fimSchemeAdapter); } - public FormData transformDocument(final Document document) { + public FormData transformDocument(final Document document, final FormData initialFormData) { final String schemeName = document.getDocumentElement().getAttribute("xmlns:xfd"); if (StringUtils.isEmpty(schemeName)) { throw new FimException("XML Document does not provide a scheme"); } final FimScheme scheme = getSchemeForIdentifier(schemeName); - final FormData.FormDataBuilder builder = fimDataMapper.apply(document, scheme); + final FormData.FormDataBuilder builder = fimDataMapper.apply(document, scheme, initialFormData.getAttachments()); final FimSchemeAdapter adapter = scheme.getSchemeAdapter(); + builder.header(initialFormData.getHeader()); + adapter.extractAntragsteller(builder); adapter.extractZustaendigeStelle(builder); diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/adapter/FimSchemeAdapter.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/adapter/FimSchemeAdapter.java index bf28b2dcf1c661e6f83010f257f76ec16bf7a33b..a7553dad6fbb7d7ff9443b1064ed63fcf7053869 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/adapter/FimSchemeAdapter.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/adapter/FimSchemeAdapter.java @@ -8,6 +8,7 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; import java.util.Map; +import java.util.Optional; public class FimSchemeAdapter { @@ -18,23 +19,26 @@ public class FimSchemeAdapter { return s.trim(); } - public String getFieldName(final Map<String, Element> fieldIndex, final String fieldName) { + public Optional<String> getFieldName(final Map<String, Element> fieldIndex, final String fieldName) { final String[] fieldNameParts = fieldName.split(":"); final String fieldNameWithoutNamespace = fieldNameParts[fieldNameParts.length - 1]; if (!fieldIndex.containsKey(fieldNameWithoutNamespace)) { throw new FimException("Cannot find Field: " + fieldName); } final Element nodeNameElement = fieldIndex.get(fieldNameWithoutNamespace); - final String nodeName = getNameForElement(nodeNameElement); - return cleanNodeName(nodeName); + final Optional<String> nodeNameOpt = getNameForElement(nodeNameElement); + if (nodeNameOpt.isEmpty()) { + return nodeNameOpt; + } + return Optional.of(cleanNodeName(nodeNameOpt.get())); } - public String getNameForElement(final Element element) { + public Optional<String> getNameForElement(final Element element) { final NodeList nameTags = element.getElementsByTagName("name"); if (nameTags.getLength() != 1) { - throw new FimException("Multiple name tags for element: " + element.getAttribute("name")); + return Optional.empty(); } - return nameTags.item(0).getTextContent(); + return Optional.ofNullable(nameTags.item(0).getTextContent()); } public void extractAntragsteller(final FormData.FormDataBuilder builder) { diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceTest.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceTest.java index 40d8d62235f712a1ea4325947c66fa5ce17711e7..30d5112f626a5175b90f5af92e16547ecb0b2522 100644 --- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceTest.java +++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceTest.java @@ -31,7 +31,7 @@ public class FimServiceTest { void shouldFailOnEmptyScheme() { Exception exception = assertThrows(FimException.class, () -> { final Document document = loadDocument("src/test/resources/test.xml"); - fimService.transformDocument(document); + fimService.transformDocument(document, FormData.builder().build()); }); String expectedMessage = "XML Document does not provide a scheme"; @@ -67,14 +67,14 @@ public class FimServiceTest { @Test void shouldTransformSimpleDocument() throws ParserConfigurationException, IOException, SAXException { final Document document = loadDocument("src/test/resources/test2.xml"); - FormData formData = fimService.transformDocument(document); + FormData formData = fimService.transformDocument(document, FormData.builder().build()); Assertions.assertEquals("Testvalue", formData.getFormData().get("Testkey")); } @Test void shouldTransformDocument() throws ParserConfigurationException, IOException, SAXException { final Document document = loadDocument("src/test/resources/S17000652V1.4_test01.xml"); - FormData formData = fimService.transformDocument(document); + FormData formData = fimService.transformDocument(document, FormData.builder().build()); assertNotNull(formData); Assertions.assertEquals(true, formData.getFormData().containsKey("EfA|SH Standard")); diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/TestNonStandardAdapter.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/TestNonStandardAdapter.java index d3114e1678b552601fe1c43baca7d05750762ac1..c2da20f9151e8570a9bc042e7cd0b1e17e18d7bb 100644 --- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/TestNonStandardAdapter.java +++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/TestNonStandardAdapter.java @@ -5,6 +5,8 @@ import org.springframework.stereotype.Service; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import java.util.Optional; + @Service public class TestNonStandardAdapter extends FimSchemeAdapter { @@ -12,11 +14,11 @@ public class TestNonStandardAdapter extends FimSchemeAdapter { return FimSchemeIdentifier.fromString("test2"); } - public String getNameForElement(final Element element) { + public Optional<String> getNameForElement(final Element element) { final NodeList nameTags = element.getElementsByTagName("non-standard-name"); if (nameTags.getLength() != 1) { - throw new FimException("Multiple name tags for element: " + element.getAttribute("non-standard-name")); + return Optional.empty(); } - return nameTags.item(0).getTextContent(); + return Optional.ofNullable(nameTags.item(0).getTextContent()); } }