View Javadoc
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  
18  package org.apache.commons.configuration2;
19  
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.Reader;
23  import java.io.Writer;
24  import java.util.Map;
25  
26  import org.apache.commons.configuration2.ex.ConfigurationException;
27  import org.apache.commons.configuration2.io.InputStreamSupport;
28  import org.apache.commons.configuration2.tree.ImmutableNode;
29  import org.yaml.snakeyaml.DumperOptions;
30  import org.yaml.snakeyaml.LoaderOptions;
31  import org.yaml.snakeyaml.Yaml;
32  import org.yaml.snakeyaml.constructor.SafeConstructor;
33  import org.yaml.snakeyaml.representer.Representer;
34  
35  /**
36   * <p>
37   * A specialized hierarchical configuration class that is able to parse YAML documents.
38   * </p>
39   *
40   * @since 2.2
41   */
42  public class YAMLConfiguration extends AbstractYAMLBasedConfiguration implements FileBasedConfiguration, InputStreamSupport {
43      /**
44       * Creates a new instance of {@code YAMLConfiguration}.
45       */
46      public YAMLConfiguration() {
47      }
48  
49      /**
50       * Creates a new instance of {@code YAMLConfiguration} as a copy of the specified configuration.
51       *
52       * @param c the configuration to be copied
53       */
54      public YAMLConfiguration(final HierarchicalConfiguration<ImmutableNode> c) {
55          super(c);
56      }
57  
58      @Override
59      public void read(final Reader in) throws ConfigurationException {
60          try {
61              final Yaml yaml = createYamlForReading(new LoaderOptions());
62              final Map<String, Object> map = yaml.load(in);
63              load(map);
64          } catch (final Exception e) {
65              rethrowException(e);
66          }
67      }
68  
69      public void read(final Reader in, final LoaderOptions options) throws ConfigurationException {
70          try {
71              final Yaml yaml = createYamlForReading(options);
72              final Map<String, Object> map = yaml.load(in);
73              load(map);
74          } catch (final Exception e) {
75              rethrowException(e);
76          }
77      }
78  
79      @Override
80      public void write(final Writer out) throws ConfigurationException, IOException {
81          final DumperOptions options = new DumperOptions();
82          options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
83          dump(out, options);
84      }
85  
86      public void dump(final Writer out, final DumperOptions options)
87              throws ConfigurationException, IOException {
88          final Yaml yaml = new Yaml(options);
89          yaml.dump(constructMap(getNodeModel().getNodeHandler().getRootNode()), out);
90      }
91  
92      /**
93       * Loads the configuration from the given input stream.
94       *
95       * @param in the input stream
96       * @throws ConfigurationException if an error occurs
97       */
98      @Override
99      public void read(final InputStream in) throws ConfigurationException {
100         try {
101             final Yaml yaml = createYamlForReading(new LoaderOptions());
102             final Map<String, Object> map = yaml.load(in);
103             load(map);
104         } catch (final Exception e) {
105             rethrowException(e);
106         }
107     }
108 
109     public void read(final InputStream in, final LoaderOptions options) throws ConfigurationException {
110         try {
111             final Yaml yaml = createYamlForReading(options);
112             final Map<String, Object> map = yaml.load(in);
113             load(map);
114         } catch (final Exception e) {
115             rethrowException(e);
116         }
117     }
118 
119     /**
120      * Creates a {@code Yaml} object for reading a Yaml file. The object is configured with some default settings.
121      *
122      * @param options options for loading the file
123      * @return the {@code Yaml} instance for loading a file
124      */
125     private static Yaml createYamlForReading(final LoaderOptions options) {
126         return new Yaml(new SafeConstructor(options), new Representer(new DumperOptions()), new DumperOptions(), options);
127     }
128 
129 }