    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
    015package org.apache.tapestry5.dom;
    016
    017public 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}