/* LanguageTool, a natural language style checker
* Copyright (C) 2014 Daniel Naber (http://www.danielnaber.de)
*
* This library 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.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package org.languagetool.dev;
import org.languagetool.Language;
import org.languagetool.Languages;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.XMLEvent;
import java.io.InputStream;
import java.util.*;
/**
* Internal tool to count XML elements and attributes used in our grammar XML files.
* @since 2.6
*/
class XmlUsageCounter {
private final Map<String,Integer> map = new HashMap<>();
private void countElementsAndAttributes(InputStream in) throws XMLStreamException {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
String elementName = event.asStartElement().getName().getLocalPart();
add(elementName);
Iterator attributes = event.asStartElement().getAttributes();
while (attributes.hasNext()) {
Attribute att = (Attribute) attributes.next();
add(elementName + "/" + att.getName());
}
}
}
}
private void add(String name) {
if (map.containsKey(name)) {
int oldCount = map.get(name);
map.put(name, oldCount+1);
} else {
map.put(name, 1);
}
}
private void printResult() {
List<ElemCount> elemCounts = new ArrayList<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
elemCounts.add(new ElemCount(entry.getKey(), entry.getValue()));
}
Collections.sort(elemCounts, (ec1, ec2) -> ec2.count - ec1.count);
for (ElemCount elemCount : elemCounts) {
System.out.println(elemCount.count + " " + elemCount.elem);
}
}
public static void main(String[] args) throws XMLStreamException {
XmlUsageCounter counter = new XmlUsageCounter();
Set<String> countedFiles = new HashSet<>();
for (Language language : Languages.get()) {
List<String> ruleFileNames = language.getRuleFileNames();
//comment in this to count disambiguation files instead:
//List<String> ruleFileNames = Collections.singletonList(ResourceDataBroker.RESOURCE_DIR + "/" +
// language.getShortCode() + "/" + "disambiguation.xml");
for (String ruleFileName : ruleFileNames) {
if (countedFiles.contains(ruleFileName)) {
continue;
}
System.err.println("Counting elements for " + ruleFileName);
InputStream ruleStream = XmlUsageCounter.class.getResourceAsStream(ruleFileName);
if (ruleStream == null) {
System.err.println("Not found, ignoring: " + ruleFileName);
continue;
}
counter.countElementsAndAttributes(ruleStream);
countedFiles.add(ruleFileName);
}
}
counter.printResult();
}
static class ElemCount {
String elem;
Integer count;
ElemCount(String elem, Integer count) {
this.elem = elem;
this.count = count;
}
}
}