Subject: [PATCH] 7_jaxb_marshal --- Index: src/main/java/ru/javaops/docjava/xml/jaxb/JaxbMarshaller.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbMarshaller.java b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbMarshaller.java new file mode 100644 --- /dev/null (date 1695983202589) +++ b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbMarshaller.java (date 1695983202589) @@ -0,0 +1,34 @@ +package ru.javaops.docjava.xml.jaxb; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; + +import javax.xml.validation.Schema; +import java.io.StringWriter; +import java.io.Writer; + +public class JaxbMarshaller { + private final Marshaller marshaller; + + public JaxbMarshaller(JAXBContext ctx) throws JAXBException { + marshaller = ctx.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); + marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); + } + + public void setSchema(Schema schema) { + marshaller.setSchema(schema); + } + + public void marshal(Object instance, Writer writer) throws JAXBException { + marshaller.marshal(instance, writer); + } + + public String marshal(Object instance) throws JAXBException { + StringWriter sw = new StringWriter(); + marshal(instance, sw); + return sw.toString(); + } +} Index: src/test/java/ru/javaops/docjava/xml/jaxb/JaxbUtilTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/java/ru/javaops/docjava/xml/jaxb/JaxbUtilTest.java b/src/test/java/ru/javaops/docjava/xml/jaxb/JaxbUtilTest.java --- a/src/test/java/ru/javaops/docjava/xml/jaxb/JaxbUtilTest.java (revision d816b29a64be19b20f51b24e37f22a31c332b076) +++ b/src/test/java/ru/javaops/docjava/xml/jaxb/JaxbUtilTest.java (date 1695983223418) @@ -17,13 +17,13 @@ @Test public void processOK() throws JAXBException, IOException { - UsersWithMeals usersWithMeals = JaxbUtil.process(inputFile, Map.of()); + UsersWithMeals usersWithMeals = JaxbUtil.process(inputFile, Map.of(), new File("out/jaxb.xml")); assertEquals(new UsersWithMeals.Users(getUsers()), usersWithMeals.getUsers()); } @Test void processFiltered() throws IOException, JAXBException { - UsersWithMeals usersWithMeals = JaxbUtil.process(inputFile, paramsMap); + UsersWithMeals usersWithMeals = JaxbUtil.process(inputFile, paramsMap, new File("out/jaxbFiltered.xml")); assertEquals(new UsersWithMeals.Users(getFilteredUsers()), usersWithMeals.getUsers()); } Index: src/main/java/ru/javaops/docjava/xml/jaxb/JaxbUtil.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbUtil.java b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbUtil.java --- a/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbUtil.java (revision d816b29a64be19b20f51b24e37f22a31c332b076) +++ b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbUtil.java (date 1695993181826) @@ -1,36 +1,39 @@ package ru.javaops.docjava.xml.jaxb; -import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import lombok.experimental.UtilityClass; import ru.javaops.docjava.schema.ObjectFactory; import ru.javaops.docjava.schema.UsersWithMeals; import ru.javaops.docjava.util.MealsUtil; -import ru.javaops.docjava.xml.xsd.Schemas; import java.io.File; import java.io.IOException; import java.io.Reader; +import java.io.Writer; import java.nio.file.Files; import java.util.Map; @UtilityClass public class JaxbUtil { + private static final JaxbParser jaxbParser; + private static final JaxbMarshaller marshaller; private static final JaxbUnmarshaller unmarshaller; static { try { - JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class); - unmarshaller = new JaxbUnmarshaller(ctx); - unmarshaller.setSchema(Schemas.of(new File("in/usersWithMeals.xsd"))); + jaxbParser = JaxbParser.of(ObjectFactory.class); + jaxbParser.setSchema(new File("in/usersWithMeals.xsd")); + marshaller = jaxbParser.createMarshaller(); + unmarshaller = jaxbParser.createUnmarshaller(); } catch (JAXBException e) { throw new RuntimeException(e); } } - public static UsersWithMeals process(File inputXml, Map params) throws IOException, JAXBException { + public static UsersWithMeals process(File inputXml, Map params, File outputXml) throws IOException, JAXBException { UsersWithMeals users = unmarshalAndFilter(inputXml, params); - System.out.println("JAXB processing completed successfully"); + marshal(users, outputXml); + System.out.println("JAXB processing completed successfully, result in " + outputXml.getAbsolutePath()); return users; } @@ -45,4 +48,10 @@ return unmarshaller.unmarshal(reader); } } + + public static void marshal(UsersWithMeals users, File outputXml) throws IOException, JAXBException { + try (Writer writer = Files.newBufferedWriter(outputXml.toPath())) { + marshaller.marshal(users, writer); + } + } } Index: src/main/java/ru/javaops/docjava/xml/jaxb/JaxbParser.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbParser.java b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbParser.java new file mode 100644 --- /dev/null (date 1695983257750) +++ b/src/main/java/ru/javaops/docjava/xml/jaxb/JaxbParser.java (date 1695983257750) @@ -0,0 +1,44 @@ +package ru.javaops.docjava.xml.jaxb; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import ru.javaops.docjava.xml.xsd.Schemas; + +import javax.xml.validation.Schema; +import java.io.File; + +public class JaxbParser { + + private final JAXBContext ctx; + protected Schema schema; + + public static JaxbParser of(Class... classesToBeBound) throws JAXBException { + return new JaxbParser(classesToBeBound); + } + + private JaxbParser(Class... classesToBeBound) throws JAXBException { + ctx = JAXBContext.newInstance(classesToBeBound); + } + + public void setSchema(File xsdSchema) { + this.schema = Schemas.of(xsdSchema); + } + + // https://stackoverflow.com/a/7400735/548473 + public JaxbMarshaller createMarshaller() throws JAXBException { + JaxbMarshaller marshaller = new JaxbMarshaller(ctx); + if (schema != null) { + marshaller.setSchema(schema); + } + return marshaller; + } + + // https://stackoverflow.com/a/7400735/548473 + public JaxbUnmarshaller createUnmarshaller() throws JAXBException { + JaxbUnmarshaller unmarshaller = new JaxbUnmarshaller(ctx); + if (schema != null) { + unmarshaller.setSchema(schema); + } + return unmarshaller; + } +} Index: src/main/java/ru/javaops/docjava/Commands.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/docjava/Commands.java b/src/main/java/ru/javaops/docjava/Commands.java --- a/src/main/java/ru/javaops/docjava/Commands.java (revision d816b29a64be19b20f51b24e37f22a31c332b076) +++ b/src/main/java/ru/javaops/docjava/Commands.java (date 1695993181825) @@ -5,7 +5,6 @@ import org.springframework.shell.standard.ShellMethod; import org.springframework.shell.standard.ShellOption; import org.xml.sax.SAXException; -import ru.javaops.docjava.schema.UsersWithMeals; import ru.javaops.docjava.xml.jaxb.JaxbUtil; import ru.javaops.docjava.xml.xsd.SchemaUtil; @@ -28,7 +27,7 @@ @ShellOption(value = {"input", "-i"}, help = "Input file") File inputFile, @ShellOption(value = {"filter", "-f"}, help = "Filter params", defaultValue = "") List params, @ShellOption(value = {"output", "-o"}, help = "Output file") File outputFile) throws JAXBException, IOException { - JaxbUtil.process(inputFile, parseParams(params)); + JaxbUtil.process(inputFile, parseParams(params), outputFile); } @ShellMethod(key = "stax", value = "Process XML file via StAX") diff --git a/out/placeholder b/out/placeholder new file mode 100644