View Javadoc
1   /*
2    * *************************************************************************************************************************************************************
3    *
4    * TheseFoolishThings: Miscellaneous utilities
5    * http://tidalwave.it/projects/thesefoolishthings
6    *
7    * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8    *
9    * *************************************************************************************************************************************************************
10   *
11   * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12   * You may obtain a copy of the License at
13   *
14   *     http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17   * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
18   *
19   * *************************************************************************************************************************************************************
20   *
21   * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
22   * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23   *
24   * *************************************************************************************************************************************************************
25   */
26  package it.tidalwave.thesefoolishthings.examples.dci.marshal.xstream;
27  
28  import javax.annotation.Nonnull;
29  import jakarta.inject.Inject;
30  import java.io.ByteArrayInputStream;
31  import java.io.ByteArrayOutputStream;
32  import java.io.IOException;
33  import java.nio.file.Path;
34  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35  import it.tidalwave.util.AsExtensions;
36  import it.tidalwave.util.ContextManager;
37  import it.tidalwave.util.Id;
38  import it.tidalwave.thesefoolishthings.examples.dci.marshal.role.XStreamContext1;
39  import it.tidalwave.thesefoolishthings.examples.dci.marshal.role.XStreamContext2;
40  import it.tidalwave.thesefoolishthings.examples.person.ListOfPersons;
41  import it.tidalwave.thesefoolishthings.examples.person.Person;
42  import lombok.experimental.ExtensionMethod;
43  import lombok.extern.slf4j.Slf4j;
44  import static it.tidalwave.thesefoolishthings.examples.dci.marshal.role.Loadable._Loadable_;
45  import static it.tidalwave.thesefoolishthings.examples.dci.marshal.role.Savable._Savable_;
46  import static java.nio.charset.StandardCharsets.UTF_8;
47  import static it.tidalwave.role.io.Marshallable._Marshallable_;
48  import static it.tidalwave.role.io.Unmarshallable._Unmarshallable_;
49  
50  /***************************************************************************************************************************************************************
51   *
52   * Note: this code uses {@code @ExtensionMethod} from Lombok to enhance datum classes with the
53   * {@link it.tidalwave.util.As#as(Class)}, but it is not strictly required.
54   *
55   * @author  Fabrizio Giudici
56   *
57   **************************************************************************************************************************************************************/
58  @ExtensionMethod(AsExtensions.class) @Slf4j
59  public class DciMarshalXStreamExample
60    {
61      @Inject
62      private ContextManager contextManager;
63  
64      public void run()
65              throws IOException
66        {
67          runWithXStreamContext1();
68          runWithXStreamContext2();
69        }
70  
71      private void runWithXStreamContext1()
72              throws IOException
73        {
74          // START SNIPPET: xstreamcontext-contextmanager
75          final var xStreamContext1 = new XStreamContext1();
76  
77          try
78            {
79              contextManager.addLocalContext(xStreamContext1);
80              codeThatUsesMarshalling();
81            }
82          finally
83            {
84              contextManager.removeLocalContext(xStreamContext1);
85            }
86          // END SNIPPET: xstreamcontext-contextmanager
87        }
88  
89      @SuppressWarnings("unused")
90      private void runWithXStreamContext2()
91              throws IOException
92        {
93          // START SNIPPET: xstreamcontext-contextmanager2
94          try (final var binder = contextManager.binder(new XStreamContext2()))
95            {
96              codeThatUsesMarshalling();
97            }
98          // END SNIPPET: xstreamcontext-contextmanager2
99        }
100 
101     @SuppressWarnings("unused") @SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD")
102     private void alternateSyntax()
103             throws IOException
104       {
105         contextManager.runEWithContexts(this::codeThatUsesMarshalling, new XStreamContext2());
106         final var s = contextManager.runEWithContexts(this::codeThatUsesMarshalling2, new XStreamContext2());
107         log.info("{}", s);
108       }
109 
110     private void codeThatUsesMarshalling()
111             throws IOException
112       {
113         final var path1 = Path.of("target/Person.xml");
114         final var path2 = Path.of("target/People.xml");
115         // START SNIPPET: xstreamcontext-example1
116         final var joe = new Person(new Id("1"), "Joe", "Smith");
117         final var luke = new Person(new Id("2"), "Luke", "Skywalker");
118 
119         var marshalledPersons = "";
120         var marshalledPerson = "";
121 
122         try (final var os = new ByteArrayOutputStream())
123           {
124             joe.as(_Marshallable_).marshal(os);
125             log.info("******** (joe as Marshallable) marshalled: {}\n", marshalledPerson = os.toString(UTF_8));
126           }
127 
128         try (final var os = new ByteArrayOutputStream())
129           {
130             ListOfPersons.of(joe, luke).as(_Marshallable_).marshal(os);
131             log.info("******** (listOfPersons as Marshallable) marshalled: {}\n", marshalledPersons = os.toString(UTF_8));
132           }
133         // END SNIPPET: xstreamcontext-example1
134 
135         // START SNIPPET: xstreamcontext-example2
136         try (final var is = new ByteArrayInputStream(marshalledPerson.getBytes(UTF_8)))
137           {
138             final var person = Person.prototype().as(_Unmarshallable_).unmarshal(is);
139             log.info("******** Unmarshalled person: {}\n", person);
140           }
141 
142         try (final var is = new ByteArrayInputStream(marshalledPersons.getBytes(UTF_8)))
143           {
144             final var listOfPersons = ListOfPersons.empty().as(_Unmarshallable_).unmarshal(is);
145             log.info("******** Unmarshalled persons: {}\n", listOfPersons);
146           }
147         // END SNIPPET: xstreamcontext-example2
148 
149         // START SNIPPET: xstreamcontext-savable-loadable
150         joe.as(_Savable_).saveTo(path1);
151         ListOfPersons.of(joe, luke).as(_Savable_).saveTo(path2);
152         final var p = Person.prototype().as(_Loadable_).loadFrom(path1);
153         final var lp = ListOfPersons.empty().as(_Loadable_).loadFrom(path2);
154         // END SNIPPET: xstreamcontext-savable-loadable
155         log.info("******** Loaded person: {}\n", p);
156         log.info("******** Loaded persons: {}\n", lp);
157       }
158 
159     @Nonnull
160     private String codeThatUsesMarshalling2()
161             throws IOException
162       {
163         codeThatUsesMarshalling();
164         return "foo bar";
165       }
166   }