Skip to content

Commit

Permalink
add set/get command for ProjectMessage
Browse files Browse the repository at this point in the history
approaches oracle#2147
  • Loading branch information
Vladimir Kotal committed Jun 11, 2018
1 parent 2d1657b commit 0738338
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.opensolaris.opengrok.configuration.Group;
import org.opensolaris.opengrok.configuration.Project;
Expand All @@ -43,6 +45,7 @@
import org.opensolaris.opengrok.history.RepositoryInfo;
import org.opensolaris.opengrok.index.IndexDatabase;
import org.opensolaris.opengrok.logger.LoggerFactory;
import org.opensolaris.opengrok.util.ClassUtil;
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
import org.opensolaris.opengrok.util.IOUtils;

Expand All @@ -56,6 +59,16 @@ public class ProjectMessage extends Message {

private static final Logger LOGGER = LoggerFactory.getLogger(ProjectMessage.class);

/**
* Pattern describes the java variable name and the assigned value.
* Examples:
* <ul>
* <li>variable = true</li>
* <li>stopOnClose = 10</li>
* </ul>
*/
private static final Pattern VARIABLE_PATTERN = Pattern.compile("([a-z_]\\w*) = (.*)");

/**
* Perform additional validation. This cannot be done in validate()
* because it does not have access to the currently used RuntimeEnvironment.
Expand Down Expand Up @@ -102,13 +115,25 @@ private List<RepositoryInfo> getRepositoriesInDir(RuntimeEnvironment env,
env.getIgnoredNames()));
}

private String getCommand() {
String command = getText();

// get/set need special treatment since the text is overloaded with actual
// command and its contents.
if (command.startsWith("set ") || command.startsWith("get ")) {
command = getText().substring(0, 3);
}

return command;
}

@Override
protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
String command = getText();
String command = getCommand();

validateMore(env);

switch (command) {
switch (getCommand()) {
case "add":
for (String projectName : getTags()) {
File srcRoot = env.getSourceRootFile();
Expand Down Expand Up @@ -248,6 +273,57 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {

env.refreshDateForLastIndexRun();
break;
case "set":
Matcher matcher = VARIABLE_PATTERN.matcher(getText().substring(4));
if (!matcher.find()) {
// invalid pattern
throw new IOException(
String.format("The pattern \"%s\" does not match \"%s\".",
VARIABLE_PATTERN.toString(),
getText()));
}

for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) != null) {
// Set the property.
ClassUtil.invokeSetter(
project,
matcher.group(1), // field
matcher.group(2) // value
);

// Refresh repositories for this project as well.
List<RepositoryInfo> riList = env.getProjectRepositoriesMap().get(project);
if (riList != null) {
for (RepositoryInfo ri : riList) {
Repository repo = getRepository(ri, false);

// set the property
ClassUtil.invokeSetter(
repo,
matcher.group(1), // field
matcher.group(2) // value
);
}
}

return String.format("Variable \"%s\" set to \"%s\".",
matcher.group(1), matcher.group(2)).getBytes();
} else {
LOGGER.log(Level.WARNING, "cannot find project " +
projectName + " to set a property");
}
}
break;
case "get":
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) != null) {
return ClassUtil.invokeGetter(project, getText().substring(4)).getBytes();
}
}
break;
case "list":
return (env.getProjectNames().stream().collect(Collectors.joining("\n")).getBytes());
case "list-indexed":
Expand Down Expand Up @@ -302,10 +378,10 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
*/
@Override
public void validate() throws Exception {
String command = getText();
String command = getCommand();
Set<String> allowedText = new TreeSet<>(Arrays.asList("add", "delete",
"list", "list-indexed", "indexed", "get-repos",
"get-repos-type"));
"get-repos-type", "get", "set"));

// Text field carries the command.
if (command == null) {
Expand All @@ -319,6 +395,10 @@ public void validate() throws Exception {
throw new Exception("The message must contain a tag (project name(s))");
}

if (command.compareTo("get") == 0 && getTags().size() != 1) {
throw new Exception("The \"get\" command can take only one project.");
}

super.validate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
import org.opensolaris.opengrok.history.HistoryGuru;
import org.opensolaris.opengrok.history.MercurialRepository;
import org.opensolaris.opengrok.history.MercurialRepositoryTest;
import org.opensolaris.opengrok.history.Repository;
import org.opensolaris.opengrok.history.RepositoryFactory;
import static org.opensolaris.opengrok.history.RepositoryFactory.getRepository;
import org.opensolaris.opengrok.history.RepositoryInfo;
import org.opensolaris.opengrok.history.SubversionRepository;
import org.opensolaris.opengrok.index.IndexDatabase;
Expand Down Expand Up @@ -495,4 +497,40 @@ public void testGetRepos() throws Exception {
out = new String(m.apply(env));
Assert.assertEquals("Mercurial", out);
}

@Test
public void testSetGet() throws Exception {
Assert.assertTrue(env.isHandleHistoryOfRenamedFiles());
Message m;

// Add a project
m = new ProjectMessage();
m.setText("add");
m.addTag("mercurial");
m.apply(env);

// Change its property.
m = new ProjectMessage();
m.setText("set handleRenamedFiles = false");
m.addTag("mercurial");
m.apply(env);

// Verify the property was set on the project and its repositories.
Project project = env.getProjects().get("mercurial");
Assert.assertNotNull(project);
Assert.assertFalse(project.isHandleRenamedFiles());
List<RepositoryInfo> riList = env.getProjectRepositoriesMap().get(project);
Assert.assertNotNull(riList);
for (RepositoryInfo ri : riList) {
Repository repo = getRepository(ri, false);
Assert.assertFalse(repo.isHandleRenamedFiles());
}

// Verify the property can be retrieved via message.
m = new ProjectMessage();
m.setText("get handleRenamedFiles");
m.addTag("mercurial");
String out = new String(m.apply(env));
Assert.assertEquals("false", out);
}
}
9 changes: 9 additions & 0 deletions tools/Messages
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ Usage()
echo " - \"list-indexed\" - list indexed projects"
echo " - \"get-repos\" - get list of repositories in the form of relative paths to source root for given project(s)"
echo " - \"get-repos-type\" - get repository type(s) for given project(s)"
echo " - \"set\" - sets a particular project property (only primitive types)"
echo " in the webapp."
echo " Examples:"
echo " tabSize = 8"
echo " handleRenamedFiles = true"
echo " Returns text describing the action."
echo " The change is NOT persistent when reindex or redeploy!"
echo " - \"get\" retrieves the particular per project property (only primitive types)"
echo " Returns string representation of the property."
echo " repository:"
echo " - repository paths relative to source root are specified as <tags>"
echo " - command is specified in message <text>:"
Expand Down

0 comments on commit 0738338

Please # to comment.