Skip to content

Commit 788e650

Browse files
committed
Show Configuration help with --detailed
1 parent 2453f15 commit 788e650

File tree

6 files changed

+424
-16
lines changed

6 files changed

+424
-16
lines changed

src/org/opensolaris/opengrok/configuration/Configuration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public Configuration() {
389389
setCachePages(5);
390390
setCommandTimeout(600); // 10 minutes
391391
setCompressXref(true);
392-
setCtags(System.getProperty("org.opensolaris.opengrok.analysis.Ctags", "ctags"));
392+
//ctags is default(String)
393393
setCurrentIndexedCollapseThreshold(27);
394394
setDataRoot(null);
395395
setDisplayRepositories(true);
@@ -408,7 +408,7 @@ public Configuration() {
408408
setIndexVersionedFilesOnly(false);
409409
setLastEditedDisplayMode(true);
410410
//luceneLocking default is OFF
411-
setMandoc(System.getProperty("org.opensolaris.opengrok.analysis.Mandoc", null));
411+
//mandoc is default(String)
412412
setMaxSearchThreadCount(2 * Runtime.getRuntime().availableProcessors());
413413
setMessageLimit(500);
414414
setOptimizeDatabase(true);
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
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, Chris Fraire <[email protected]>.
22+
*/
23+
24+
package org.opensolaris.opengrok.configuration;
25+
26+
import java.lang.annotation.Annotation;
27+
import java.lang.reflect.InvocationTargetException;
28+
import java.lang.reflect.Method;
29+
import java.lang.reflect.Modifier;
30+
import java.lang.reflect.ParameterizedType;
31+
import java.lang.reflect.Type;
32+
import java.util.ArrayList;
33+
import java.util.HashSet;
34+
import java.util.List;
35+
import java.util.Map;
36+
import java.util.Set;
37+
import java.util.TreeMap;
38+
import org.opensolaris.opengrok.authorization.AuthControlFlag;
39+
import org.opensolaris.opengrok.authorization.AuthorizationPlugin;
40+
import org.opensolaris.opengrok.authorization.AuthorizationStack;
41+
import org.opensolaris.opengrok.history.RepositoryInfo;
42+
import org.opensolaris.opengrok.index.Filter;
43+
import org.opensolaris.opengrok.index.IgnoredNames;
44+
45+
/**
46+
* Represents a utility class to present some user-readable help regarding
47+
* {@link Configuration}.
48+
*/
49+
public class ConfigurationHelp {
50+
/**
51+
* Gets sample content for a configuration XML file.
52+
* @return a defined instance
53+
* @throws RuntimeException if an error occurs producing the sample
54+
*/
55+
public static String getSamples()
56+
throws RuntimeException {
57+
58+
Configuration conf = new Configuration();
59+
Class klass = conf.getClass();
60+
klass.getDeclaredMethods();
61+
62+
StringBuilder b = new StringBuilder();
63+
b.append("Configuration examples:\n");
64+
b.append("\n");
65+
66+
String sample = conf.getXMLRepresentationAsString();
67+
b.append("<!-- Sample empty configuration.xml -->\n");
68+
b.append(sample);
69+
b.append("\n");
70+
71+
List<Method> mthds = getSetters(klass);
72+
for (Method mthd : mthds) {
73+
// Get a pristine instance.
74+
conf = new Configuration();
75+
Object defaultValue = getDefaultValue(klass, mthd, conf);
76+
// Get a pristine instance.
77+
conf = new Configuration();
78+
Object sampleValue = getSampleValue(mthd, defaultValue);
79+
if (sampleValue == null) continue;
80+
81+
try {
82+
mthd.invoke(conf, sampleValue);
83+
} catch (IllegalAccessException|IllegalArgumentException|
84+
InvocationTargetException ex) {
85+
throw new RuntimeException("error setting sample value for " +
86+
mthd);
87+
}
88+
89+
sample = conf.getXMLRepresentationAsString();
90+
sample = sample.replaceFirst(
91+
"(?sx)^<\\?xml.*Configuration\\d*\">\\n", "");
92+
sample = sample.replaceFirst("</object>\\n</java>", "");
93+
94+
b.append(" <!-- Sample for ");
95+
b.append(mthd.getName());
96+
b.append(". Default is: ");
97+
b.append(defaultValue);
98+
b.append(" -->");
99+
b.append("\n");
100+
b.append(sample);
101+
}
102+
return b.toString();
103+
}
104+
105+
private static List<Method> getSetters(Class klass) {
106+
List<Method> res = new ArrayList<>();
107+
Method[] methods = klass.getDeclaredMethods();
108+
for (Method mth : methods) {
109+
int mod = mth.getModifiers();
110+
if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) &&
111+
mth.getParameterCount() == 1 &&
112+
mth.getName().matches("^set.*") && !isDeprecated(mth)) {
113+
res.add(mth);
114+
}
115+
}
116+
res.sort((o1, o2) -> {
117+
int cmp = o1.getName().compareToIgnoreCase(o2.getName());
118+
return cmp;
119+
});
120+
return res;
121+
}
122+
123+
private static Object getSampleValue(Method setter, Object defaultValue) {
124+
125+
Class paramType = setter.getParameterTypes()[0];
126+
Type genType = setter.getGenericParameterTypes()[0];
127+
128+
if (setter.getName().equals("setBugPattern")) {
129+
return "Sample Bug \\#(\\d+)";
130+
} else if (setter.getName().equals("setReviewPattern")) {
131+
return "Sample Issue \\#(\\d+)";
132+
} else if (paramType == String.class) {
133+
return "user-specified-value";
134+
} else if (paramType == int.class) {
135+
return 1 + (int)defaultValue;
136+
} else if (paramType == short.class) {
137+
return (short)(1 + (short)defaultValue);
138+
} else if (paramType == boolean.class) {
139+
if (defaultValue == null) return null;
140+
return !(boolean)defaultValue;
141+
} else if (paramType == double.class) {
142+
return 1 + (double)defaultValue;
143+
} else if (paramType == List.class) {
144+
return getSampleListValue(genType);
145+
} else if (paramType == Map.class) {
146+
return getSampleMapValue(genType);
147+
} else if (paramType == Set.class) {
148+
return getSampleSetValue(genType);
149+
} else if (paramType == AuthorizationStack.class) {
150+
AuthorizationStack astck = new AuthorizationStack(
151+
AuthControlFlag.REQUIRED, "user-specified-value");
152+
astck.add(new AuthorizationPlugin(AuthControlFlag.REQUISITE,
153+
"user-specified-value"));
154+
return astck;
155+
} else if (paramType == Filter.class) {
156+
Filter flt = new Filter();
157+
flt.add("user-specified-(patterns)*");
158+
flt.add("user-specified-filename");
159+
flt.add("user/specified/path");
160+
return flt;
161+
} else if (paramType == IgnoredNames.class) {
162+
IgnoredNames inm = new IgnoredNames();
163+
inm.add("f:user-specified-value");
164+
inm.add("d:user-specified-value");
165+
return inm;
166+
} else if (paramType.isEnum()) {
167+
for (Object value : paramType.getEnumConstants()) {
168+
if (!value.equals(defaultValue)) return value;
169+
}
170+
return null;
171+
} else {
172+
throw new UnsupportedOperationException("getSampleValue() for " +
173+
paramType + ", " + genType);
174+
}
175+
}
176+
177+
private static Object getSampleListValue(Type genType) {
178+
if (!(genType instanceof ParameterizedType)) {
179+
return null;
180+
}
181+
ParameterizedType genParamType = (ParameterizedType)genType;
182+
Type actType = genParamType.getActualTypeArguments()[0];
183+
Object res = null;
184+
185+
if (actType == RepositoryInfo.class) {
186+
// ignore
187+
}
188+
else {
189+
throw new UnsupportedOperationException("Not supported yet for " +
190+
actType);
191+
}
192+
return res;
193+
}
194+
195+
private static Object getSampleMapValue(Type genType) {
196+
if (!(genType instanceof ParameterizedType)) {
197+
return null;
198+
}
199+
ParameterizedType genParamType = (ParameterizedType)genType;
200+
Type[] actualTypeArguments = genParamType.getActualTypeArguments();
201+
Type actType0 = actualTypeArguments[0];
202+
Type actType1 = actualTypeArguments[1];
203+
Object res = null;
204+
205+
if (actType0 == String.class) {
206+
if (actType1 == String.class) {
207+
Map<String, String> strmap = new TreeMap<>();
208+
strmap.put("user-defined-key", "user-defined-value");
209+
res = strmap;
210+
} else if (actType1 == Project.class) {
211+
Map<String, Project> strmap = new TreeMap<>();
212+
String nm = "user-defined-key";
213+
strmap.put(nm, getSampleProject(nm));
214+
res = strmap;
215+
} else {
216+
throw new UnsupportedOperationException(
217+
"Not supported yet for " + actType0 + " " + actType1);
218+
}
219+
} else {
220+
throw new UnsupportedOperationException("Not supported yet for " +
221+
actType0 + " " + actType1);
222+
}
223+
return res;
224+
}
225+
226+
private static Object getSampleSetValue(Type genType) {
227+
if (!(genType instanceof ParameterizedType)) {
228+
return null;
229+
}
230+
ParameterizedType genParamType = (ParameterizedType)genType;
231+
Type actType = genParamType.getActualTypeArguments()[0];
232+
Object res = null;
233+
234+
if (actType == String.class) {
235+
Set<String> strset = new HashSet<>();
236+
strset.add("user-defined-element");
237+
res = strset;
238+
} else if (actType == Group.class) {
239+
Set<Group> grpset = new HashSet<>();
240+
Group g = new Group("user-defined-name", "user-defined-pattern");
241+
grpset.add(g);
242+
res = grpset;
243+
} else if (actType == Project.class) {
244+
Set<Project> prjset = new HashSet<>();
245+
Project p = getSampleProject("user-defined-name");
246+
prjset.add(p);
247+
res = prjset;
248+
} else {
249+
throw new UnsupportedOperationException("Not supported yet for " +
250+
actType);
251+
}
252+
return res;
253+
}
254+
255+
private static Project getSampleProject(String name) {
256+
Project p = new Project(name, "/user/defined/path");
257+
p.setNavigateWindowEnabled(true);
258+
p.setTabSize(8);
259+
return p;
260+
}
261+
262+
private static Object getDefaultValue(Class<?> klass, Method setter,
263+
Configuration cinst) {
264+
265+
String gname = setter.getName();
266+
gname = gname.replaceFirst("^set", "get");
267+
Method getter;
268+
try {
269+
getter = klass.getDeclaredMethod(gname);
270+
} catch (NoSuchMethodException|SecurityException ex) {
271+
return null;
272+
}
273+
274+
try {
275+
return getter.invoke(cinst);
276+
} catch (IllegalAccessException|IllegalArgumentException|
277+
InvocationTargetException ex) {
278+
return null;
279+
}
280+
}
281+
282+
private static boolean isDeprecated(Method mth) {
283+
for (Annotation annotation : mth.getAnnotations()) {
284+
if (annotation instanceof Deprecated) return true;
285+
}
286+
return false;
287+
}
288+
}

0 commit comments

Comments
 (0)