001package com.hfg.util;
002
003import java.io.ByteArrayInputStream;
004import java.lang.reflect.Constructor;
005import java.util.Collection;
006import java.util.HashMap;
007import java.util.List;
008import java.util.Map;
009
010import com.hfg.exception.ProgrammingException;
011import com.hfg.util.collection.CollectionUtil;
012import com.hfg.xml.HfgXML;
013import com.hfg.xml.HfgXMLSerializable;
014import com.hfg.xml.XMLNode;
015import com.hfg.xml.XMLTag;
016import com.hfg.xml.XMLizable;
017
018
019//------------------------------------------------------------------------------
020/**
021 Generic attribute manager.
022 <div>
023 @author J. Alex Taylor, hairyfatguy.com
024 </div>
025 */
026//------------------------------------------------------------------------------
027// com.hfg XML/HTML Coding Library
028//
029// This library is free software; you can redistribute it and/or
030// modify it under the terms of the GNU Lesser General Public
031// License as published by the Free Software Foundation; either
032// version 2.1 of the License, or (at your option) any later version.
033//
034// This library is distributed in the hope that it will be useful,
035// but WITHOUT ANY WARRANTY; without even the implied warranty of
036// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
037// Lesser General Public License for more details.
038//
039// You should have received a copy of the GNU Lesser General Public
040// License along with this library; if not, write to the Free Software
041// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
042//
043// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
044// jataylor@hairyfatguy.com
045//------------------------------------------------------------------------------
046
047public class AttributeMgr implements Cloneable, HfgXMLSerializable
048{
049   private Map<String, Object> mAttributes;
050
051
052   //--------------------------------------------------------------------------
053   public AttributeMgr()
054   {
055   }
056
057   //--------------------------------------------------------------------------
058   public AttributeMgr(XMLNode inXML)
059   {
060      inXML.verifyTagName(HfgXML.ATTRIBUTES);
061
062      List<? extends XMLNode> attributeTags = inXML.getSubtagsByName(HfgXML.ATTRIBUTE);
063      for (XMLNode attrTag : attributeTags)
064      {
065         String name = attrTag.getAttributeValue(HfgXML.NAME_ATT);
066         String className = attrTag.getAttributeValue(HfgXML.CLASS_ATT);
067         if (attrTag.getAttributeValue(HfgXML.IS_NULL_ATT) != null)
068         {
069            setAttribute(name, null);
070         }
071         else
072         {
073            String value = attrTag.getUnescapedContent();
074            try
075            {
076               Class clazz = Class.forName(className);
077               if (String.class.getName().equals(className))
078               {
079                  setAttribute(name, value);
080               }
081               else if (Integer.class.getName().equals(className))
082               {
083                  setAttribute(name, Integer.valueOf(value));
084               }
085               else if (Long.class.getName().equals(className))
086               {
087                  setAttribute(name, Long.valueOf(value));
088               }
089               else if (Float.class.getName().equals(className))
090               {
091                  setAttribute(name, Float.valueOf(value));
092               }
093               else if (Double.class.getName().equals(className))
094               {
095                  setAttribute(name, Double.valueOf(value));
096               }
097               else if (Boolean.class.getName().equals(className))
098               {
099                  setAttribute(name, Boolean.valueOf(value));
100               }
101               else
102               {
103                  try
104                  {
105                     Constructor constructor = clazz.getConstructor(XMLTag.class);
106                     setAttribute(name, constructor.newInstance(new XMLTag(new ByteArrayInputStream(value.getBytes()))));
107                  }
108                  catch (NoSuchMethodException e)
109                  {
110                     Constructor constructor = clazz.getConstructor(String.class);
111                     setAttribute(name, constructor.newInstance(value));
112                  }
113               }
114            }
115            catch (Exception e)
116            {
117               throw new RuntimeException("Problem extracting the value for attribute " + StringUtil.singleQuote(name) + "!", e);
118            }
119         }
120      }
121   }
122
123
124   //--------------------------------------------------------------------------
125   public AttributeMgr setAttribute(String inName, Object inValue)
126   {
127      if (null == mAttributes)
128      {
129         mAttributes = new HashMap<>();
130      }
131
132      mAttributes.put(inName, inValue);
133
134      return this;
135   }
136
137   //--------------------------------------------------------------------------
138   public boolean hasAttributes()
139   {
140      return CollectionUtil.hasValues(mAttributes);
141   }
142
143   //--------------------------------------------------------------------------
144   public boolean hasAttribute(String inName)
145   {
146      return mAttributes != null && mAttributes.containsKey(inName);
147   }
148
149   //--------------------------------------------------------------------------
150   public Object getAttribute(String inName)
151   {
152      Object attr = null;
153      if (mAttributes != null)
154      {
155         attr = mAttributes.get(inName);
156      }
157
158      return attr;
159   }
160
161   //--------------------------------------------------------------------------
162   public Collection<String> getAttributeNames()
163   {
164      Collection<String> attrNames = null;
165      if (mAttributes != null)
166      {
167         attrNames = mAttributes.keySet();
168      }
169
170      return attrNames;
171   }
172
173   //--------------------------------------------------------------------------
174   public void clearAttributes()
175   {
176      if (mAttributes != null)
177      {
178         mAttributes.clear();
179      }
180   }
181
182   //--------------------------------------------------------------------------
183   public Object removeAttribute(String inName)
184   {
185      Object attr = null;
186      if (mAttributes != null)
187      {
188         attr  = mAttributes.remove(inName);
189      }
190
191      return attr;
192   }
193
194   //--------------------------------------------------------------------------
195   public AttributeMgr clone()
196   {
197      AttributeMgr cloneObj;
198      try
199      {
200         cloneObj = (AttributeMgr) super.clone();
201      }
202      catch (CloneNotSupportedException e)
203      {
204         throw new ProgrammingException(e);
205      }
206
207      if (mAttributes != null)
208      {
209         cloneObj.mAttributes = new HashMap<>(mAttributes.size());
210         for (String key : mAttributes.keySet())
211         {
212            Object value = mAttributes.get(key);
213            cloneObj.mAttributes.put(key, value != null ? value : null);
214         }
215      }
216
217      return cloneObj;
218   }
219
220
221   //--------------------------------------------------------------------------
222   public XMLNode toXMLNode()
223   {
224      XMLNode node = new XMLTag(HfgXML.ATTRIBUTES);
225
226      for (String attrName : mAttributes.keySet())
227      {
228         XMLNode attributeTag = new XMLTag(HfgXML.ATTRIBUTE);
229         attributeTag.setAttribute(HfgXML.NAME_ATT, attrName);
230
231         Object value = mAttributes.get(attrName);
232         if (value != null)
233         {
234            attributeTag.setAttribute(HfgXML.CLASS_ATT, value.getClass().getName());
235            if (value instanceof XMLizable)
236            {
237               attributeTag.addContentWithoutEscaping(((XMLizable)value).toXML());
238            }
239            else
240            {
241               attributeTag.setContent(value.toString());
242            }
243         }
244         else
245         {
246            attributeTag.setAttribute(HfgXML.IS_NULL_ATT, 1);
247         }
248
249         node.addSubtag(attributeTag);
250      }
251
252      return node;
253   }
254
255}