View Javadoc

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