001    // Copyright 2008 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;
016    
017    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
018    
019    import java.util.Collections;
020    import java.util.List;
021    
022    /**
023     * Utility methods related to generating markup.
024     */
025    public class MarkupUtils
026    {
027        static final char APOS = '\'';
028        static final char QUOTE = '"';
029        static final char SLASH = '\\';
030    
031        /**
032         * Quotes the provided value as a JavaScript string literal. The input value is surrounded by single quotes and any
033         * interior backslash, single or double quotes are escaped (a preceding backslash is added).
034         *
035         * @param text
036         * @return quoted text
037         */
038        public static String quote(String text)
039        {
040            StringBuilder result = new StringBuilder(text.length() * 2);
041    
042            result.append(APOS);
043    
044            for (char ch : text.toCharArray())
045            {
046                switch (ch)
047                {
048                    case APOS:
049                    case QUOTE:
050                    case SLASH:
051    
052                        result.append(SLASH);
053    
054                    default:
055                        result.append(ch);
056                        break;
057                }
058            }
059    
060            result.append(APOS);
061    
062            return result.toString();
063        }
064    
065        /**
066         * Joins together several strings, sorting them alphabetically and separating them with spaces. This is often used
067         * when setting the CSS class attribute of an element.
068         */
069        public static String join(String... values)
070        {
071            List<String> list = CollectionFactory.newList(values);
072    
073            return sortAndJoin(list);
074        }
075    
076        /**
077         * Joins together several strings, sorting them alphabetically and separating them with spaces. This is often used
078         * when setting the CSS class attribute of an element.
079         */
080        public static String join(List<String> values)
081        {
082            List<String> copy = CollectionFactory.newList(values);
083    
084            return sortAndJoin(copy);
085        }
086    
087        static String sortAndJoin(List<String> list)
088        {
089            Collections.sort(list);
090    
091            StringBuilder builder = new StringBuilder(10 * list.size());
092    
093            String sep = "";
094    
095            for (String name : list)
096            {
097                builder.append(sep);
098                builder.append(name);
099    
100                sep = " ";
101            }
102    
103            return builder.toString();
104        }
105    }