001package com.hfg.xml;
002
003import com.hfg.exception.ProgrammingException;
004import com.hfg.util.StringUtil;
005
006import java.util.HashMap;
007import java.util.Map;
008
009//------------------------------------------------------------------------------
010/**
011  Class to encapsulate an XML namespace.
012  <div>
013  <pre>
014  EX:  &lt;name xmlns:foo="http://bar.com/foo"/&gt;
015     The prefix is 'foo' and the URI is 'http://bar.com/foo'. 
016  </pre>
017  To conserve object space, XMLNamespace objects cannot be constructed directly
018  but are rather constructed through the static factory getNamespace() method.
019  </div>
020  
021  @author J. Alex Taylor, hairyfatguy.com
022 */
023//------------------------------------------------------------------------------
024
025
026public class XMLNamespace implements Cloneable
027{
028
029   //###########################################################################
030   // PRIVATE FIELDS
031   //###########################################################################
032   
033   private String  mPrefix;
034   private String  mURI;
035   private boolean mIsDefault;
036
037   private static Map<String, XMLNamespace> sURIMap    = new HashMap<>(50);
038   private static Map<String, XMLNamespace> sPrefixMap = new HashMap<>(50);
039
040   //###########################################################################
041   // PUBLIC FIELDS
042   //###########################################################################
043
044   public static XMLNamespace XHTML = new XMLNamespace("xhtml", "http://www.w3.org/1999/xhtml");
045   public static XMLNamespace SVG   = new XMLNamespace("svg",   "http://www.w3.org/2000/svg");
046   public static XMLNamespace XLINK = new XMLNamespace("xlink", "http://www.w3.org/1999/xlink");
047
048   //###########################################################################
049   // CONSTRUCTORS
050   //###########################################################################
051    
052   //---------------------------------------------------------------------------
053   private XMLNamespace(String inURI)
054   {
055      mURI    = inURI;
056   }
057   
058   //---------------------------------------------------------------------------
059   private XMLNamespace(String inPrefix, String inURI)
060   {
061      mPrefix = inPrefix;
062      mURI    = inURI;
063
064      sURIMap.put(inURI, this);
065      if (StringUtil.isSet(inPrefix)) sPrefixMap.put(inPrefix, this);
066   }
067   
068   //###########################################################################
069   // PUBLIC METHODS
070   //###########################################################################
071   
072   //---------------------------------------------------------------------------
073   public static XMLNamespace getNamespace(String inURI)
074   {
075      return getNamespace(null, inURI);
076   }
077
078   //---------------------------------------------------------------------------
079   public XMLNamespace setIsDefault(boolean inValue)
080   {
081      mIsDefault = inValue;
082      return this;
083   }
084
085   //---------------------------------------------------------------------------
086   public boolean isDefault()
087   {
088      return mIsDefault;
089   }
090
091   //---------------------------------------------------------------------------
092   @Override
093   public int hashCode()
094   {
095      return getURI().hashCode();
096   }
097
098   //---------------------------------------------------------------------------
099   @Override
100   public boolean equals(Object inObj2)
101   {
102      boolean result = false;
103      if (inObj2 instanceof XMLNamespace)
104      {
105         XMLNamespace namespace2 = (XMLNamespace) inObj2;
106         result = (getURI() != null ? getURI().equals(namespace2.getURI()) : null == namespace2.getURI());
107      }
108
109      return result;
110   }
111
112   //---------------------------------------------------------------------------
113   public XMLNamespace clone()
114   {
115      XMLNamespace cloneObj;
116      try
117      {
118         cloneObj = (XMLNamespace) super.clone();
119      }
120      catch (CloneNotSupportedException e)
121      {
122         throw new ProgrammingException("Error cloning XMLNamespace object!", e);
123      }
124
125      return cloneObj;
126   }
127
128   //---------------------------------------------------------------------------
129   public static XMLNamespace getNamespace(String inPrefix, String inURI)
130   {
131       XMLNamespace namespace;
132       if (StringUtil.isSet(inURI))
133       {
134           namespace = sURIMap.get(inURI);
135           if (namespace != null
136               && null == namespace.getPrefix()
137               && StringUtil.isSet(inPrefix))
138           {
139              namespace.setPrefix(inPrefix);
140              sPrefixMap.put(inPrefix, namespace);
141           }
142       }
143       else
144       {
145           namespace = sPrefixMap.get(inPrefix);
146       }
147
148       if (null == namespace)
149       {
150           namespace = new XMLNamespace(inPrefix, inURI);
151       }
152
153      return namespace;
154   }
155
156   //---------------------------------------------------------------------------
157   public static XMLNamespace getNamespaceViaPrefix(String inPrefix)
158   {
159      XMLNamespace namespace = sPrefixMap.get(inPrefix);
160      if (null == namespace)
161      {
162         namespace = new XMLNamespace(inPrefix, null);
163         sPrefixMap.put(inPrefix, namespace);
164      }
165
166      return namespace;
167   }
168
169   //---------------------------------------------------------------------------
170   public String getPrefix()
171   {
172      return mPrefix;
173   }
174   
175   //---------------------------------------------------------------------------
176   public String getURI()
177   {
178      return mURI;
179   }
180
181   //---------------------------------------------------------------------------
182   public void setURI(String inValue)
183   {
184      sURIMap.remove(getURI());
185      mURI = inValue;
186      sURIMap.put(inValue, this);
187   }
188
189
190   //---------------------------------------------------------------------------
191   public String toString()
192   {
193      return getPrefix();
194   }
195
196   //---------------------------------------------------------------------------
197   private void setPrefix(String inValue)
198   {
199      mPrefix = inValue;
200   }
201}