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 * @version $Id$
030 */
031public class AptUtils
032{
033
034    /**
035     * Replace all characters in a text.
036     *
037     * <pre>
038     * AptTools.encodeFragment( null ) = null
039     * AptTools.encodeFragment( "" ) = ""
040     * AptTools.encodeFragment( "http://www.google.com" ) = "httpwwwgooglecom"
041     * </pre>
042     *
043     * @param text the String to check, may be null.
044     * @return the text with only letter and digit, null if null String input.
045     * @deprecated This method was used for the original apt format, which
046     * removed all non alphanumeric characters from anchors.
047     * Use {@link #encodeAnchor(String)} instead.
048     */
049    public static String encodeFragment( String text )
050    {
051        if ( text == null )
052        {
053            return null;
054        }
055
056        return linkToKey( text );
057    }
058
059    /**
060     * Checks if the given string corresponds to an external URI,
061     * ie is not a link within the same document nor a link to another
062     * document within the same site. This forwards to
063     * {@link org.apache.maven.doxia.util.DoxiaUtils#isExternalLink(String)}.
064     *
065     * @param link The link to check.
066     * @return True if DoxiaUtils.isExternalLink(link) returns true.
067     *
068     * @see org.apache.maven.doxia.util.DoxiaUtils#isExternalLink(String)
069     * @see #isInternalLink(String)
070     * @see #isLocalLink(String)
071     */
072    public static boolean isExternalLink( String link )
073    {
074        return DoxiaUtils.isExternalLink( link );
075    }
076
077    /**
078     * Checks if the given string corresponds to an internal link,
079     * ie it is a link to an anchor within the same document.
080     *
081     * @param link The link to check.
082     * @return True if link is neither an {@link #isExternalLink(String) external}
083     * nor a {@link #isLocalLink(String) local} link.
084     *
085     * @see org.apache.maven.doxia.util.DoxiaUtils#isInternalLink(String)
086     * @see #isExternalLink(String)
087     * @see #isLocalLink(String)
088     */
089    public static boolean isInternalLink( String link )
090    {
091        return ( !isExternalLink( link ) && !isLocalLink( link ) );
092    }
093
094    /**
095     * Checks if the given string corresponds to a relative link to another document
096     * within the same site.
097     *
098     * @param link The link to check.
099     * @return True if the link starts with either "/", "./" or "../".
100     *
101     * @see org.apache.maven.doxia.util.DoxiaUtils#isLocalLink(String)
102     * @see #isExternalLink(String)
103     * @see #isInternalLink(String)
104     */
105    public static boolean isLocalLink( String link )
106    {
107        return ( link.startsWith( "/" ) || link.startsWith( "./" ) || link.startsWith( "../" ) );
108    }
109
110    /**
111     * Transforms the given text such that it can be used as a link.
112     * All non-LetterOrDigit characters are removed and the remaining
113     * characters are transformed to lower-case.
114     *
115     * @param text The text to transform.
116     * @return The text with all non-LetterOrDigit characters removed.
117     * @deprecated This method was used for the original apt format, which
118     * removed all non alphanumeric characters from anchors.
119     * Use {@link #encodeAnchor(String)} instead.
120     */
121    public static String linkToKey( String text )
122    {
123        int length = text.length();
124        StringBuilder buffer = new StringBuilder( length );
125
126        for ( int i = 0; i < length; ++i )
127        {
128            char c = text.charAt( i );
129            if ( Character.isLetterOrDigit( c ) )
130            {
131                buffer.append( Character.toLowerCase( c ) );
132            }
133        }
134
135        return buffer.toString();
136    }
137
138    /**
139     * Construct a valid anchor. This is a simplified version of
140     * {@link org.apache.maven.doxia.util.DoxiaUtils#encodeId(String)}
141     * to ensure the anchor is a valid Doxia id.
142     * The procedure is identical to the one in
143     * {@link org.apache.maven.doxia.util.HtmlTools#encodeId(String)}:
144     *
145     * <ol>
146     *   <li> Trim the id</li>
147     *   <li> If the first character is not a letter, prepend the letter 'a'</li>
148     *   <li> Any space is replaced with an underscore '_'</li>
149     *   <li> Remove any non alphanumeric characters  except ':', '_', '.', '-'.</li>
150     * </ol>
151     *
152     * @param id The id to be encoded.
153     * @return The trimmed and encoded id, or null if id is null.
154     */
155    public static String encodeAnchor( String id )
156    {
157        if ( id == null )
158        {
159            return null;
160        }
161
162        id = id.trim();
163
164        int length = id.length();
165        StringBuilder buffer = new StringBuilder( length );
166
167        for ( int i = 0; i < length; ++i )
168        {
169            char c = id.charAt( i );
170
171            if ( ( i == 0 ) && ( !Character.isLetter( c ) ) )
172            {
173                buffer.append( 'a' );
174            }
175
176            if ( c == ' ' )
177            {
178                buffer.append( '_' );
179            }
180            else if ( ( Character.isLetterOrDigit( c ) ) || ( c == '-' ) || ( c == '_' ) || ( c == ':' )
181                            || ( c == '.' ) )
182            {
183                buffer.append( c );
184            }
185        }
186
187        return buffer.toString();
188    }
189
190    private AptUtils()
191    {
192        // utility class
193    }
194}