public void transform(final GroupElement parent) throws InvalidPatternException { final List<GroupElement> orsList = new ArrayList<GroupElement>(); // must keep order, so, using array final RuleConditionElement[] others = new RuleConditionElement[parent.getChildren().size()]; // first we split children as OR or not OR int permutations = 1; int index = 0; for (final RuleConditionElement child : parent.getChildren()) { if ((child instanceof GroupElement) && ((GroupElement) child).isOr()) { permutations *= ((GroupElement) child).getChildren().size(); orsList.add((GroupElement) child); } else { others[index] = child; } index++; } // transform parent into an OR parent.setType(GroupElement.OR); parent.getChildren().clear(); // prepare arrays and indexes to calculate permutation final int[] indexes = new int[orsList.size()]; // now we know how many permutations we will have, so create it for (int i = 1; i <= permutations; i++) { final GroupElement and = GroupElementFactory.newAndInstance(); // create the actual permutations int mod = 1; for (int j = orsList.size() - 1; j >= 0; j--) { GroupElement or = orsList.get(j); // we must insert at the beginning to keep the order and.addChild(0, or.getChildren().get(indexes[j]).clone()); if ((i % mod) == 0) { indexes[j] = (indexes[j] + 1) % or.getChildren().size(); } mod *= or.getChildren().size(); } // elements originally outside OR will be in every permutation, so add them // in their original position for (int j = 0; j < others.length; j++) { if (others[j] != null) { // always add clone of them to avoid offset conflicts in declarations // HERE IS THE MESSY PROBLEM: need to change further references to the appropriate // cloned ref and.addChild(j, others[j].clone()); } } parent.addChild(and); } // remove duplications parent.pack(); }
public GroupElement[] transform(final GroupElement cloned, Map<String, Class<?>> globals) throws InvalidPatternException { // moved cloned to up // final GroupElement cloned = (GroupElement) and.clone(); boolean hasNamedConsequenceAndIsStream = processTree(cloned); cloned.pack(); GroupElement[] ands; // is top element an AND? if (cloned.isAnd()) { // Yes, so just return it ands = new GroupElement[] {cloned}; } else if (cloned.isOr()) { // it is an OR, so each child is an AND branch ands = splitOr(cloned); } else { // no, so just wrap into an AND final GroupElement wrapper = GroupElementFactory.newAndInstance(); wrapper.addChild(cloned); ands = new GroupElement[] {wrapper}; } for (GroupElement and : ands) { // fix the cloned declarations this.fixClonedDeclarations(and, globals); and.setRoot(true); } return hasNamedConsequenceAndIsStream ? processNamedConsequences(ands) : ands; }
public GroupElement[] transform(final GroupElement cloned) throws InvalidPatternException { // moved cloned to up // final GroupElement cloned = (GroupElement) and.clone(); processTree(cloned); cloned.pack(); GroupElement[] ands; // is top element an AND? if (cloned.isAnd()) { // Yes, so just return it ands = new GroupElement[] {cloned}; } else if (cloned.isOr()) { // it is an OR, so each child is an AND branch ands = splitOr(cloned); } else { // no, so just wrap into an AND final GroupElement wrapper = GroupElementFactory.newAndInstance(); wrapper.addChild(cloned); ands = new GroupElement[] {wrapper}; } for (int i = 0; i < ands.length; i++) { // fix the cloned declarations this.fixClonedDeclarations(ands[i]); ands[i].setRoot(true); } return ands; }
private GroupElement[] processNamedConsequences(GroupElement[] ands) { List<GroupElement> result = new ArrayList<GroupElement>(); for (GroupElement and : ands) { List<RuleConditionElement> children = and.getChildren(); for (int i = 0; i < children.size(); i++) { RuleConditionElement child = children.get(i); if (child instanceof NamedConsequence) { GroupElement clonedAnd = GroupElementFactory.newAndInstance(); for (int j = 0; j < i; j++) { clonedAnd.addChild(children.get(j).clone()); } ((NamedConsequence) child).setTerminal(true); clonedAnd.addChild(child); children.remove(i--); result.add(clonedAnd); } } result.add(and); } return result.toArray(new GroupElement[result.size()]); }
public void transform(final GroupElement parent) throws InvalidPatternException { if ((!(parent.getChildren().get(0) instanceof GroupElement)) || (!((GroupElement) parent.getChildren().get(0)).isOr())) { throw new RuntimeException( "NotOrTransformation expected 'OR' but instead found '" + parent.getChildren().get(0).getClass().getName() + "'"); } // we know a Not only ever has one child, and the previous algorithm // has confirmed the child is an OR final GroupElement or = (GroupElement) parent.getChildren().get(0); parent.setType(GroupElement.AND); parent.getChildren().clear(); for (RuleConditionElement ruleConditionElement : or.getChildren()) { final GroupElement newNot = GroupElementFactory.newNotInstance(); newNot.addChild(ruleConditionElement); parent.addChild(newNot); } parent.pack(); }