package lt.inventi.wicket.js; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.wicket.markup.head.HeaderItem; import org.apache.wicket.markup.head.IReferenceHeaderItem; import org.apache.wicket.request.resource.JavaScriptResourceReference; import org.apache.wicket.request.resource.ResourceReference; public interface JavaScriptSettingsBuilder { interface BootstrapJsBuilderFactory { BootstrapJsBuilder newBuilder(JavaScriptSettingsBuilder settingsBuilder); } interface BootstrapJsBuilder { BootstrapJsBuilder withAllBootstrapJs(JavaScriptResourceReference all); BootstrapJsSettings build(); JavaScriptSettingsBuilder endBootstrapJs(); } static class BootstrapJs2xBuilder implements BootstrapJsBuilder { private final JavaScriptSettingsBuilder settingsBuilder; private JavaScriptResourceReference bsTransitions, bsModal, bsDropdown, bsScrollspy, bsTab, bsTooltip, bsPopover, bsAlert, bsButton, bsCollapse, bsCarousel, bsTypeahead, bsAffix; public BootstrapJs2xBuilder(JavaScriptSettingsBuilder settingsBuilder) { this.settingsBuilder = settingsBuilder; } @Override public BootstrapJsBuilder withAllBootstrapJs(JavaScriptResourceReference all) { this.bsTransitions = bsModal = bsDropdown = bsScrollspy = bsTab = bsTooltip = bsPopover = bsAlert = bsButton = bsCollapse = bsCarousel = bsTypeahead = bsAffix = all; return this; } @Override public JavaScriptSettingsBuilder endBootstrapJs() { return settingsBuilder; } @Override public BootstrapJsSettings build() { return new BootstrapJsSettings(bsTransitions, bsModal, bsDropdown, bsScrollspy, bsTab, bsTooltip, bsPopover, bsAlert, bsButton, bsCollapse, bsCarousel, bsTypeahead, bsAffix); } } interface JQueryUiBuilderFactory { JQueryUiBuilder newBuilder(JavaScriptSettingsBuilder settingsBuilder); } interface UiCoreBuilder { UiCoreBuilder withUiCoreWidget(JavaScriptResourceReference widget); UiCoreBuilder withUiCoreMouse(JavaScriptResourceReference mouse); UiCoreBuilder withUiCorePosition(JavaScriptResourceReference mouse); JQueryUiBuilder endUiCore(); } interface UiWidgetsBuilder { UiWidgetsBuilder withUiWidgetsMenu(JavaScriptResourceReference menu); UiWidgetsBuilder withUiWidgetsAutocomplete(JavaScriptResourceReference autocomplete); JQueryUiBuilder endUiWidgets(); } interface JQueryUiBuilder { JQueryUiBuilder withAllUi(JavaScriptResourceReference jqueryUi); JQueryUiBuilder withAllUiCore(JavaScriptResourceReference core); UiCoreBuilder withUiCore(JavaScriptResourceReference core); UiWidgetsBuilder withUiWidgets(); JavaScriptSettingsBuilder endJqueryUi(); JQueryUiSettings build(); } static class JQueryUi192Builder implements JQueryUiBuilder { class CoreBuilder implements UiCoreBuilder { @Override public UiCoreBuilder withUiCoreWidget(JavaScriptResourceReference widget) { ensureContains(toSet(widget.getDependencies()), JQueryUi192Builder.this.uiCoreCore); JQueryUi192Builder.this.uiCoreWidget = widget; return this; } @Override public UiCoreBuilder withUiCorePosition(JavaScriptResourceReference position) { JQueryUi192Builder.this.uiCorePosition = position; return this; } @Override public UiCoreBuilder withUiCoreMouse(JavaScriptResourceReference mouse) { JQueryUi192Builder.this.uiCoreMouse = mouse; return this; } @Override public JQueryUiBuilder endUiCore() { return JQueryUi192Builder.this; } } class WidgetsBuilder implements UiWidgetsBuilder { @Override public UiWidgetsBuilder withUiWidgetsMenu(JavaScriptResourceReference menu) { Set<ResourceReference> dependencies = toSet(menu.getDependencies()); ensureContains(dependencies, JQueryUi192Builder.this.uiCoreCore, JQueryUi192Builder.this.uiCoreWidget, JQueryUi192Builder.this.uiCorePosition); JQueryUi192Builder.this.uiWidgetsMenu = menu; return this; } @Override public UiWidgetsBuilder withUiWidgetsAutocomplete(JavaScriptResourceReference autocomplete) { Set<ResourceReference> dependencies = toSet(autocomplete.getDependencies()); ensureContains(dependencies, JQueryUi192Builder.this.uiCoreCore, JQueryUi192Builder.this.uiCoreWidget, JQueryUi192Builder.this.uiCorePosition, JQueryUi192Builder.this.uiWidgetsMenu); JQueryUi192Builder.this.uiWidgetsAutocomplete = autocomplete; return this; } @Override public JQueryUiBuilder endUiWidgets() { return JQueryUi192Builder.this; } } private final JavaScriptSettingsBuilder settingsBuilder; private JavaScriptResourceReference uiCoreCore, uiCoreWidget, uiCorePosition, uiCoreMouse; private JavaScriptResourceReference uiWidgetsAutocomplete, uiWidgetsMenu; public JQueryUi192Builder(JavaScriptSettingsBuilder settingsBuilder) { this.settingsBuilder = settingsBuilder; } @Override public JQueryUiBuilder withAllUi(JavaScriptResourceReference jqueryUi) { withAllUiCore(jqueryUi); this.uiWidgetsAutocomplete = this.uiWidgetsMenu = jqueryUi; return this; } @Override public JQueryUiBuilder withAllUiCore(JavaScriptResourceReference fullCore) { this.uiCoreCore = this.uiCoreWidget = this.uiCorePosition = this.uiCoreMouse = fullCore; return this; } @Override public UiCoreBuilder withUiCore(JavaScriptResourceReference core) { this.uiCoreCore = core; return new CoreBuilder(); } @Override public JavaScriptSettingsBuilder endJqueryUi() { return settingsBuilder; } @Override public UiWidgetsBuilder withUiWidgets() { return new WidgetsBuilder(); } @Override public JQueryUiSettings build() { return new JQueryUiSettings(uiCoreCore, uiCoreWidget, uiCoreMouse, uiCorePosition, uiWidgetsMenu, uiWidgetsAutocomplete); } private static void ensureContains(Set<ResourceReference> dependences, ResourceReference... expected) { for (ResourceReference dep : expected) { if (dep == null || !dependences.contains(dep)) { throw new IllegalStateException("Expected dependency " + dep + " doesn't exist in " + expected + "!"); } } } private static Set<ResourceReference> toSet(Iterable<? extends HeaderItem> dependencies) { Set<ResourceReference> result = new HashSet<ResourceReference>(); for (HeaderItem dep : dependencies) { if (dep instanceof IReferenceHeaderItem) { result.add(((IReferenceHeaderItem) dep).getReference()); } result.addAll(dependenciesOf(dep)); } return result; } private static Collection<ResourceReference> dependenciesOf(HeaderItem dep) { if (!dep.getDependencies().iterator().hasNext()) { return Collections.emptySet(); } Set<ResourceReference> result = new HashSet<ResourceReference>(); result.addAll(toSet(dep.getDependencies())); return result; } } public enum BootstrapJsVersions implements BootstrapJsBuilderFactory { v2_x { @Override public BootstrapJsBuilder newBuilder(JavaScriptSettingsBuilder settingsBuilder) { return new BootstrapJs2xBuilder(settingsBuilder); } } } public enum JQueryUiVersions implements JQueryUiBuilderFactory { v1_9_2 { @Override public JQueryUiBuilder newBuilder(final JavaScriptSettingsBuilder settingsBuilder) { return new JQueryUi192Builder(settingsBuilder); } } } BootstrapJsBuilder withBootstrapJs(BootstrapJsBuilderFactory factory); JQueryUiBuilder withJqueryUi(JQueryUiBuilderFactory factory); JavaScriptSettings build(); }