1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */ 
17  package org.apache.commons.betwixt.strategy;
18  
19  import java.io.StringReader;
20  import java.io.StringWriter;
21  
22  import org.apache.commons.betwixt.AbstractTestCase;
23  import org.apache.commons.betwixt.expression.Context;
24  import org.apache.commons.betwixt.io.BeanReader;
25  import org.apache.commons.betwixt.io.BeanWriter;
26  import org.xml.sax.InputSource;
27  
28  /**
29   */
30  public class TestIdStorageStrategy extends AbstractTestCase {
31  
32      public TestIdStorageStrategy(String testName) {
33          super(testName);   
34      }
35  
36      public void testWrite() throws Exception {
37          
38          final Element alpha = new Element("ONE");
39          Element beta = new Element("TWO");
40          ElementsList elements = new ElementsList();
41          elements.addElement(alpha);
42          elements.addElement(beta);
43          
44          IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
45  
46              public String getReferenceFor(Context context, Object bean) {
47                  String result = null;
48                  if (bean == alpha) {
49                      result = "ALPHA";
50                  }
51                  else
52                  {
53                      result = super.getReferenceFor(context, bean);
54                  }
55                  return result;
56              }
57  
58              public void setReference(Context context, Object bean, String id) {
59                  if (bean != alpha) {
60                       super.setReference(context, bean, id);
61                  }
62              }            
63          };
64          
65          StringWriter out = new StringWriter();
66          out.write("<?xml version='1.0'?>");
67          BeanWriter writer = new BeanWriter(out);
68          writer.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
69          writer.write(elements);
70          
71          String expected = "<?xml version='1.0'?>" +
72                  "<ElementsList id='1'>" +
73                  "   <elements>" +
74                  "       <element idref='ALPHA'/>" +
75                  "       <element id='2'>" +
76                  "           <value>TWO</value>" +
77                  "       </element>" +
78                  "   </elements>" +
79                  "</ElementsList>";
80  
81          xmlAssertIsomorphicContent(parseString(expected), parseString(out));
82      }
83      
84      public void testRead() throws Exception {
85          
86          String xml = "<?xml version='1.0'?>" +
87          "<ElementsList id='1'>" +
88          "   <elements>" +
89          "       <element idref='ALPHA'/>" +
90          "       <element id='2'>" +
91          "           <value>TWO</value>" +
92          "       </element>" +
93          "   </elements>" +
94          "</ElementsList>";
95          
96          final Element alpha = new Element("ONE");
97          
98          IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
99  
100             public void setReference(Context context, Object bean, String id) {
101                 if (bean != alpha) {
102                      super.setReference(context, bean, id);
103                 }
104             }     
105             
106             public Object getReferenced(Context context, String id) {
107                 if ("ALPHA".equals(id)) {
108                     return alpha;
109                 }
110                 return getReferenced(context, id);
111             }
112             
113         };
114         
115         BeanReader reader = new BeanReader();
116         reader.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
117         reader.registerBeanClass(ElementsList.class);
118         ElementsList elements = (ElementsList) reader.parse(new StringReader(xml));
119         assertNotNull(elements);
120         Element one = elements.get(0);
121         assertTrue(one == alpha);
122         Element two = elements.get(1);
123         assertNotNull(two);
124     }
125     
126     
127     public void testWriteWithOptions() throws Exception {
128         
129         final Element alpha = new Element("ONE");
130         Element beta = new Element("TWO");
131         ElementsList elements = new ElementsList();
132         elements.addElement(alpha);
133         elements.addElement(beta);
134         
135         String MAPPING = "<?xml version='1.0'?>" +
136         "<betwixt-config>" +
137         "  <class name=\"" + ElementsList.class.getName() + "\">" +
138         "    <element name=\"ElementsList\">" +
139         "      <option>" +
140         "        <name>id-strategy-prefix</name>" +
141         "        <value>alice</value>" +
142         "      </option>" +
143         "      <element name=\"elements\">" +
144         "        <element property=\"elements\">" +
145         "          <option>" +
146         "            <name>id-strategy-prefix</name>" +
147         "            <value>bob</value>" +
148         "          </option>" +
149         "        </element>" +
150         "      </element>" +
151         "    </element>" +
152         "  </class>" +
153         "</betwixt-config>";
154 
155         IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
156 
157             public String getReferenceFor(Context context, Object bean) {
158                 String result = null;
159                 if( bean instanceof ElementsList) {
160                     assertNotNull( context.getOptions() );
161                     assertEquals("Checking ElementsList option","alice",context.getOptions().getValue("id-strategy-prefix"));
162                 }
163                 if( bean instanceof Element) {
164                     assertNotNull( context.getOptions() );
165                     assertEquals("Checking Element option","bob",context.getOptions().getValue("id-strategy-prefix"));
166                 }
167                 if (bean == alpha) {
168                     result = "ALPHA";
169                 }
170                 else
171                 {
172                     result = super.getReferenceFor(context, bean);
173                 }
174                 return result;
175             }
176 
177             public void setReference(Context context, Object bean, String id) {
178                 if (bean != alpha) {
179                      super.setReference(context, bean, id);
180                 }
181             }            
182         };
183         
184         StringWriter out = new StringWriter();
185         out.write("<?xml version='1.0'?>");
186         BeanWriter writer = new BeanWriter(out);
187         writer.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
188         writer.getXMLIntrospector().register(new InputSource(new StringReader(MAPPING)));
189         writer.write(elements);
190         
191         String expected = "<?xml version='1.0'?>" +
192                 "<ElementsList id='1'>" +
193                 "   <elements>" +
194                 "       <Element idref='ALPHA'/>" +
195                 "       <Element id='2'>" +
196                 "           <value>TWO</value>" +
197                 "       </Element>" +
198                 "   </elements>" +
199                 "</ElementsList>";
200 
201         xmlAssertIsomorphicContent(parseString(expected), parseString(out));
202     }
203     
204     public void testWriteWithParentOptions() throws Exception {
205         
206         AlphaBean alpha = new AlphaBean();
207         alpha.setName("apple");
208         BetaBean beta = new BetaBean();
209         beta.setName("banana");
210         alpha.setBetaBean(beta);
211         
212         String MAPPING = "<?xml version='1.0'?>" +
213         "<betwixt-config>" +
214         "  <class name=\"" + AlphaBean.class.getName() + "\">" +
215         "    <element name=\"alpha\">" +
216         "      <element name=\"name\" property=\"name\" />" +
217         "      <element property=\"betaBean\">" +
218         "        <option>" +
219         "          <name>id-strategy-prefix</name>" +
220         "          <value>parent</value>" +
221         "        </option>" +
222         "      </element>" +
223         "    </element>" +
224         "  </class>" +
225         "  <class name=\"" + BetaBean.class.getName() + "\">" +
226         "    <element name=\"beta\">" +
227         "      <element name=\"name\" property=\"name\" />" +
228         "    </element>" +
229         "  </class>" +
230         "</betwixt-config>";
231 
232         IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
233             public String getReferenceFor(Context context, Object bean) {
234                 if( bean instanceof BetaBean) {
235                     assertNotNull( context.getOptions() );
236                     assertEquals("Checking BetaBean option","parent",context.getOptions().getValue("id-strategy-prefix"));
237                 }
238                 return super.getReferenceFor(context, bean);
239             }
240         };
241         
242         StringWriter out = new StringWriter();
243         out.write("<?xml version='1.0'?>");
244         BeanWriter writer = new BeanWriter(out);
245         writer.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
246         writer.getXMLIntrospector().register(new InputSource(new StringReader(MAPPING)));
247         writer.write(alpha);
248         
249         String expected = "<?xml version='1.0'?>" +
250                 "<alpha id=\"1\">" +
251                 "  <name>apple</name>" +
252                 "  <beta id=\"2\">" +
253                 "    <name>banana</name>"+
254                 "  </beta>" +
255                 "</alpha>";
256 
257         xmlAssertIsomorphicContent(parseString(expected), parseString(out));
258     }
259     
260     public void testWriteWithTargetOptions() throws Exception {
261         
262         AlphaBean alpha = new AlphaBean();
263         alpha.setName("apple");
264         BetaBean beta = new BetaBean();
265         beta.setName("banana");
266         alpha.setBetaBean(beta);
267         
268         String MAPPING = "<?xml version='1.0'?>" +
269         "<betwixt-config>" +
270         "  <class name=\"" + AlphaBean.class.getName() + "\">" +
271         "    <element name=\"alpha\">" +
272         "      <element name=\"name\" property=\"name\" />" +
273         "      <element property=\"betaBean\" />" +
274         "    </element>" +
275         "  </class>" +
276         "  <class name=\"" + BetaBean.class.getName() + "\">" +
277         "    <element name=\"beta\">" +
278         "      <option>" +
279         "        <name>id-strategy-prefix</name>" +
280         "        <value>target</value>" +
281         "      </option>" +
282         "      <element name=\"name\" property=\"name\" />" +
283         "    </element>" +
284         "  </class>" +
285         "</betwixt-config>";
286 
287         IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
288             public String getReferenceFor(Context context, Object bean) {
289                 if( bean instanceof BetaBean) {
290                     assertNotNull( context.getOptions() );
291                     assertEquals("Checking BetaBean option","target",context.getOptions().getValue("id-strategy-prefix"));
292                 }
293                 return super.getReferenceFor(context, bean);
294             }
295         };
296         
297         StringWriter out = new StringWriter();
298         out.write("<?xml version='1.0'?>");
299         BeanWriter writer = new BeanWriter(out);
300         writer.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
301         writer.getXMLIntrospector().register(new InputSource(new StringReader(MAPPING)));
302         writer.write(alpha);
303         
304         String expected = "<?xml version='1.0'?>" +
305                 "<alpha id=\"1\">" +
306                 "  <name>apple</name>" +
307                 "  <beta id=\"2\">" +
308                 "    <name>banana</name>"+
309                 "  </beta>" +
310                 "</alpha>";
311 
312         xmlAssertIsomorphicContent(parseString(expected), parseString(out));
313     }
314     
315     public void testWriteWithParentAndTargetOptions() throws Exception {
316         
317         AlphaBean alpha = new AlphaBean();
318         alpha.setName("apple");
319         BetaBean beta = new BetaBean();
320         beta.setName("banana");
321         alpha.setBetaBean(beta);
322         
323         String MAPPING = "<?xml version='1.0'?>" +
324         "<betwixt-config>" +
325         "  <class name=\"" + AlphaBean.class.getName() + "\">" +
326         "    <element name=\"alpha\">" +
327         "      <element name=\"name\" property=\"name\" />" +
328         "      <element property=\"betaBean\">" +
329         "        <option>" +
330         "          <name>id-strategy-prefix</name>" +
331         "          <value>parent</value>" +
332         "        </option>" +
333         "      </element>" +
334         "    </element>" +
335         "  </class>" +
336         "  <class name=\"" + BetaBean.class.getName() + "\">" +
337         "    <element name=\"beta\">" +
338         "      <option>" +
339         "        <name>id-strategy-prefix</name>" +
340         "        <value>target</value>" +
341         "      </option>" +
342         "      <element name=\"name\" property=\"name\" />" +
343         "    </element>" +
344         "  </class>" +
345         "</betwixt-config>";
346 
347         IdStoringStrategy storingStrategy = new DefaultIdStoringStrategy() {
348             public String getReferenceFor(Context context, Object bean) {
349                 if( bean instanceof BetaBean) {
350                     assertNotNull( context.getOptions() );
351                     assertEquals("Checking BetaBean option","parent",context.getOptions().getValue("id-strategy-prefix"));
352                 }
353                 return super.getReferenceFor(context, bean);
354             }
355         };
356         
357         StringWriter out = new StringWriter();
358         out.write("<?xml version='1.0'?>");
359         BeanWriter writer = new BeanWriter(out);
360         writer.getBindingConfiguration().setIdMappingStrategy(storingStrategy);
361         writer.getXMLIntrospector().register(new InputSource(new StringReader(MAPPING)));
362         writer.write(alpha);
363         
364         String expected = "<?xml version='1.0'?>" +
365                 "<alpha id=\"1\">" +
366                 "  <name>apple</name>" +
367                 "  <beta id=\"2\">" +
368                 "    <name>banana</name>"+
369                 "  </beta>" +
370                 "</alpha>";
371 
372         xmlAssertIsomorphicContent(parseString(expected), parseString(out));
373     }
374 }