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

oracle / opengrok / #3670

01 Nov 2023 10:10AM UTC coverage: 74.437% (-0.7%) from 75.16%
#3670

push

web-flow
Fix Sonar codesmell issues (#4460)

Signed-off-by: Gino Augustine <ginoaugustine@gmail.com>

308 of 308 new or added lines in 27 files covered. (100.0%)

43623 of 58604 relevant lines covered (74.44%)

0.74 hits per line

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

89.15
/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/ConfigurationHelp.java
1
/*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License (the "License").
6
 * You may not use this file except in compliance with the License.
7
 *
8
 * See LICENSE.txt included in this distribution for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing Covered Code, include this CDDL HEADER in each
12
 * file and include the License file at LICENSE.txt.
13
 * If applicable, add the following below this CDDL HEADER, with the
14
 * fields enclosed by brackets "[]" replaced with your own identifying
15
 * information: Portions Copyright [yyyy] [name of copyright owner]
16
 *
17
 * CDDL HEADER END
18
 */
19

20
/*
21
 * Copyright (c) 2018, 2020, Chris Fraire <cfraire@me.com>.
22
 */
23
package org.opengrok.indexer.configuration;
24

25
import java.lang.annotation.Annotation;
26
import java.lang.reflect.InvocationTargetException;
27
import java.lang.reflect.Method;
28
import java.lang.reflect.Modifier;
29
import java.lang.reflect.ParameterizedType;
30
import java.lang.reflect.Type;
31
import java.util.ArrayList;
32
import java.util.HashSet;
33
import java.util.List;
34
import java.util.Map;
35
import java.util.Set;
36
import java.util.TreeMap;
37
import org.opengrok.indexer.authorization.AuthControlFlag;
38
import org.opengrok.indexer.authorization.AuthorizationPlugin;
39
import org.opengrok.indexer.authorization.AuthorizationStack;
40
import org.opengrok.indexer.history.RepositoryInfo;
41
import org.opengrok.indexer.util.StringUtils;
42

43
/**
44
 * Represents a utility class to present some user-readable help regarding
45
 * {@link Configuration}.
46
 */
47
public class ConfigurationHelp {
48

49
    private static final String XML_COMMENT_START = "  <!-- ";
50
    private static final String USER_DEFINED_KEY = "user-defined-key";
51
    private static final String USER_DEFINED_VALUE = "user-specified-value";
52
    private static final String NOT_SUPPORTED_MSG = "Not supported yet for ";
53

54

55
    private ConfigurationHelp() {
56
    }
57

58
    /**
59
     * Gets sample content for a configuration XML file.
60
     * @return a defined instance
61
     * @throws RuntimeException if an error occurs producing the sample
62
     */
63
    public static String getSamples() throws RuntimeException {
64

65
        Configuration conf = new Configuration();
1✔
66
        Class<?> klass = conf.getClass();
1✔
67

68
        StringBuilder b = new StringBuilder();
1✔
69
        LinesBuilder h = new LinesBuilder();
1✔
70

71
        b.append("Configuration examples:\n");
1✔
72
        b.append("\n");
1✔
73

74
        String sample = conf.getXMLRepresentationAsString();
1✔
75
        b.append("<!-- Sample empty configuration.xml -->\n");
1✔
76
        b.append(sample);
1✔
77
        b.append("\n");
1✔
78

79
        List<Method> mthds = getSetters(klass);
1✔
80
        for (Method mthd : mthds) {
1✔
81
            // Get a pristine instance.
82
            conf = new Configuration();
1✔
83
            Object defaultValue = getDefaultValue(klass, mthd, conf);
1✔
84
            // Get a pristine instance.
85
            conf = new Configuration();
1✔
86
            Object sampleValue = getSampleValue(mthd, defaultValue);
1✔
87
            if (sampleValue == null) {
1✔
88
                continue;
1✔
89
            }
90

91
            try {
92
                mthd.invoke(conf, sampleValue);
1✔
93
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
×
94
                throw new RuntimeException("error setting sample value for " +
×
95
                    mthd);
96
            }
1✔
97

98
            sample = conf.getXMLRepresentationAsString();
1✔
99
            sample = sample.replaceFirst(
1✔
100
                "(?sx)^<\\?xml.*Configuration\\d*\">\\n", "");
101
            sample = sample.replaceFirst("</object>\\n</java>", "");
1✔
102

103
            h.clear();
1✔
104
            h.append(XML_COMMENT_START);
1✔
105
            h.append("Sample for ");
1✔
106
            h.append(mthd.getName());
1✔
107
            h.append(". Default is ");
1✔
108
            h.appendWords(defaultValue);
1✔
109
            h.appendWords(" -->");
1✔
110
            h.appendLine();
1✔
111

112
            b.append(h);
1✔
113
            b.append(sample);
1✔
114
        }
1✔
115
        return b.toString();
1✔
116
    }
117

118
    private static List<Method> getSetters(Class<?> klass) {
119
        List<Method> res = new ArrayList<>();
1✔
120
        Method[] methods = klass.getDeclaredMethods();
1✔
121
        for (Method mth : methods) {
1✔
122
            int mod = mth.getModifiers();
1✔
123
            if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) &&
1✔
124
                mth.getParameterCount() == 1 &&
1✔
125
                mth.getName().matches("^set.*") && !isDeprecated(mth)) {
1✔
126
                res.add(mth);
1✔
127
            }
128
        }
129
        res.sort((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
1✔
130
        return res;
1✔
131
    }
132

133
    private static Object getSampleValue(Method setter, Object defaultValue) {
134

135
        Class<?> paramType = setter.getParameterTypes()[0];
1✔
136
        Type genType = setter.getGenericParameterTypes()[0];
1✔
137

138
        if (setter.getName().equals("setBugPattern")) {
1✔
139
            return "Sample Bug \\#(\\d+)";
1✔
140
        } else if (setter.getName().equals("setReviewPattern")) {
1✔
141
            return "Sample Issue \\#(\\d+)";
1✔
142
        } else if (paramType == String.class) {
1✔
143
            return USER_DEFINED_VALUE;
1✔
144
        } else if (paramType == int.class) {
1✔
145
            return 1 + (int) defaultValue;
1✔
146
        } else if (paramType == long.class) {
1✔
147
            return 1 + (long) defaultValue;
1✔
148
        } else if (paramType == short.class) {
1✔
149
            return (short) (1 + (short) defaultValue);
1✔
150
        } else if (paramType == boolean.class) {
1✔
151
            if (defaultValue == null) {
1✔
152
                return null;
×
153
            }
154
            return !(boolean) defaultValue;
1✔
155
        } else if (paramType == double.class) {
1✔
156
            return 1 + (double) defaultValue;
1✔
157
        } else if (paramType == List.class) {
1✔
158
            return getSampleListValue(genType);
1✔
159
        } else if (paramType == Map.class) {
1✔
160
            return getSampleMapValue(genType);
1✔
161
        } else if (paramType == Set.class) {
1✔
162
            return getSampleSetValue(genType);
1✔
163
        } else if (paramType == AuthorizationStack.class) {
1✔
164
            AuthorizationStack astck = new AuthorizationStack(
1✔
165
                AuthControlFlag.REQUIRED, USER_DEFINED_VALUE);
166
            astck.add(new AuthorizationPlugin(AuthControlFlag.REQUISITE,
1✔
167
                USER_DEFINED_VALUE));
168
            return astck;
1✔
169
        } else if (paramType == Filter.class) {
1✔
170
            Filter flt = new Filter();
1✔
171
            flt.add("user-specified-(patterns)*");
1✔
172
            flt.add("user-specified-filename");
1✔
173
            flt.add("user/specified/path");
1✔
174
            return flt;
1✔
175
        } else if (paramType == IgnoredNames.class) {
1✔
176
            IgnoredNames inm = new IgnoredNames();
1✔
177
            inm.add("f:user-specified-value");
1✔
178
            inm.add("d:user-specified-value");
1✔
179
            return inm;
1✔
180
        } else if (paramType.isEnum()) {
1✔
181
            for (Object value : paramType.getEnumConstants()) {
1✔
182
                if (!value.equals(defaultValue)) {
1✔
183
                    return value;
1✔
184
                }
185
            }
186
            return null;
×
187
        } else if (paramType == SuggesterConfig.class) {
1✔
188
            return SuggesterConfig.getForHelp();
1✔
189
        } else if (paramType == StatsdConfig.class) {
1✔
190
            return StatsdConfig.getForHelp();
1✔
191
        } else {
192
            throw new UnsupportedOperationException("getSampleValue() for " +
×
193
                paramType + ", " + genType);
194
        }
195
    }
196

197
    private static Object getSampleListValue(Type genType) {
198
        if (!(genType instanceof ParameterizedType)) {
1✔
199
            return null;
×
200
        }
201
        ParameterizedType genParamType = (ParameterizedType) genType;
1✔
202
        Type actType = genParamType.getActualTypeArguments()[0];
1✔
203

204
        if (actType != RepositoryInfo.class) {
1✔
205
            throw new UnsupportedOperationException(NOT_SUPPORTED_MSG + actType);
×
206
        }
207
        return null;
1✔
208
    }
209

210
    private static Object getSampleMapValue(Type genType) {
211
        if (!(genType instanceof ParameterizedType)) {
1✔
212
            return null;
×
213
        }
214
        ParameterizedType genParamType = (ParameterizedType) genType;
1✔
215
        Type[] actualTypeArguments = genParamType.getActualTypeArguments();
1✔
216
        Type actType0 = actualTypeArguments[0];
1✔
217
        Type actType1 = actualTypeArguments[1];
1✔
218
        Object res;
219

220
        if (actType0 == String.class) {
1✔
221
            if (actType1 == String.class) {
1✔
222
                Map<String, String> strmap = new TreeMap<>();
1✔
223
                strmap.put(USER_DEFINED_KEY, "user-defined-value");
1✔
224
                res = strmap;
1✔
225
            } else if (actType1 == Project.class) {
1✔
226
                Map<String, Project> strmap = new TreeMap<>();
1✔
227
                String nm = USER_DEFINED_KEY;
1✔
228
                strmap.put(nm, getSampleProject(nm));
1✔
229
                res = strmap;
1✔
230
            } else if (actType1 == Group.class) {
1✔
231
                Map<String, Group> strmap = new TreeMap<>();
1✔
232
                String nm = USER_DEFINED_KEY;
1✔
233
                strmap.put(nm, getSampleGroup(nm));
1✔
234
                res = strmap;
1✔
235
            } else {
1✔
236
                throw new UnsupportedOperationException(
×
237
                    NOT_SUPPORTED_MSG + actType0 + " " + actType1);
238
            }
239
        } else {
240
            throw new UnsupportedOperationException(NOT_SUPPORTED_MSG +
×
241
                actType0 + " " + actType1);
242
        }
243
        return res;
1✔
244
    }
245

246
    private static Object getSampleSetValue(Type genType) {
247
        if (!(genType instanceof ParameterizedType)) {
1✔
248
            return null;
×
249
        }
250
        ParameterizedType genParamType = (ParameterizedType) genType;
1✔
251
        Type actType = genParamType.getActualTypeArguments()[0];
1✔
252
        Object res;
253

254
        if (actType == String.class) {
1✔
255
            Set<String> strset = new HashSet<>();
1✔
256
            strset.add("user-defined-element");
1✔
257
            res = strset;
1✔
258
        } else if (actType == Group.class) {
1✔
259
            Set<Group> grpset = new HashSet<>();
×
260
            Group g = new Group("user-defined-name", "user-defined-pattern");
×
261
            grpset.add(g);
×
262
            res = grpset;
×
263
        } else if (actType == Project.class) {
1✔
264
            Set<Project> prjset = new HashSet<>();
1✔
265
            Project p = getSampleProject("user-defined-name");
1✔
266
            prjset.add(p);
1✔
267
            res = prjset;
1✔
268
        } else {
1✔
269
            throw new UnsupportedOperationException(NOT_SUPPORTED_MSG +
×
270
                actType);
271
        }
272
        return res;
1✔
273
    }
274

275
    private static Project getSampleProject(String name) {
276
        Project p = new Project(name, "/user/defined/path");
1✔
277
        p.setNavigateWindowEnabled(true);
1✔
278
        p.setTabSize(8);
1✔
279
        return p;
1✔
280
    }
281

282
    private static Group getSampleGroup(String name) {
283
        Group grp = new Group(name, name);
1✔
284
        grp.setFlag(1);
1✔
285
        return grp;
1✔
286
    }
287

288
    private static Object getDefaultValue(Class<?> klass, Method setter,
289
        Configuration cinst) {
290

291
        String gname = setter.getName().replaceFirst("^set", "get");
1✔
292
        Method getter;
293
        try {
294
            getter = klass.getDeclaredMethod(gname);
1✔
295
        } catch (NoSuchMethodException | SecurityException ex) {
1✔
296
            gname = setter.getName().replaceFirst("^set", "is");
1✔
297
            try {
298
                getter = klass.getDeclaredMethod(gname);
1✔
299
            } catch (NoSuchMethodException | SecurityException ex2) {
×
300
                return null;
×
301
            }
1✔
302
        }
1✔
303

304
        // Return a text override for some objects.
305
        switch (gname) {
1✔
306
            case "getSuggesterConfig":
307
                return "as below but with Boolean opposites, non-zeroes decremented by 1, null " +
1✔
308
                        "for allowed-projects, and also including \"full\" in allowed-fields";
309
            case "getPluginStack":
310
                return "an empty stack";
1✔
311
            case "getIncludedNames":
312
                return "an empty filter";
1✔
313
            case "getIgnoredNames":
314
                return "OpenGrok's standard set of ignored files and directories";
1✔
315
        }
316

317
        try {
318
            return getter.invoke(cinst);
1✔
319
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
×
320
            return null;
×
321
        }
322
    }
323

324
    private static boolean isDeprecated(Method mth) {
325
        for (Annotation annotation : mth.getAnnotations()) {
1✔
326
            if (annotation instanceof Deprecated) {
×
327
                return true;
×
328
            }
329
        }
330
        return false;
1✔
331
    }
332

333
    private static class LinesBuilder {
1✔
334
        static final int LINE_LENGTH = 80;
335

336
        final StringBuilder b = new StringBuilder();
1✔
337
        int length;
338

339
        void clear() {
340
            b.setLength(0);
1✔
341
            length = 0;
1✔
342
        }
1✔
343

344
        void append(String value) {
345
            b.append(value);
1✔
346
            length += value.length();
1✔
347
        }
1✔
348

349
        void appendWords(Object value) {
350
            if (value == null) {
1✔
351
                appendWords("null");
1✔
352
            } else {
353
                appendWords(value.toString());
1✔
354
            }
355
        }
1✔
356

357
        void appendWords(String value) {
358
            if (length > LINE_LENGTH) {
1✔
359
                appendLine();
×
360
            }
361

362
            int i = 0;
1✔
363
            while (true) {
364
                int spaceLen = StringUtils.whitespaceOrControlLength(value, i, true);
1✔
365
                int wordLen = StringUtils.whitespaceOrControlLength(value, i + spaceLen, false);
1✔
366

367
                if (wordLen < 1) {
1✔
368
                    break;
1✔
369
                }
370

371
                String word = value.substring(i + spaceLen, i + spaceLen + wordLen);
1✔
372
                if (length + spaceLen + wordLen > LINE_LENGTH) {
1✔
373
                    appendLine();
1✔
374
                    for (int j = 0; j < XML_COMMENT_START.length(); ++j) {
1✔
375
                        append(" ");
1✔
376
                    }
377
                } else {
378
                    append(value.substring(i, i + spaceLen));
1✔
379
                }
380
                append(word);
1✔
381

382
                i += spaceLen + wordLen;
1✔
383
            }
1✔
384
        }
1✔
385

386
        void appendLine() {
387
            b.append("\n");
1✔
388
            length = 0;
1✔
389
        }
1✔
390

391
        @Override
392
        public String toString() {
393
            return b.toString();
1✔
394
        }
395
    }
396
}
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

© 2025 Coveralls, Inc