• 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/LanguageDecoratorMapper.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2011-2026 Hazendaz
4
 */
5
/*
6
 * Title:        LanguageDecoratorMapper
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 LanguageDecoratorMapper can determine the preferred language set in the browser requesting a page, and map to a
31
 * suitable Decorator (using the "Accept-Language" HTTP header).
32
 * <p>
33
 * This can be useful for supplying different versions of the same content for different languages.
34
 * </p>
35
 * <p>
36
 * When LanguageDecoratorMapper is in the chain, it will request the appropriate Decorator from its parent. It will then
37
 * add an extention to the filename of the Decorator, and if that file exists it shall be used as the Decorator instead.
38
 * For example, if the Decorator path is <code>/blah.jsp</code> and the detected preferred language is <code>en</code>,
39
 * the path <code>/blah-en.jsp</code> shall be used.
40
 * </p>
41
 * <p>
42
 * The language mappings are configured by passing properties with <code>match.</code> as a prefix. For example:
43
 * 'match.en'=engl , 'match.nl'=dutch .
44
 * </p>
45
 *
46
 * @author <a href="mailto:pathos@pandora.be">Mathias Bogaert</a>
47
 *
48
 * @see com.opensymphony.module.sitemesh.DecoratorMapper
49
 */
50
public class LanguageDecoratorMapper extends AbstractDecoratorMapper {
×
51

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

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

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

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

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

85
    /**
86
     * Get extention for the language.
87
     *
88
     * @param acceptLanguage
89
     *            the accept language
90
     *
91
     * @return the ext
92
     */
93
    private String getExt(String acceptLanguage) {
94
        for (Map.Entry<String, Object> entry : map.entrySet()) {
×
95

96
            // Get the first language (preferred one) in the header, and
97
            // only check the first two chars (the acceptLanguage could be en-gb, but
98
            // we don't support this for now).
99
            if (acceptLanguage.substring(0, 2).equals(entry.getKey())) {
×
100
                return (String) entry.getValue();
×
101
            }
102

103
            // When the user-agent has multiple accept-languages (separated by ;),
104
            // these are ignored because the site creator may wish that if the
105
            // preferred language is not supported, the page uses the default
106
            // decorator (in the default language), and not in some other
107
            // language given by the browser (most of them are specified by
108
            // default at install).
109
        }
×
110
        return null;
×
111
    }
112

113
    /**
114
     * Change /abc/def.jsp into /abc/def-XYZ.jsp
115
     *
116
     * @param path
117
     *            the path
118
     * @param ext
119
     *            the ext
120
     *
121
     * @return the string
122
     */
123
    private static String modifyPath(String path, String ext) {
124
        int dot = path.indexOf('.');
×
125
        if (dot > -1) {
×
126
            return path.substring(0, dot) + '-' + ext + path.substring(dot);
×
127
        }
128
        return path + '-' + ext;
×
129
    }
130

131
    /**
132
     * Initialize language mappings.
133
     *
134
     * @param props
135
     *            the props
136
     */
137
    private void initMap(Properties props) {
138
        for (Map.Entry<Object, Object> entry : props.entrySet()) {
×
139
            String key = (String) entry.getKey();
×
140
            if (key.startsWith("match.")) {
×
141
                String match = key.substring(6);
×
142
                map.put(match, entry.getValue());
×
143
            }
144
        }
×
145
    }
×
146
}
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