litesoft
@ 947
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
// This Source Code is in the Public Domain per: http://unlicense.org package org.litesoft.ui.def.nonpublic.support; import org.litesoft.ui.def.*; public abstract class UiD_Visitor { /** * Allways called! Do any processing on Current before any children (if any) are processed * * @param pUiDef Current * @param pParameter Parameter for Current */ protected void visit1PreAnyChildProcessing( UiDef pUiDef, Object pParameter ) { } /** * Called if Current is a UiContainerMarker. Do any processing re Current on set of Children * * @param pUiDef Current * @param pParameter Parameter for Current * @param pHelper from Container (Current) */ protected void visit2ChildrenHelper( UiDef pUiDef, Object pParameter, AbstractUiChildrenHelper pHelper ) { } /** * Called if Current is a UiContainerMarker. Allows the Parameter for Current to be changed uniformly for ALL its children. * * @param pUiDef Current * @param pParameter Parameter for Current * * @return possibly changed Parameter */ protected Object visit3mutateParameterForChildren( UiDef pUiDef, Object pParameter ) { return pParameter; } /** * Called for each child. Allows the Parameter to be changed for each child. * * @param pUiDef Current * @param pParameter possibly mutated (by visit3mutateParameterForChildren) Parameter for Current * @param pChild Child * * @return possibly changed Parameter */ protected Object visit4mutateParameterForChild( UiDef pUiDef, Object pParameter, UiDef pChild ) { return pParameter; } /** * Allways called! Do any processing on Current after any children (if any) are processed * * @param pUiDef Current * @param pParameter possibly mutated (by visit3mutateParameterForChildren) Parameter for Current */ protected void visit5PostAllChildProcessing( UiDef pUiDef, Object pParameter ) { } public final void process( UiDef pUiDef ) { process( pUiDef, null ); } public final void process( UiDef pUiDef, Object pParameter ) { if ( pUiDef != null ) { for ( RecursiveHelper zRH = new RecursiveHelper( pUiDef, pParameter ); zRH.process(); ) { // Nothing as all work is performed in processEntry() } } } private class RecursiveHelper { private Node mTop; public RecursiveHelper( UiDef pInitialUiDef, Object pParameter ) { mTop = createNode( pInitialUiDef, pParameter ); } public boolean process() { mTop = mTop.process(); return (mTop != null); } private Node createNode( UiDef pUiDef, Object pParameter ) { if ( pUiDef instanceof UiContainerMarker ) { UiChildrenHelper helper = ((UiContainerMarker) pUiDef).getChildrenHelper(); if ( helper instanceof AbstractUiChildrenHelper ) { return new ContainerNode( pUiDef, pParameter ); } } return new SimpleNode( pUiDef, pParameter ); } private abstract class Node { protected Node mParent = null; protected Node mNext = null; protected UiDef mUiDef; protected Object mParameter; public Node( UiDef pUiDef, Object pParameter ) { mUiDef = pUiDef; mParameter = pParameter; } public Node init( Node pParent, Node pNext ) { mParent = pParent; mNext = pNext; return this; } public abstract Node process(); } private class SimpleNode extends Node { public SimpleNode( UiDef pUiDef, Object pParameter ) { super( pUiDef, pParameter ); } public Node process() { visit1PreAnyChildProcessing( mUiDef, mParameter ); visit5PostAllChildProcessing( mUiDef, mParameter ); return mNext; } } private class ContainerNode extends Node { private boolean mDoPostProcess = false; public ContainerNode( UiDef pUiDef, Object pParameter ) { super( pUiDef, pParameter ); } public Node process() { if ( !mDoPostProcess ) { mDoPostProcess = true; return doPreChildren(); } return doPostChildren(); } private Node doPreChildren() { if ( checkForRecursiveUseage( mUiDef ) ) { throw new IllegalStateException( "Recursively contained UiDef: " + mUiDef ); } visit1PreAnyChildProcessing( mUiDef, mParameter ); UiChildrenHelper helper = ((UiContainerMarker) mUiDef).getChildrenHelper(); visit2ChildrenHelper( mUiDef, mParameter, (AbstractUiChildrenHelper) helper ); mParameter = visit3mutateParameterForChildren( mUiDef, mParameter ); Node rv = this; UiDef[] children = helper.getChildren(); if ( (children != null) && (children.length != 0) ) { for ( int i = children.length; --i >= 0; ) // Note Reverse Order Required!!! { UiDef child = children[i]; Object param = visit4mutateParameterForChild( mUiDef, mParameter, child ); rv = createNode( child, param ).init( this, rv ); } } return rv; } private Node doPostChildren() { visit5PostAllChildProcessing( mUiDef, mParameter ); return mNext; } private boolean checkForRecursiveUseage( UiDef pUiDef ) { for ( Node ancestor = mParent; ancestor != null; ancestor = ancestor.mParent ) { if ( pUiDef == ancestor.mUiDef ) { return true; } } return false; } } } } |