package org.nlamah.QL.Builders; import java.util.ArrayList; import java.util.List; import org.nlamah.QL.Interfaces.QLFormElementVisitor; import org.nlamah.QL.Model.Form.ComputedQuestion; import org.nlamah.QL.Model.Form.ConditionalBlock; import org.nlamah.QL.Model.Form.ElseIfThenBlock; import org.nlamah.QL.Model.Form.ElseThenBlock; import org.nlamah.QL.Model.Form.Form; import org.nlamah.QL.Model.Form.IfThenBlock; import org.nlamah.QL.Model.Form.InputQuestion; import org.nlamah.QL.Model.Form.Abstract.FormElement; /* * This class breaks a form into fragments containing only one question, preserving nested structures. * This makes it possible to move separate questions to complete unrelated pages/sections adapting QLS. * * EXAMPLE: form example { question1 text "example quesiton1" if (question1 == "hello") { question2 number "example question2" } else { question3 boolean "example question3" question4 boolean "example question4" } } * QLFORMFRAGMENTISER YIELDS: form example { question1 text "example quesiton1" if (question1 == "hello") { question2 number "example question2" } else { } if (question1 == "hello") { } else { question3 boolean "example question3" } if (question1 == "hello") { } else { question4 boolean "example question4" } } * * */ public class QLFormFragmentiser implements QLFormElementVisitor { private Form fragmentedForm; private List<FormElement> justAcceptedFragementedFormElementList; private ConditionalBlock currentConditionalBlock; public QLFormFragmentiser(Form form) { form.accept(this); } public Form form() { return fragmentedForm; } @Override public void visit(Form form) { List<FormElement> newFormElements = new ArrayList<FormElement>(); for (FormElement formElement : form.childElements()) { formElement.accept(this); newFormElements.addAll(justAcceptedFragementedFormElementList); } fragmentedForm = new Form(form.title(), newFormElements); } @Override public void visit(ElseIfThenBlock elseIfThenBlock) { List<FormElement> fragementedElseIfThenBlockList = new ArrayList<FormElement>(); for (FormElement childElement : elseIfThenBlock.childElements()) { childElement.accept(this); for (FormElement justAcceptedElement : justAcceptedFragementedFormElementList) { //IfThenBlock IfThenBlock emptyIfThenBlock = new IfThenBlock(currentConditionalBlock.ifThenBlock().expression(), new ArrayList<FormElement>()); //ElseIfThenBlocks List<ElseIfThenBlock> copiedElseIfThenBlocks = new ArrayList<ElseIfThenBlock>(); for (ElseIfThenBlock loopedElseIfThenBlock : currentConditionalBlock.elseIfThenBlocks()) { ElseIfThenBlock copiedElseIfThenBlock; if (loopedElseIfThenBlock.equals(elseIfThenBlock)) { List<FormElement> singleFormElementList = new ArrayList<FormElement>(); singleFormElementList.add(justAcceptedElement); copiedElseIfThenBlock = new ElseIfThenBlock(loopedElseIfThenBlock.expression(), singleFormElementList); } else { copiedElseIfThenBlock = new ElseIfThenBlock(loopedElseIfThenBlock.expression(), new ArrayList<FormElement>()); } copiedElseIfThenBlocks.add(copiedElseIfThenBlock); } //ElseThenBlock ElseThenBlock emptyElseThenBlock = new ElseThenBlock(new ArrayList<FormElement>()); //ConditionalBlock ConditionalBlock newConditionalBlock = new ConditionalBlock(emptyIfThenBlock, copiedElseIfThenBlocks, emptyElseThenBlock); fragementedElseIfThenBlockList.add(newConditionalBlock); } } justAcceptedFragementedFormElementList = fragementedElseIfThenBlockList; } @Override public void visit(ElseThenBlock elseThenBlock) { List<FormElement> fragementedElseThenBlockList = new ArrayList<FormElement>(); for (FormElement childElement : elseThenBlock.childElements()) { childElement.accept(this); for (FormElement justAcceptedElement : justAcceptedFragementedFormElementList) { //IfThenBlock IfThenBlock emptyIfThenBlock = new IfThenBlock(currentConditionalBlock.ifThenBlock().expression(), new ArrayList<FormElement>()); //ElseIfThenBlocks List<ElseIfThenBlock> emptyElseIfThenBlocks = new ArrayList<ElseIfThenBlock>(); for (ElseIfThenBlock elseIfThenBlock : currentConditionalBlock.elseIfThenBlocks()) { ElseIfThenBlock emptyElseIfThenBlock = new ElseIfThenBlock(elseIfThenBlock.expression(), new ArrayList<FormElement>()); emptyElseIfThenBlocks.add(emptyElseIfThenBlock); } //ElseThenBlock List<FormElement> singleFormElementList = new ArrayList<FormElement>(); singleFormElementList.add(justAcceptedElement); //ConditionalBlock ConditionalBlock newConditionalBlock = new ConditionalBlock(emptyIfThenBlock, emptyElseIfThenBlocks, new ElseThenBlock(singleFormElementList)); fragementedElseThenBlockList.add(newConditionalBlock); } } justAcceptedFragementedFormElementList = fragementedElseThenBlockList; } @Override public void visit(IfThenBlock ifThenBlock) { List<FormElement> fragementedIfThenBlockList = new ArrayList<FormElement>(); for (FormElement childElement : ifThenBlock.childElements()) { childElement.accept(this); for (FormElement justAcceptedElement : justAcceptedFragementedFormElementList) { //IfThenBlock List<FormElement> singleFormElementList = new ArrayList<FormElement>(); singleFormElementList.add(justAcceptedElement); //ElseIfThenBlocks List<ElseIfThenBlock> emptyElseIfThenBlocks = new ArrayList<ElseIfThenBlock>(); for (ElseIfThenBlock elseIfThenBlock : currentConditionalBlock.elseIfThenBlocks()) { ElseIfThenBlock emptyElseIfThenBlock = new ElseIfThenBlock(elseIfThenBlock.expression(), new ArrayList<FormElement>()); emptyElseIfThenBlocks.add(emptyElseIfThenBlock); } //ElseThenBlock ElseThenBlock emptyElseThenBlock = new ElseThenBlock(new ArrayList<FormElement>()); //ConditionalBlock ConditionalBlock newConditionalBlock = new ConditionalBlock(new IfThenBlock(ifThenBlock.expression(), singleFormElementList), emptyElseIfThenBlocks, emptyElseThenBlock); fragementedIfThenBlockList.add(newConditionalBlock); } } justAcceptedFragementedFormElementList = fragementedIfThenBlockList; } @Override public void visit(ConditionalBlock conditionalBlock) { currentConditionalBlock = conditionalBlock; List<FormElement> fragmentedConditionalBlockList = new ArrayList<FormElement>(); //IfThenBlock conditionalBlock.ifThenBlock().accept(this); fragmentedConditionalBlockList.addAll(justAcceptedFragementedFormElementList); //ElseIfThenBlocks for (ElseIfThenBlock elseIfThenBlock : conditionalBlock.elseIfThenBlocks()) { elseIfThenBlock.accept(this); fragmentedConditionalBlockList.addAll(justAcceptedFragementedFormElementList); } //ElseThenBlock if (conditionalBlock.elseThenBlock() != null) { conditionalBlock.elseThenBlock().accept(this); fragmentedConditionalBlockList.addAll(justAcceptedFragementedFormElementList); } justAcceptedFragementedFormElementList = fragmentedConditionalBlockList; } @Override public void visit(InputQuestion inputQuestion) { justAcceptedFragementedFormElementList = new ArrayList<FormElement>(); justAcceptedFragementedFormElementList.add(inputQuestion); } @Override public void visit(ComputedQuestion computedQuestion) { justAcceptedFragementedFormElementList = new ArrayList<FormElement>(); justAcceptedFragementedFormElementList.add(computedQuestion); } }