    001    //  Copyright 2008, 2009, 2010 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    //     http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.dom;
    016
    017    public abstract class AbstractMarkupModel implements MarkupModel
    018    {
    019        private final boolean useApostropheForAttributes;
    020
    021        protected AbstractMarkupModel(boolean useApostropheForAttributes)
    022        {
    023            this.useApostropheForAttributes = useApostropheForAttributes;
    024        }
    025
    026        public char getAttributeQuote()
    027        {
    028            return useApostropheForAttributes ? '\'' : '"';
    029        }
    030
    031        /**
    032         * Passes all characters but '&lt;', '&gt;' and '&amp;' through unchanged.
    033         */
    034        public String encode(String content)
    035        {
    036            int length = content.length();
    037
    038            StringBuilder builder = null;
    039
    040            for (int i = 0; i < length; i++)
    041            {
    042                char ch = content.charAt(i);
    043
    044                switch (ch)
    045                {
    046                    case '<':
    047
    048                        if (builder == null)
    049                        {
    050                            builder = new StringBuilder(2 * length);
    051
    052                            builder.append(content.substring(0, i));
    053                        }
    054
    055                        builder.append("&lt;");
    056                        continue;
    057
    058                    case '>':
    059
    060                        if (builder == null)
    061                        {
    062                            builder = new StringBuilder(2 * length);
    063
    064                            builder.append(content.substring(0, i));
    065                        }
    066
    067                        builder.append("&gt;");
    068                        continue;
    069
    070                    case '&':
    071
    072                        if (builder == null)
    073                        {
    074                            builder = new StringBuilder(2 * length);
    075
    076                            builder.append(content.substring(0, i));
    077                        }
    078
    079                        builder.append("&amp;");
    080                        continue;
    081
    082                    default:
    083
    084                        if (builder != null)
    085                            builder.append(ch);
    086                }
    087            }
    088
    089            return builder == null ? content : builder.toString();
    090        }
    091
    092        public void encodeQuoted(String content, StringBuilder builder)
    093        {
    094            assert content != null;
    095            int length = content.length();
    096
    097            for (int i = 0; i < length; i++)
    098            {
    099                char ch = content.charAt(i);
    100
    101                switch (ch)
    102                {
    103                    case '<':
    104
    105                        builder.append("&lt;");
    106                        continue;
    107
    108                    case '>':
    109
    110                        builder.append("&gt;");
    111                        continue;
    112
    113                    case '&':
    114
    115                        builder.append("&amp;");
    116                        continue;
    117
    118                    case '"':
    119
    120                        if (!useApostropheForAttributes)
    121                        {
    122                            builder.append("&quot;");
    123                            continue;
    124                        }
    125
    126                        builder.append(ch);
    127                        continue;
    128
    129                    case '\'':
    130
    131                        if (useApostropheForAttributes)
    132                        {
    133                            //TAP5-714
    134                            builder.append("&#39;");
    135                            continue;
    136                        }
    137
    138
    139                        // Fall through
    140
    141                    default:
    142
    143                        builder.append(ch);
    144                }
    145            }
    146        }
    147    }