001    /* 
002     * This file is part of the Echo Point Project.  This project is a collection
003     * of Components that have extended the Echo Web Application Framework.
004     *
005     * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006     *
007     * The contents of this file are subject to the Mozilla Public License Version
008     * 1.1 (the "License"); you may not use this file except in compliance with
009     * the License. You may obtain a copy of the License at
010     * http://www.mozilla.org/MPL/
011     *
012     * Software distributed under the License is distributed on an "AS IS" basis,
013     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014     * for the specific language governing rights and limitations under the
015     * License.
016     *
017     * Alternatively, the contents of this file may be used under the terms of
018     * either the GNU General Public License Version 2 or later (the "GPL"), or
019     * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020     * in which case the provisions of the GPL or the LGPL are applicable instead
021     * of those above. If you wish to allow use of your version of this file only
022     * under the terms of either the GPL or the LGPL, and not to allow others to
023     * use your version of this file under the terms of the MPL, indicate your
024     * decision by deleting the provisions above and replace them with the notice
025     * and other provisions required by the GPL or the LGPL. If you do not delete
026     * the provisions above, a recipient may use your version of this file under
027     * the terms of any one of the MPL, the GPL or the LGPL.
028     */
029    
030    /*
031     * This file was taken from the Echo 1.x code base on the 23rd Jan 2006 and made part of
032     * EchoPointNG.  It is therefore Copyright (C) 2002-2004 NextApp, Inc.
033     */
034    
035    /* 
036     * This file is part of the Echo Web Application Framework (hereinafter "Echo").
037     * Copyright (C) 2002-2004 NextApp, Inc.
038     *
039     * Version: MPL 1.1/GPL 2.0/LGPL 2.1
040     *
041     * The contents of this file are subject to the Mozilla Public License Version
042     * 1.1 (the "License"); you may not use this file except in compliance with
043     * the License. You may obtain a copy of the License at
044     * http://www.mozilla.org/MPL/
045     *
046     * Software distributed under the License is distributed on an "AS IS" basis,
047     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
048     * for the specific language governing rights and limitations under the
049     * License.
050     *
051     * Alternatively, the contents of this file may be used under the terms of
052     * either the GNU General Public License Version 2 or later (the "GPL"), or
053     * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
054     * in which case the provisions of the GPL or the LGPL are applicable instead
055     * of those above. If you wish to allow use of your version of this file only
056     * under the terms of either the GPL or the LGPL, and not to allow others to
057     * use your version of this file under the terms of the MPL, indicate your
058     * decision by deleting the provisions above and replace them with the notice
059     * and other provisions required by the GPL or the LGPL. If you do not delete
060     * the provisions above, a recipient may use your version of this file under
061     * the terms of any one of the MPL, the GPL or the LGPL.
062     */
063    
064    package echopoint.util;
065    
066    import java.util.ArrayList;
067    import java.util.List;
068    
069    import nextapp.echo.app.ImageReference;
070    
071    import org.w3c.dom.Document;
072    import org.w3c.dom.Node;
073    
074    //import echopoint.ui.util.ImageManager;
075    
076    /**
077     * Encodes text strings into HTML.
078     */
079    public class HtmlKit {
080    
081            public static final int NEWLINE_REMOVE = 3;
082    
083            public static final int NEWLINE_TO_BR = 2;
084    
085            public static final int NEWLINE_TO_SPACE = 1;
086    
087            public static final int NEWLINE_TRANSPARENT = 0;
088    
089            /**
090             * Encodes a string of text into HTML by replacing less than, greater than,
091             * ampersand, and quotation mark characters with their HTML escaped
092             * equivalents. Groups of spaces are replaced with alternating spaces and
093             * non-breaking space characters.
094             * 
095             * @param text
096             *            The text to be encoded into HTML.
097             * @return The text, converted to HTML. Newlines will be left intact, NOT
098             *         translated to <br> tags.
099             */
100            public static String encode(String text) {
101                    return encode(text, NEWLINE_TRANSPARENT);
102            }
103            /**
104             * Encodes a string of text into HTML by replacing less than, greater than,
105             * ampersand, and quotation mark characters with their HTML escaped
106             * equivalents. Groups of spaces are replaced with alternating spaces and
107             * non-breaking space characters.
108             * 
109             * @param text
110             *            The text to be encoded into HTML.
111             * @param newLinePolicy
112             *            The policy for handling newline characters, one of the
113             *            following values:
114             *            <ul>
115             *            <li>NEWLINE_TRANSPARENT - Leave newline characters intact.</li>
116             *            <li>NEWLINE_TO_SPACE - Convert newlines to spaces.</li>
117             *            <li>NEWLINE_TO_BR - Convert newlines to &lt;br&gt; tags.</li>
118             *            <li>NEWLINE_REMOVE - Remove newlines entirely.</li>
119             *            </ul>
120             * @return The text, converted to HTML.
121             */
122            public static String encode(String text, int newLinePolicy) {
123                    StringBuffer sb = new StringBuffer();
124                    
125                    final String quot       = "&quot;";         // String.valueOf((char) 0x0022); // why can I do "\u0022"
126                    final String amp        = "&amp;";          //"\u0026"; 
127                    final String lt         = "&lt;";           //"\u003C";
128                    final String gt         = "&gt;";           //"\u003E";
129                    final String nbsp       = "&nbsp;";         //"\u00a0"; 
130                    
131    
132                    if (text != null) {
133                            int length = text.length();
134                            int startIndex = 0;
135                            int index = 0;
136    
137                            while (index < length) {
138                                    switch (text.charAt(index)) {
139                                    case ' ':
140                                            if (index == 0 || index == length - 1) {
141                                                    // Convert spaces at beginning or end of text string to
142                                                    // NBSPs.
143                                                    if (startIndex < index) {
144                                                            sb.append(text.substring(startIndex, index));
145                                                    }
146                                                    sb.append(nbsp);
147                                                    startIndex = index + 1;
148                                            } else if (index < length - 1 && text.charAt(index + 1) == ' ') {
149                                                    // Break down blocks of spaces in text so that text is
150                                                    // formatted correctly.
151                                                    // This code, while moderately confusing is necessary.
152                                                    // The rule is that non-breaking space (NBSP)
153                                                    // characters should replace every other space in a
154                                                    // continued string of spaces. The exception is
155                                                    // that a NBSP should never immediately precede a
156                                                    // character.
157                                                    if (startIndex < index) {
158                                                            sb.append(text.substring(startIndex, index));
159                                                    }
160                                                    if (index < length - 3 && text.charAt(index + 2) == ' ' && text.charAt(index + 3) != ' ') {
161                                                            sb.append(nbsp);
162                                                            sb.append(nbsp);
163                                                            sb.append(" ");
164                                                            index += 2; // skip second and third space.
165                                                    } else {
166                                                            sb.append(nbsp);
167                                                            sb.append(" ");
168                                                            ++index; // skip second space.
169                                                    }
170                                                    startIndex = index + 1;
171                                            }
172                                            break;
173                                    case '\r':
174                                    case '\n':
175                                            if (newLinePolicy != NEWLINE_TRANSPARENT) {
176                                                    if (startIndex < index) {
177                                                            sb.append(text.substring(startIndex, index));
178                                                    }
179                                                    if (index < length - 1
180                                                                    && ((text.charAt(index) == '\r' && text.charAt(index + 1) == '\n') || (text.charAt(index) == '\n' && text
181                                                                                    .charAt(index + 1) == '\r'))) {
182                                                            ++index; // skip second character of newline
183                                                            // sequence.
184                                                    }
185                                                    switch (newLinePolicy) {
186                                                    case NEWLINE_TO_SPACE:
187                                                            sb.append(" ");
188                                                            break;
189                                                    case NEWLINE_TO_BR:
190                                                            sb.append("<br/>\n");
191                                                            break;
192                                                    // NEWLINE_REMOVE will not add any characters to output.
193                                                    }
194                                                    startIndex = index + 1;
195                                            }
196                                            break;
197                                    case '<':
198                                            if (startIndex < index) {
199                                                    sb.append(text.substring(startIndex, index));
200                                            }
201                                            sb.append(lt);
202                                            startIndex = index + 1;
203                                            break;
204                                    case '>':
205                                            if (startIndex < index) {
206                                                    sb.append(text.substring(startIndex, index));
207                                            }
208                                            sb.append(gt);
209                                            startIndex = index + 1;
210                                            break;
211                                    case '"':
212                                            if (startIndex < index) {
213                                                    sb.append(text.substring(startIndex, index));
214                                            }
215                                            sb.append(quot);
216                                            startIndex = index + 1;
217                                            break;
218                                    case '&':
219                                            if (startIndex < index) {
220                                                    sb.append(text.substring(startIndex, index));
221                                            }
222                                            sb.append(amp);
223                                            startIndex = index + 1;
224                                            break;
225                                    }
226    
227                                    ++index;
228                            }
229    
230                            if (startIndex < index) {
231                                    sb.append(text.substring(startIndex));
232                            }
233                    }
234    
235                    return sb.toString();
236            }
237    
238            /**
239             * Encodes a string of text into DOM Nodes by taking new lines and replacing
240             * them aoccording to the policy provided.
241             * 
242             * @param text
243             *            The text to be encoded into DOM Nodes.
244             * @param newLinePolicy
245             *            The policy for handling newline characters, one of the
246             *            following values:
247             *            <ul>
248             *            <li>NEWLINE_TRANSPARENT - Leave newline characters intact.</li>
249             *            <li>NEWLINE_TO_SPACE - Convert newlines to spaces.</li>
250             *            <li>NEWLINE_TO_BR - Convert newlines to &lt;br&gt; tags.</li>
251             *            <li>NEWLINE_REMOVE - Remove newlines entirely.</li>
252             *            </ul>
253             * @return The text, converted to an array of DOM Nodes.
254             */
255            public static Node[] encodeNewLines(Document document, String text, int newLinePolicy) {
256                    List nodeList = new ArrayList();
257                    StringBuffer sb = new StringBuffer();
258                    int length = text.length();
259                    int startIndex = 0;
260                    int index = 0;
261    
262                    while (index < length) {
263                            switch (text.charAt(index)) {
264                            case '\r':
265                            case '\n':
266                                    if (newLinePolicy != NEWLINE_TRANSPARENT) {
267                                            if (startIndex < index) {
268                                                    sb.append(text.substring(startIndex, index));
269                                            }
270                                            if (index < length - 1
271                                                            && ((text.charAt(index) == '\r' && text.charAt(index + 1) == '\n') || (text.charAt(index) == '\n' && text
272                                                                            .charAt(index + 1) == '\r'))) {
273                                                    ++index; // skip second character of newline
274                                                    // sequence.
275                                            }
276                                            switch (newLinePolicy) {
277                                            case NEWLINE_TO_SPACE:
278                                                    sb.append(" ");
279                                                    break;
280                                            case NEWLINE_TO_BR:
281                                                    Node node = document.createTextNode(sb.toString());
282                                                    nodeList.add(node);
283                                                    node = document.createElement("br");
284                                                    nodeList.add(node);
285                                                    sb.setLength(0);
286                                                    break;
287                                            // NEWLINE_REMOVE will not add any characters to output.
288                                            }
289                                            startIndex = index + 1;
290                                    }
291                                    break;
292                            }
293                            ++index;
294                    }
295                    if (startIndex < index) {
296                            sb.append(text.substring(startIndex));
297                            Node node = document.createTextNode(sb.toString());
298                            nodeList.add(node);
299                    }
300                    return (Node[]) nodeList.toArray(new Node[nodeList.size()]);
301            }
302    
303            /**
304         * todo Fix this method!
305             * This returns the URI for the given <code>ImageReference</code>
306             * 
307             * @param imageReference -
308             *            the <code>ImageReference</code> to get a URI for
309             * @return the URI for the given <code>ImageReference</code>
310             * @throws IllegalArgumentException -
311             *             if the <code>ImageReference</code> is null
312             */
313    //      public static String getImageURI(ImageReference imageReference) {
314    //              if (imageReference == null) {
315    //                      throw new IllegalArgumentException("The imageReference must not be null!");
316    //              }
317    //              return ImageManager.getURI(imageReference);
318    //      }
319    
320            /** Non-instantiable class. */
321            private HtmlKit() {
322            }
323    }