001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.configuration2; 019 020import java.io.IOException; 021import java.io.InputStream; 022import java.io.Reader; 023import java.io.Writer; 024 025import org.apache.commons.configuration2.ex.ConfigurationException; 026import org.apache.commons.configuration2.io.InputStreamSupport; 027import org.apache.commons.configuration2.tree.ImmutableNode; 028import org.yaml.snakeyaml.DumperOptions; 029import org.yaml.snakeyaml.LoaderOptions; 030import org.yaml.snakeyaml.Yaml; 031import org.yaml.snakeyaml.constructor.SafeConstructor; 032import org.yaml.snakeyaml.representer.Representer; 033 034/** 035 * <p> 036 * A specialized hierarchical configuration class that is able to parse YAML documents. 037 * </p> 038 * 039 * @since 2.2 040 */ 041public class YAMLConfiguration extends AbstractYAMLBasedConfiguration implements FileBasedConfiguration, InputStreamSupport { 042 043 /** 044 * Creates a {@code Yaml} object for reading a Yaml file. The object is configured with some default settings. 045 * 046 * @param options options for loading the file 047 * @return the {@code Yaml} instance for loading a file 048 */ 049 private static Yaml createYamlForReading(final LoaderOptions options) { 050 return new Yaml(new SafeConstructor(options), new Representer(new DumperOptions()), new DumperOptions(), options); 051 } 052 053 /** 054 * Creates a new instance of {@code YAMLConfiguration}. 055 */ 056 public YAMLConfiguration() { 057 } 058 059 /** 060 * Creates a new instance of {@code YAMLConfiguration} as a copy of the specified configuration. 061 * 062 * @param c the configuration to be copied 063 */ 064 public YAMLConfiguration(final HierarchicalConfiguration<ImmutableNode> c) { 065 super(c); 066 } 067 068 public void dump(final Writer out, final DumperOptions options) 069 throws ConfigurationException, IOException { 070 new Yaml(options).dump(constructMap(getNodeModel().getNodeHandler().getRootNode()), out); 071 } 072 073 /** 074 * Loads the configuration from the given input stream. 075 * 076 * @param in the input stream 077 * @throws ConfigurationException if an error occurs 078 */ 079 @Override 080 public void read(final InputStream in) throws ConfigurationException { 081 try { 082 load(createYamlForReading(new LoaderOptions()).load(in)); 083 } catch (final Exception e) { 084 rethrowException(e); 085 } 086 } 087 088 public void read(final InputStream in, final LoaderOptions options) throws ConfigurationException { 089 try { 090 load(createYamlForReading(options).load(in)); 091 } catch (final Exception e) { 092 rethrowException(e); 093 } 094 } 095 096 @Override 097 public void read(final Reader in) throws ConfigurationException { 098 try { 099 load(createYamlForReading(new LoaderOptions()).load(in)); 100 } catch (final Exception e) { 101 rethrowException(e); 102 } 103 } 104 105 public void read(final Reader in, final LoaderOptions options) throws ConfigurationException { 106 try { 107 load(createYamlForReading(options).load(in)); 108 } catch (final Exception e) { 109 rethrowException(e); 110 } 111 } 112 113 @Override 114 public void write(final Writer out) throws ConfigurationException, IOException { 115 final DumperOptions options = new DumperOptions(); 116 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); 117 dump(out, options); 118 } 119 120}