001/* 002 * Portions of this software was developed by employees of the National Institute 003 * of Standards and Technology (NIST), an agency of the Federal Government and is 004 * being made available as a public service. Pursuant to title 17 United States 005 * Code Section 105, works of NIST employees are not subject to copyright 006 * protection in the United States. This software may be subject to foreign 007 * copyright. Permission in the United States and in foreign countries, to the 008 * extent that NIST may hold copyright, to use, copy, modify, create derivative 009 * works, and distribute this software and its documentation without fee is hereby 010 * granted on a non-exclusive basis, provided that this notice and disclaimer 011 * of warranty appears in all copies. 012 * 013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 025 */ 026 027package gov.nist.secauto.metaschema.core.model; 028 029import java.util.Collection; 030 031import edu.umd.cs.findbugs.annotations.NonNull; 032 033/** 034 * Walks a Metaschema model. The "visit" methods can be implemented by child 035 * classes to perform processing on a visited node. 036 * 037 * @param <DATA> 038 * state information that is carried through the walk 039 */ 040public abstract class ModelWalker<DATA> { 041 /** 042 * Generate default state information. 043 * 044 * @return the state information 045 */ 046 protected abstract DATA getDefaultData(); 047 048 /** 049 * Will visit the provided metaschema flag definition. 050 * 051 * @param flag 052 * the metaschema flag definition to walk 053 */ 054 public void walk(@NonNull IFlagDefinition flag) { 055 walk(flag, getDefaultData()); 056 } 057 058 /** 059 * Will visit the provided metaschema flag definition. 060 * 061 * @param flag 062 * the metaschema flag definition to walk 063 * @param data 064 * additional state information to operate on 065 */ 066 public void walk(@NonNull IFlagDefinition flag, DATA data) { 067 visit(flag, data); 068 } 069 070 /** 071 * Will visit the provided metaschema field definition, and then walk the 072 * associated flag instances. 073 * 074 * @param field 075 * the metaschema field definition to walk 076 */ 077 public void walk(@NonNull IFieldDefinition field) { 078 walk(field, getDefaultData()); 079 } 080 081 /** 082 * Will visit the provided metaschema field definition, and then walk the 083 * associated flag instances. 084 * 085 * @param field 086 * the metaschema field definition to walk 087 * @param data 088 * additional state information to operate on 089 */ 090 public void walk(@NonNull IFieldDefinition field, DATA data) { 091 if (visit(field, data)) { 092 walkFlagInstances(field.getFlagInstances(), data); 093 } 094 } 095 096 /** 097 * Will visit the provided metaschema assembly definition, and then walk the 098 * associated flag and model instances. 099 * 100 * @param assembly 101 * the metaschema assembly definition to walk 102 */ 103 public void walk(@NonNull IAssemblyDefinition assembly) { 104 walk(assembly, getDefaultData()); 105 } 106 107 /** 108 * Will visit the provided metaschema assembly definition, and then walk the 109 * associated flag and model instances. 110 * 111 * @param assembly 112 * the metaschema assembly definition to walk 113 * @param data 114 * additional state information to operate on 115 */ 116 public void walk(@NonNull IAssemblyDefinition assembly, DATA data) { 117 if (visit(assembly, data)) { 118 walkFlagInstances(assembly.getFlagInstances(), data); 119 walkModelInstances(assembly.getModelInstances(), data); 120 } 121 } 122 123 /** 124 * Will visit the provided metaschema flag instance, and then walk the 125 * associated flag definition. 126 * 127 * @param instance 128 * the metaschema flag instance to walk 129 * @param data 130 * additional state information to operate on 131 */ 132 public void walk(@NonNull IFlagInstance instance, DATA data) { 133 if (visit(instance, data)) { 134 walk(instance.getDefinition(), data); 135 } 136 } 137 138 /** 139 * Will visit the provided metaschema field instance, and then walk the 140 * associated field definition. 141 * 142 * @param instance 143 * the metaschema field instance to walk 144 * @param data 145 * additional state information to operate on 146 */ 147 public void walk(@NonNull IFieldInstance instance, DATA data) { 148 if (visit(instance, data)) { 149 walk(instance.getDefinition(), data); 150 } 151 } 152 153 /** 154 * Will visit the provided metaschema assembly instance, and then walk the 155 * associated assembly definition. 156 * 157 * @param instance 158 * the metaschema assembly instance to walk 159 * @param data 160 * additional state information to operate on 161 */ 162 public void walk(@NonNull IAssemblyInstance instance, DATA data) { 163 if (visit(instance, data)) { 164 walk(instance.getDefinition(), data); 165 } 166 } 167 168 /** 169 * Will visit the provided metaschema choice instance, and then walk the 170 * choice's child model instances. 171 * 172 * @param instance 173 * the metaschema choice instance to walk 174 * @param data 175 * additional state information to operate on 176 */ 177 public void walk(@NonNull IChoiceInstance instance, DATA data) { 178 if (visit(instance, data)) { 179 walkModelInstances(instance.getModelInstances(), data); 180 } 181 } 182 183 /** 184 * Will walk the provided model definition. 185 * 186 * @param definition 187 * the definition to walk 188 */ 189 public void walkDefinition(@NonNull IDefinition definition) { 190 walkDefinition(definition, getDefaultData()); 191 } 192 193 /** 194 * Will walk the provided model definition. 195 * 196 * @param definition 197 * the definition to walk 198 * @param data 199 * additional state information to operate on 200 */ 201 public void walkDefinition(@NonNull IDefinition definition, DATA data) { 202 if (definition instanceof IAssemblyDefinition) { 203 walk((IAssemblyDefinition) definition, data); 204 } else if (definition instanceof IFieldDefinition) { 205 walk((IFieldDefinition) definition, data); 206 } else if (definition instanceof IFlagDefinition) { 207 walk((IFlagDefinition) definition, data); 208 } 209 } 210 211 /** 212 * Will walk each of the provided flag instances. 213 * 214 * @param instances 215 * a collection of flag instances to visit 216 * @param data 217 * additional state information to operate on 218 */ 219 protected void walkFlagInstances(@NonNull Collection<? extends IFlagInstance> instances, DATA data) { 220 for (IFlagInstance instance : instances) { 221 assert instance != null; 222 walk(instance, data); 223 } 224 } 225 226 /** 227 * Will walk each of the provided model instances. 228 * 229 * @param instances 230 * a collection of model instances to visit 231 * @param data 232 * additional state information to operate on 233 */ 234 protected void walkModelInstances(@NonNull Collection<? extends IModelInstance> instances, DATA data) { 235 for (IModelInstance instance : instances) { 236 assert instance != null; 237 walkModelInstance(instance, data); 238 } 239 } 240 241 /** 242 * Will walk the provided model instance. 243 * 244 * @param instance 245 * the instance to walk 246 * @param data 247 * additional state information to operate on 248 */ 249 protected void walkModelInstance(@NonNull IModelInstance instance, DATA data) { 250 if (instance instanceof IAssemblyInstance) { 251 walk((IAssemblyInstance) instance, data); 252 } else if (instance instanceof IFieldInstance) { 253 walk((IFieldInstance) instance, data); 254 } else if (instance instanceof IChoiceInstance) { 255 walk((IChoiceInstance) instance, data); 256 } 257 } 258 259 /** 260 * Called when the provided definition is walked. This can be overridden by 261 * child classes to enable processing of the visited definition. 262 * 263 * @param def 264 * the definition that is visited 265 * @param data 266 * additional state information to operate on 267 */ 268 protected abstract void visit(@NonNull IFlagDefinition def, DATA data); 269 270 /** 271 * Called when the provided definition is walked. This can be overridden by 272 * child classes to enable processing of the visited definition. 273 * 274 * @param def 275 * the definition that is visited 276 * @param data 277 * additional state information to operate on 278 * @return {@code true} if child instances are to be walked, or {@code false} 279 * otherwise 280 */ 281 protected boolean visit(@NonNull IFieldDefinition def, DATA data) { 282 return true; 283 } 284 285 /** 286 * Called when the provided definition is walked. This can be overridden by 287 * child classes to enable processing of the visited definition. 288 * 289 * @param def 290 * the definition that is visited 291 * @param data 292 * additional state information to operate on 293 * @return {@code true} if child instances are to be walked, or {@code false} 294 * otherwise 295 */ 296 protected boolean visit(@NonNull IAssemblyDefinition def, DATA data) { 297 return true; 298 } 299 300 /** 301 * Called when the provided instance is walked. This can be overridden by child 302 * classes to enable processing of the visited instance. 303 * 304 * @param instance 305 * the instance that is visited 306 * @param data 307 * additional state information to operate on 308 * @return {@code true} if the associated definition is to be walked, or 309 * {@code false} otherwise 310 */ 311 protected boolean visit(@NonNull IFlagInstance instance, DATA data) { 312 return true; 313 } 314 315 /** 316 * Called when the provided instance is walked. This can be overridden by child 317 * classes to enable processing of the visited instance. 318 * 319 * @param instance 320 * the instance that is visited 321 * @param data 322 * additional state information to operate on 323 * @return {@code true} if the associated definition is to be walked, or 324 * {@code false} otherwise 325 */ 326 protected boolean visit(@NonNull IFieldInstance instance, DATA data) { 327 return true; 328 } 329 330 /** 331 * Called when the provided instance is walked. This can be overridden by child 332 * classes to enable processing of the visited instance. 333 * 334 * @param instance 335 * the instance that is visited 336 * @param data 337 * additional state information to operate on 338 * @return {@code true} if the associated definition is to be walked, or 339 * {@code false} otherwise 340 */ 341 protected boolean visit(@NonNull IAssemblyInstance instance, DATA data) { 342 return true; 343 } 344 345 /** 346 * Called when the provided instance is walked. This can be overridden by child 347 * classes to enable processing of the visited instance. 348 * 349 * @param instance 350 * the instance that is visited 351 * @param data 352 * additional state information to operate on 353 * @return {@code true} if the child instances are to be walked, or 354 * {@code false} otherwise 355 */ 356 protected boolean visit(@NonNull IChoiceInstance instance, DATA data) { 357 return true; 358 } 359}