/* * CCVisu is a tool for visual graph clustering * and general force-directed graph layout. * This file is part of CCVisu. * * Copyright (C) 2005-2012 Dirk Beyer * * CCVisu is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * CCVisu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CCVisu; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Please find the GNU Lesser General Public License in file * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt * * Dirk Beyer (firstname.lastname@uni-passau.de) * University of Passau, Bavaria, Germany */ package org.sosy_lab.ccvisu.readers; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.sosy_lab.ccvisu.graph.Relation; import org.sosy_lab.ccvisu.graph.Tuple; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXHandlerDOXIndex extends DefaultHandler { // COMPOUND kind values: class, struct, union, interface, protocol, category, // exception, file, namespace, group, page, example, dir // MEMBER kind values: define, property, event, variable, typedef, // enum, enumvalue, function, signal, prototype, // friend, dcop, slot private enum TagType { UNKNOWN, COMPOUND, MEMBER }; private class Entry { private int level = 1; private String kind = ""; private String id = ""; private String name = ""; Entry(int level, String kind, String id) { assert (level > 0); this.level = level; this.kind = kind; this.id = id; } } private int xmlLevel = 0; private TagType detectingNameOfTagType = TagType.UNKNOWN; private Entry currentCompound = new Entry(1, "", ""); private Entry currentMember = new Entry(1, "", ""); private List<String> xmlFileIds = new ArrayList<String>(); private Relation relations; public SAXHandlerDOXIndex(Relation relations) { super(); this.relations = relations; } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ @Override public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { xmlLevel++; detectingNameOfTagType = TagType.UNKNOWN; if (qName.toLowerCase().equals("compound") || qName.toLowerCase().equals("member")) { // COMPOUND and MEMBER assert (attrs != null); String id = attrs.getValue("refid"); assert (id != null); String kind = attrs.getValue("kind"); assert (kind != null); if (qName.toLowerCase().equals("compound")) { currentCompound = new Entry(xmlLevel, kind, id); } else { currentMember = new Entry(xmlLevel, kind, id); } } else if (qName.toLowerCase().equals("name")) { // NAME if (xmlLevel == currentCompound.level + 1) { detectingNameOfTagType = TagType.COMPOUND; } else { assert (xmlLevel == currentCompound.level + 2); assert (xmlLevel == currentMember.level + 1); detectingNameOfTagType = TagType.MEMBER; } } else if (qName.toLowerCase().equals("doxygenindex")) { // DOXYGENINDEX // Not needed. } else { assert (false); } } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { detectingNameOfTagType = TagType.UNKNOWN; if (qName.toLowerCase().equals("compound")) { // COMPOUND assert (xmlLevel == currentCompound.level); if (currentCompound.name.equals("")) { System.err.println("Runtime Error: No name found for compound " + currentCompound.id + "."); System.exit(1); } List<String> tuple = new ArrayList<String>(); tuple.add(currentCompound.kind); tuple.add(currentCompound.id); tuple.add(currentCompound.name); relations.addTuple(new Tuple("COMPOUND", tuple)); } else if (qName.toLowerCase().equals("member")) { // MEMBER assert (xmlLevel == currentCompound.level + 1); assert (xmlLevel == currentMember.level); if (currentMember.name.equals("")) { System.err.println("Runtime Error: No name found for member " + currentMember.id + "."); System.exit(1); } { List<String> newTuple = new ArrayList<String>(3); newTuple.add(currentMember.kind); newTuple.add(currentMember.id); newTuple.add(currentCompound.name + "." + currentMember.name); relations.addTuple(new Tuple("MEMBER", newTuple)); } { List<String> newTuple = new ArrayList<String>(2); newTuple.add(currentMember.id); newTuple.add(currentCompound.id); relations.addTuple(new Tuple("CONTAINEDIN", newTuple)); } } xmlLevel--; } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */ @Override public void characters(char[] ch, int start, int len) throws SAXException { String name = new String(ch, start, len); if (name.trim().equals("")) { return; } if (detectingNameOfTagType == TagType.COMPOUND) { // COMPOUND name xmlFileIds.add(currentCompound.id); // Concatenate the two strings (e.g. "MyClass<T" + ">"). currentCompound.name += name; } else if (detectingNameOfTagType == TagType.MEMBER) { // MEMBER name // Concatenate the two strings (e.g. "operator" + "<="). currentMember.name += name; } } /** * @return list of file names to process. */ public List<String> getXmlFileIds() { return Collections.unmodifiableList(xmlFileIds); } }