001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.configuration;
018:
019: import java.io.Reader;
020: import java.io.StringReader;
021: import java.io.StringWriter;
022: import java.util.Iterator;
023:
024: import org.apache.commons.configuration.event.ConfigurationEvent;
025:
026: import junit.framework.TestCase;
027:
028: /**
029: * Test class for PropertiesConfigurationLayout.
030: *
031: * @author <a
032: * href="http://jakarta.apache.org/commons/configuration/team-list.html">Commons
033: * Configuration team</a>
034: * @version $Id: TestPropertiesConfigurationLayout.java 439648 2006-09-02 20:42:10Z oheger $
035: */
036: public class TestPropertiesConfigurationLayout extends TestCase {
037: /** Constant for the line break character. */
038: static final String CR = System.getProperty("line.separator");
039:
040: /** Constant for a test property key. */
041: static final String TEST_KEY = "myProperty";
042:
043: /** Constant for a test comment. */
044: static final String TEST_COMMENT = "A comment for my test property";
045:
046: /** Constant for a test property value. */
047: static final String TEST_VALUE = "myPropertyValue";
048:
049: /** The layout object under test. */
050: PropertiesConfigurationLayout layout;
051:
052: /** The associated configuration object. */
053: LayoutTestConfiguration config;
054:
055: /** A properties builder that can be used for testing. */
056: PropertiesBuilder builder;
057:
058: protected void setUp() throws Exception {
059: super .setUp();
060: config = new LayoutTestConfiguration();
061: layout = new PropertiesConfigurationLayout(config);
062: config.setLayout(layout);
063: builder = new PropertiesBuilder();
064: }
065:
066: /**
067: * Tests a newly created instance.
068: */
069: public void testInit() {
070: assertTrue("Object contains keys", layout.getKeys().isEmpty());
071: assertNull("Header comment not null", layout.getHeaderComment());
072: Iterator it = config.getConfigurationListeners().iterator();
073: assertTrue("No event listener registered", it.hasNext());
074: assertSame("Layout not registered as event listener", layout,
075: it.next());
076: assertFalse("Multiple event listeners registered", it.hasNext());
077: assertSame("Configuration not stored", config, layout
078: .getConfiguration());
079: assertFalse("Force single line flag set", layout
080: .isForceSingleLine());
081: }
082:
083: /**
084: * Tests creating a layout object with a null configuration. This should
085: * cause an exception.
086: */
087: public void testInitNull() {
088: try {
089: new PropertiesConfigurationLayout(null);
090: fail("Could create instance with null config!");
091: } catch (IllegalArgumentException iex) {
092: // ok
093: }
094: }
095:
096: /**
097: * Tests reading a simple properties file.
098: */
099: public void testReadSimple() throws ConfigurationException {
100: builder.addComment(TEST_COMMENT);
101: builder.addProperty(TEST_KEY, TEST_VALUE);
102: layout.load(builder.getReader());
103: assertNull("A header comment was found", layout
104: .getHeaderComment());
105: assertEquals("Wrong number of properties", 1, layout.getKeys()
106: .size());
107: assertTrue("Property not found", layout.getKeys().contains(
108: TEST_KEY));
109: assertEquals("Comment not found", TEST_COMMENT, layout
110: .getCanonicalComment(TEST_KEY, false));
111: assertEquals("Wrong number of blanc lines", 0, layout
112: .getBlancLinesBefore(TEST_KEY));
113: assertTrue("Wrong single line flag", layout
114: .isSingleLine(TEST_KEY));
115: assertEquals("Property not stored in config", TEST_VALUE,
116: config.getString(TEST_KEY));
117: }
118:
119: /**
120: * Tests whether blanc lines before a property are correctly detected.
121: */
122: public void testBlancLines() throws ConfigurationException {
123: builder.addProperty("prop", "value");
124: builder.addComment(null);
125: builder.addComment(null);
126: builder.addComment(TEST_COMMENT);
127: builder.addComment(null);
128: builder.addProperty(TEST_KEY, TEST_VALUE);
129: layout.load(builder.getReader());
130: assertEquals("Wrong number of blanc lines", 2, layout
131: .getBlancLinesBefore(TEST_KEY));
132: assertEquals("Wrong comment", TEST_COMMENT + CR, layout
133: .getCanonicalComment(TEST_KEY, false));
134: assertEquals("Wrong property value", TEST_VALUE, config
135: .getString(TEST_KEY));
136: }
137:
138: /**
139: * Tests the single line flag for a simple property definition.
140: */
141: public void testIsSingleLine() throws ConfigurationException {
142: builder.addProperty(TEST_KEY, TEST_VALUE + "," + TEST_VALUE
143: + "2");
144: layout.load(builder.getReader());
145: assertTrue("Wrong single line flag", layout
146: .isSingleLine(TEST_KEY));
147: assertEquals("Wrong number of values", 2, config.getList(
148: TEST_KEY).size());
149: }
150:
151: /**
152: * Tests the single line flag if there are multiple property definitions.
153: */
154: public void testIsSingleLineMulti() throws ConfigurationException {
155: builder.addProperty(TEST_KEY, TEST_VALUE);
156: builder.addProperty("anotherProp", "a value");
157: builder.addProperty(TEST_KEY, TEST_VALUE + "2");
158: layout.load(builder.getReader());
159: assertFalse("Wrong single line flag", layout
160: .isSingleLine(TEST_KEY));
161: assertEquals("Wrong number of values", 2, config.getList(
162: TEST_KEY).size());
163: }
164:
165: /**
166: * Tests whether comments are combined for multiple occurrences.
167: */
168: public void testCombineComments() throws ConfigurationException {
169: builder.addComment(TEST_COMMENT);
170: builder.addProperty(TEST_KEY, TEST_VALUE);
171: builder.addComment(null);
172: builder.addComment(TEST_COMMENT);
173: builder.addProperty(TEST_KEY, TEST_VALUE + "2");
174: layout.load(builder.getReader());
175: assertEquals("Wrong combined comment", TEST_COMMENT + CR
176: + TEST_COMMENT, layout.getCanonicalComment(TEST_KEY,
177: false));
178: assertEquals("Wrong combined blanc numbers", 0, layout
179: .getBlancLinesBefore(TEST_KEY));
180: }
181:
182: /**
183: * Tests if a header comment is detected.
184: */
185: public void testHeaderComment() throws ConfigurationException {
186: builder.addComment(TEST_COMMENT);
187: builder.addComment(null);
188: builder.addProperty(TEST_KEY, TEST_VALUE);
189: layout.load(builder.getReader());
190: assertEquals("Wrong header comment", TEST_COMMENT, layout
191: .getCanonicalHeaderComment(false));
192: assertNull("Wrong comment for property", layout
193: .getCanonicalComment(TEST_KEY, false));
194: }
195:
196: /**
197: * Tests if a header comment containing blanc lines is correctly detected.
198: */
199: public void testHeaderCommentWithBlancs()
200: throws ConfigurationException {
201: builder.addComment(TEST_COMMENT);
202: builder.addComment(null);
203: builder.addComment(TEST_COMMENT);
204: builder.addComment(null);
205: builder.addProperty(TEST_KEY, TEST_VALUE);
206: layout.load(builder.getReader());
207: assertEquals("Wrong header comment", TEST_COMMENT + CR + CR
208: + TEST_COMMENT, layout.getCanonicalHeaderComment(false));
209: assertNull("Wrong comment for property", layout
210: .getComment(TEST_KEY));
211: }
212:
213: /**
214: * Tests if a header comment is correctly detected when it contains blanc
215: * lines and the first property has a comment, too.
216: */
217: public void testHeaderCommentWithBlancsAndPropComment()
218: throws ConfigurationException {
219: builder.addComment(TEST_COMMENT);
220: builder.addComment(null);
221: builder.addComment(TEST_COMMENT);
222: builder.addComment(null);
223: builder.addComment(TEST_COMMENT);
224: builder.addProperty(TEST_KEY, TEST_VALUE);
225: layout.load(builder.getReader());
226: assertEquals("Wrong header comment", TEST_COMMENT + CR + CR
227: + TEST_COMMENT, layout.getCanonicalHeaderComment(false));
228: assertEquals("Wrong comment for property", TEST_COMMENT, layout
229: .getCanonicalComment(TEST_KEY, false));
230: }
231:
232: /**
233: * Tests fetching a canonical header comment when no comment is set.
234: */
235: public void testHeaderCommentNull() {
236: assertNull("No null comment with comment chars", layout
237: .getCanonicalHeaderComment(true));
238: assertNull("No null comment without comment chars", layout
239: .getCanonicalHeaderComment(false));
240: }
241:
242: /**
243: * Tests if a property add event is correctly processed.
244: */
245: public void testEventAdd() {
246: ConfigurationEvent event = new ConfigurationEvent(this ,
247: AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY,
248: TEST_VALUE, false);
249: layout.configurationChanged(event);
250: assertTrue("Property not stored", layout.getKeys().contains(
251: TEST_KEY));
252: assertEquals("Blanc lines before new property", 0, layout
253: .getBlancLinesBefore(TEST_KEY));
254: assertTrue("No single line property", layout
255: .isSingleLine(TEST_KEY));
256: }
257:
258: /**
259: * Tests adding a property multiple time through an event. The property
260: * should then be a multi-line property.
261: */
262: public void testEventAddMultiple() {
263: ConfigurationEvent event = new ConfigurationEvent(this ,
264: AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY,
265: TEST_VALUE, false);
266: layout.configurationChanged(event);
267: layout.configurationChanged(event);
268: assertFalse("No multi-line property", layout
269: .isSingleLine(TEST_KEY));
270: }
271:
272: /**
273: * Tests if an add event is correctly processed if the affected property is
274: * already stored in the layout object.
275: */
276: public void testEventAddExisting() throws ConfigurationException {
277: builder.addComment(TEST_COMMENT);
278: builder.addProperty(TEST_KEY, TEST_VALUE);
279: layout.load(builder.getReader());
280: ConfigurationEvent event = new ConfigurationEvent(this ,
281: AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY,
282: TEST_VALUE, false);
283: layout.configurationChanged(event);
284: assertFalse("No multi-line property", layout
285: .isSingleLine(TEST_KEY));
286: assertEquals("Comment was modified", TEST_COMMENT, layout
287: .getCanonicalComment(TEST_KEY, false));
288: }
289:
290: /**
291: * Tests if a set property event for a non existing property is correctly
292: * handled.
293: */
294: public void testEventSetNonExisting() {
295: ConfigurationEvent event = new ConfigurationEvent(this ,
296: AbstractConfiguration.EVENT_SET_PROPERTY, TEST_KEY,
297: TEST_VALUE, false);
298: layout.configurationChanged(event);
299: assertTrue("New property was not found", layout.getKeys()
300: .contains(TEST_KEY));
301: }
302:
303: /**
304: * Tests if a property delete event is correctly processed.
305: */
306: public void testEventDelete() {
307: ConfigurationEvent event = new ConfigurationEvent(this ,
308: AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY,
309: TEST_VALUE, false);
310: layout.configurationChanged(event);
311: event = new ConfigurationEvent(this ,
312: AbstractConfiguration.EVENT_CLEAR_PROPERTY, TEST_KEY,
313: null, false);
314: layout.configurationChanged(event);
315: assertFalse("Property still existing", layout.getKeys()
316: .contains(TEST_KEY));
317: }
318:
319: /**
320: * Tests if a clear event is correctly processed.
321: */
322: public void testEventClearConfig() throws ConfigurationException {
323: fillLayout();
324: ConfigurationEvent event = new ConfigurationEvent(this ,
325: AbstractConfiguration.EVENT_CLEAR, null, null, false);
326: layout.configurationChanged(event);
327: assertTrue("Keys not empty", layout.getKeys().isEmpty());
328: assertNull("Header comment was not reset", layout
329: .getHeaderComment());
330: }
331:
332: /**
333: * Tests if a before update event is correctly ignored.
334: */
335: public void testEventAddBefore() {
336: ConfigurationEvent event = new ConfigurationEvent(this ,
337: AbstractConfiguration.EVENT_ADD_PROPERTY, TEST_KEY,
338: TEST_VALUE, true);
339: layout.configurationChanged(event);
340: assertFalse("Property already stored", layout.getKeys()
341: .contains(TEST_KEY));
342: }
343:
344: /**
345: * Tests if a reload update is correctly processed.
346: */
347: public void testEventReload() {
348: fillLayout();
349: ConfigurationEvent event = new ConfigurationEvent(this ,
350: AbstractFileConfiguration.EVENT_RELOAD, null, null,
351: true);
352: layout.configurationChanged(event);
353: assertTrue("Keys not empty", layout.getKeys().isEmpty());
354: assertNull("Header comment was not reset", layout
355: .getHeaderComment());
356: }
357:
358: /**
359: * Tests the event after a reload has been performed. This should be
360: * ignored.
361: */
362: public void testEventReloadAfter() {
363: fillLayout();
364: ConfigurationEvent event = new ConfigurationEvent(this ,
365: AbstractFileConfiguration.EVENT_RELOAD, null, null,
366: false);
367: layout.configurationChanged(event);
368: assertFalse("Keys are empty", layout.getKeys().isEmpty());
369: assertNotNull("Header comment was reset", layout
370: .getHeaderComment());
371: }
372:
373: /**
374: * Tests a recursive load call.
375: */
376: public void testRecursiveLoadCall() throws ConfigurationException {
377: PropertiesBuilder b = new PropertiesBuilder();
378: b.addComment("A nested header comment.");
379: b.addComment("With multiple lines");
380: b.addComment(null);
381: b.addComment("Second comment");
382: b.addProperty(TEST_KEY, TEST_VALUE);
383: b.addProperty(TEST_KEY + "2", TEST_VALUE + "2");
384: config.builder = b;
385:
386: builder.addComment("Header comment");
387: builder.addComment(null);
388: builder.addComment(TEST_COMMENT);
389: builder.addProperty(TEST_KEY, TEST_VALUE);
390: builder.addComment("Include file");
391: builder.addProperty(PropertiesConfiguration.getInclude(),
392: "test");
393:
394: layout.load(builder.getReader());
395:
396: assertEquals("Wrong header comment", "Header comment", layout
397: .getCanonicalHeaderComment(false));
398: assertFalse("Include property was stored", layout.getKeys()
399: .contains(PropertiesConfiguration.getInclude()));
400: assertEquals("Wrong comment for property", TEST_COMMENT + CR
401: + "A nested header comment." + CR
402: + "With multiple lines" + CR + CR + "Second comment",
403: layout.getCanonicalComment(TEST_KEY, false));
404: }
405:
406: /**
407: * Tests whether the output of the layout object is identical to the source
408: * file (at least for simple properties files).
409: */
410: public void testReadAndWrite() throws ConfigurationException {
411: builder.addComment("This is my test properties file,");
412: builder.addComment("which contains a header comment.");
413: builder.addComment(null);
414: builder.addComment(TEST_COMMENT);
415: builder.addProperty(TEST_KEY, TEST_COMMENT);
416: builder.addComment(null);
417: builder.addComment(null);
418: builder.addComment("Another comment");
419: builder.addProperty("property", "and a value");
420: layout.load(builder.getReader());
421: checkLayoutString(builder.toString());
422: }
423:
424: /**
425: * Tests if the content of the layout object is correctly written.
426: */
427: public void testSave() throws ConfigurationException {
428: config.addProperty(TEST_KEY, TEST_VALUE);
429: layout.setComment(TEST_KEY, TEST_COMMENT);
430: config.addProperty(TEST_KEY, TEST_VALUE + "2");
431: config.addProperty("AnotherProperty", "AnotherValue");
432: config.addProperty("AnotherProperty", "3rdValue");
433: layout.setComment("AnotherProperty", "AnotherComment");
434: layout.setBlancLinesBefore("AnotherProperty", 2);
435: layout.setSingleLine("AnotherProperty", true);
436: layout.setHeaderComment("A header comment" + CR
437: + "for my properties");
438: checkLayoutString("# A header comment" + CR
439: + "# for my properties" + CR + CR + "# " + TEST_COMMENT
440: + CR + TEST_KEY + " = " + TEST_VALUE + CR + TEST_KEY
441: + " = " + TEST_VALUE + "2" + CR + CR + CR
442: + "# AnotherComment" + CR
443: + "AnotherProperty = AnotherValue,3rdValue" + CR);
444: }
445:
446: /**
447: * Tests the force single line flag.
448: */
449: public void testSaveForceSingleLine() throws ConfigurationException {
450: config.setListDelimiter(';');
451: config.addProperty(TEST_KEY, TEST_VALUE);
452: config.addProperty(TEST_KEY, TEST_VALUE + "2");
453: config.addProperty("AnotherProperty", "value1;value2;value3");
454: layout.setComment(TEST_KEY, TEST_COMMENT);
455: layout.setForceSingleLine(true);
456: checkLayoutString("# " + TEST_COMMENT + CR + TEST_KEY + " = "
457: + TEST_VALUE + ';' + TEST_VALUE + "2" + CR
458: + "AnotherProperty = value1;value2;value3" + CR);
459: }
460:
461: /**
462: * Tests the trimComment method.
463: */
464: public void testTrimComment() {
465: assertEquals("Wrong trimmed comment", "This is a comment" + CR
466: + "that spans multiple" + CR + "lines in a" + CR
467: + " complex way.", PropertiesConfigurationLayout
468: .trimComment(" # This is a comment" + CR
469: + "that spans multiple" + CR + "!lines in a"
470: + CR + " complex way.", false));
471: }
472:
473: /**
474: * Tests trimming a comment with trailing CRs.
475: */
476: public void testTrimCommentTrainlingCR() {
477: assertEquals("Wrong trimmed comment", "Comment with" + CR
478: + "trailing CR" + CR, PropertiesConfigurationLayout
479: .trimComment(
480: "Comment with" + CR + "! trailing CR" + CR,
481: false));
482: }
483:
484: /**
485: * Tests enforcing comment characters in a comment.
486: */
487: public void testTrimCommentFalse() {
488: assertEquals("Wrong trimmed comment", "# Comment with" + CR
489: + " ! some mixed " + CR + "#comment" + CR + "# lines",
490: PropertiesConfigurationLayout.trimComment(
491: "Comment with" + CR + " ! some mixed " + CR
492: + "#comment" + CR + "lines", true));
493: }
494:
495: /**
496: * Tests accessing data for a property, which is not stored.
497: */
498: public void testGetNonExistingLayouData() {
499: assertNull("A comment was found", layout.getComment("unknown"));
500: assertTrue("A multi-line property", layout
501: .isSingleLine("unknown"));
502: assertEquals("Leading blanc lines", 0, layout
503: .getBlancLinesBefore("unknown"));
504: }
505:
506: /**
507: * Tests accessing a property with a null key. This should throw an
508: * exception.
509: */
510: public void testGetNullLayouttData() {
511: try {
512: layout.setComment(null, TEST_COMMENT);
513: fail("Could access null property key!");
514: } catch (IllegalArgumentException iex) {
515: // ok
516: }
517: }
518:
519: /**
520: * Tests resetting a comment.
521: */
522: public void testSetNullComment() {
523: fillLayout();
524: layout.setComment(TEST_KEY, null);
525: assertNull("Comment was not reset", layout.getComment(TEST_KEY));
526: }
527:
528: /**
529: * Tests saving when a comment for a non existing property is contained in
530: * the layout object. This comment should be ignored.
531: */
532: public void testSaveCommentForUnexistingProperty()
533: throws ConfigurationException {
534: fillLayout();
535: layout.setComment("NonExistingKey", "NonExistingComment");
536: String output = getLayoutString();
537: assertTrue("Non existing key was found", output
538: .indexOf("NonExistingKey") < 0);
539: assertTrue("Non existing comment was found", output
540: .indexOf("NonExistingComment") < 0);
541: }
542:
543: /**
544: * Tests saving an empty layout object.
545: */
546: public void testSaveEmptyLayout() throws ConfigurationException {
547: checkLayoutString("");
548: }
549:
550: /**
551: * Tests the copy constructor.
552: */
553: public void testInitCopy() {
554: fillLayout();
555: PropertiesConfigurationLayout l2 = new PropertiesConfigurationLayout(
556: config, layout);
557: assertEquals("Wrong number of keys", layout.getKeys().size(),
558: l2.getKeys().size());
559: for (Iterator it = layout.getKeys().iterator(); it.hasNext();) {
560: Object key = it.next();
561: assertTrue("Key was not found: " + key, l2.getKeys()
562: .contains(key));
563: }
564: }
565:
566: /**
567: * Tests if the copy and the original are independend from each other.
568: */
569: public void testInitCopyModify() {
570: fillLayout();
571: PropertiesConfigurationLayout l2 = new PropertiesConfigurationLayout(
572: config, layout);
573: assertEquals("Comments are not equal", layout
574: .getComment(TEST_KEY), l2.getComment(TEST_KEY));
575: layout.setComment(TEST_KEY, "A new comment");
576: assertEquals("Comment was changed", TEST_COMMENT, l2
577: .getCanonicalComment(TEST_KEY, false));
578: l2.setBlancLinesBefore(TEST_KEY, l2
579: .getBlancLinesBefore(TEST_KEY) + 1);
580: assertFalse("Blanc lines do not differ", layout
581: .getBlancLinesBefore(TEST_KEY) == l2
582: .getBlancLinesBefore(TEST_KEY));
583: }
584:
585: /**
586: * Helper method for filling the layout object with some properties.
587: */
588: private void fillLayout() {
589: builder.addComment("A header comment");
590: builder.addComment(null);
591: builder.addProperty("prop", "value");
592: builder.addComment(TEST_COMMENT);
593: builder.addProperty(TEST_KEY, TEST_VALUE);
594: builder.addProperty("anotherProp", "anotherValue");
595: try {
596: layout.load(builder.getReader());
597: } catch (ConfigurationException cex) {
598: // should not happen
599: fail("Exception was thrown: " + cex);
600: }
601: }
602:
603: /**
604: * Writes the layout's data into a string.
605: *
606: * @return the layout file's content as string
607: * @throws ConfigurationException if an error occurs
608: */
609: private String getLayoutString() throws ConfigurationException {
610: StringWriter out = new StringWriter();
611: layout.save(out);
612: return out.toString();
613: }
614:
615: /**
616: * Checks if the layout's output is correct.
617: *
618: * @param expected the expected result
619: * @throws ConfigurationException if an error occurs
620: */
621: private void checkLayoutString(String expected)
622: throws ConfigurationException {
623: assertEquals("Wrong layout file content", expected,
624: getLayoutString());
625: }
626:
627: /**
628: * A helper class used for constructing test properties files.
629: */
630: static class PropertiesBuilder {
631: /** A buffer for storing the data. */
632: private StringBuffer buf = new StringBuffer();
633:
634: /** A counter for varying the comment character. */
635: private int commentCounter;
636:
637: /**
638: * Adds a property to the simulated file.
639: *
640: * @param key the property key
641: * @param value the value
642: */
643: public void addProperty(String key, String value) {
644: buf.append(key).append(" = ").append(value).append(CR);
645: }
646:
647: /**
648: * Adds a comment line.
649: *
650: * @param s the comment (can be <b>null</b>, then a blanc line is
651: * added)
652: */
653: public void addComment(String s) {
654: if (s != null) {
655: if (commentCounter % 2 == 0) {
656: buf.append("# ");
657: } else {
658: buf.append("! ");
659: }
660: buf.append(s);
661: }
662: buf.append(CR);
663: }
664:
665: /**
666: * Returns a reader for the simulated properties.
667: *
668: * @return a reader
669: */
670: public Reader getReader() {
671: return new StringReader(buf.toString());
672: }
673:
674: /**
675: * Returns a string representation of the buffer's content.
676: *
677: * @return the buffer as string
678: */
679: public String toString() {
680: return buf.toString();
681: }
682: }
683:
684: /**
685: * A mock properties configuration implementation that is used to check
686: * whether some expected methods are called.
687: */
688: static class LayoutTestConfiguration extends
689: PropertiesConfiguration {
690: /** Stores a builder object. */
691: public PropertiesBuilder builder;
692:
693: /**
694: * Simulates the propertyLoaded() callback. If a builder was set, a
695: * load() call on the layout is invoked.
696: */
697: boolean propertyLoaded(String key, String value)
698: throws ConfigurationException {
699: if (builder == null) {
700: return super .propertyLoaded(key, value);
701: } else {
702: if (PropertiesConfiguration.getInclude().equals(key)) {
703: getLayout().load(builder.getReader());
704: return false;
705: } else {
706: return true;
707: }
708: }
709: }
710: }
711: }
|