33
33
import java .util .TreeSet ;
34
34
import java .util .logging .Level ;
35
35
import java .util .logging .Logger ;
36
+ import java .util .regex .Matcher ;
37
+ import java .util .regex .Pattern ;
36
38
import java .util .stream .Collectors ;
37
39
import org .opensolaris .opengrok .configuration .Group ;
38
40
import org .opensolaris .opengrok .configuration .Project ;
43
45
import org .opensolaris .opengrok .history .RepositoryInfo ;
44
46
import org .opensolaris .opengrok .index .IndexDatabase ;
45
47
import org .opensolaris .opengrok .logger .LoggerFactory ;
48
+ import org .opensolaris .opengrok .util .ClassUtil ;
46
49
import org .opensolaris .opengrok .util .ForbiddenSymlinkException ;
47
50
import org .opensolaris .opengrok .util .IOUtils ;
48
51
@@ -56,6 +59,16 @@ public class ProjectMessage extends Message {
56
59
57
60
private static final Logger LOGGER = LoggerFactory .getLogger (ProjectMessage .class );
58
61
62
+ /**
63
+ * Pattern describes the java variable name and the assigned value.
64
+ * Examples:
65
+ * <ul>
66
+ * <li>variable = true</li>
67
+ * <li>stopOnClose = 10</li>
68
+ * </ul>
69
+ */
70
+ private static final Pattern VARIABLE_PATTERN = Pattern .compile ("([a-z_]\\ w*) = (.*)" );
71
+
59
72
/**
60
73
* Perform additional validation. This cannot be done in validate()
61
74
* because it does not have access to the currently used RuntimeEnvironment.
@@ -102,12 +115,24 @@ private List<RepositoryInfo> getRepositoriesInDir(RuntimeEnvironment env,
102
115
env .getIgnoredNames ()));
103
116
}
104
117
118
+ private String getCommand () {
119
+ String command = getText ();
120
+
121
+ // get/set need special treatment since the text is overloaded with actual
122
+ // command and its contents.
123
+ if (command .startsWith ("set " ) || command .startsWith ("get " )) {
124
+ command = getText ().substring (0 , 3 );
125
+ }
126
+
127
+ return command ;
128
+ }
129
+
105
130
@ Override
106
131
protected byte [] applyMessage (RuntimeEnvironment env ) throws Exception {
107
- String command = getText ();
132
+ String command = getCommand ();
108
133
109
134
validateMore (env );
110
-
135
+
111
136
switch (command ) {
112
137
case "add" :
113
138
for (String projectName : getTags ()) {
@@ -248,6 +273,65 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
248
273
249
274
env .refreshDateForLastIndexRun ();
250
275
break ;
276
+ case "set" :
277
+ Matcher matcher = VARIABLE_PATTERN .matcher (getText ().substring (4 ));
278
+ if (!matcher .find ()) {
279
+ // invalid pattern
280
+ throw new IOException (
281
+ String .format ("The pattern \" %s\" does not match \" %s\" ." ,
282
+ VARIABLE_PATTERN .toString (),
283
+ getText ()));
284
+ }
285
+
286
+ // Perform a best effort on setting the project properties.
287
+ // If property cannot be set for one project, keep going on.
288
+ List <String > projectsDone = new ArrayList <>();
289
+ for (String projectName : getTags ()) {
290
+ Project project ;
291
+ if ((project = env .getProjects ().get (projectName )) != null ) {
292
+ // Set the property.
293
+ ClassUtil .invokeSetter (
294
+ project ,
295
+ matcher .group (1 ), // field
296
+ matcher .group (2 ) // value
297
+ );
298
+
299
+ // Refresh repositories for this project as well.
300
+ List <RepositoryInfo > riList = env .getProjectRepositoriesMap ().get (project );
301
+ if (riList != null ) {
302
+ for (RepositoryInfo ri : riList ) {
303
+ Repository repo = getRepository (ri , false );
304
+
305
+ // set the property
306
+ ClassUtil .invokeSetter (
307
+ repo ,
308
+ matcher .group (1 ), // field
309
+ matcher .group (2 ) // value
310
+ );
311
+ }
312
+ }
313
+
314
+ projectsDone .add (projectName );
315
+ } else {
316
+ LOGGER .log (Level .WARNING , "cannot find project " +
317
+ projectName + " to set a property" );
318
+ }
319
+ }
320
+
321
+ return String .format ("Variable \" %s\" set to \" %s\" for projects: %s" ,
322
+ matcher .group (1 ), matcher .group (2 ),
323
+ String .join ("," , projectsDone )).getBytes ();
324
+ case "get" :
325
+ for (String projectName : getTags ()) {
326
+ Project project = env .getProjects ().get (projectName );
327
+ if (project != null ) {
328
+ return ClassUtil .invokeGetter (project , getText ().substring (4 )).getBytes ();
329
+ } else {
330
+ LOGGER .log (Level .WARNING , "cannot find project " +
331
+ projectName + " to get a property" );
332
+ }
333
+ }
334
+ break ;
251
335
case "list" :
252
336
return (env .getProjectNames ().stream ().collect (Collectors .joining ("\n " )).getBytes ());
253
337
case "list-indexed" :
@@ -257,8 +341,8 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
257
341
List <String > repos = new ArrayList <>();
258
342
259
343
for (String projectName : getTags ()) {
260
- Project project ;
261
- if (( project = env . getProjects (). get ( projectName )) == null ) {
344
+ Project project = env . getProjects (). get ( projectName ) ;
345
+ if (project == null ) {
262
346
continue ;
263
347
}
264
348
List <RepositoryInfo > infos = env .getProjectRepositoriesMap ().
@@ -302,10 +386,10 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
302
386
*/
303
387
@ Override
304
388
public void validate () throws Exception {
305
- String command = getText ();
389
+ String command = getCommand ();
306
390
Set <String > allowedText = new TreeSet <>(Arrays .asList ("add" , "delete" ,
307
391
"list" , "list-indexed" , "indexed" , "get-repos" ,
308
- "get-repos-type" ));
392
+ "get-repos-type" , "get" , "set" ));
309
393
310
394
// Text field carries the command.
311
395
if (command == null ) {
@@ -319,6 +403,10 @@ public void validate() throws Exception {
319
403
throw new Exception ("The message must contain a tag (project name(s))" );
320
404
}
321
405
406
+ if (command .equals ("get" ) && getTags ().size () != 1 ) {
407
+ throw new Exception ("The \" get\" command can take only one project." );
408
+ }
409
+
322
410
super .validate ();
323
411
}
324
412
}
0 commit comments