/*******************************************************************************
* Copyright (c) 2008 Pierre-Antoine Grégoire.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre-Antoine Grégoire - initial API and implementation
*******************************************************************************/
package org.org.eclipse.cheatsheet.catalog.internal.xml;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCatalog;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCatalogReference;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCatalogReferenceType;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCategory;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetReference;
import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetReferenceType;
import org.org.eclipse.cheatsheet.catalog.internal.model.Tags;
import org.org.model.IModelItem;
import org.org.model.IModelItemVisitor;
public class StaxXmlCatalogBinder implements IXmlCatalogBinder {
public class CheatSheetReferenceCreationVisitor implements IModelItemVisitor {
private XMLEventWriter parser;
private XMLEventFactory eventFactory;
private XMLStreamException occuredException;
public CheatSheetReferenceCreationVisitor(XMLEventWriter parser, XMLEventFactory eventFactory) {
this.parser = parser;
this.eventFactory = eventFactory;
}
@SuppressWarnings("rawtypes")
public boolean visit(IModelItem modelItem) {
boolean keepOnVisiting = true;
if (modelItem instanceof CheatSheetReference) {
CheatSheetReference cheatSheetReference = (CheatSheetReference) modelItem;
Set<Attribute> attributes = new LinkedHashSet<Attribute>();
attributes.add(eventFactory.createAttribute(new QName(ID), cheatSheetReference.getId()));
attributes.add(eventFactory.createAttribute(new QName(NAME), cheatSheetReference.getName()));
if (cheatSheetReference.getDescription() != null) {
attributes.add(eventFactory.createAttribute(new QName(DESCRIPTION), cheatSheetReference.getDescription()));
}
attributes.add(eventFactory.createAttribute(new QName(TYPE), cheatSheetReference.getType().name()));
attributes.add(eventFactory.createAttribute(new QName(URL), cheatSheetReference.getUrl()));
attributes.add(eventFactory.createAttribute(new QName(CATEGORY), cheatSheetReference.getParent().getName()));
attributes.add(eventFactory.createAttribute(new QName(TAGS), cheatSheetReference.getTags().getTagsString()));
try {
parser.add(eventFactory.createStartElement(new QName(CHEATSHEET_REFERENCE), attributes.iterator(), null));
parser.add(eventFactory.createEndElement(new QName(CHEATSHEET_REFERENCE), null));
} catch (XMLStreamException e) {
this.occuredException = e;
}
}
return keepOnVisiting;
}
public XMLStreamException getOccuredException() {
return occuredException;
}
}
public CheatSheetCatalog parseXmlCatalog(InputStream inputStream) {
CheatSheetCatalog result = null;
XMLInputFactory factory = XMLInputFactory.newInstance();
try {
XMLEventReader parser = factory.createXMLEventReader(inputStream);
Map<String, CheatSheetCategory> registeredCategories = new HashMap<String, CheatSheetCategory>();
while (true) {
XMLEvent event = parser.nextEvent();
if (event.isEndDocument()) {
parser.close();
break;
}
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
if (startElement.getName().getLocalPart().equals(CHEATSHEET_CATALOG)) {
String name = null;
String provider = null;
String description = null;
String type = null;
String url = null;
for (Iterator<?> it = startElement.getAttributes(); it.hasNext();) {
Attribute attribute = (Attribute) it.next();
name = name == null ? getAttributeValue(NAME, attribute) : name;
provider = provider == null ? getAttributeValue(PROVIDER, attribute) : provider;
description = description == null ? getAttributeValue(DESCRIPTION, attribute) : description;
type = type == null ? getAttributeValue(TYPE, attribute) : type;
url = url == null ? getAttributeValue(URL, attribute) : url;
}
result = new CheatSheetCatalog(name, provider);
CheatSheetCatalogReferenceType cheatSheetCatalogReferenceType = type == null ? null : CheatSheetCatalogReferenceType.valueOf(type);
if (cheatSheetCatalogReferenceType != null && url != null) {
result.setReference(new CheatSheetCatalogReference(cheatSheetCatalogReferenceType, url));
}
result.setDescription(description);
continue;
}
if (startElement.getName().getLocalPart().equals(CHEATSHEET_REFERENCE)) {
String id = null;
String name = null;
String url = null;
String category = null;
String[] tags = null;
String description = null;
String type = null;
for (Iterator<?> it = startElement.getAttributes(); it.hasNext();) {
Attribute attribute = (Attribute) it.next();
id = id == null ? getAttributeValue(ID, attribute) : id;
name = name == null ? getAttributeValue(NAME, attribute) : name;
description = description == null ? getAttributeValue(DESCRIPTION, attribute) : description;
url = url == null ? getAttributeValue(URL, attribute) : url;
type = type == null ? getAttributeValue(TYPE, attribute) : type;
category = category == null ? getAttributeValue(CATEGORY, attribute) : category;
if (tags == null) {
String tagsString = getAttributeValue(TAGS, attribute);
tags = tagsString == null ? null : tagsString.split(",");
}
}
CheatSheetCategory cheatSheetCategory = null;
if (registeredCategories.containsKey(category)) {
cheatSheetCategory = registeredCategories.get(category);
} else {
cheatSheetCategory = new CheatSheetCategory(category);
registeredCategories.put(cheatSheetCategory.getName(), cheatSheetCategory);
}
CheatSheetReferenceType cheatSheetReferenceType = type == null ? null : CheatSheetReferenceType.valueOf(type);
CheatSheetReference cheatSheetReference = null;
if (cheatSheetReferenceType != null && url != null) {
cheatSheetReference = new CheatSheetReference(cheatSheetReferenceType, id, name, url, new Tags(tags));
} else {
if (url.startsWith("http")) {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.HTTP, id, name, url, new Tags(tags));
} else if (url.startsWith("platform")) {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.PLATFORM, id, name, url, new Tags(tags));
} else {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.FILE_SYSTEM, id, name, url, new Tags(tags));
}
}
cheatSheetReference.setDescription(description);
if (!result.hasChild(cheatSheetCategory.getUID())) {
cheatSheetCategory.addChild(cheatSheetReference);
result.addChild(cheatSheetCategory);
} else {
result.getChild(cheatSheetCategory.getUID()).addChild(cheatSheetReference);
cheatSheetCategory = null;
}
continue;
}
}
}
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
private String getAttributeValue(String attributeName, Attribute attribute) {
String result = null;
if (attribute.getName().getLocalPart().equals(attributeName)) {
result = attribute.getValue();
}
return result;
}
public CheatSheetCatalog parseXmlCatalog(String inputString) {
InputStream inputStream = new ByteArrayInputStream(inputString.getBytes());
return parseXmlCatalog(inputStream);
}
public String toXmlCatalog(CheatSheetCatalog cheatSheetCatalog) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
toXmlCatalog(cheatSheetCatalog, outputStream);
return new String(outputStream.toByteArray());
}
public void toXmlCatalog(CheatSheetCatalog cheatSheetCatalog, OutputStream outputStream) {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
try {
XMLEventWriter parser = factory.createXMLEventWriter(outputStream);
parser.add(eventFactory.createStartDocument(UTF_8, XML_VERSION_1_0));
parser.add(eventFactory.createIgnorableSpace("\n"));
createCatalog(cheatSheetCatalog, eventFactory, parser);
parser.add(eventFactory.createEndDocument());
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
private void createCatalog(CheatSheetCatalog cheatSheetCatalog, XMLEventFactory eventFactory, XMLEventWriter parser) throws XMLStreamException {
Set<Attribute> attributes = new LinkedHashSet<Attribute>();
attributes.add(eventFactory.createAttribute(new QName(NAME), cheatSheetCatalog.getName()));
attributes.add(eventFactory.createAttribute(new QName(PROVIDER), cheatSheetCatalog.getProvider()));
if (cheatSheetCatalog.getReference() != null) {
attributes.add(eventFactory.createAttribute(new QName(TYPE), cheatSheetCatalog.getReference().getReferenceType().name()));
attributes.add(eventFactory.createAttribute(new QName(URL), cheatSheetCatalog.getReference().getUri()));
}
parser.add(eventFactory.createStartElement(new QName(CHEATSHEET_CATALOG), attributes.iterator(), null));
IModelItemVisitor cheatsheetReferenceCreationVisitor = new CheatSheetReferenceCreationVisitor(parser, eventFactory);
cheatSheetCatalog.accept(cheatsheetReferenceCreationVisitor);
parser.add(eventFactory.createEndElement(new QName(CHEATSHEET_CATALOG), null));
}
public List<CheatSheetCatalog> parseXmlCatalogs(InputStream inputStream) {
List<CheatSheetCatalog> result = new ArrayList<CheatSheetCatalog>();
XMLInputFactory factory = XMLInputFactory.newInstance();
CheatSheetCatalog tmpCatalog = null;
try {
XMLEventReader parser = factory.createXMLEventReader(inputStream);
Map<String, CheatSheetCategory> registeredCategories = new HashMap<String, CheatSheetCategory>();
while (true) {
XMLEvent event = parser.nextEvent();
if (event.isEndDocument()) {
parser.close();
break;
}
if (event.isEndElement()) {
EndElement startElement = event.asEndElement();
if (startElement.getName().getLocalPart().equals(CHEATSHEET_CATALOG)) {
result.add(tmpCatalog);
}
}
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
if (startElement.getName().getLocalPart().equals(CHEATSHEET_CATALOG)) {
String name = null;
String provider = null;
String description = null;
String type = null;
String url = null;
for (Iterator<?> it = startElement.getAttributes(); it.hasNext();) {
Attribute attribute = (Attribute) it.next();
name = name == null ? getAttributeValue(NAME, attribute) : name;
provider = provider == null ? getAttributeValue(PROVIDER, attribute) : provider;
description = description == null ? getAttributeValue(DESCRIPTION, attribute) : description;
type = type == null ? getAttributeValue(TYPE, attribute) : type;
url = url == null ? getAttributeValue(URL, attribute) : url;
}
tmpCatalog = new CheatSheetCatalog(name, provider);
CheatSheetCatalogReferenceType cheatSheetCatalogReferenceType = type == null ? null : CheatSheetCatalogReferenceType.valueOf(type);
if (cheatSheetCatalogReferenceType != null && url != null) {
tmpCatalog.setReference(new CheatSheetCatalogReference(cheatSheetCatalogReferenceType, url));
}
tmpCatalog.setDescription(description);
continue;
}
if (startElement.getName().getLocalPart().equals(CHEATSHEET_REFERENCE)) {
String id = null;
String name = null;
String url = null;
String category = null;
String[] tags = null;
String description = null;
String type = null;
for (Iterator<?> it = startElement.getAttributes(); it.hasNext();) {
Attribute attribute = (Attribute) it.next();
id = id == null ? getAttributeValue(ID, attribute) : id;
name = name == null ? getAttributeValue(NAME, attribute) : name;
description = description == null ? getAttributeValue(DESCRIPTION, attribute) : description;
url = url == null ? getAttributeValue(URL, attribute) : url;
type = type == null ? getAttributeValue(TYPE, attribute) : type;
category = category == null ? getAttributeValue(CATEGORY, attribute) : category;
if (tags == null) {
String tagsString = getAttributeValue(TAGS, attribute);
tags = tagsString == null ? null : tagsString.split(",");
}
}
CheatSheetCategory cheatSheetCategory = null;
if (registeredCategories.containsKey(category)) {
cheatSheetCategory = registeredCategories.get(category);
} else {
cheatSheetCategory = new CheatSheetCategory(category);
registeredCategories.put(cheatSheetCategory.getName(), cheatSheetCategory);
}
CheatSheetReferenceType cheatSheetReferenceType = type == null ? null : CheatSheetReferenceType.valueOf(type);
CheatSheetReference cheatSheetReference = null;
if (cheatSheetReferenceType != null && url != null) {
cheatSheetReference = new CheatSheetReference(cheatSheetReferenceType, id, name, url, new Tags(tags));
} else {
if (url.startsWith("http")) {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.HTTP, id, name, url, new Tags(tags));
} else if (url.startsWith("platform")) {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.PLATFORM, id, name, url, new Tags(tags));
} else {
cheatSheetReference = new CheatSheetReference(CheatSheetReferenceType.FILE_SYSTEM, id, name, url, new Tags(tags));
}
}
cheatSheetReference.setDescription(description);
if (!tmpCatalog.hasChild(cheatSheetCategory.getUID())) {
cheatSheetCategory.addChild(cheatSheetReference);
tmpCatalog.addChild(cheatSheetCategory);
} else {
tmpCatalog.getChild(cheatSheetCategory.getUID()).addChild(cheatSheetReference);
cheatSheetCategory = null;
}
continue;
}
}
}
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
tmpCatalog = null;
}
return result;
}
public List<CheatSheetCatalog> parseXmlCatalogs(String inputString) {
InputStream inputStream = new ByteArrayInputStream(inputString.getBytes());
return parseXmlCatalogs(inputStream);
}
public String toXmlCatalogs(List<CheatSheetCatalog> cheatSheetCatalogs) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
toXmlCatalogs(cheatSheetCatalogs, outputStream);
return new String(outputStream.toByteArray());
}
public void toXmlCatalogs(List<CheatSheetCatalog> cheatSheetCatalogs, OutputStream outputStream) {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
try {
XMLEventWriter parser = factory.createXMLEventWriter(outputStream);
parser.add(eventFactory.createStartDocument(UTF_8, XML_VERSION_1_0));
parser.add(eventFactory.createIgnorableSpace("\n"));
parser.add(eventFactory.createStartElement(new QName(CHEATSHEET_CATALOGS), null, null));
for (CheatSheetCatalog cheatSheetCatalog : cheatSheetCatalogs) {
createCatalog(cheatSheetCatalog, eventFactory, parser);
}
parser.add(eventFactory.createEndElement(new QName(CHEATSHEET_CATALOGS), null));
parser.add(eventFactory.createEndDocument());
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
}