001/* $Id: LocationTrackerTestCase.java 1125368 2011-05-20 13:06:27Z simonetripodi $ 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.commons.digester3; 020 021import static org.apache.commons.digester3.binder.DigesterLoader.newLoader; 022 023import static org.junit.Assert.assertEquals; 024import static org.junit.Assert.assertNotNull; 025 026import java.io.StringReader; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031import org.apache.commons.digester3.Digester; 032import org.apache.commons.digester3.StackAction; 033import org.apache.commons.digester3.binder.AbstractRulesModule; 034import org.junit.Test; 035import org.xml.sax.Locator; 036 037/** 038 * Tests that StackAction can be used to track the source location of objects created from input xml stream. 039 */ 040 041public class LocationTrackerTestCase 042{ 043 044 private static class LocationTracker 045 implements StackAction 046 { 047 public Map<Object, String> locations = new HashMap<Object, String>(); 048 049 public <T> T onPush( Digester d, String stackName, T o ) 050 { 051 if ( stackName == null ) 052 { 053 // we only care about the real object stack 054 055 // note that a Locator object can also provide 056 // publicId and systemId info. 057 Locator l = d.getDocumentLocator(); 058 StringBuilder locn = new StringBuilder(); 059 locn.append( "line=" ); 060 locn.append( l.getLineNumber() ); 061 locations.put( o, locn.toString() ); 062 } 063 return o; 064 } 065 066 public <T> T onPop( Digester d, String stackName, T o ) 067 { 068 return o; 069 } 070 } 071 072 @Test 073 public void testAll() 074 throws Exception 075 { 076 final String TEST_XML = 077 "<?xml version='1.0'?>\n" + "<box id='root'>\n" + " <subBox id='box1'/>\n" + " <ignoreme/>\n" 078 + " <subBox id='box2'/> <subBox id='box3'/>\n" + "</box>"; 079 080 LocationTracker locnTracker = new LocationTracker(); 081 082 Digester digester = newLoader( new AbstractRulesModule() 083 { 084 085 @Override 086 protected void configure() 087 { 088 forPattern( "box" ).createObject().ofType( Box.class ) 089 .then() 090 .setProperties(); 091 forPattern( "box/subBox" ).createObject().ofType( Box.class ) 092 .then() 093 .setProperties() 094 .then() 095 .setNext( "addChild" ); 096 } 097 098 }) 099 .setStackAction( locnTracker ) 100 .newDigester(); 101 102 Box root = digester.parse( new StringReader( TEST_XML ) ); 103 assertNotNull( root ); 104 List<Box> children = root.getChildren(); 105 assertEquals( 3, children.size() ); 106 Box box1 = children.get( 0 ); 107 Box box2 = children.get( 1 ); 108 Box box3 = children.get( 2 ); 109 110 assertEquals( "line=2", locnTracker.locations.get( root ) ); 111 assertEquals( "line=3", locnTracker.locations.get( box1 ) ); 112 assertEquals( "line=5", locnTracker.locations.get( box2 ) ); 113 assertEquals( "line=5", locnTracker.locations.get( box3 ) ); 114 } 115}