All Downloads are FREE. Search and download functionalities are using the official Maven repository.

metridoc.sushi.client.SushiResponseParser.groovy Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010 Trustees of the University of Pennsylvania Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 * http://www.osedu.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package metridoc.sushi.client


import groovy.xml.XmlUtil;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

import org.apache.commons.lang.StringEscapeUtils;
import org.codehaus.staxmate.dom.DOMConverter;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
/**
 * 
 * @author Narine Ghochikyan
 *
 */
public class SushiResponseParser{

	private static final Logger LOG = LoggerFactory.getLogger(SushiResponseParser.class);

	public enum SushiFields {
		PLATFORM, PUBLISHER, ISSN, ISBN, PRINT_ISSN,
		ONLINE_ISSN, PRINT_ISBN, ONLINE_ISBN, NAME, DATATYPE
	}

	def currentItem = null;
	def performanceIndex = getInitialPerformanceIndex();
	def outputStream;

	private static final String inputDatePattern = "yyyy-MM-dd";
	private static final DateTimeFormatter inputDateFormatter = DateTimeFormat.forPattern(inputDatePattern)
	private static final DateTimeFormatter outputDateFormatter = DateTimeFormat.forPattern("yyyy-MMM")
	def DateTime beginDate = null;
	def DateTime endDate = null;

	private DOMConverter domConverter = new DOMConverter();

	public boolean process(inputStream){
		use (StaxCategory) { processStream(inputStream) }
	}

	private boolean processStream(inputStream){
		def reader
		try {
			reader = XMLInputFactory.newInstance()
					.createXMLStreamReader(inputStream)

			while (reader.hasNext()) {
				if (reader.startElement){
					processStartElement(reader)
				}
				reader.next()
			}
			startNewItem()
		} finally {
			reader?.close()
		}
	}

	private void processStartElement(element) {
		switch(element.name()) {
			case 'ReportItems':
				startNewItem()
				break
			case 'ItemPlatform':
				currentItem[SushiFields.PLATFORM.ordinal()] = prepareValue(element.text())
				break
			case 'ItemPublisher':
				currentItem[SushiFields.PUBLISHER.ordinal()] = prepareValue(element.text())
				break
			case 'ItemIdentifier':
				processItemIdentifier(domConverter.buildDocument(element).getDocumentElement());
				break
			case 'ItemName':
				currentItem[SushiFields.NAME.ordinal()] = prepareValue(element.text())
				break
			case 'ItemDataType':
				currentItem[SushiFields.DATATYPE.ordinal()] = prepareValue(element.text())
				break
			case 'ItemPerformance':
				processItemPerformance(domConverter.buildDocument(element).getDocumentElement())
				break

			case 'UsageDateRange':
				processUsageDateRange(domConverter.buildDocument(element).getDocumentElement())
				break

			case 'Exception':
				processException(domConverter.buildDocument(element).getDocumentElement())
				break
		}
	}

	private void startNewItem(){
		if(currentItem != null){
			writeItem(currentItem)
		}else{
			writeHeader();
		}
		performanceIndex = getInitialPerformanceIndex();
		currentItem = []
	}

	private getInitialPerformanceIndex(){
		return SushiFields.values().size() - 1;
	}

	private void writeHeader(){
		String header = SushiFields.values().join(',')

		if(beginDate != null && endDate != null){
			DateTime dateTime = beginDate;
			while(dateTime.compareTo(endDate) < 0){
				header += ", " + outputDateFormatter.print(dateTime);
				dateTime = dateTime.plusMonths(1)
			}
		}
		writeLine(header)
	}

	private void writeItem(item){
		writeLine(item.join(','))
	}
	private String prepareValue(String value){
		return StringEscapeUtils.escapeCsv(value)
	}

	private void writeLine(String data){
		def line = data  + "\n"
		if(outputStream != null){
			outputStream.write(line.bytes)
		}else{
			println line
		}
	}
	private void processItemPerformance(Element performanceElement){
		String metricType = performanceElement.getElementsByTagNameNS("*", "MetricType").item(0).getTextContent()
		if("ft_total".equals(metricType)){
			performanceIndex++
			currentItem[performanceIndex] = performanceElement.getElementsByTagNameNS("*", "Count").item(0).getTextContent()
		}
	}

	private void processUsageDateRange(Element dateRangeElement){
		String dateStr = getDateString(dateRangeElement, "Begin");
		beginDate = inputDateFormatter.parseDateTime (dateStr)
		dateStr = getDateString(dateRangeElement, "End");
		endDate = inputDateFormatter.parseDateTime (dateStr)
	}

	private String getDateString(Element dateRangeElement, String tagName){
		String dateStr = dateRangeElement.getElementsByTagNameNS("*", tagName).item(0).getTextContent()
		if(dateStr.length() > inputDatePattern.length()){
			dateStr = dateStr.substring (0, inputDatePattern.length());
		}
		return dateStr;
	}

	private void processItemIdentifier(Element itemIdentifier){
		String itemIdentifierType =  itemIdentifier.getElementsByTagNameNS("*", "Type").item(0).getTextContent()
		String itemIdentifierValue =  itemIdentifier.getElementsByTagNameNS("*", "Value").item(0).getTextContent()
		try{
			SushiFields field = SushiFields.valueOf(itemIdentifierType.toUpperCase())
			if(field != null){
				currentItem[field.ordinal()] = prepareValue(itemIdentifierValue)
			}
		}catch(IllegalArgumentException ex){
			LOG.warn "Skipping unknown type of itemIdentifier: " + itemIdentifierType + ".";
		}
	}

	private void processException(Element exceptionElement){
		String exceptionString = XmlUtil.serialize(exceptionElement)
		throw new RuntimeException("Returned response contains exception: \n\n" + exceptionString);
	}
	static class StaxCategory {
		static Object get(XMLStreamReader self, String key) {
			return self.getAttributeValue(null, key)
		}
		static String name(XMLStreamReader self) {
			return self.name.localPart//toString()
		}
		static String text(XMLStreamReader self) {
			return self.elementText
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy