github.com/astaxie/beego@v1.12.3/config/xml/xml.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package xml for config provider.
    16  //
    17  // depend on github.com/beego/x2j.
    18  //
    19  // go install github.com/beego/x2j.
    20  //
    21  // Usage:
    22  //  import(
    23  //    _ "github.com/astaxie/beego/config/xml"
    24  //      "github.com/astaxie/beego/config"
    25  //  )
    26  //
    27  //  cnf, err := config.NewConfig("xml", "config.xml")
    28  //
    29  //More docs http://beego.me/docs/module/config.md
    30  package xml
    31  
    32  import (
    33  	"encoding/xml"
    34  	"errors"
    35  	"fmt"
    36  	"io/ioutil"
    37  	"os"
    38  	"strconv"
    39  	"strings"
    40  	"sync"
    41  
    42  	"github.com/astaxie/beego/config"
    43  	"github.com/beego/x2j"
    44  )
    45  
    46  // Config is a xml config parser and implements Config interface.
    47  // xml configurations should be included in <config></config> tag.
    48  // only support key/value pair as <key>value</key> as each item.
    49  type Config struct{}
    50  
    51  // Parse returns a ConfigContainer with parsed xml config map.
    52  func (xc *Config) Parse(filename string) (config.Configer, error) {
    53  	context, err := ioutil.ReadFile(filename)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	return xc.ParseData(context)
    59  }
    60  
    61  // ParseData xml data
    62  func (xc *Config) ParseData(data []byte) (config.Configer, error) {
    63  	x := &ConfigContainer{data: make(map[string]interface{})}
    64  
    65  	d, err := x2j.DocToMap(string(data))
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	x.data = config.ExpandValueEnvForMap(d["config"].(map[string]interface{}))
    71  
    72  	return x, nil
    73  }
    74  
    75  // ConfigContainer A Config represents the xml configuration.
    76  type ConfigContainer struct {
    77  	data map[string]interface{}
    78  	sync.Mutex
    79  }
    80  
    81  // Bool returns the boolean value for a given key.
    82  func (c *ConfigContainer) Bool(key string) (bool, error) {
    83  	if v := c.data[key]; v != nil {
    84  		return config.ParseBool(v)
    85  	}
    86  	return false, fmt.Errorf("not exist key: %q", key)
    87  }
    88  
    89  // DefaultBool return the bool value if has no error
    90  // otherwise return the defaultval
    91  func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
    92  	v, err := c.Bool(key)
    93  	if err != nil {
    94  		return defaultval
    95  	}
    96  	return v
    97  }
    98  
    99  // Int returns the integer value for a given key.
   100  func (c *ConfigContainer) Int(key string) (int, error) {
   101  	return strconv.Atoi(c.data[key].(string))
   102  }
   103  
   104  // DefaultInt returns the integer value for a given key.
   105  // if err != nil return defaultval
   106  func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
   107  	v, err := c.Int(key)
   108  	if err != nil {
   109  		return defaultval
   110  	}
   111  	return v
   112  }
   113  
   114  // Int64 returns the int64 value for a given key.
   115  func (c *ConfigContainer) Int64(key string) (int64, error) {
   116  	return strconv.ParseInt(c.data[key].(string), 10, 64)
   117  }
   118  
   119  // DefaultInt64 returns the int64 value for a given key.
   120  // if err != nil return defaultval
   121  func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
   122  	v, err := c.Int64(key)
   123  	if err != nil {
   124  		return defaultval
   125  	}
   126  	return v
   127  
   128  }
   129  
   130  // Float returns the float value for a given key.
   131  func (c *ConfigContainer) Float(key string) (float64, error) {
   132  	return strconv.ParseFloat(c.data[key].(string), 64)
   133  }
   134  
   135  // DefaultFloat returns the float64 value for a given key.
   136  // if err != nil return defaultval
   137  func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
   138  	v, err := c.Float(key)
   139  	if err != nil {
   140  		return defaultval
   141  	}
   142  	return v
   143  }
   144  
   145  // String returns the string value for a given key.
   146  func (c *ConfigContainer) String(key string) string {
   147  	if v, ok := c.data[key].(string); ok {
   148  		return v
   149  	}
   150  	return ""
   151  }
   152  
   153  // DefaultString returns the string value for a given key.
   154  // if err != nil return defaultval
   155  func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
   156  	v := c.String(key)
   157  	if v == "" {
   158  		return defaultval
   159  	}
   160  	return v
   161  }
   162  
   163  // Strings returns the []string value for a given key.
   164  func (c *ConfigContainer) Strings(key string) []string {
   165  	v := c.String(key)
   166  	if v == "" {
   167  		return nil
   168  	}
   169  	return strings.Split(v, ";")
   170  }
   171  
   172  // DefaultStrings returns the []string value for a given key.
   173  // if err != nil return defaultval
   174  func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
   175  	v := c.Strings(key)
   176  	if v == nil {
   177  		return defaultval
   178  	}
   179  	return v
   180  }
   181  
   182  // GetSection returns map for the given section
   183  func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
   184  	if v, ok := c.data[section].(map[string]interface{}); ok {
   185  		mapstr := make(map[string]string)
   186  		for k, val := range v {
   187  			mapstr[k] = config.ToString(val)
   188  		}
   189  		return mapstr, nil
   190  	}
   191  	return nil, fmt.Errorf("section '%s' not found", section)
   192  }
   193  
   194  // SaveConfigFile save the config into file
   195  func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
   196  	// Write configuration file by filename.
   197  	f, err := os.Create(filename)
   198  	if err != nil {
   199  		return err
   200  	}
   201  	defer f.Close()
   202  	b, err := xml.MarshalIndent(c.data, "  ", "    ")
   203  	if err != nil {
   204  		return err
   205  	}
   206  	_, err = f.Write(b)
   207  	return err
   208  }
   209  
   210  // Set writes a new value for key.
   211  func (c *ConfigContainer) Set(key, val string) error {
   212  	c.Lock()
   213  	defer c.Unlock()
   214  	c.data[key] = val
   215  	return nil
   216  }
   217  
   218  // DIY returns the raw value by a given key.
   219  func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
   220  	if v, ok := c.data[key]; ok {
   221  		return v, nil
   222  	}
   223  	return nil, errors.New("not exist key")
   224  }
   225  
   226  func init() {
   227  	config.Register("xml", &Config{})
   228  }