package xapi.ui.autoui.impl; import xapi.ui.autoui.api.UiRenderer; import xapi.ui.autoui.api.UiRendererSelector; import xapi.ui.autoui.api.UiRenderingContext; import xapi.ui.autoui.api.UserInterface; import xapi.util.X_Debug; public abstract class AbstractUserInterface <T> implements UserInterface <T>{ private UiRenderingContext[] renderers; private int[] head, body, tail; @Override public final UserInterface<T> setRenderers(UiRenderingContext[] renderers) { this.renderers = renderers; head = new int[renderers.length]; body = new int[renderers.length]; tail = new int[renderers.length]; int h=0,b=0,t=0; // sort matches for (int i = 0, m = renderers.length; i<m; i++) { UiRenderingContext ctx = renderers[i]; if (ctx.isHead()) { head[h++] = i; } else if (ctx.isTail()) { tail[t++] = i; } else { body[b++] = i; } } // trim head = copyOf(head, h); body = copyOf(body, b); tail = copyOf(tail, t); return this; } private static int[] copyOf(int[] arr, int len) { if (len == arr.length) { return arr; } int[] copy = new int[len]; System.arraycopy(arr, 0, copy, 0, len); return copy; } @Override public final UserInterface<T> renderUi(T model) { for (int i : head) { doRender(renderers[i], model); } for (int i : body) { doRender(renderers[i], model); } for (int i : tail) { doRender(renderers[i], model); } return this; } protected abstract void doRender(UiRenderingContext ctx, T model); @SuppressWarnings({"rawtypes", "unchecked"}) protected void recursiveRender(UiRenderingContext ctx, UiRenderer renderer, T model){ UiRendererSelector selector = ctx.getSelector(); if (ctx.isWrapper()) { for (String key : ctx.getBeanValueProvider().getChildKeys()) { try { if (selector.useRenderer(this, renderer, key, model)) { renderer.renderInto(this, ctx, key, model); } } catch(ClassCastException e) { e.printStackTrace(); } catch(Throwable e) { throw X_Debug.rethrow(e); } } } else { if (selector.useRenderer(this, renderer, ctx.getName(), model)) { renderer.renderInto(this, ctx, ctx.getName(), model); } } } }