package org.nocket.gen.page.visitor.bind;
import gengui.domain.DomainObjectReference;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.html.form.FormComponent;
import org.nocket.gen.domain.element.DomainElementI;
import org.nocket.gen.domain.element.MultivaluePropertyElement;
import org.nocket.gen.page.DMDWebGenPageContext;
import org.nocket.gen.page.element.AbstractPageHeaderElement;
import org.nocket.gen.page.element.BodyElement;
import org.nocket.gen.page.element.ButtonElement;
import org.nocket.gen.page.element.CheckboxInputElement;
import org.nocket.gen.page.element.ContainerElement;
import org.nocket.gen.page.element.DivElement;
import org.nocket.gen.page.element.FeedbackElement;
import org.nocket.gen.page.element.FileDownloadElement;
import org.nocket.gen.page.element.FileInputElement;
import org.nocket.gen.page.element.FormElement;
import org.nocket.gen.page.element.GroupTabbedPanelElement;
import org.nocket.gen.page.element.HeaderLinkElement;
import org.nocket.gen.page.element.HeaderScriptElement;
import org.nocket.gen.page.element.ImageElement;
import org.nocket.gen.page.element.LabelElement;
import org.nocket.gen.page.element.LinkElement;
import org.nocket.gen.page.element.ModalElement;
import org.nocket.gen.page.element.PageElementI;
import org.nocket.gen.page.element.PasswordInputElement;
import org.nocket.gen.page.element.PromptElement;
import org.nocket.gen.page.element.RadioInputElement;
import org.nocket.gen.page.element.RepeatingPanelElement;
import org.nocket.gen.page.element.SelectElement;
import org.nocket.gen.page.element.TableElement;
import org.nocket.gen.page.element.TextAreaElement;
import org.nocket.gen.page.element.TextInputElement;
import org.nocket.gen.page.element.UnknownPageElementI;
import org.nocket.gen.page.element.synchronizer.DomainComponentBehaviour;
import org.nocket.gen.page.visitor.AbstractPageElementVisitor;
import org.nocket.gen.page.visitor.bind.builder.BindingBuilderI;
import org.nocket.gen.page.visitor.bind.builder.components.HeaderContributor;
import org.nocket.gen.page.visitor.bind.builder.components.SQLInjectionValidator;
// TODO: Auto-generated Javadoc
/**
* The Class BindingVisitor.
*/
public class BindingVisitor extends AbstractPageElementVisitor {
/** The binding builder. */
private final BindingBuilderI bindingBuilder;
/** The panel stack. */
private final Deque<MarkupContainer> panelStack;
/** The next container. */
private ContainerElement nextContainer;
/** The header elements. */
private List<AbstractPageHeaderElement> headerElements = new ArrayList<AbstractPageHeaderElement>();
/**
* Instantiates a new binding visitor.
*
* @param context the context
* @param bindingBuilder the binding builder
*/
public BindingVisitor(DMDWebGenPageContext context, BindingBuilderI bindingBuilder) {
super(context);
this.bindingBuilder = bindingBuilder;
this.panelStack = new ArrayDeque<MarkupContainer>();
this.panelStack.addLast(context.getPage());
}
/**
* Adds the container.
*
* @param e the e
* @param c the c
*/
private void addContainer(PageElementI<?> e, MarkupContainer c) {
panelStack.getLast().add(c);
if (nextContainer != null) {
panelStack.addLast(c);
nextContainer = null;
}
}
/**
* Adds the component.
*
* @param c the c
*/
private void addComponent(Component c) {
if (nextContainer != null) {
throw new IllegalArgumentException("Expected a " + MarkupContainer.class.getSimpleName() + " instead of a "
+ Component.class.getSimpleName() + " as next element!");
}
panelStack.getLast().add(c);
}
/**
* Adds the.
*
* @param e the e
* @param c the c
*/
protected void add(PageElementI<?> e, Component c) {
// an unknown element is a container but was not bound
if (c == null) {
return;
}
if (c instanceof FormComponent) {
c.add(new SQLInjectionValidator());
}
// add domain behaviour
if (e.isDomainElement() && !(e.getDomainElement() instanceof MultivaluePropertyElement)) {
c.add(new DomainComponentBehaviour(e, c));
}
// add normal component
if (c instanceof MarkupContainer) {
addContainer(e, (MarkupContainer) c);
} else {
addComponent(c);
}
getContext().getComponentRegistry().addComponent(c);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitModal(org.nocket.gen.page.element.ModalElement)
*/
@Override
public void visitModal(ModalElement e) {
Component modal = bindingBuilder.createModal(e);
add(e, modal);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitFeedback(org.nocket.gen.page.element.FeedbackElement)
*/
@Override
public void visitFeedback(FeedbackElement e) {
Component feedback = bindingBuilder.createFeedback(e);
add(e, feedback);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitForm(org.nocket.gen.page.element.FormElement)
*/
@Override
public void visitForm(FormElement e) {
Component form = bindingBuilder.createForm(e);
add(e, form);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitLabel(org.nocket.gen.page.element.LabelElement)
*/
@Override
public void visitLabel(LabelElement e) {
Component label = bindingBuilder.createLabel(e);
add(e, label);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitPrompt(org.nocket.gen.page.element.PromptElement)
*/
@Override
public void visitPrompt(PromptElement e) {
Component label = bindingBuilder.createPrompt(e);
add(e, label);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitTextInput(org.nocket.gen.page.element.TextInputElement)
*/
@Override
public void visitTextInput(TextInputElement e) {
Component textInput = bindingBuilder.createTextInput(e);
add(e, textInput);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitPasswordInput(org.nocket.gen.page.element.PasswordInputElement)
*/
@Override
public void visitPasswordInput(PasswordInputElement e) {
Component textInput = bindingBuilder.createPasswordInput(e);
add(e, textInput);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitFileInput(org.nocket.gen.page.element.FileInputElement)
*/
@Override
public void visitFileInput(FileInputElement e) {
Component fileInput = bindingBuilder.createFileInput(e);
add(e, fileInput);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitFileDownload(org.nocket.gen.page.element.FileDownloadElement)
*/
@Override
public void visitFileDownload(FileDownloadElement e) {
Component fileDownload = bindingBuilder.createFileDownload(e);
add(e, fileDownload);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitTextArea(org.nocket.gen.page.element.TextAreaElement)
*/
@Override
public void visitTextArea(TextAreaElement e) {
Component textArea = bindingBuilder.createTextArea(e);
add(e, textArea);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitCheckboxInput(org.nocket.gen.page.element.CheckboxInputElement)
*/
@Override
public void visitCheckboxInput(CheckboxInputElement e) {
Component textInput = bindingBuilder.createCheckboxInput(e);
add(e, textInput);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitRadioInput(org.nocket.gen.page.element.RadioInputElement)
*/
@Override
public void visitRadioInput(RadioInputElement e) {
Component textInput = bindingBuilder.createRadioInput(e);
add(e, textInput);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitSelect(org.nocket.gen.page.element.SelectElement)
*/
@Override
public void visitSelect(SelectElement e) {
Component select = bindingBuilder.createSelect(e);
add(e, select);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitImage(org.nocket.gen.page.element.ImageElement)
*/
@Override
public void visitImage(ImageElement e) {
Component image = bindingBuilder.createImage(e);
add(e, image);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitLink(org.nocket.gen.page.element.LinkElement)
*/
@Override
public void visitLink(LinkElement e) {
Component link = bindingBuilder.createLink(e);
add(e, link);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitTable(org.nocket.gen.page.element.TableElement)
*/
@Override
public void visitTable(TableElement e) {
Component table = bindingBuilder.createTable(e);
add(e, table);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitButton(org.nocket.gen.page.element.ButtonElement)
*/
@Override
public void visitButton(ButtonElement e) {
Component button = bindingBuilder.createButton(e);
add(e, button);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitContainerOpen(org.nocket.gen.page.element.ContainerElement)
*/
@Override
public void visitContainerOpen(ContainerElement e) {
if (nextContainer != null) {
throw new IllegalStateException("Did not expect a new " + ContainerElement.class.getSimpleName()
+ " while another is waiting for its element visit!");
}
nextContainer = e;
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitContainerClose()
*/
@Override
public void visitContainerClose() {
if (nextContainer != null) {
nextContainer = null;
} else if (panelStack.removeLast() == null) {
throw new IllegalStateException("PanelStack improperly implemented, did not expect a panel to be null!");
}
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitUnknown(org.nocket.gen.page.element.UnknownPageElementI)
*/
@Override
public void visitUnknown(UnknownPageElementI<?> e) {
Component button = bindingBuilder.createUnknown(e);
add(e, button);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#finish(java.util.List)
*/
@Override
public void finish(List<DomainElementI<DomainObjectReference>> unboundDomainElements) {
addHeaderContributions(getContext().getPage());
}
/**
* Adds the header contributions.
*
* @param page the page
*/
protected void addHeaderContributions(MarkupContainer page) {
if (headerElements.size() > 0) {
HeaderContributor hc = new HeaderContributor();
for (AbstractPageHeaderElement headerElement : headerElements)
hc.addContribution(headerElement);
page.add(hc);
}
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitRepeatingPanel(org.nocket.gen.page.element.RepeatingPanelElement)
*/
@Override
public void visitRepeatingPanel(RepeatingPanelElement e) {
Component listView = bindingBuilder.createListView(e);
add(e, listView);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitHeaderLink(org.nocket.gen.page.element.HeaderLinkElement)
*/
@Override
public void visitHeaderLink(HeaderLinkElement headerLinkElement) {
headerElements.add(headerLinkElement);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitHeaderScript(org.nocket.gen.page.element.HeaderScriptElement)
*/
@Override
public void visitHeaderScript(HeaderScriptElement headerScriptElement) {
headerElements.add(headerScriptElement);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitBody(org.nocket.gen.page.element.BodyElement)
*/
@Override
public void visitBody(BodyElement bodyElement) {
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitGroupTabbedPanel(org.nocket.gen.page.element.GroupTabbedPanelElement)
*/
@Override
public void visitGroupTabbedPanel(GroupTabbedPanelElement e) {
Component button = bindingBuilder.createGroupTabbedPanel(e);
add(e, button);
}
/* (non-Javadoc)
* @see org.nocket.gen.page.visitor.PageElementVisitorI#visitDiv(org.nocket.gen.page.element.DivElement)
*/
@Override
public void visitDiv(DivElement e) {
Component div = bindingBuilder.createDiv(e);
add(e, div);
}
}