org.unix4j.codegen.optset.OptionSetDefinitionLoader Maven / Gradle / Ivy
package org.unix4j.codegen.optset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.unix4j.codegen.command.def.CommandDef;
import org.unix4j.codegen.command.def.OptionDef;
import org.unix4j.codegen.def.TypeDef;
import org.unix4j.codegen.optset.constraint.OptionConstraint;
import org.unix4j.codegen.optset.def.ActiveSetDef;
import org.unix4j.codegen.optset.def.OptionGroupDef;
import org.unix4j.codegen.optset.def.OptionSetDef;
public class OptionSetDefinitionLoader {
public OptionSetDef create(CommandDef commandDef) {
final OptionSetDef def = createOptionSetDef(commandDef);
final Collection constraints = Constraints.getOptionConstraints(commandDef);
final Map initialActiveSets = new ActiveSetPermutationBuilder(constraints).generateActiveSetsForGroup(commandDef.options);
// print("", initialActiveSets);
// if (true) return null;
addGroupsDerivedFromActiveSets(def, initialActiveSets);
return def;
}
@SuppressWarnings("unused")
private void print(String indent, Map activeSets) {
for (final Map.Entry e : activeSets.entrySet()) {
System.out.println(indent + e.getKey() + ": " + e.getValue().name);
print(indent + "\t", e.getValue().next);
}
}
private void addGroupsDerivedFromActiveSets(OptionSetDef def, Map initialActiveSets) {
//create groups first
final Map, OptionGroupDef> optionsToGroup = createGroupsFromActiveSets(def, initialActiveSets);
// //initial level
for (final ActiveSetDef initialSet : initialActiveSets.values()) {
addGroupsDerivedFromActiveSets(optionsToGroup, initialSet);
}
//recurse all other levels now
int level = 1;
while (populateLevelActiveSetsToGroups(optionsToGroup, level)) {
level++;
}
//set initial group
def.initialGroup = optionsToGroup.get(def.command.options.keySet());
//now add groups to def
def.groups.addAll(optionsToGroup.values());
}
private Map, OptionGroupDef> createGroupsFromActiveSets(OptionSetDef def, Map initialActiveSets) {
final Map, OptionGroupDef> optionsToGroup = new LinkedHashMap, OptionGroupDef>();
//first, simply add the options
addGroupsForActiveSets(def.command, optionsToGroup, initialActiveSets.values());
final Set allOptions = def.command.options.keySet();
if (!optionsToGroup.containsKey(allOptions)) {
optionsToGroup.put(allOptions, createGroupFor(def.command, allOptions));
}
//now, fill the optionToNextGroup values
final OptionGroupDef allOptionsGroup = getGroupForOptions(optionsToGroup, allOptions);
fillOptionToNextGroup(optionsToGroup, allOptionsGroup, initialActiveSets);
//done
return optionsToGroup;
}
private void addGroupsForActiveSets(CommandDef commandDef, Map, OptionGroupDef> optionsToGroup, Iterable activeSets) {
for (final ActiveSetDef activeSet : activeSets) {
final Set options = activeSet.getAllOptions();
OptionGroupDef grp = optionsToGroup.get(options);
if (grp == null) {
grp = createGroupFor(commandDef, options);
optionsToGroup.put(options, grp);
addGroupsForActiveSets(commandDef, optionsToGroup, activeSet.next.values());
}
}
}
private void addGroupsDerivedFromActiveSets(final Map, OptionGroupDef> optionsToGroup, ActiveSetDef activeSet) {
final OptionGroupDef group = getGroupForActiveSet(optionsToGroup, activeSet);
if (group == null) {
throw new IllegalArgumentException("group not found for active options " + activeSet.getAllOptions() + ", group options=" + optionsToGroup.keySet());
}
getLevelSetFor(group, activeSet.active.size(), true).put(activeSet.name, activeSet);
}
private void fillOptionToNextGroup(Map, OptionGroupDef> optionsToGroup, OptionGroupDef group, Map newActiveToActiveSet) {
for (final Map.Entry e : newActiveToActiveSet.entrySet()) {
final String newActive = e.getKey();
final ActiveSetDef activeSet = e.getValue();
final OptionGroupDef nextGroup = getGroupForActiveSet(optionsToGroup, activeSet);
group.optionToNextGroup.put(newActive, nextGroup);
fillOptionToNextGroup(optionsToGroup, nextGroup, activeSet.next);
}
}
private OptionGroupDef getGroupForActiveSet(final Map, OptionGroupDef> optionsToGroup, final ActiveSetDef activeSet) {
return getGroupForOptions(optionsToGroup, activeSet.getAllOptions());
}
private OptionGroupDef getGroupForOptions(final Map, OptionGroupDef> optionsToGroup, final Set options) {
final OptionGroupDef grp = optionsToGroup.get(options);
if (grp == null) {
throw new IllegalArgumentException("no option group for options=" + options + ", groups exist for " + optionsToGroup.keySet());
}
return grp;
}
private boolean populateLevelActiveSetsToGroups(final Map, OptionGroupDef> optionsToGroup, int level) {
boolean anyAdded = false;
for (final OptionGroupDef group : optionsToGroup.values()) {
final Map setsForThisLevel = getLevelSetFor(group, level, false);
for (final ActiveSetDef activeSet : setsForThisLevel.values()) {
for (ActiveSetDef next : activeSet.next.values()) {
addGroupsDerivedFromActiveSets(optionsToGroup, next);
anyAdded = true;
}
}
}
return anyAdded;
}
private Map getLevelSetFor(OptionGroupDef group, int level, boolean create) {
final Map lastLevelSet = getLastLevelSet(group);
if (lastLevelSet != null && lastLevelSet.get(lastLevelSet.keySet().iterator().next()).active.size() == level) {
return lastLevelSet;
}
if (create) {
final Map newLastLevelSet = new LinkedHashMap();
group.levelActiveSets.add(newLastLevelSet);
return newLastLevelSet;
}
return new TreeMap();
}
private Map getLastLevelSet(OptionGroupDef group) {
final int size = group.levelActiveSets.size();
return size == 0 ? null : group.levelActiveSets.get(size - 1);
}
private OptionSetDef createOptionSetDef(CommandDef commandDef) {
final TypeDef optionType = new TypeDef(commandDef.command.simpleName + "Option", commandDef.pkg.name);
final OptionSetDef def = new OptionSetDef(commandDef, optionType);
return def;
}
private OptionGroupDef createGroupFor(CommandDef commandDef, Set options) {
final List optionDefs = new ArrayList(options.size());
for (final String opt : options) {
optionDefs.add(commandDef.options.get(opt));
}
return createGroupFor(commandDef, optionDefs);
}
private OptionGroupDef createGroupFor(CommandDef commandDef, Collection options) {
final OptionGroupDef grp = new OptionGroupDef(commandDef, options);
for (final OptionDef opt : options) {
grp.options.put(opt.name, opt);
}
return grp;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy