001package org.apache.maven.doxia.module.apt;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.doxia.util.DoxiaUtils;
023
024/**
025 * A collection of utility methods for dealing with APT documents.
026 *
027 * @author ltheussl
028 * @since 1.1
029 */
030public class AptUtils
031{
032
033    /**
034     * Replace all characters in a text.
035     *
036     * <pre>
037     * AptTools.encodeFragment( null ) = null
038     * AptTools.encodeFragment( "" ) = ""
039     * AptTools.encodeFragment( "http://www.google.com" ) = "httpwwwgooglecom"
040     * </pre>
041     *
042     * @param text the String to check, may be null.
043     * @return the text with only letter and digit, null if null String input.
044     * @deprecated This method was used for the original apt format, which
045     * removed all non alphanumeric characters from anchors.
046     * Use {@link #encodeAnchor(String)} instead.
047     */
048    public static String encodeFragment( String text )
049    {
050        if ( text == null )
051        {
052            return null;
053        }
054
055        return linkToKey( text );
056    }
057
058    /**
059     * Checks if the given string corresponds to an external URI,
060     * ie is not a link within the same document nor a link to another
061     * document within the same site. This forwards to
062     * {@link org.apache.maven.doxia.util.DoxiaUtils#isExternalLink(String)}.
063     *
064     * @param link The link to check.
065     * @return True if DoxiaUtils.isExternalLink(link) returns true.
066     * @see org.apache.maven.doxia.util.DoxiaUtils#isExternalLink(String)
067     * @see #isInternalLink(String)
068     * @see #isLocalLink(String)
069     */
070    public static boolean isExternalLink( String link )
071    {
072        return DoxiaUtils.isExternalLink( link );
073    }
074
075    /**
076     * Checks if the given string corresponds to an internal link,
077     * ie it is a link to an anchor within the same document.
078     *
079     * @param link The link to check.
080     * @return True if link is neither an {@link #isExternalLink(String) external}
081     * nor a {@link #isLocalLink(String) local} link.
082     * @see org.apache.maven.doxia.util.DoxiaUtils#isInternalLink(String)
083     * @see #isExternalLink(String)
084     * @see #isLocalLink(String)
085     */
086    public static boolean isInternalLink( String link )
087    {
088        return ( !isExternalLink( link ) && !isLocalLink( link ) );
089    }
090
091    /**
092     * Checks if the given string corresponds to a relative link to another document
093     * within the same site.
094     *
095     * @param link The link to check.
096     * @return True if the link starts with either "/", "./" or "../".
097     * @see org.apache.maven.doxia.util.DoxiaUtils#isLocalLink(String)
098     * @see #isExternalLink(String)
099     * @see #isInternalLink(String)
100     */
101    public static boolean isLocalLink( String link )
102    {
103        return ( link.startsWith( "/" ) || link.startsWith( "./" ) || link.startsWith( "../" ) );
104    }
105
106    /**
107     * Transforms the given text such that it can be used as a link.
108     * All non-LetterOrDigit characters are removed and the remaining
109     * characters are transformed to lower-case.
110     *
111     * @param text The text to transform.
112     * @return The text with all non-LetterOrDigit characters removed.
113     * @deprecated This method was used for the original apt format, which
114     * removed all non alphanumeric characters from anchors.
115     * Use {@link #encodeAnchor(String)} instead.
116     */
117    public static String linkToKey( String text )
118    {
119        int length = text.length();
120        StringBuilder buffer = new StringBuilder( length );
121
122        for ( int i = 0; i < length; ++i )
123        {
124            char c = text.charAt( i );
125            if ( Character.isLetterOrDigit( c ) )
126            {
127                buffer.append( Character.toLowerCase( c ) );
128            }
129        }
130
131        return buffer.toString();
132    }
133
134    /**
135     * Construct a valid anchor. This is a simplified version of
136     * {@link org.apache.maven.doxia.util.DoxiaUtils#encodeId(String)}
137     * to ensure the anchor is a valid Doxia id.
138     * The procedure is identical to the one in
139     * {@link org.apache.maven.doxia.util.HtmlTools#encodeId(String)}:
140     *
141     * <ol>
142     *   <li> Trim the id</li>
143     *   <li> If the first character is not a letter, prepend the letter 'a'</li>
144     *   <li> Any space is replaced with an underscore '_'</li>
145     *   <li> Remove any non alphanumeric characters  except ':', '_', '.', '-'.</li>
146     * </ol>
147     *
148     * @param id The id to be encoded.
149     * @return The trimmed and encoded id, or null if id is null.
150     */
151    public static String encodeAnchor( String id )
152    {
153        if ( id == null )
154        {
155            return null;
156        }
157
158        id = id.trim();
159
160        int length = id.length();
161        StringBuilder buffer = new StringBuilder( length );
162
163        for ( int i = 0; i < length; ++i )
164        {
165            char c = id.charAt( i );
166
167            if ( ( i == 0 ) && ( !Character.isLetter( c ) ) )
168            {
169                buffer.append( 'a' );
170            }
171
172            if ( c == ' ' )
173            {
174                buffer.append( '_' );
175            }
176            else if ( ( Character.isLetterOrDigit( c ) ) || ( c == '-' ) || ( c == '_' ) || ( c == ':' )
177                            || ( c == '.' ) )
178            {
179                buffer.append( c );
180            }
181        }
182
183        return buffer.toString();
184    }
185
186    private AptUtils()
187    {
188        // utility class
189    }
190}