• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / displaytag / 1753

12 Feb 2026 03:17AM UTC coverage: 77.321% (-0.01%) from 77.334%
1753

push

github

web-flow
Merge pull request #1102 from hazendaz/renovate/javax-support-logback-monorepo

Update dependency ch.qos.logback:logback-classic to v1.5.29 (javax-support)

1438 of 2003 branches covered (71.79%)

Branch coverage included in aggregate %.

4034 of 5074 relevant lines covered (79.5%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.76
/displaytag/src/main/java/org/displaytag/decorator/AutolinkColumnDecorator.java
1
/*
2
 * SPDX-License-Identifier: MIT
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2002-2026 Fabrizio Giustina, the Displaytag team
6
 */
7
package org.displaytag.decorator;
8

9
import javax.servlet.jsp.PageContext;
10

11
import org.apache.commons.lang3.ArrayUtils;
12
import org.apache.commons.lang3.StringUtils;
13
import org.displaytag.properties.MediaTypeEnum;
14
import org.displaytag.util.TagConstants;
15

16
/**
17
 * This takes the string that is passed in, and "auto-links" it, it turns email addresses into hyperlinks, and also
18
 * turns things that looks like URLs into hyperlinks as well.
19
 */
20
public class AutolinkColumnDecorator implements DisplaytagColumnDecorator {
1✔
21

22
    /**
23
     * Instance used for the "autolink" tag attribute.
24
     */
25
    public static final DisplaytagColumnDecorator INSTANCE = new AutolinkColumnDecorator();
1✔
26

27
    /**
28
     * "://".
29
     */
30
    private static final String URL_DELIM = "://"; //$NON-NLS-1$
31

32
    /**
33
     * Urls.
34
     */
35
    private static final String[] URLS_PREFIXES = //
1✔
36
            { "http", "https", "ftp" }; //$NON-NLS-1$
37

38
    /**
39
     * Decorate.
40
     *
41
     * @param columnValue
42
     *            the column value
43
     * @param pageContext
44
     *            the page context
45
     * @param media
46
     *            the media
47
     *
48
     * @return the object
49
     *
50
     * @see org.displaytag.decorator.DisplaytagColumnDecorator#decorate(Object, PageContext, MediaTypeEnum)
51
     */
52
    @Override
53
    public Object decorate(final Object columnValue, final PageContext pageContext, final MediaTypeEnum media) {
54

55
        if (columnValue == null) {
1!
56
            return null;
×
57
        }
58
        String work = columnValue.toString();
1✔
59

60
        int urlBegin;
61
        StringBuilder buffer = new StringBuilder();
1✔
62

63
        // First check for email addresses.
64
        while ((urlBegin = work.indexOf('@')) != -1) {
1✔
65
            int start = 0;
1✔
66
            int end = work.length() - 1;
1✔
67

68
            // scan backwards...
69
            for (int j = urlBegin; j >= 0; j--) {
1✔
70
                if (Character.isWhitespace(work.charAt(j))) {
1✔
71
                    start = j + 1;
1✔
72
                    break;
1✔
73
                }
74
            }
75

76
            // scan forwards...
77
            for (int j = urlBegin; j <= end; j++) {
1✔
78
                if (Character.isWhitespace(work.charAt(j))) {
1!
79
                    end = j - 1;
×
80
                    break;
×
81
                }
82
            }
83

84
            final String email = work.substring(start, end + 1);
1✔
85

86
            buffer.append(work.substring(0, start)).append("<a href=\"mailto:") //$NON-NLS-1$
1✔
87
                    .append(email + "\">") //$NON-NLS-1$
1✔
88
                    .append(email).append("</a>"); //$NON-NLS-1$
1✔
89

90
            if (end == work.length()) {
1!
91
                work = TagConstants.EMPTY_STRING;
×
92
            } else {
93
                work = work.substring(end + 1);
1✔
94
            }
95
        }
1✔
96

97
        work = buffer.toString() + work;
1✔
98
        buffer = new StringBuilder();
1✔
99

100
        // Now check for urls...
101
        while ((urlBegin = work.indexOf(AutolinkColumnDecorator.URL_DELIM)) != -1) {
1✔
102

103
            // scan backwards...
104
            int fullUrlBegin = urlBegin;
1✔
105
            final StringBuilder prefixBuffer = new StringBuilder(10);
1✔
106
            for (int j = fullUrlBegin - 1; j >= 0; j--) {
1✔
107
                if (Character.isWhitespace(work.charAt(j))) {
1✔
108
                    fullUrlBegin = j + 1;
1✔
109
                    break;
1✔
110
                }
111
                fullUrlBegin = j;
1✔
112
                prefixBuffer.append(work.charAt(j));
1✔
113
            }
114

115
            if (!ArrayUtils.contains(AutolinkColumnDecorator.URLS_PREFIXES,
1✔
116
                    StringUtils.reverse(prefixBuffer.toString()))) {
1✔
117

118
                buffer.append(work.substring(0, urlBegin + 3));
1✔
119
                work = work.substring(urlBegin + 3);
1✔
120
                continue;
1✔
121
            }
122

123
            int urlEnd = work.length();
1✔
124

125
            // scan forwards...
126
            for (int j = urlBegin; j < urlEnd; j++) {
1✔
127
                if (Character.isWhitespace(work.charAt(j))) {
1✔
128
                    urlEnd = j;
1✔
129
                    break;
1✔
130
                }
131
            }
132

133
            final String url = work.substring(fullUrlBegin, urlEnd);
1✔
134

135
            buffer.append(work.substring(0, fullUrlBegin)).append("<a href=\"")//$NON-NLS-1$
1✔
136
                    .append(url).append("\">")//$NON-NLS-1$
1✔
137
                    .append(url).append("</a>"); //$NON-NLS-1$
1✔
138

139
            if (urlEnd >= work.length()) {
1✔
140
                work = TagConstants.EMPTY_STRING;
1✔
141
            } else {
142
                work = work.substring(urlEnd);
1✔
143
            }
144
        }
1✔
145

146
        buffer.append(work);
1✔
147
        return buffer.toString();
1✔
148
    }
149

150
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc