001package com.hfg.setting;
002
003import java.lang.reflect.Constructor;
004import java.lang.reflect.Method;
005import java.util.List;
006
007import com.hfg.exception.UnimplementedMethodException;
008import com.hfg.util.StringUtil;
009import com.hfg.util.collection.CollectionUtil;
010import com.hfg.xml.XMLTag;
011
012//------------------------------------------------------------------------------
013/**
014 Custom XML-serializable settings.
015 Requires getInstance(), valueOf(), an XMLTag constructor, or a default constructor.
016 <div>
017   @author J. Alex Taylor, hairyfatguy.com
018 </div>
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 ComplexSetting extends SettingImpl implements Setting<Object>
042{
043
044   //###########################################################################
045   // CONSTRUCTORS
046   //###########################################################################
047
048   //---------------------------------------------------------------------------
049   public ComplexSetting(String inName)
050   {
051      super(inName);
052   }
053
054   //---------------------------------------------------------------------------
055   public ComplexSetting(String inName, Object inValue)
056   {
057      super(inName, inValue);
058   }
059
060   //---------------------------------------------------------------------------
061   /**
062    * Copy constructor.
063    * @param inObj2 the ComplexSetting to clone
064    */
065   public ComplexSetting(ComplexSetting inObj2)
066   {
067      this(inObj2.name(), inObj2.getValue());
068   }
069
070   //---------------------------------------------------------------------------
071   public ComplexSetting(XMLTag inXMLTag)
072   {
073      super(inXMLTag);
074
075      List<XMLTag> subtags = inXMLTag.getSubtags();
076      if (CollectionUtil.hasValues(subtags))
077      {
078         if (subtags.size() > 1)
079         {
080            throw new RuntimeException("Only one subtag can be present in a ComplexSetting!");
081         }
082
083         XMLTag subtag = subtags.get(0);
084
085         String classname = subtag.getAttributeValue(SettingXML.CLASS_ATT);
086         if (StringUtil.isSet(classname))
087         {
088            try
089            {
090               Class clazz = Class.forName(classname);
091
092               if (Boolean.valueOf(subtag.getAttributeValue(SettingXML.INSTANCE_ATT)))
093               {
094                  Method method = clazz.getMethod("getInstance");
095                  setValue(method.invoke(null));
096               }
097               else if (Boolean.valueOf(subtag.getAttributeValue(SettingXML.ENUM_ATT)))
098               {
099                  Method method = clazz.getMethod("valueOf", String.class);
100                  setValue(method.invoke(null, subtag.getUnescapedContent()));
101               }
102               else
103               {
104                  try
105                  {
106                     Constructor constructor = clazz.getConstructor(XMLTag.class);
107                     setValue(constructor.newInstance(subtag));
108                  }
109                  catch (NoSuchMethodException e)
110                  {
111                     Constructor constructor = clazz.getConstructor();
112                     setValue(constructor.newInstance());
113                  }
114               }
115            }
116            catch (Exception e)
117            {
118               throw new RuntimeException("Problem extracting setting!", e);
119            }
120         }
121      }
122   }
123
124   //###########################################################################
125   // PUBLIC METHODS
126   //###########################################################################
127
128   //---------------------------------------------------------------------------
129   @Override
130   public ComplexSetting setValue(Object inValue)
131   {
132      super.setObjectValue(inValue);
133      return this;
134   }
135
136    //---------------------------------------------------------------------------
137   @Override
138   public Object getValue()
139   {
140      return super.getObjectValue();
141   }
142
143    //---------------------------------------------------------------------------
144   @Override
145   protected void setValueFromString(String inValue)
146   {
147      throw new UnimplementedMethodException();
148   }
149
150   //---------------------------------------------------------------------------
151   @Override
152   public ComplexSetting clone()
153   {
154      return new ComplexSetting(this);
155   }
156}