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 * http://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; 024import java.util.Map; 025 026import org.apache.commons.configuration2.ex.ConfigurationException; 027import org.apache.commons.configuration2.io.InputStreamSupport; 028import org.apache.commons.configuration2.tree.ImmutableNode; 029import org.yaml.snakeyaml.DumperOptions; 030import org.yaml.snakeyaml.LoaderOptions; 031import org.yaml.snakeyaml.Yaml; 032import org.yaml.snakeyaml.constructor.SafeConstructor; 033import org.yaml.snakeyaml.representer.Representer; 034 035/** 036 * <p> 037 * A specialized hierarchical configuration class that is able to parse YAML documents. 038 * </p> 039 * 040 * @since 2.2 041 */ 042public class YAMLConfiguration extends AbstractYAMLBasedConfiguration implements FileBasedConfiguration, InputStreamSupport { 043 /** 044 * Creates a new instance of {@code YAMLConfiguration}. 045 */ 046 public YAMLConfiguration() { 047 } 048 049 /** 050 * Creates a new instance of {@code YAMLConfiguration} as a copy of the specified configuration. 051 * 052 * @param c the configuration to be copied 053 */ 054 public YAMLConfiguration(final HierarchicalConfiguration<ImmutableNode> c) { 055 super(c); 056 } 057 058 @Override 059 public void read(final Reader in) throws ConfigurationException { 060 try { 061 final Yaml yaml = createYamlForReading(new LoaderOptions()); 062 final Map<String, Object> map = yaml.load(in); 063 load(map); 064 } catch (final Exception e) { 065 rethrowException(e); 066 } 067 } 068 069 public void read(final Reader in, final LoaderOptions options) throws ConfigurationException { 070 try { 071 final Yaml yaml = createYamlForReading(options); 072 final Map<String, Object> map = yaml.load(in); 073 load(map); 074 } catch (final Exception e) { 075 rethrowException(e); 076 } 077 } 078 079 @Override 080 public void write(final Writer out) throws ConfigurationException, IOException { 081 final DumperOptions options = new DumperOptions(); 082 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); 083 dump(out, options); 084 } 085 086 public void dump(final Writer out, final DumperOptions options) 087 throws ConfigurationException, IOException { 088 final Yaml yaml = new Yaml(options); 089 yaml.dump(constructMap(getNodeModel().getNodeHandler().getRootNode()), out); 090 } 091 092 /** 093 * Loads the configuration from the given input stream. 094 * 095 * @param in the input stream 096 * @throws ConfigurationException if an error occurs 097 */ 098 @Override 099 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}