/*
* citygml4j - The Open Source Java API for CityGML
* https://github.com/citygml4j
*
* Copyright 2013-2017 Claus Nagel <claus.nagel@gmail.com>
*
* 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
*
* 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 org.citygml4j.builder.jaxb.xml.io.reader;
import java.util.Stack;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.citygml4j.model.module.citygml.AppearanceModule;
import org.citygml4j.model.module.citygml.CityGMLModule;
import org.citygml4j.model.module.citygml.CityGMLModuleType;
import org.citygml4j.model.module.citygml.CityGMLVersion;
import org.citygml4j.model.module.citygml.CoreModule;
import org.citygml4j.model.module.citygml.GenericsModule;
import org.citygml4j.model.module.citygml.TexturedSurfaceModule;
public class CityGMLNamespaceMapper implements XMLStreamReader {
private final XMLStreamReader reader;
private Stack<ParentFeatureElement> parents;
private ParentFeatureElement parent;
private QName currentName;
private boolean isCityGML;
private int depth = 0;
public CityGMLNamespaceMapper(XMLStreamReader reader) {
this.reader = reader;
parents = new Stack<ParentFeatureElement>();
}
public void close() throws XMLStreamException {
reader.close();
parents = null;
}
public int getAttributeCount() {
return reader.getAttributeCount();
}
public String getAttributeLocalName(int arg0) {
return reader.getAttributeLocalName(arg0);
}
public QName getAttributeName(int arg0) {
return reader.getAttributeName(arg0);
}
public String getAttributeNamespace(int arg0) {
String namespaceURI = reader.getAttributeNamespace(arg0);
return (namespaceURI != null && namespaceURI.startsWith("http://www.citygml.org/citygml")) ? currentName.getNamespaceURI() : reader.getAttributeNamespace(arg0);
}
public String getAttributePrefix(int arg0) {
return reader.getAttributePrefix(arg0);
}
public String getAttributeType(int arg0) {
return reader.getAttributeType(arg0);
}
public String getAttributeValue(int arg0) {
return reader.getAttributeValue(arg0);
}
public String getAttributeValue(String arg0, String arg1) {
return reader.getAttributeValue(arg0, arg1);
}
public String getCharacterEncodingScheme() {
return reader.getCharacterEncodingScheme();
}
public String getElementText() throws XMLStreamException {
return reader.getElementText();
}
public String getEncoding() {
return reader.getEncoding();
}
public int getEventType() {
return reader.getEventType();
}
public String getLocalName() {
return isCityGML ? currentName.getLocalPart() : reader.getLocalName();
}
public Location getLocation() {
return reader.getLocation();
}
public QName getName() {
return isCityGML ? currentName : reader.getName();
}
public NamespaceContext getNamespaceContext() {
return reader.getNamespaceContext();
}
public int getNamespaceCount() {
return reader.getNamespaceCount();
}
public String getNamespacePrefix(int arg0) {
return reader.getNamespacePrefix(arg0);
}
public String getNamespaceURI() {
return isCityGML ? currentName.getNamespaceURI() : reader.getNamespaceURI();
}
public String getNamespaceURI(String arg0) {
return reader.getNamespaceURI(arg0);
}
public String getNamespaceURI(int arg0) {
return reader.getNamespaceURI(arg0);
}
public String getPIData() {
return reader.getPIData();
}
public String getPITarget() {
return reader.getPITarget();
}
public String getPrefix() {
return reader.getPrefix();
}
public Object getProperty(String arg0) throws IllegalArgumentException {
return reader.getProperty(arg0);
}
public String getText() {
return reader.getText();
}
public char[] getTextCharacters() {
return reader.getTextCharacters();
}
public int getTextCharacters(int arg0, char[] arg1, int arg2, int arg3) throws XMLStreamException {
return reader.getTextCharacters(arg0, arg1, arg2, arg3);
}
public int getTextLength() {
return reader.getTextLength();
}
public int getTextStart() {
return reader.getTextStart();
}
public String getVersion() {
return reader.getVersion();
}
public boolean hasName() {
return reader.hasName();
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public boolean hasText() {
return reader.hasText();
}
public boolean isAttributeSpecified(int arg0) {
return reader.isAttributeSpecified(arg0);
}
public boolean isCharacters() {
return reader.isCharacters();
}
public boolean isEndElement() {
return reader.isEndElement();
}
public boolean isStandalone() {
return reader.isStandalone();
}
public boolean isStartElement() {
return reader.isStartElement();
}
public boolean isWhiteSpace() {
return reader.isWhiteSpace();
}
public int next() throws XMLStreamException {
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT) {
String localPart = reader.getLocalName();
String namespaceURI = reader.getNamespaceURI();
depth++;
if (namespaceURI.startsWith("http://www.citygml.org/citygml")) {
isCityGML = true;
if (localPart.equals("creationDate") ||
localPart.equals("terminationDate") ||
localPart.equals("generalizesTo")) {
namespaceURI = CoreModule.v1_0_0.getNamespaceURI();
}
else if (localPart.equals("externalReference")) {
parents.push(parent);
parent = new ParentFeatureElement(localPart, CoreModule.v1_0_0.getNamespaceURI(), depth);
namespaceURI = CoreModule.v1_0_0.getNamespaceURI();
}
else if (localPart.equals("stringAttribute") ||
localPart.equals("intAttribute") ||
localPart.equals("doubleAttribute") ||
localPart.equals("dateAttribute") ||
localPart.equals("uriAttribute")) {
parents.push(parent);
parent = new ParentFeatureElement(localPart, GenericsModule.v1_0_0.getNamespaceURI(), depth);
namespaceURI = GenericsModule.v1_0_0.getNamespaceURI();
}
else if (localPart.equals("appearanceMember")) {
if (parent != null && !parent.localPart.equals("CityModel"))
localPart = "appearance";
namespaceURI = AppearanceModule.v1_0_0.getNamespaceURI();
}
else if (localPart.equals("TexturedSurface") ||
localPart.equals("SimpleTexture") ||
localPart.equals("Material")) {
namespaceURI = TexturedSurfaceModule.v1_0_0.getNamespaceURI();
}
else {
for (CityGMLModule module : CityGMLVersion.v1_0_0.getCityGMLModules()) {
if (module.getType() == CityGMLModuleType.BRIDGE || module.getType() == CityGMLModuleType.TUNNEL)
continue;
if (module.hasFeatureElement(localPart)) {
parents.push(parent);
parent = new ParentFeatureElement(localPart, module.getNamespaceURI(), depth);
break;
}
}
namespaceURI = parent.namespaceURI;
}
} else
isCityGML = false;
currentName = new QName(namespaceURI, localPart);
} else if (event == XMLStreamConstants.END_ELEMENT) {
if (parent != null && parent.depth == depth)
parent = parents.pop();
depth--;
}
return event;
}
public int nextTag() throws XMLStreamException {
return reader.nextTag();
}
public void require(int arg0, String arg1, String arg2) throws XMLStreamException {
reader.require(arg0, arg1, arg2);
}
public boolean standaloneSet() {
return reader.standaloneSet();
}
private final class ParentFeatureElement {
private final String localPart;
private final String namespaceURI;
private final int depth;
public ParentFeatureElement(String localPart, String namespaceURI, int depth) {
this.localPart = localPart;
this.namespaceURI = namespaceURI;
this.depth = depth;
}
}
}