Skip to content

Commit e347df4

Browse files
author
Vladimir Kotal
authored
Config merge tool (#1590)
fixes #1580
1 parent e181bd2 commit e347df4

File tree

7 files changed

+460
-15
lines changed

7 files changed

+460
-15
lines changed

opengrok-web-nbproject/nbproject/project.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ endorsed.classpath=
3434
excludes=
3535
file.reference.bcel-6.0.jar=../lib/bcel-6.0.jar
3636
file.reference.json-simple-1.1.1.jar=../lib/json-simple-1.1.1.jar
37-
j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/antlr-4.6-complete.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.2.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
37+
j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.5.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
3838
lucene.version=6.5.1
3939
lucene-core.jar=lucene-core-${lucene.version}.jar
4040
lucene-analyzers-common.jar=lucene-analyzers-common-${lucene.version}.jar

platform/solaris/ips/create.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ PKG pkgsend add file platform/solaris/smf/ogindexd mode=0555 owner=root group=bi
199199

200200
PKG pkgsend add file OpenGrok mode=0555 owner=root group=bin path=/usr/opengrok/bin/OpenGrok
201201
PKG pkgsend add file tools/Groups mode=0555 owner=root group=bin path=/usr/opengrok/bin/Groups
202+
PKG pkgsend add file tools/ConfigMerge mode=0555 owner=root group=bin path=/usr/opengrok/bin/ConfigMerge
202203
PKG pkgsend add file tools/Messages mode=0555 owner=root group=bin path=/usr/opengrok/bin/Messages
203204

204205
PKG pkgsend add file dist/opengrok.jar mode=0444 owner=root group=bin path=/usr/opengrok/lib/opengrok.jar

platform/solaris/pkgdef/prototype

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#
1717
# CDDL HEADER END
1818
#
19-
# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
19+
# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
2020
#
2121

2222
i pkginfo
@@ -49,6 +49,7 @@ f manifest var/svc/manifest/application/opengrok.xml=platform/solaris/smf/opengr
4949
f none lib/svc/method/svc-opengrok=platform/solaris/smf/svc-opengrok 555 root bin
5050
f none usr/opengrok/bin/OpenGrok=OpenGrok 0555 bin bin
5151
f none usr/opengrok/bin/Groups=tools/Groups 0555 bin bin
52+
f none usr/opengrok/bin/ConfigMerge=tools/ConfigMerge 0555 bin bin
5253
f none usr/opengrok/bin/Messages=tools/Messages 0555 bin bin
5354
f none usr/opengrok/doc/logging.properties=logging.properties 0444 root sys
5455
f none usr/opengrok/doc/README.txt=README.txt 0444 root sys
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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) 2017, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opensolaris.opengrok.configuration;
24+
25+
import java.beans.IntrospectionException;
26+
import java.beans.PropertyDescriptor;
27+
import java.io.File;
28+
import java.io.IOException;
29+
import java.io.OutputStream;
30+
import java.lang.reflect.Field;
31+
import java.lang.reflect.Method;
32+
import java.lang.reflect.Modifier;
33+
import java.text.ParseException;
34+
import java.util.logging.Level;
35+
import java.util.logging.Logger;
36+
import org.opensolaris.opengrok.util.Getopt;
37+
38+
/**
39+
* Merge 2 config files together. More precisely, take the 1st as a base and
40+
* set all properties from the 2nd in it.
41+
*
42+
* @author Vladimir Kotal
43+
*/
44+
public class ConfigMerge {
45+
46+
private static final String name = "ConfigMerge";
47+
48+
/**
49+
* Merge base and new configuration.
50+
* @param cfgBase base configuration
51+
* @param cfgNew new configuration, will receive properties from the base configuration
52+
*/
53+
public static void merge(Configuration cfgBase, Configuration cfgNew) throws Exception {
54+
Configuration cfgDefault = new Configuration();
55+
56+
// Basic strategy: take all non-static/transient fields that have a setter
57+
// from cfgBase that are not of default value and set them to cfgNew.
58+
for (Field field : cfgBase.getClass().getDeclaredFields()) {
59+
String fieldName = field.getName();
60+
int modifiers = field.getModifiers();
61+
if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers) ||
62+
Modifier.isFinal(modifiers)) {
63+
continue;
64+
}
65+
PropertyDescriptor desc = null;
66+
try {
67+
desc = new PropertyDescriptor(fieldName, Configuration.class);
68+
} catch (IntrospectionException ex) {
69+
throw new Exception("cannot get property descriptor for '" + fieldName + "'");
70+
}
71+
72+
Method setter = desc.getWriteMethod();
73+
if (setter == null) {
74+
throw new Exception("no setter for '" + fieldName + "'");
75+
}
76+
77+
Method getter = desc.getReadMethod();
78+
if (getter == null) {
79+
throw new Exception("no getter for '" + fieldName + "'");
80+
}
81+
82+
try {
83+
Object obj = getter.invoke(cfgBase);
84+
if ((obj == null && getter.invoke(cfgDefault) == null) ||
85+
obj.equals(getter.invoke(cfgDefault))) {
86+
continue;
87+
}
88+
} catch (Exception ex) {
89+
throw new Exception("failed to invoke getter for " + fieldName + ": " + ex);
90+
}
91+
92+
try {
93+
setter.invoke(cfgNew, getter.invoke(cfgBase));
94+
} catch (Exception ex) {
95+
throw new Exception("failed to invoke setter for '" + fieldName + "'");
96+
}
97+
}
98+
}
99+
100+
public static void main(String[] argv) {
101+
102+
Getopt getopt = new Getopt(argv, "h?");
103+
104+
try {
105+
getopt.parse();
106+
} catch (ParseException ex) {
107+
System.err.println(name + ": " + ex.getMessage());
108+
b_usage();
109+
System.exit(1);
110+
}
111+
112+
int cmd;
113+
File f;
114+
getopt.reset();
115+
while ((cmd = getopt.getOpt()) != -1) {
116+
switch (cmd) {
117+
case '?':
118+
case 'h':
119+
a_usage();
120+
System.exit(0);
121+
break;
122+
default:
123+
System.err.println("Internal Error - Not implemented option: " + (char) cmd);
124+
b_usage();
125+
System.exit(1);
126+
break;
127+
}
128+
}
129+
130+
int optind = getopt.getOptind();
131+
if (optind < 0 || argv.length - optind != 2) {
132+
a_usage();
133+
System.exit(1);
134+
}
135+
136+
Configuration cfgBase = null;
137+
try {
138+
cfgBase = Configuration.read(new File(argv[optind]));
139+
} catch (IOException ex) {
140+
System.err.println("cannot read base file " + argv[optind] + ":" + ex);
141+
System.exit(1);
142+
}
143+
144+
Configuration cfgNew = null;
145+
try {
146+
cfgNew = Configuration.read(new File(argv[optind + 1]));
147+
} catch (IOException ex) {
148+
System.err.println("cannot read file " + argv[optind + 1]);
149+
System.exit(1);
150+
}
151+
152+
try {
153+
merge(cfgBase, cfgNew);
154+
} catch (Exception ex) {
155+
System.err.print(ex);
156+
System.exit(1);
157+
}
158+
159+
// Write the resulting XML representation to standard output.
160+
OutputStream os = System.out;
161+
cfgNew.encodeObject(os);
162+
}
163+
164+
private static final void a_usage() {
165+
System.err.println("Usage:");
166+
System.err.println(name + " [-h] <config_file_base> <config_file_new>");
167+
System.err.println();
168+
System.err.println("OPTIONS:");
169+
System.err.println("Help");
170+
System.err.println("-? print this help message");
171+
System.err.println("-h print this help message");
172+
System.err.println();
173+
}
174+
175+
private static final void b_usage() {
176+
System.err.println("Maybe try to run " + name + " -h");
177+
}
178+
}

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,23 +152,21 @@ public final class Configuration {
152152
private String webappLAF;
153153
private RemoteSCM remoteScmSupported;
154154
private boolean optimizeDatabase;
155-
private boolean useLuceneLocking;
155+
private boolean usingLuceneLocking;
156156
private boolean compressXref;
157157
private boolean indexVersionedFilesOnly;
158158
private boolean tagsEnabled;
159159
private int hitsPerPage;
160160
private int cachePages;
161161
private boolean lastEditedDisplayMode;
162-
private String databaseDriver;
163-
private String databaseUrl;
164162
private String CTagsExtraOptionsFile;
165163
private int scanningDepth;
166164
private Set<String> allowedSymlinks;
167165
private boolean obfuscatingEMailAddresses;
168166
private boolean chattyStatusPage;
169167
private final Map<String, String> cmds; // repository type -> command
170168
private int tabSize;
171-
private int command_timeout; // in seconds
169+
private int commandTimeout; // in seconds
172170
private int indexRefreshPeriod; // in seconds
173171
private boolean scopesEnabled;
174172
private boolean foldingEnabled;
@@ -279,21 +277,21 @@ public void setScanningDepth(int scanningDepth) throws IllegalArgumentException
279277
}
280278

281279
public int getCommandTimeout() {
282-
return command_timeout;
280+
return commandTimeout;
283281
}
284282

285283
/**
286284
* Set the command timeout to a new value
287285
*
288-
* @param command_timeout the new value
286+
* @param commandTimeout the new value
289287
* @throws IllegalArgumentException when the timeout is negative
290288
*/
291-
public void setCommandTimeout(int command_timeout) throws IllegalArgumentException {
292-
if (command_timeout < 0) {
289+
public void setCommandTimeout(int commandTimeout) throws IllegalArgumentException {
290+
if (commandTimeout < 0) {
293291
throw new IllegalArgumentException(
294-
String.format(NEGATIVE_NUMBER_ERROR, "command_timeout", command_timeout));
292+
String.format(NEGATIVE_NUMBER_ERROR, "commandTimeout", commandTimeout));
295293
}
296-
this.command_timeout = command_timeout;
294+
this.commandTimeout = commandTimeout;
297295
}
298296

299297
public int getIndexRefreshPeriod() {
@@ -835,11 +833,15 @@ public void setOptimizeDatabase(boolean optimizeDatabase) {
835833
}
836834

837835
public boolean isUsingLuceneLocking() {
838-
return useLuceneLocking;
836+
return usingLuceneLocking;
837+
}
838+
839+
public boolean getUsingLuceneLocking() {
840+
return usingLuceneLocking;
839841
}
840842

841843
public void setUsingLuceneLocking(boolean useLuceneLocking) {
842-
this.useLuceneLocking = useLuceneLocking;
844+
this.usingLuceneLocking = useLuceneLocking;
843845
}
844846

845847
public void setCompressXref(boolean compressXref) {
@@ -1127,7 +1129,7 @@ public String getXMLRepresentationAsString() {
11271129
return bos.toString();
11281130
}
11291131

1130-
private void encodeObject(OutputStream out) {
1132+
public void encodeObject(OutputStream out) {
11311133
try (XMLEncoder e = new XMLEncoder(new BufferedOutputStream(out))) {
11321134
e.writeObject(this);
11331135
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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) 2017, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opensolaris.opengrok.configuration;
24+
25+
import java.io.File;
26+
import java.io.IOException;
27+
import static org.junit.Assert.assertEquals;
28+
import org.junit.Test;
29+
import static org.opensolaris.opengrok.configuration.ConfigMerge.merge;
30+
31+
/**
32+
*
33+
* @author vkotal
34+
*/
35+
public class ConfigMergeTest {
36+
@Test
37+
public void basicTest() throws Exception {
38+
39+
String srcRoot = "/foo";
40+
String dataRoot = "/bar";
41+
String bugPage = "https://foo/bar";
42+
43+
Configuration cfgBase = new Configuration();
44+
cfgBase.setSourceRoot(srcRoot);
45+
cfgBase.setDataRoot(dataRoot);
46+
47+
Configuration cfgNew = new Configuration();
48+
cfgNew.setBugPage(bugPage);
49+
50+
merge(cfgBase, cfgNew);
51+
52+
assertEquals(cfgNew.getSourceRoot(), srcRoot);
53+
assertEquals(cfgNew.getDataRoot(), dataRoot);
54+
assertEquals(cfgNew.getBugPage(), bugPage);
55+
}
56+
}

0 commit comments

Comments
 (0)