001/* 002 * Copyright (C) 2005 Christian Schulte <cs@schulte.it> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: Section.java 5091 2016-04-04 15:40:17Z schulte $ 029 * 030 */ 031package org.jomc.util; 032 033import java.util.ArrayList; 034import java.util.List; 035 036/** 037 * Section of text. 038 * 039 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 040 * @version $JOMC: Section.java 5091 2016-04-04 15:40:17Z schulte $ 041 */ 042public class Section 043{ 044 045 /** 046 * Constant for the mode during parsing the head content of a section. 047 */ 048 static final int MODE_HEAD = 1; 049 050 /** 051 * Constant for the mode during parsing the tail content of a section. 052 */ 053 static final int MODE_TAIL = 2; 054 055 /** 056 * The current parsing mode. 057 */ 058 private int mode = MODE_HEAD; 059 060 /** 061 * The name of this section. 062 */ 063 private String name; 064 065 /** 066 * The parsed head content of this section. 067 */ 068 private StringBuilder headContent; 069 070 /** 071 * The parsed tail content of this section. 072 */ 073 private StringBuilder tailContent; 074 075 /** 076 * Line marking the start of this section. 077 */ 078 private String startingLine; 079 080 /** 081 * Line marking the end of this section. 082 */ 083 private String endingLine; 084 085 /** 086 * The child sections of this section. 087 */ 088 private List<Section> sections; 089 090 /** 091 * Creates a new {@code Section} instance. 092 */ 093 public Section() 094 { 095 super(); 096 } 097 098 /** 099 * Gets the name of this section. 100 * 101 * @return The name of this section or {@code null}. 102 */ 103 public String getName() 104 { 105 return this.name; 106 } 107 108 /** 109 * Sets the name of this section. 110 * 111 * @param value The new name of this section or {@code null}. 112 */ 113 public void setName( final String value ) 114 { 115 this.name = value; 116 } 117 118 /** 119 * Gets the line marking the start of this section. 120 * 121 * @return The line marking the start of this section. 122 */ 123 public String getStartingLine() 124 { 125 return this.startingLine; 126 } 127 128 /** 129 * Sets the line marking the start of this section. 130 * 131 * @param value The new line marking the start of this section. 132 */ 133 public void setStartingLine( final String value ) 134 { 135 this.startingLine = value; 136 } 137 138 /** 139 * Gets the line marking the end of this section. 140 * 141 * @return The line marking the end of this section. 142 */ 143 public String getEndingLine() 144 { 145 return this.endingLine; 146 } 147 148 /** 149 * Sets the line marking the end of this section. 150 * 151 * @param value The new line marking the end of this section. 152 */ 153 public void setEndingLine( final String value ) 154 { 155 this.endingLine = value; 156 } 157 158 /** 159 * Gets the content of this section preceding any child section content. 160 * 161 * @return The content of this section preceding any child section content. 162 */ 163 public StringBuilder getHeadContent() 164 { 165 if ( this.headContent == null ) 166 { 167 this.headContent = new StringBuilder( 512 ); 168 } 169 170 return this.headContent; 171 } 172 173 /** 174 * Gets the content of this section succeeding any child section content. 175 * 176 * @return The content of this section succeeding any child section content. 177 */ 178 public StringBuilder getTailContent() 179 { 180 if ( this.tailContent == null ) 181 { 182 this.tailContent = new StringBuilder( 512 ); 183 } 184 185 return this.tailContent; 186 } 187 188 /** 189 * Gets the child sections of this section. 190 * <p> 191 * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make 192 * to the returned list will be present inside the object. This is why there is no {@code set} method for the 193 * sections property. 194 * </p> 195 * 196 * @return A list of child sections of this section. 197 */ 198 public List<Section> getSections() 199 { 200 if ( this.sections == null ) 201 { 202 this.sections = new ArrayList<Section>(); 203 } 204 205 return this.sections; 206 } 207 208 /** 209 * Gets a child section matching a given name. 210 * 211 * @param sectionName The name of the section to return. 212 * 213 * @return The first child section matching {@code sectionName} or {@code null}, if no such section is found. 214 * 215 * @throws NullPointerException if {@code sectionName} is {@code null}. 216 */ 217 public Section getSection( final String sectionName ) 218 { 219 if ( sectionName == null ) 220 { 221 throw new NullPointerException( "sectionName" ); 222 } 223 224 return this.getSection( this, sectionName ); 225 } 226 227 private Section getSection( final Section current, final String sectionName ) 228 { 229 if ( sectionName.equals( current.getName() ) ) 230 { 231 return current; 232 } 233 234 for ( final Section child : current.getSections() ) 235 { 236 if ( sectionName.equals( child.getName() ) ) 237 { 238 return child; 239 } 240 241 if ( child.getName() == null ) 242 { 243 final Section section = child.getSection( sectionName ); 244 245 if ( section != null ) 246 { 247 return section; 248 } 249 } 250 } 251 252 return null; 253 } 254 255 /** 256 * Gets the parsing mode of the instance. 257 * 258 * @return The parsing mode of the instance. 259 * 260 * @see #MODE_HEAD 261 * @see #MODE_TAIL 262 */ 263 int getMode() 264 { 265 return this.mode; 266 } 267 268 /** 269 * Sets the parsing mode of the instance. 270 * 271 * @param value The new parsing mode of the instance. 272 * 273 * @see #MODE_HEAD 274 * @see #MODE_TAIL 275 */ 276 void setMode( final int value ) 277 { 278 this.mode = value; 279 } 280 281}