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

hazendaz / sitemesh2 / 59

22 Mar 2026 02:30AM UTC coverage: 40.347%. Remained the same
59

push

github

hazendaz
[mvn] Update maven wrapper

698 of 1891 branches covered (36.91%)

Branch coverage included in aggregate %.

1555 of 3693 relevant lines covered (42.11%)

0.42 hits per line

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

0.0
/src/main/java/com/opensymphony/module/sitemesh/mapper/AgentDecoratorMapper.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2011-2026 Hazendaz
4
 */
5
/*
6
 * Title:        AgentDecoratorMapper
7
 * Description:
8
 *
9
 * This software is published under the terms of the OpenSymphony Software
10
 * License version 1.1, of which a copy has been included with this
11
 * distribution in the LICENSE.txt file.
12
 */
13

14
package com.opensymphony.module.sitemesh.mapper;
15

16
import com.opensymphony.module.sitemesh.Config;
17
import com.opensymphony.module.sitemesh.Decorator;
18
import com.opensymphony.module.sitemesh.DecoratorMapper;
19
import com.opensymphony.module.sitemesh.Page;
20

21
import jakarta.servlet.http.HttpServletRequest;
22

23
import java.io.File;
24
import java.nio.file.Path;
25
import java.util.HashMap;
26
import java.util.Map;
27
import java.util.Properties;
28

29
/**
30
 * The AgentDecoratorMapper can determine the user-agent (i.e. web-browser) requesting a page, and map to a suitable
31
 * Decorator.
32
 * <p>
33
 * This can be useful for supplying different versions of the same content for different browsers (e.g. vanilla HTML for
34
 * Lynx, complex tables and frames for Netscape, extra stuff for IE5, etc).
35
 * <p>
36
 * This can also be used to enhance search-engine ratings by using a 'bait and switch' system - this involves showing a
37
 * search-engine friendly of the content to spiders only.
38
 * <p>
39
 * When AgentDecoratorMapper is in the chain, it will request the appropriate Decorator from its parent. It will then
40
 * add an extention to the filename of the Decorator, and if that file exists it shall be used as the Decorator instead.
41
 * For example, if the Decorator path is <code>/blah.jsp</code> and the detected user-agent is <code>ie</code>, the path
42
 * <code>/blah-ie.jsp</code> shall be used.
43
 * <p>
44
 * The agent mappings are configured by passing properties with <code>match.</code> as a prefix. For example:
45
 * 'match.MSIE'=ie , 'match.Lynx'=plain .
46
 *
47
 * @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
48
 *
49
 * @see com.opensymphony.module.sitemesh.DecoratorMapper
50
 */
51
public class AgentDecoratorMapper extends AbstractDecoratorMapper {
×
52

53
    /** The map. */
54
    private Map<Object, Object> map;
55

56
    @Override
57
    public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
58
        super.init(config, properties, parent);
×
59
        map = new HashMap<>();
×
60
        initMap(properties);
×
61
    }
×
62

63
    @Override
64
    public Decorator getDecorator(HttpServletRequest request, Page page) {
65
        try {
66
            Decorator result = null;
×
67
            final Decorator d = super.getDecorator(request, page);
×
68
            String path = modifyPath(d.getPage(), getExt(request.getHeader("User-Agent")));
×
69

70
            File decFile = Path.of(config.getServletContext().getRealPath(path)).toFile();
×
71

72
            if (decFile.isFile()) {
×
73
                result = new DefaultDecorator(d.getName(), path, null) {
×
74
                    @Override
75
                    public String getInitParameter(String paramName) {
76
                        return d.getInitParameter(paramName);
×
77
                    }
78
                };
79
            }
80
            return result == null ? super.getDecorator(request, page) : result;
×
81
        } catch (NullPointerException e) {
×
82
            return super.getDecorator(request, page);
×
83
        }
84
    }
85

86
    /**
87
     * Get extention for user-agent.
88
     *
89
     * @param userAgent
90
     *            the user agent
91
     *
92
     * @return the ext
93
     */
94
    private String getExt(String userAgent) {
95
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
×
96
            String curr = (String) entry.getKey();
×
97
            if (userAgent.indexOf(curr) > -1) {
×
98
                return (String) entry.getValue();
×
99
            }
100
        }
×
101
        return null;
×
102
    }
103

104
    /**
105
     * Change /abc/def.jsp into /abc/def-XYZ.jsp
106
     *
107
     * @param path
108
     *            the path
109
     * @param ext
110
     *            the ext
111
     *
112
     * @return the string
113
     */
114
    private static String modifyPath(String path, String ext) {
115
        int dot = path.indexOf('.');
×
116
        if (dot > -1) {
×
117
            return path.substring(0, dot) + '-' + ext + path.substring(dot);
×
118
        }
119
        return path + '-' + ext;
×
120
    }
121

122
    /**
123
     * Initialize user-agent mappings.
124
     *
125
     * @param props
126
     *            the props
127
     */
128
    private void initMap(Properties props) {
129
        for (Map.Entry<Object, Object> entry : props.entrySet()) {
×
130
            String key = (String) entry.getKey();
×
131
            if (key.startsWith("match.")) {
×
132
                String match = key.substring(6);
×
133
                String ext = (String) entry.getValue();
×
134
                map.put(match, ext);
×
135
            }
136
        }
×
137
    }
×
138
}
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