001 package com.croftsoft.core.text.sml; 002 003 import java.util.Vector; 004 005 import com.croftsoft.core.lang.NullArgumentException; 006 import com.croftsoft.core.text.ParseLib; 007 008 /********************************************************************* 009 * Simplified Markup Language (SML) node. 010 * 011 * <p> 012 * Java 1.1 compatible. 013 * </p> 014 * 015 * @version 016 * 2001-09-12 017 * @since 018 * 2001-03-05 019 * @author 020 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 021 *********************************************************************/ 022 023 public final class SmlNode 024 ////////////////////////////////////////////////////////////////////// 025 ////////////////////////////////////////////////////////////////////// 026 { 027 028 private static final Object [ ] ZERO_LENGTH_OBJECT_ARRAY 029 = new Object [ ] { }; 030 031 private String name; 032 033 private Object [ ] children = ZERO_LENGTH_OBJECT_ARRAY; 034 035 ////////////////////////////////////////////////////////////////////// 036 // constructor methods 037 ////////////////////////////////////////////////////////////////////// 038 039 public SmlNode ( String name ) 040 ////////////////////////////////////////////////////////////////////// 041 { 042 NullArgumentException.check ( this.name = name ); 043 } 044 045 public SmlNode ( 046 String name, 047 String childString ) 048 ////////////////////////////////////////////////////////////////////// 049 { 050 this ( name ); 051 052 if ( childString != null ) 053 { 054 add ( childString ); 055 } 056 } 057 058 ////////////////////////////////////////////////////////////////////// 059 // accessor methods 060 ////////////////////////////////////////////////////////////////////// 061 062 public int childCount ( ) 063 ////////////////////////////////////////////////////////////////////// 064 { 065 return children.length; 066 } 067 068 public String getName ( ) 069 ////////////////////////////////////////////////////////////////////// 070 { 071 return name; 072 } 073 074 /********************************************************************* 075 * @return 076 * Returns zero-length array if childless; never returns null. 077 *********************************************************************/ 078 public Object [ ] getChildren ( ) 079 ////////////////////////////////////////////////////////////////////// 080 { 081 return children; 082 } 083 084 public Object getChild ( int index ) 085 ////////////////////////////////////////////////////////////////////// 086 { 087 if ( index >= children.length ) 088 { 089 return null; 090 } 091 092 return children [ index ]; 093 } 094 095 /********************************************************************* 096 * Returns the first SmlNode child with the given name. 097 * 098 * @return 099 * 100 * May return null. 101 *********************************************************************/ 102 public SmlNode getChildNode ( String childNodeName ) 103 ////////////////////////////////////////////////////////////////////// 104 { 105 NullArgumentException.check ( childNodeName ); 106 107 Object [ ] children = this.children; 108 109 for ( int i = 0; i < children.length; i++ ) 110 { 111 Object child = children [ i ]; 112 113 if ( child instanceof SmlNode ) 114 { 115 SmlNode childSmlNode = ( SmlNode ) child; 116 117 if ( childSmlNode.getName ( ).equals ( childNodeName ) ) 118 { 119 return childSmlNode; 120 } 121 } 122 } 123 124 return null; 125 } 126 127 /********************************************************************* 128 * Returns all SmlNode children with the given name. 129 * 130 * @return 131 * 132 * May return an empty array. 133 *********************************************************************/ 134 public SmlNode [ ] getChildNodes ( String childNodeName ) 135 ////////////////////////////////////////////////////////////////////// 136 { 137 NullArgumentException.check ( childNodeName ); 138 139 Object [ ] children = this.children; 140 141 Vector childNodeVector = new Vector ( ); 142 143 for ( int i = 0; i < children.length; i++ ) 144 { 145 Object child = children [ i ]; 146 147 if ( child instanceof SmlNode ) 148 { 149 SmlNode childSmlNode = ( SmlNode ) child; 150 151 if ( childSmlNode.getName ( ).equals ( childNodeName ) ) 152 { 153 childNodeVector.addElement ( childSmlNode ); 154 } 155 } 156 } 157 158 SmlNode [ ] childNodes = new SmlNode [ childNodeVector.size ( ) ]; 159 160 childNodeVector.copyInto ( childNodes ); 161 162 return childNodes; 163 } 164 165 /********************************************************************* 166 * return ParseLib.parseBoolean ( getString ( childNodeName ), def ); 167 *********************************************************************/ 168 public boolean getBoolean ( String childNodeName, boolean def ) 169 ////////////////////////////////////////////////////////////////////// 170 { 171 return ParseLib.parseBoolean ( getString ( childNodeName ), def ); 172 } 173 174 /********************************************************************* 175 * return ParseLib.parseInt ( getString ( childNodeName ), def ); 176 *********************************************************************/ 177 public int getInt ( String childNodeName, int def ) 178 ////////////////////////////////////////////////////////////////////// 179 { 180 return ParseLib.parseInt ( getString ( childNodeName ), def ); 181 } 182 183 /********************************************************************* 184 * return ParseLib.parseLong ( getString ( childNodeName ), def ); 185 *********************************************************************/ 186 public long getLong ( String childNodeName, int def ) 187 ////////////////////////////////////////////////////////////////////// 188 { 189 return ParseLib.parseLong ( getString ( childNodeName ), def ); 190 } 191 192 /********************************************************************* 193 * Returns the named child node's first child as cast to a String. 194 * 195 * @return 196 * 197 * May return null. 198 *********************************************************************/ 199 public String getString ( String childNodeName ) 200 ////////////////////////////////////////////////////////////////////// 201 { 202 SmlNode childNode = getChildNode ( childNodeName ); 203 204 if ( childNode == null ) 205 { 206 return null; 207 } 208 209 return SmlCoder.decode ( ( String ) childNode.getChild ( 0 ) ); 210 } 211 212 /********************************************************************* 213 * Finds direct children with the given name and returns their values. 214 * 215 * @return 216 * 217 * May return an empty array. 218 *********************************************************************/ 219 public String [ ] getStrings ( String childNodeName ) 220 ////////////////////////////////////////////////////////////////////// 221 { 222 NullArgumentException.check ( childNodeName ); 223 224 Object [ ] children = this.children; 225 226 Vector childStringVector = new Vector ( ); 227 228 for ( int i = 0; i < children.length; i++ ) 229 { 230 Object child = children [ i ]; 231 232 if ( child instanceof SmlNode ) 233 { 234 SmlNode childSmlNode = ( SmlNode ) child; 235 236 if ( childSmlNode.getName ( ).equals ( childNodeName ) ) 237 { 238 childStringVector.addElement ( SmlCoder.decode ( 239 ( String ) childSmlNode.getChild ( 0 ) ) ); 240 } 241 } 242 } 243 244 String [ ] strings = new String [ childStringVector.size ( ) ]; 245 246 childStringVector.copyInto ( strings ); 247 248 return strings; 249 } 250 251 public boolean hasChild ( ) 252 ////////////////////////////////////////////////////////////////////// 253 { 254 return children.length > 0; 255 } 256 257 ////////////////////////////////////////////////////////////////////// 258 // mutator methods 259 ////////////////////////////////////////////////////////////////////// 260 261 public void add ( Object smlNodeOrString ) 262 ////////////////////////////////////////////////////////////////////// 263 { 264 NullArgumentException.check ( smlNodeOrString ); 265 266 synchronized ( this ) 267 { 268 int childCount = children.length; 269 270 Object [ ] newChildren = new Object [ childCount + 1 ]; 271 272 System.arraycopy ( children, 0, newChildren, 0, childCount ); 273 274 newChildren [ childCount ] = smlNodeOrString; 275 276 children = newChildren; 277 } 278 } 279 280 public void removeChildren ( ) 281 ////////////////////////////////////////////////////////////////////// 282 { 283 children = ZERO_LENGTH_OBJECT_ARRAY; 284 } 285 286 ////////////////////////////////////////////////////////////////////// 287 // object methods 288 ////////////////////////////////////////////////////////////////////// 289 290 public String toString ( ) 291 ////////////////////////////////////////////////////////////////////// 292 { 293 return toString ( -1, 0 ); 294 } 295 296 public String toString ( int indent, int tabSize ) 297 ////////////////////////////////////////////////////////////////////// 298 { 299 StringBuffer stringBuffer = new StringBuffer ( ); 300 301 for ( int i = 0; i < indent; i++ ) 302 { 303 stringBuffer.append ( ' ' ); 304 } 305 306 stringBuffer.append ( '<' ); 307 308 stringBuffer.append ( name ); 309 310 Object [ ] children = this.children; 311 312 if ( children.length < 1 ) 313 { 314 stringBuffer.append ( "/>" ); 315 } 316 else 317 { 318 stringBuffer.append ( ">" ); 319 320 Object child = null; 321 322 for ( int i = 0; i < children.length; i++ ) 323 { 324 child = children [ i ]; 325 326 if ( child instanceof SmlNode ) 327 { 328 if ( indent > -1 ) 329 { 330 stringBuffer.append ( '\n' ); 331 } 332 333 stringBuffer.append ( ( ( SmlNode ) child ) 334 .toString ( indent + tabSize, tabSize ) ); 335 } 336 else 337 { 338 stringBuffer.append ( 339 SmlCoder.encode ( child.toString ( ) ) ); 340 } 341 } 342 343 if ( child instanceof SmlNode ) 344 { 345 if ( indent > -1 ) 346 { 347 stringBuffer.append ( '\n' ); 348 349 for ( int i = 0; i < indent; i++ ) 350 { 351 stringBuffer.append ( ' ' ); 352 } 353 } 354 } 355 356 stringBuffer.append ( "</" ); 357 358 stringBuffer.append ( name ); 359 360 stringBuffer.append ( ">" ); 361 } 362 363 return stringBuffer.toString ( ); 364 } 365 366 ////////////////////////////////////////////////////////////////////// 367 ////////////////////////////////////////////////////////////////////// 368 }