package rocks.inspectit.ui.rcp.model;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import rocks.inspectit.shared.all.cmr.model.PlatformIdent;
import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData;
import rocks.inspectit.shared.all.util.ObjectUtils;
import rocks.inspectit.ui.rcp.InspectIT;
import rocks.inspectit.ui.rcp.InspectITImages;
import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition;
/**
* Factory for creating the input data representing the agents in the tree folder structure.
*
* @author Ivan Senic
*
*/
public final class AgentFolderFactory {
/**
* Folder split regex.
*/
private static final String FOLDER_SPLIT_REGEX = "/";
/**
* Private constructor.
*/
private AgentFolderFactory() {
}
/**
* Returns the list of components representing the input tree structure of agents divided if
* needed to folders.
*
* @param platformIdentMap
* {@link Map} of {@link PlatformIdent}s and their statuses.
* @param cmrRepositoryDefinition
* Repository agents belong to.
* @return List of components.
*/
public static List<Component> getAgentFolderTree(Map<PlatformIdent, AgentStatusData> platformIdentMap, CmrRepositoryDefinition cmrRepositoryDefinition) {
Composite dummy = new Composite();
for (Entry<PlatformIdent, AgentStatusData> entry : platformIdentMap.entrySet()) {
PlatformIdent platformIdent = entry.getKey();
AgentStatusData agentStatusData = entry.getValue();
addToFolder(dummy, 0, platformIdent, agentStatusData, cmrRepositoryDefinition);
}
return dummy.getChildren();
}
/**
* Adds the platform to the folder on the given level. This method is recursive. If agent name
* is not fitting the level, it will be added to the given composite. If it fitting for the
* level, proper search will be done for sub-composite to insert the platform.
*
* @param folder
* Top composite.
* @param level
* Wanted level.
* @param platformIdent
* {@link PlatformIdent}.
* @param agentStatusData
* {@link AgentStatusData}.
* @param cmrRepositoryDefinition
* Repository agent is belonging to.
*/
private static void addToFolder(Composite folder, int level, PlatformIdent platformIdent, AgentStatusData agentStatusData, CmrRepositoryDefinition cmrRepositoryDefinition) {
if (!accessibleForLevel(platformIdent.getAgentName(), level)) {
// if name is not matching the level just add th leaf
AgentLeaf agentLeaf = new AgentLeaf(platformIdent, agentStatusData, cmrRepositoryDefinition, level != 0);
folder.addChild(agentLeaf);
} else {
// search for proper folder
boolean folderExisting = false;
String agentLevelName = getFolderNameFromAgent(platformIdent.getAgentName(), level);
for (Component child : folder.getChildren()) {
if ((child instanceof Composite) && ObjectUtils.equals(child.getName(), agentLevelName)) {
addToFolder((Composite) child, level + 1, platformIdent, agentStatusData, cmrRepositoryDefinition);
folderExisting = true;
}
}
// if not found create new one
if (!folderExisting) {
Composite newFolder = createFolder(agentLevelName);
addToFolder(newFolder, level + 1, platformIdent, agentStatusData, cmrRepositoryDefinition);
folder.addChild(newFolder);
}
}
}
/**
* Creates new folder with given name.
*
* @param levelName
* Name.
* @return {@link Composite}.
*/
private static Composite createFolder(String levelName) {
Composite composite = new Composite();
composite.setName(levelName);
composite.setImage(InspectIT.getDefault().getImage(InspectITImages.IMG_FOLDER));
return composite;
}
/**
* Does agent name applies that agent should be put in the folder.
*
* @param agentName
* Name of the agent
* @return True if name of the agent has correctly specified folder structure at least for the 0
* level (root folder).
*/
public static boolean accessibleForFolder(String agentName) {
return accessibleForLevel(agentName, 0);
}
/**
* Returns what should be the name of the agent if the agent is located in a folder.
*
* @param agentName
* Name of the agent
* @return Display name. Result is the string between last found {@value #FOLDER_SPLIT_REGEX}
* and end of name.
*/
public static String getAgentDisplayNameInFolder(String agentName) {
String[] splitted = getSplittedAgentName(agentName);
return splitted[splitted.length - 1];
}
/**
* Checks if the name of the agent is accessible for the given level of folder.
*
* @param agentName
* Name of the agent
* @param level
* Level
* @return True if name of the agent has correctly specified folder structure for given level.
*/
private static boolean accessibleForLevel(String agentName, int level) {
String[] splitted = getSplittedAgentName(agentName);
if (splitted.length > (level + 1)) {
for (String string : splitted) {
if (StringUtils.isEmpty(string)) {
return false;
}
}
return true;
} else {
return false;
}
}
/**
* Returns folder name by extracting it from the agent name.
*
* @param agentName
* Name of the agent
* @param level
* Level
* @return Name or <code>null</code> if the agent name is not accessible for the given level.
*/
private static String getFolderNameFromAgent(String agentName, int level) {
String[] splitted = getSplittedAgentName(agentName);
if (splitted.length > level) {
return splitted[level];
} else {
return null;
}
}
/**
* @param agentName
* Agent name.
* @return Splits the agent name to several strings that represent the folder names.
*/
private static String[] getSplittedAgentName(String agentName) {
if (null != agentName) {
return agentName.split(FOLDER_SPLIT_REGEX);
} else {
return new String[0];
}
}
}