/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package org.ebayopensource.turmeric.eclipse.typelibrary.utils;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.ebayopensource.turmeric.eclipse.typelibrary.exception.ImportTypeException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Extract type definitions from XSD file.
*
* @author mzang
*
*/
enum SchemaProcessStage {
/**
*
*/
NotStart, Processing, Processed
}
/**
* The Class SAXParserForTypesInWSDL.
*/
public class SAXParserForTypesInWSDL extends DefaultHandler {
private static String DEF_NODE = "definitions";
private static String TYPE_NODE = "types";
private static String SCHEMA_NODE = "schema";
private static String XMLNS = "xmlns";
private List<String> nodePath = new ArrayList<String>();
private StringBuffer xsd = null;
private List<StringBuffer> xsdContents = new ArrayList<StringBuffer>();
private SchemaProcessStage status = SchemaProcessStage.NotStart;
private StringBuffer attrInWSDL = new StringBuffer();
/**
* Gets the type defs from wsdl.
*
* @param wsdlPath the wsdl path
* @return the type defs from wsdl
* @throws ImportTypeException the import type exception
*/
public List<StringBuffer> getTypeDefsFromWSDL(String wsdlPath) throws ImportTypeException {
InputStream stream;
try {
stream = new FileInputStream(wsdlPath);
SAXParserFactory saxfac = SAXParserFactory.newInstance();
SAXParser saxParser = saxfac.newSAXParser();
saxParser.parse(stream, this);
if (xsd != null) {
xsdContents.add(xsd);
}
} catch (Exception e) {
throw new ImportTypeException("Exception happens when parsing WSDL:", e);
}
return xsdContents;
}
private static String getNodeName(String qName) {
int index = qName.indexOf(':');
if (index > -1) {
qName = qName.substring(index + 1);
}
return qName;
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (status == SchemaProcessStage.Processing) {
appendXSD(new String(ch, start, length));
}
super.characters(ch, start, length);
}
/* (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 {
boolean isSchemaNode = isSchemaNode();
nodePath.remove(nodePath.size() - 1);
if (status == SchemaProcessStage.Processing) {
appendXSD("</" + qName + ">");
}
if (isSchemaNode == true) {
status = SchemaProcessStage.Processed;
}
}
private boolean isWSDLDefNode() {
if (nodePath.size() == 1) {
return DEF_NODE.equals(getNodeName(nodePath.get(0)));
}
return false;
}
private boolean isSchemaNode() {
if (nodePath.size() == 3) {
return DEF_NODE.equals(getNodeName(nodePath.get(0)))
&& TYPE_NODE.equals(getNodeName(nodePath.get(1)))
&& SCHEMA_NODE.equals(getNodeName(nodePath.get(2)));
}
return false;
}
/* (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 attributes) throws SAXException {
nodePath.add(qName);
boolean inDefStart = isWSDLDefNode();
boolean inSchema = isSchemaNode();
if (inSchema == true) {
status = SchemaProcessStage.Processing;
if (xsd != null) {
xsdContents.add(xsd);
}
xsd = new StringBuffer(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
}
if (status == SchemaProcessStage.Processing) {
appendXSD("<" + qName + "");
}
for (int index = 0; index < attributes.getLength(); index++) {
String attrName = attributes.getQName(index);
if (inDefStart) {
if (attrName.toLowerCase().contains(XMLNS)) {
attrInWSDL.append(" " + attrName + "=\""
+ attributes.getValue(index) + "\" ");
}
} else if (inSchema) {
appendXSD(" " + attrName + "=\"" + attributes.getValue(index)
+ "\" ");
} else if (status == SchemaProcessStage.Processing) {
appendXSD(" " + attrName + "=\"" + attributes.getValue(index)
+ "\" ");
}
}
if (inSchema == true && attrInWSDL != null) {
appendXSD(attrInWSDL.toString());
appendXSD(">");
}
if ((inSchema == false) && status == SchemaProcessStage.Processing) {
appendXSD(">");
}
}
private void appendXSD(String content) {
if (status == SchemaProcessStage.Processing) {
xsd.append(content);
}
}
}