001package com.hfg.xml;
002
003import java.io.OutputStream;
004import java.io.Writer;
005import java.io.IOException;
006
007import com.hfg.exception.ProgrammingException;
008
009//------------------------------------------------------------------------------
010/**
011 * Represents a CDATA block.
012 *
013 * @author J. Alex Taylor, hairyfatguy.com
014 */
015//------------------------------------------------------------------------------
016// com.hfg XML/HTML Coding Library
017//
018// This library is free software; you can redistribute it and/or
019// modify it under the terms of the GNU Lesser General Public
020// License as published by the Free Software Foundation; either
021// version 2.1 of the License, or (at your option) any later version.
022//
023// This library is distributed in the hope that it will be useful,
024// but WITHOUT ANY WARRANTY; without even the implied warranty of
025// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
026// Lesser General Public License for more details.
027//
028// You should have received a copy of the GNU Lesser General Public
029// License along with this library; if not, write to the Free Software
030// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
031//
032// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
033// jataylor@hairyfatguy.com
034//------------------------------------------------------------------------------
035
036/*
037For XHTML or XML the script should be escaped like so:
038<script>
039 <![CDATA[
040 ... unescaped script content ...
041 ]]>
042 </script>
043
044 However, older browser (such as IE5 on Mac) won't take kindly to this.
045 IE6 doesn't seem to like such escaping in returned AJAX content.
046
047 See  http://www.sitepoint.com/forums/showthread.php?p=1955911
048 or this extracted page:  http://web-development.tuljo.com/cdata-comments.html
049
050*/
051public class XMLCDATA implements XMLizable
052{
053   private String mContent;
054   private boolean mHideWithCommentsForLegacyBrowsers;
055
056   private static boolean sDefaultHideWithCommentsForLegacyBrowsers = false;
057
058   //##########################################################################
059   // CONSTRUCTORS
060   //##########################################################################
061
062   //--------------------------------------------------------------------------
063   public XMLCDATA()
064   {
065      mHideWithCommentsForLegacyBrowsers = sDefaultHideWithCommentsForLegacyBrowsers;
066   }
067
068   //--------------------------------------------------------------------------
069   public XMLCDATA(String inContent)
070   {
071      this();
072      mContent = inContent;
073   }
074
075   //##########################################################################
076   // PUBLIC METHODS
077   //##########################################################################
078
079   //---------------------------------------------------------------------------
080   public XMLCDATA clone()
081   {
082      XMLCDATA cloneObj;
083      try
084      {
085         cloneObj = (XMLCDATA) super.clone();
086      }
087      catch (CloneNotSupportedException e)
088      {
089         throw new ProgrammingException(e);
090      }
091
092      return cloneObj;
093   }
094
095   //---------------------------------------------------------------------------
096   public static void setDefaultHideWithCommentsForLegacyBrowsers(boolean inValue)
097   {
098      sDefaultHideWithCommentsForLegacyBrowsers = inValue;
099   }
100
101
102   //---------------------------------------------------------------------------
103   public static boolean getDefaultHideWithCommentsForLegacyBrowsers()
104   {
105      return sDefaultHideWithCommentsForLegacyBrowsers;
106   }
107
108
109   //---------------------------------------------------------------------------
110
111   /**
112    * Sets whether or not to 'hide' the CDATA structure from browsers that are too
113    * old to support it. This is done by adding '//&gt;&lt;!--\n' and '\n//--&gt;&lt;!' inside
114    * the CDATA.
115    * For a discussion of where this syntax comes from, see
116    * <a href='http://web-development.tuljo.com/cdata-comments.html'>this discussion</a>.
117    */
118   public XMLCDATA setHideWithCommentsForLegacyBrowsers(boolean inValue)
119   {
120      mHideWithCommentsForLegacyBrowsers = inValue;
121      return this;
122   }
123
124
125   //---------------------------------------------------------------------------
126   public boolean getHideWithCommentsForLegacyBrowsers()
127   {
128      return mHideWithCommentsForLegacyBrowsers;
129   }
130
131   //---------------------------------------------------------------------------
132   public boolean hasContent()
133   {
134      return true;
135   }
136
137
138   //---------------------------------------------------------------------------
139   public void setContent(CharSequence inContent)
140   {
141      clearContent();
142
143      addContent(inContent);
144   }
145
146   //---------------------------------------------------------------------------
147   /**
148    Clears content (not subtags).
149    */
150   public void clearContent()
151   {
152      mContent = null;
153   }
154
155   //---------------------------------------------------------------------------
156   public void addContent(CharSequence inContent)
157   {
158      if (inContent != null)
159      {
160         if (mContent != null)
161         {
162            mContent += inContent;
163         }
164         else
165         {
166            mContent = inContent.toString();
167         }
168      }
169   }
170
171   //---------------------------------------------------------------------------
172   /**
173    The returned content does not contain any embedded subtags.
174    */
175   public String getContent()
176   {
177      return mContent;
178   }
179
180   //---------------------------------------------------------------------------
181   public String toXML()
182   {
183//      return "<![CDATA[//><!--\n" + mContent + "\n//--><!]]>";
184
185      StringBuilder buffer = new StringBuilder(mContent != null ? mContent.length() : 30);
186      buffer.append("<![CDATA[");
187      if (mHideWithCommentsForLegacyBrowsers) buffer.append("//><!--\n");
188      if (mContent != null) buffer.append(mContent);
189      if (mHideWithCommentsForLegacyBrowsers) buffer.append("\n//--><!");
190      buffer.append("]]>");
191
192      return buffer.toString();
193   }
194
195   //---------------------------------------------------------------------------
196   public void toXML(Writer inWriter)
197   {
198      try
199      {
200         inWriter.write(toXML());
201      }
202      catch (IOException e)
203      {
204         throw new RuntimeException(e);
205      }
206   }
207
208   //---------------------------------------------------------------------------
209   public void toXML(OutputStream inStream)
210   {
211      try
212      {
213         inStream.write(toXML().getBytes());
214      }
215      catch (Exception e)
216      {
217         throw new XMLException(e);
218      }
219   }
220
221
222
223   //--------------------------------------------------------------------------
224   public String toIndentedXML(int inInitialIndentLevel, int inIndentSize)
225   {
226      return toXML();
227   }
228
229   //--------------------------------------------------------------------------
230   public void toIndentedXML(OutputStream inOutputStream, int inInitialIndentLevel, int inIndentSize)
231   {
232      toXML(inOutputStream);
233   }
234
235   //--------------------------------------------------------------------------
236   public void toIndentedXML(Writer inWriter, int inInitialIndentLevel, int inIndentSize)
237   {
238      toXML(inWriter);
239   }
240}
241
242