001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: */
024:
025: package it.businesslogic.ireport.compiler.xml;
026:
027: import it.businesslogic.ireport.util.*;
028: import java.util.HashMap;
029: import java.util.LinkedList;
030: import java.util.Map;
031:
032: import net.sf.jasperreports.engine.xml.JRXmlDigester;
033:
034: import org.apache.commons.digester.FactoryCreateRule;
035: import org.xml.sax.Attributes;
036: import org.xml.sax.Locator;
037: import org.xml.sax.SAXException;
038: import org.xml.sax.XMLReader;
039:
040: /**
041: * @author Lucian Chirita (lucianc@users.sourceforge.net)
042: * @version $Id: SourceTraceDigester.java 22 2007-03-08 15:18:26Z lucianc $
043: */
044: public class SourceTraceDigester extends JRXmlDigester {
045:
046: private final Map sourceLocations = new HashMap();
047:
048: protected static class ElementStack {
049: protected static class ElementInfo {
050: private String path;
051: private final Map childrenCounts = new HashMap();
052:
053: public int addChild(String name) {
054: Integer last = (Integer) childrenCounts.get(name);
055: int position = last == null ? 1 : (last.intValue() + 1);
056: childrenCounts.put(name, new Integer(position));
057: return position;
058: }
059:
060: public String getPath() {
061: return path;
062: }
063:
064: public void setPath(String path) {
065: this .path = path;
066: }
067: }
068:
069: private final LinkedList infoStack = new LinkedList();
070:
071: public void pushElement(String elementName) {
072: String currentPath;
073: if (infoStack.isEmpty()) {
074: currentPath = "/" + elementName;
075: } else {
076: ElementInfo parentInfo = (ElementInfo) infoStack
077: .getFirst();
078: int position = parentInfo.addChild(elementName);
079: currentPath = parentInfo.getPath() + "/" + elementName
080: + "[" + position + "]";
081: }
082:
083: ElementInfo info = new ElementInfo();
084: info.setPath(currentPath);
085:
086: infoStack.addFirst(info);
087: }
088:
089: public void popElement() {
090: infoStack.removeFirst();
091: }
092:
093: public String getCurrentPath() {
094: ElementInfo info = (ElementInfo) infoStack.getFirst();
095: return info.getPath();
096: }
097: }
098:
099: private final ElementStack elementStack = new ElementStack();
100:
101: public SourceTraceDigester() {
102: super ();
103: }
104:
105: public SourceTraceDigester(XMLReader xmlReader) {
106: super (xmlReader);
107: }
108:
109: public void addFactoryCreate(String pattern, Class clazz) {
110: addRule(pattern, new SourceTraceFactoryCreateRule(clazz));
111: }
112:
113: public void addFactoryCreate(String pattern, String className) {
114: addRule(pattern, new SourceTraceFactoryCreateRule(className));
115: }
116:
117: public void addFactoryCreate(String pattern, Class clazz,
118: String attributeName) {
119: addRule(pattern, new SourceTraceFactoryCreateRule(clazz,
120: attributeName));
121: }
122:
123: public void addFactoryCreate(String pattern, String className,
124: String attributeName) {
125: addRule(pattern, new SourceTraceFactoryCreateRule(className,
126: attributeName));
127: }
128:
129: public SourceLocation getLocation(Object instance) {
130: return (SourceLocation) sourceLocations.get(instance);
131: }
132:
133: public void startElement(String namespaceURI, String localName,
134: String qName, Attributes list) throws SAXException {
135: String name = localName != null && localName.length() > 0 ? localName
136: : qName;
137: elementStack.pushElement(name);
138:
139: super .startElement(namespaceURI, localName, qName, list);
140: }
141:
142: public void endElement(String namespaceURI, String localName,
143: String qName) throws SAXException {
144: super .endElement(namespaceURI, localName, qName);
145:
146: elementStack.popElement();
147: }
148:
149: protected void objectCreated() {
150: Object instance = peek();
151: if (instance != null && !sourceLocations.containsKey(instance)) {
152: SourceLocation location = currentLocation();
153: sourceLocations.put(instance, location);
154: }
155: }
156:
157: protected SourceLocation currentLocation() {
158: Locator documentLocator = getDocumentLocator();
159: SourceLocation location = new SourceLocation();
160: location.setLineNumber(documentLocator.getLineNumber());
161: location.setColumnNumber(documentLocator.getColumnNumber());
162: location.setXPath(elementStack.getCurrentPath());
163: return location;
164: }
165:
166: protected class SourceTraceFactoryCreateRule extends
167: FactoryCreateRule {
168:
169: public SourceTraceFactoryCreateRule(Class clazz) {
170: super (clazz, false);
171: }
172:
173: public SourceTraceFactoryCreateRule(String className) {
174: super (className, false);
175: }
176:
177: public SourceTraceFactoryCreateRule(Class clazz,
178: String attributeName) {
179: super (clazz, attributeName, false);
180: }
181:
182: public SourceTraceFactoryCreateRule(String className,
183: String attributeName) {
184: super (className, attributeName, false);
185: }
186:
187: public void begin(String namespace, String name,
188: Attributes attributes) throws Exception {
189: super.begin(namespace, name, attributes);
190:
191: objectCreated();
192: }
193:
194: }
195: }
|