PageRenderTime 22ms CodeModel.GetById 15ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/hudson-core/src/main/java/hudson/AbstractMarkupText.java

http://github.com/hudson/hudson
Java | 166 lines | 59 code | 20 blank | 87 comment | 7 complexity | c128c3d31771d601d1d64555bd7467bd MD5 | raw file
  1/*
  2 * The MIT License
  3 * 
  4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
  5 * 
  6 * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 * of this software and associated documentation files (the "Software"), to deal
  8 * in the Software without restriction, including without limitation the rights
  9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 * copies of the Software, and to permit persons to whom the Software is
 11 * furnished to do so, subject to the following conditions:
 12 * 
 13 * The above copyright notice and this permission notice shall be included in
 14 * all copies or substantial portions of the Software.
 15 * 
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 * THE SOFTWARE.
 23 */
 24package hudson;
 25
 26import hudson.MarkupText.SubText;
 27
 28import java.util.List;
 29import java.util.ArrayList;
 30import java.util.regex.Pattern;
 31import java.util.regex.Matcher;
 32
 33/**
 34 * Common part between {@link MarkupText} and {@link MarkupText.SubText}.
 35 *
 36 * <p>
 37 * See {@link MarkupText} for more discussion about what this class represents.
 38 *
 39 * @author Kohsuke Kawaguchi
 40 * @since 1.250
 41 */
 42public abstract class AbstractMarkupText {
 43    /*package*/ AbstractMarkupText() {} // limit who can subclass this type.
 44
 45
 46    /**
 47     * Returns the plain text portion of this {@link MarkupText} without
 48     * any markup, nor any escape.
 49     */
 50    public abstract String getText();
 51
 52    public char charAt(int idx) {
 53        return getText().charAt(idx);
 54    }
 55
 56    /**
 57     * Length of the plain text.
 58     */
 59    public final int length() {
 60        return getText().length();
 61    }
 62
 63    /**
 64     * Returns a subtext.
 65     *
 66     * @param end
 67     *      If negative, -N means "trim the last N-1 chars". That is, (s,-1) is the same as (s,length)
 68     */
 69    public abstract MarkupText.SubText subText(int start, int end);
 70
 71    /**
 72     * Adds a start tag and end tag at the specified position.
 73     *
 74     * <p>
 75     * For example, if the text was "abc", then <tt>addMarkup(1,2,"&lt;b>","&lt;/b>")</tt>
 76     * would generate <tt>"a&lt;b>b&lt;/b>c"</tt>
 77     */
 78    public abstract void addMarkup( int startPos, int endPos, String startTag, String endTag );
 79
 80    /**
 81     * Inserts an A tag that surrounds the given position.
 82     *
 83     * @since 1.349
 84     */
 85    public void addHyperlink( int startPos, int endPos, String url ) {
 86        addMarkup(startPos,endPos,"<a href='"+url+"'>","</a>");
 87    }
 88
 89    /**
 90     * Inserts an A tag that surrounds the given position.
 91     * But this hyperlink is less visible.
 92     *
 93     * @since 1.395
 94     */
 95    public void addHyperlinkLowKey( int startPos, int endPos, String url ) {
 96        addMarkup(startPos,endPos,"<a class='lowkey' href='"+url+"'>","</a>");
 97    }
 98
 99    /**
100     * Hides the given text.
101     */
102    public void hide( int startPos, int endPos ) {
103        addMarkup(startPos,endPos,"<span style='display:none'>","</span>");
104    }
105
106    /**
107     * Adds a start tag and end tag around the entire text
108     */
109    public final void wrapBy(String startTag, String endTag) {
110        addMarkup(0,length(),startTag,endTag);
111    }
112
113    /**
114     * Find the first occurrence of the given pattern in this text, or null.
115     *
116     * @since 1.349
117     */
118    public MarkupText.SubText findToken(Pattern pattern) {
119        String text = getText();
120        Matcher m = pattern.matcher(text);
121
122        if(m.find())
123            return createSubText(m);
124
125        return null;
126    }
127
128    /**
129     * Find all "tokens" that match the given pattern in this text.
130     *
131     * <p>
132     * A token is like a substring, except that it's aware of word boundaries.
133     * For example, while "bc" is a string of "abc", calling {@code findTokens}
134     * with "bc" as a pattern on string "abc" won't match anything.
135     *
136     * <p>
137     * This method is convenient for finding keywords that follow a certain syntax
138     * from natural text. You can then use {@link MarkupText.SubText#surroundWith(String,String)}
139     * to put mark up around such text.
140     */
141    public List<MarkupText.SubText> findTokens(Pattern pattern) {
142        String text = getText();
143        Matcher m = pattern.matcher(text);
144        List<SubText> r = new ArrayList<SubText>();
145
146        while(m.find()) {
147            int idx = m.start();
148            if(idx>0) {
149                char ch = text.charAt(idx-1);
150                if(Character.isLetter(ch) || Character.isDigit(ch))
151                    continue;   // not at a word boundary
152            }
153            idx = m.end();
154            if(idx<text.length()) {
155                char ch = text.charAt(idx);
156                if(Character.isLetter(ch) || Character.isDigit(ch))
157                    continue;   // not at a word boundary
158            }
159            r.add(createSubText(m));
160        }
161
162        return r;
163    }
164
165    protected abstract SubText createSubText(Matcher m);
166}