package codeine.configuration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import codeine.jsons.command.CommandInfo;
import codeine.jsons.project.ProjectJson;
import codeine.model.Constants;
import codeine.utils.FilesUtils;
import codeine.utils.JsonFileUtils;
import codeine.utils.JsonUtils;
import codeine.utils.exceptions.ProjectNotFoundException;
import codeine.utils.logging.LogUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.reflect.TypeToken;
public class ConfigurationReadManagerServer implements IConfigurationManager
{
private static final Logger log = Logger.getLogger(ConfigurationReadManagerServer.class);
public static final ProjectJson NODES_INTERNAL_PROJECT = new ProjectJson(Constants.CODEINE_NODES_PROJECT_NAME);
private Map<String, ProjectJson> projects = Maps.newConcurrentMap();
private JsonFileUtils jsonFileUtils;
private PathHelper pathHelper;
@Inject
public ConfigurationReadManagerServer(JsonFileUtils jsonFileUtils, PathHelper pathHelper)
{
this.jsonFileUtils = jsonFileUtils;
this.pathHelper = pathHelper;
refresh();
}
@Override
public void refresh() {
Map<String, ProjectJson> projects1 = Maps.newConcurrentMap();
try {
String projectsDir = pathHelper.getProjectsDir();
log.info("loading configuration, projects from " + projectsDir);
List<String> files = FilesUtils.getFilesInDir(projectsDir);
for (String file : files) {
try {
if (file.startsWith(".")){
log.info("will ignore project dir " + file);
continue;
}
ProjectJson projectJson = getProjectFromDisk(file);
projects1.put(projectJson.name(), projectJson);
FilesUtils.mkdirs(pathHelper.getAllCommandsInProjectOutputDir(projectJson.name()));
} catch (IllegalArgumentException e1) {
log.error("failed to configure project " + file + " " + e1.getMessage());
}catch (Exception e) {
log.error("failed to configure project " + file, e);
}
}
} catch (RuntimeException e) {
log.error("error", e);
throw e;
}
projects(projects1);
}
protected ProjectJson getProjectFromDisk(String file) {
String fileFullPath = pathHelper.getProjectsDir() + "/" + file + "/" + Constants.PROJECT_CONF_FILE;
if (!FilesUtils.exists(fileFullPath)) {
log.info("conf file not exists " + fileFullPath);
throw new IllegalArgumentException("project not found " + file);
}
ProjectJson projectJson = jsonFileUtils.getConfFromFile(fileFullPath, ProjectJson.class);
return projectJson;
}
@Override
public List<ProjectJson> getConfiguredProjects() {
return Lists.newArrayList(projects().values());
}
private ProjectJson getProjectForNameOrNull(String projectName) {
Preconditions.checkNotNull(projectName);
if (Constants.CODEINE_NODES_PROJECT_NAME.equals(projectName)) {
return NODES_INTERNAL_PROJECT;
}
List<ProjectJson> configuredProjects = getConfiguredProjects();
for (ProjectJson projectJson : configuredProjects) {
if (projectName.equals(projectJson.name())){
return projectJson;
}
}
return null;
}
@Override
public ProjectJson getProjectForName(String projectName) {
ProjectJson $ = getProjectForNameOrNull(projectName);
if (null == $) {
throw new ProjectNotFoundException(projectName);
}
return $;
}
public Map<String, ProjectJson> projects() {
return projects;
}
public void projects(Map<String, ProjectJson> projects) {
LogUtils.assertTrue(log, projects instanceof ConcurrentHashMap, "created a map that is not concurrent");
this.projects = projects;
}
@Override
public boolean hasProject(String projectName) {
return projects.containsKey(projectName);
}
public CommandInfo getCommandOfProject(String projectName, String command_name) {
List<CommandInfo> commands = getProjectCommands(projectName);
for (CommandInfo c : commands) {
if (c.name().equals(command_name)){
return c;
}
}
throw new IllegalArgumentException("command not found " + projectName + " " + command_name);
}
public List<CommandInfo> getProjectCommands(String projectName) {
List<CommandInfo> $ = Lists.newArrayList();
ProjectJson project = getProjectForName(projectName);
$.addAll(project.commands());
if (!project.include_project_commands().isEmpty()) {
for (String p : project.include_project_commands()) {
ProjectJson projectForNameOrNull = getProjectForNameOrNull(p);
if (null == projectForNameOrNull) {
log.warn("project not found " + p + " to include from project " + projectName);
continue;
}
$.addAll(projectForNameOrNull.commands());
}
}
List<CommandInfo> clonedList = JsonUtils.cloneJson($, new TypeToken<List<CommandInfo>>(){}.getType());
for (CommandInfo commandInfo : clonedList) {
commandInfo.project_name(projectName);
}
return clonedList;
}
}