001package com.hfg.setting;
002
003import java.lang.reflect.Constructor;
004import java.util.HashMap;
005import java.util.List;
006import java.util.Map;
007
008import com.hfg.exception.ProgrammingException;
009import com.hfg.util.collection.OrderedMap;
010import com.hfg.util.StringUtil;
011import com.hfg.xml.XMLName;
012import com.hfg.xml.XMLTag;
013
014//------------------------------------------------------------------------------
015/**
016 * A collection of XML-serializable settings.
017 *
018 * @author J. Alex Taylor, hairyfatguy.com
019 */
020//------------------------------------------------------------------------------
021// com.hfg XML/HTML Coding Library
022//
023// This library is free software; you can redistribute it and/or
024// modify it under the terms of the GNU Lesser General Public
025// License as published by the Free Software Foundation; either
026// version 2.1 of the License, or (at your option) any later version.
027//
028// This library is distributed in the hope that it will be useful,
029// but WITHOUT ANY WARRANTY; without even the implied warranty of
030// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
031// Lesser General Public License for more details.
032//
033// You should have received a copy of the GNU Lesser General Public
034// License along with this library; if not, write to the Free Software
035// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
036//
037// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
038// jataylor@hairyfatguy.com
039//------------------------------------------------------------------------------
040
041public class Settings implements Cloneable
042{
043   private String mName;
044   private XMLName mTagName = SettingXML.SETTINGS;
045
046   private Map<String, Setting> mSettingMap = new OrderedMap<>(25);
047
048   //###########################################################################
049   // CONSTRUCTORS
050   //###########################################################################
051
052   //---------------------------------------------------------------------------
053   public Settings()
054   {
055      init();
056   }
057
058   //---------------------------------------------------------------------------
059   public Settings(XMLTag inXMLTag)
060   {
061      this();
062
063      inXMLTag.verifyTagName(mTagName);
064
065      setName(inXMLTag.getAttributeValue(SettingXML.NAME_ATT));
066
067      List<XMLTag> subtags = inXMLTag.getSubtags();
068      if (subtags != null)
069      {
070         for (XMLTag subtag : subtags)
071         {
072            String classname = subtag.getAttributeValue(SettingXML.TYPE_ATT);
073            if (StringUtil.isSet(classname))
074            {
075               try
076               {
077                  Class clazz = Class.forName(classname);
078                  Constructor constructor = clazz.getConstructor(XMLTag.class);
079                  add((Setting) constructor.newInstance(subtag));
080               }
081               catch (Exception e)
082               {
083                  throw new RuntimeException("Problem extracting setting!", e);
084               }
085            }
086         }
087      }
088   }
089
090   //###########################################################################
091   // PUBLIC METHODS
092   //###########################################################################
093
094   //---------------------------------------------------------------------------
095   @Override
096   public Settings clone()
097   {
098      Settings cloneObj = null;
099      try
100      {
101         cloneObj = (Settings) super.clone();
102      }
103      catch (CloneNotSupportedException e)
104      {
105         throw new ProgrammingException(e);
106      }
107
108      cloneObj.mSettingMap = new HashMap<>(mSettingMap.size());
109      for (String settingKey : mSettingMap.keySet())
110      {
111         cloneObj.mSettingMap.put(settingKey, mSettingMap.get(settingKey).clone());
112      }
113
114      return cloneObj;
115   }
116
117   //---------------------------------------------------------------------------
118   public int size()
119   {
120      return mSettingMap.size();
121   }
122
123   //---------------------------------------------------------------------------
124   public XMLTag toXMLTag()
125   {
126      XMLTag tag = new XMLTag(SettingXML.SETTINGS);
127
128      if (StringUtil.isSet(mName))
129      {
130         tag.setAttribute(SettingXML.NAME_ATT, mName);
131      }
132
133      for (Setting setting : mSettingMap.values())
134      {
135         tag.addSubtag(setting.toXMLTag());
136      }
137
138      return tag;
139   }
140
141   //---------------------------------------------------------------------------
142   public Settings add(Setting inValue)
143   {
144      mSettingMap.put(inValue.name(), inValue);
145      return this;
146   }
147
148   //---------------------------------------------------------------------------
149   public Setting get(String inName)
150   {
151      return mSettingMap.get(inName);
152   }
153
154   //---------------------------------------------------------------------------
155   public Settings setName(String inName)
156   {
157      mName = inName;
158      return this;
159   }
160
161   //---------------------------------------------------------------------------
162   public String name()
163   {
164      return mName;
165   }
166
167   //---------------------------------------------------------------------------
168   public Settings setTagName(XMLName inName)
169   {
170      mTagName = inName;
171      return this;
172   }
173
174   //###########################################################################
175   // PROTECTED METHODS
176   //###########################################################################
177
178   //---------------------------------------------------------------------------
179   /**
180    For subclasses to override.
181    */
182   protected void init()
183   {
184
185   }
186}