1 /*
2 * Copyright (C) Christian Schulte, 2005-206
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * o Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * o Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $JOMC: Section.java 4613 2012-09-22 10:07:08Z schulte $
29 *
30 */
31 package org.jomc.util;
32
33 import java.util.ArrayList;
34 import java.util.List;
35
36 /**
37 * Section of text.
38 *
39 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
40 * @version $JOMC: Section.java 4613 2012-09-22 10:07:08Z schulte $
41 */
42 public class Section
43 {
44
45 /** Constant for the mode during parsing the head content of a section. */
46 static final int MODE_HEAD = 1;
47
48 /** Constant for the mode during parsing the tail content of a section. */
49 static final int MODE_TAIL = 2;
50
51 /** The current parsing mode. */
52 private int mode = MODE_HEAD;
53
54 /** The name of this section. */
55 private String name;
56
57 /** The parsed head content of this section. */
58 private StringBuilder headContent;
59
60 /** The parsed tail content of this section. */
61 private StringBuilder tailContent;
62
63 /** Line marking the start of this section. */
64 private String startingLine;
65
66 /** Line marking the end of this section. */
67 private String endingLine;
68
69 /** The child sections of this section. */
70 private List<Section> sections;
71
72 /** Creates a new {@code Section} instance. */
73 public Section()
74 {
75 super();
76 }
77
78 /**
79 * Gets the name of this section.
80 *
81 * @return The name of this section or {@code null}.
82 */
83 public String getName()
84 {
85 return this.name;
86 }
87
88 /**
89 * Sets the name of this section.
90 *
91 * @param value The new name of this section or {@code null}.
92 */
93 public void setName( final String value )
94 {
95 this.name = value;
96 }
97
98 /**
99 * Gets the line marking the start of this section.
100 *
101 * @return The line marking the start of this section.
102 */
103 public String getStartingLine()
104 {
105 return this.startingLine;
106 }
107
108 /**
109 * Sets the line marking the start of this section.
110 *
111 * @param value The new line marking the start of this section.
112 */
113 public void setStartingLine( final String value )
114 {
115 this.startingLine = value;
116 }
117
118 /**
119 * Gets the line marking the end of this section.
120 *
121 * @return The line marking the end of this section.
122 */
123 public String getEndingLine()
124 {
125 return this.endingLine;
126 }
127
128 /**
129 * Sets the line marking the end of this section.
130 *
131 * @param value The new line marking the end of this section.
132 */
133 public void setEndingLine( final String value )
134 {
135 this.endingLine = value;
136 }
137
138 /**
139 * Gets the content of this section preceding any child section content.
140 *
141 * @return The content of this section preceding any child section content.
142 */
143 public StringBuilder getHeadContent()
144 {
145 if ( this.headContent == null )
146 {
147 this.headContent = new StringBuilder( 512 );
148 }
149
150 return this.headContent;
151 }
152
153 /**
154 * Gets the content of this section succeeding any child section content.
155 *
156 * @return The content of this section succeeding any child section content.
157 */
158 public StringBuilder getTailContent()
159 {
160 if ( this.tailContent == null )
161 {
162 this.tailContent = new StringBuilder( 512 );
163 }
164
165 return this.tailContent;
166 }
167
168 /**
169 * Gets the child sections of this section.
170 * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make
171 * to the returned list will be present inside the object. This is why there is no {@code set} method for the
172 * sections property.</p>
173 *
174 * @return A list of child sections of this section.
175 */
176 public List<Section> getSections()
177 {
178 if ( this.sections == null )
179 {
180 this.sections = new ArrayList<Section>();
181 }
182
183 return this.sections;
184 }
185
186 /**
187 * Gets a child section matching a given name.
188 *
189 * @param sectionName The name of the section to return.
190 *
191 * @return The first child section matching {@code sectionName} or {@code null}, if no such section is found.
192 *
193 * @throws NullPointerException if {@code sectionName} is {@code null}.
194 */
195 public Section getSection( final String sectionName )
196 {
197 if ( sectionName == null )
198 {
199 throw new NullPointerException( "sectionName" );
200 }
201
202 return this.getSection( this, sectionName );
203 }
204
205 private Section getSection( final Section current, final String sectionName )
206 {
207 if ( sectionName.equals( current.getName() ) )
208 {
209 return current;
210 }
211
212 for ( Section child : current.getSections() )
213 {
214 if ( sectionName.equals( child.getName() ) )
215 {
216 return child;
217 }
218
219 if ( child.getName() == null )
220 {
221 final Section section = child.getSection( sectionName );
222
223 if ( section != null )
224 {
225 return section;
226 }
227 }
228 }
229
230 return null;
231 }
232
233 /**
234 * Gets the parsing mode of the instance.
235 *
236 * @return The parsing mode of the instance.
237 *
238 * @see #MODE_HEAD
239 * @see #MODE_TAIL
240 */
241 int getMode()
242 {
243 return this.mode;
244 }
245
246 /**
247 * Sets the parsing mode of the instance.
248 *
249 * @param value The new parsing mode of the instance.
250 *
251 * @see #MODE_HEAD
252 * @see #MODE_TAIL
253 */
254 void setMode( final int value )
255 {
256 this.mode = value;
257 }
258
259 }