View Javadoc

1   /**
2    * Copyright (c) 2008-2011, http://www.snakeyaml.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.yaml.snakeyaml.issues.issue99;
18  
19  import java.io.BufferedInputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.util.Map;
23  
24  import junit.framework.TestCase;
25  
26  import org.yaml.snakeyaml.Util;
27  import org.yaml.snakeyaml.Yaml;
28  import org.yaml.snakeyaml.YamlDocument;
29  import org.yaml.snakeyaml.constructor.AbstractConstruct;
30  import org.yaml.snakeyaml.constructor.Constructor;
31  import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
32  import org.yaml.snakeyaml.nodes.Node;
33  import org.yaml.snakeyaml.nodes.ScalarNode;
34  import org.yaml.snakeyaml.nodes.Tag;
35  
36  /**
37   * Example for issue 99
38   * 
39   * @see http://code.google.com/p/snakeyaml/issues/detail?id=99
40   */
41  public class YamlBase64Test extends TestCase {
42  
43      /**
44       * test base64 decoding
45       */
46      public void testBase64() throws IOException {
47          String text = Util.getLocalResource("issues/issue99-base64_literal.yaml");
48          String[] lines = text.split("\n");
49          String all = "";
50          for (int i = 1; i < lines.length; i++) {// skip first line
51              all = all + lines[i].trim();
52          }
53          // System.out.println(all);
54          byte[] decoded = Base64Coder.decode(all.toCharArray());
55          assertEquals(3737, decoded.length);
56          checkBytes(decoded);
57      }
58  
59      @SuppressWarnings("unchecked")
60      public void testYamlBase64Loading() throws IOException {
61          Yaml yaml = new Yaml();
62          InputStream inputStream = YamlBase64Test.class
63                  .getResourceAsStream("/issues/issue99-base64_double_quoted.yaml");
64          Map<String, Object> bean = (Map<String, Object>) yaml.load(inputStream);
65          byte[] jpeg = (byte[]) bean.get("jpegPhoto");
66          checkBytes(jpeg);
67          inputStream.close();
68      }
69  
70      private void checkBytes(byte[] jpeg) throws IOException {
71          InputStream input;
72          input = YamlDocument.class.getClassLoader().getResourceAsStream("issues/issue99.jpeg");
73          BufferedInputStream is = new BufferedInputStream(input);
74          int i = 0;
75          while (i < jpeg.length) {
76              int etalon = is.read();
77              if (jpeg[i] < 0) {
78                  assertEquals(etalon, jpeg[i] + 256);
79              } else {
80                  assertEquals(etalon, jpeg[i]);
81              }
82              i++;
83          }
84          is.close();
85      }
86  
87      /**
88       * In the literal scalar all the line breaks are significant
89       * 
90       * @throws IOException
91       */
92      public void testYamlBase64LoadingLiteral() throws IOException {
93          Yaml yaml = new Yaml();
94          InputStream inputStream = YamlBase64Test.class
95                  .getResourceAsStream("/issues/issue99-base64_literal.yaml");
96          try {
97              yaml.load(inputStream);
98              fail("In the literal scalar all the line breaks are significant");
99          } catch (Exception e) {
100             assertEquals("Length of Base64 encoded input string is not a multiple of 4.",
101                     e.getMessage());
102         } finally {
103             inputStream.close();
104         }
105     }
106 
107     /**
108      * Redefine the !!binary global tag in a way that it ignores all the white
109      * spaces to be able to use literal scalar
110      */
111     @SuppressWarnings("unchecked")
112     public void testRedefineBinaryTag() throws IOException {
113         Yaml yaml = new Yaml(new SpecialContructor(Tag.BINARY));
114         InputStream inputStream = YamlBase64Test.class
115                 .getResourceAsStream("/issues/issue99-base64_literal.yaml");
116         Map<String, Object> bean = (Map<String, Object>) yaml.load(inputStream);
117         byte[] jpeg = (byte[]) bean.get("jpegPhoto");
118         checkBytes(jpeg);
119         inputStream.close();
120     }
121 
122     private class SpecialContructor extends Constructor {
123         public SpecialContructor(Tag tag) {
124             this.yamlConstructors.put(tag, new MyBinaryConstructor());
125         }
126 
127         private class MyBinaryConstructor extends AbstractConstruct {
128             public Object construct(Node node) {
129                 String contentWithNewLines = constructScalar((ScalarNode) node).toString();
130                 String noNewLines = contentWithNewLines.replaceAll("\\s", "");
131                 byte[] decoded = Base64Coder.decode(noNewLines.toCharArray());
132                 return decoded;
133             }
134         }
135     }
136 
137     /**
138      * Define a local tag to ignore all the white spaces to be able to use
139      * literal scalar
140      */
141     @SuppressWarnings("unchecked")
142     public void testLocalBinaryTag() throws IOException {
143         Yaml yaml = new Yaml(new SpecialContructor(new Tag("!beautiful")));
144         InputStream inputStream = YamlBase64Test.class
145                 .getResourceAsStream("/issues/issue99-base64_literal_custom_tag.yaml");
146         Map<String, Object> bean = (Map<String, Object>) yaml.load(inputStream);
147         byte[] jpeg = (byte[]) bean.get("jpegPhoto");
148         checkBytes(jpeg);
149         inputStream.close();
150     }
151 }