blob: 3058ea0922ddd5b0227137ea7d71ad142ff82c5e [file] [log] [blame]
/**
* Copyright (c) 2013 itemis AG and others.
* 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:
* itemis AG - initial API and implementation
*/
package org.eclipse.rmf.internal.serialization;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.xerces.impl.Constants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.ClassNotFoundException;
import org.eclipse.emf.ecore.xmi.FeatureNotFoundException;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.SAXXMLHandler;
import org.eclipse.emf.ecore.xml.type.AnyType;
import org.eclipse.rmf.serialization.XMLPersistenceMappingExtendedMetaData;
import org.eclipse.rmf.serialization.XMLPersistenceMappingExtendedMetaDataImpl;
import org.eclipse.rmf.serialization.XMLPersistenceMappingResource;
// TODO: add javadoc for each state chart
// TODO: add pool that reuses loadpatterns (reduces GC overhead)
// TODO: assert that extended metadata is available.
// TODO: assert that xmlMap is never used
// TODO: check for correct handling of types, object stacks.
// TODO: consider using symboltyble and replace .equals by ==
// TODO: create assertions in case the Handler is not used corretly. e.g. extennded metadata has incorrect format
// TODO: log info if options are used that are not supported
public class XMLPersistenceMappingHandler extends SAXXMLHandler {
String xsiType;
XMLPersistenceMappingExtendedMetaData xmlPersistenceMappingExtendedMetaData = null;
MyStack<LoadPattern> loadPatternStack = null;
IProgressMonitor progressMonitor = null;
int progressMonitorChunksRead = 0;
int progressMonitorChunkSize = 2048;
int progressMonitorLastStartInChunk = 0;
int progressMonitorNumberOfChunksPerUpdate = 500;
private Set<String> progressReportedNamespaces = new HashSet<String>();
interface LoadPattern {
public static int STATE_READY = 0;
public static int STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT = 1;
public static int STATE_HAS_SEEN_START_FEATURE_ELEMENT = 2;
public static int STATE_HAS_SEEN_START_CLASSIFIER_WRAPPER_ELEMENT = 3;
public static int STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT = 4;
public static int STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT = 5;
public static int STATE_HAS_SEEN_END_FEATURE_ELEMENT = 6;
public static int STATE_HAS_SEEN_END_CLASSIFIER_WRAPPER_ELEMENT = 7;
public static int STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT = 8;
public static int STATE_DELEGATE_CHILD_NEEDED = -1;
public static int STATE_DELEGATE_PARENT_NEEDED = -2;
public static int STATE_DELEGATE_SIBLING_NEEDED = -3;
public static int STATE_UNEXPECTED_ELEMENT = -100;
void startElement(String namespace, String xmlName);
void endElement(String namespace, String xmlName);
boolean needsDelegateChild();
boolean needsDelegateSibling();
boolean needsDelegateParent();
}
abstract class AbstractLoadPatternImpl implements LoadPattern {
final EObject anchorEObject;
final EStructuralFeature feature;
int currentState;
public AbstractLoadPatternImpl(EObject anchorEObject, EStructuralFeature feature) {
this.anchorEObject = anchorEObject;
this.feature = feature;
currentState = STATE_READY;
}
public boolean needsDelegateChild() {
return STATE_DELEGATE_CHILD_NEEDED == currentState;
}
public boolean needsDelegateParent() {
return STATE_DELEGATE_PARENT_NEEDED == currentState;
}
public boolean needsDelegateSibling() {
return STATE_DELEGATE_SIBLING_NEEDED == currentState;
}
}
class LoadPatternEReferenceContained0001Impl extends AbstractLoadPatternImpl {
String classifierName = null;
public LoadPatternEReferenceContained0001Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
classifierName = xmlName;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
currentState = STATE_DELEGATE_CHILD_NEEDED;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
if (xmlName.equals(classifierName)) {
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
// this happens if there are no nested structures
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_DELEGATE_CHILD_NEEDED:
// this happens if there are nested structures
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceContained0100Impl extends AbstractLoadPatternImpl {
String featureName;
public LoadPatternEReferenceContained0100Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
featureName = xmlName;
// This puts the newly created eObject onto the objects stack
createObject(anchorEObject, feature);
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_CHILD_NEEDED;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
if (featureName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
createObject(anchorEObject, feature);
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_DELEGATE_CHILD_NEEDED:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceContained0101Impl extends AbstractLoadPatternImpl {
String featureName = null;
public LoadPatternEReferenceContained0101Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
currentState = STATE_DELEGATE_CHILD_NEEDED;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
// for robustness: we allow multiple classiefier elements in a feature element. a warning should be
// created
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
if (featureName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
// only the feature element was available => consider it as a null value;
if (feature.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
values.clear();
} else {
setFeatureValue(anchorEObject, feature, null);
}
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_DELEGATE_CHILD_NEEDED:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceContained1001Impl extends AbstractLoadPatternImpl {
String featureWrapperName = null;
public LoadPatternEReferenceContained1001Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureWrapperName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
currentState = STATE_DELEGATE_CHILD_NEEDED;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
if (featureWrapperName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
// only the feature element was available => consider it as a null value;
if (feature.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
values.clear();
} else {
setFeatureValue(anchorEObject, feature, null);
}
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_DELEGATE_CHILD_NEEDED:
handleEndCreateObjectElement();
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
/**
* This class implements.... <img src="doc-files/LoadPatternEAttributeContained0100.png">
*/
class LoadPatternEAttributeContained0100Impl extends AbstractLoadPatternImpl {
String featureName = null;
int depthsOfUnknownElements = 0;
String value = null;
public LoadPatternEAttributeContained0100Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
featureName = xmlName;
types.push(feature);
if (!isNull()) {
text = new StringBuffer();
}
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
if (featureName.equals(xmlName)) {
text = new StringBuffer(); // record all strings
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
// wait to read contained text
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
if (isNull()) {
setFeatureValue(anchorEObject, feature, null);
} else {
setFeatureValue(anchorEObject, feature, text == null ? null : text.toString());
}
text = null;
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEAttributeContained1000Impl extends AbstractLoadPatternImpl {
String featureWrapperName = null;
int depthsOfUnknownElements = 0;
public LoadPatternEAttributeContained1000Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
featureWrapperName = xmlName;
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
if (featureWrapperName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
text = new StringBuffer(); // record all strings
// wait to read contained text
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
if (null == text) {
setFeatureValue(anchorEObject, feature, null);
} else {
String svalues = text.toString();
StringTokenizer st = new StringTokenizer(svalues);
String svalue;
while (st.hasMoreTokens()) {
svalue = st.nextToken();
setFeatureValue(anchorEObject, feature, svalue);
}
}
text = null;
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEAttributeContained1100Impl extends AbstractLoadPatternImpl {
String featureWrapperName = null;
int depthsOfUnknownElements = 0;
public LoadPatternEAttributeContained1100Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureWrapperName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
if (featureWrapperName == xmlName) {
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
text = new StringBuffer(); // record all strings
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_READY;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
setFeatureValue(anchorEObject, feature, text == null ? null : text.toString());
text = null;
currentState = STATE_READY;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceReferenced0100Impl extends AbstractLoadPatternImpl {
String featureName = null;
InternalEObject proxy;
int depthsOfUnknownElements = 0;
public LoadPatternEReferenceReferenced0100Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
createObject(anchorEObject, feature);
proxy = (InternalEObject) objects.peekEObject();
text = new StringBuffer(); // record all strings
featureName = xmlName;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
if (featureName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
createObject(anchorEObject, feature);
proxy = (InternalEObject) objects.peekEObject();
text = new StringBuffer(); // record all strings
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
if (null != proxy) {
handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
objects.pop();
} else {
// NOP: error already handled during startElement()
}
text = null;
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceReferenced0101Impl extends AbstractLoadPatternImpl {
String featureName = null;
InternalEObject proxy = null;
int depthsOfUnknownElements = 0;
public LoadPatternEReferenceReferenced0101Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
// for robustness: we allow multiple classifier elements in a feature element. a warning should be
// created
proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
if (featureName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
if (null != proxy) {
handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
objects.pop();
} else {
// NOP: error already handled during startElement
}
text = null;
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceReferenced1001Impl extends AbstractLoadPatternImpl {
InternalEObject proxy = null;
String featureWrapperName = null;
int depthsOfUnknownElements = 0;
public LoadPatternEReferenceReferenced1001Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureWrapperName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
// for robustness: we allow multiple classiefier elements in a feature element. a warning should be
// created
currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
if (featureWrapperName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
// only the feature element was available => consider it as a null value;
if (feature.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
values.clear();
} else {
setFeatureValue(anchorEObject, feature, null);
}
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
if (null != proxy) {
objects.pop();
handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
}
text = null;
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
break;
case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternEReferenceReferenced1100Impl extends AbstractLoadPatternImpl {
String featureWrapperName = null;
EObject proxy;
int depthsOfUnknownElements = 0;
public LoadPatternEReferenceReferenced1100Impl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
featureWrapperName = xmlName;
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
createObject(anchorEObject, feature);
text = new StringBuffer(); // record all strings
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
if (featureWrapperName.equals(xmlName)) {
currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
} else {
currentState = STATE_DELEGATE_SIBLING_NEEDED;
}
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
createObject(anchorEObject, feature);
text = new StringBuffer(); // record all strings
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_READY;
break;
case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
if (null != proxy) {
handleProxy((InternalEObject) objects.peekEObject(), resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
objects.pop();
}
text = null;
currentState = STATE_READY;
break;
case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
class LoadPatternUnknownImpl extends AbstractLoadPatternImpl {
int depthsOfUnknownElements = 0;
public LoadPatternUnknownImpl(EObject anchorEObject, EStructuralFeature feature) {
super(anchorEObject, feature);
}
public void startElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_UNEXPECTED_ELEMENT;
depthsOfUnknownElements = 1;
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements++;
break;
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void endElement(String namespace, String xmlName) {
switch (currentState) {
case STATE_READY:
currentState = STATE_DELEGATE_PARENT_NEEDED;
break;
case STATE_UNEXPECTED_ELEMENT:
depthsOfUnknownElements--;
if (0 > depthsOfUnknownElements) {
currentState = STATE_DELEGATE_PARENT_NEEDED;
}
break;
case STATE_DELEGATE_CHILD_NEEDED:
case STATE_DELEGATE_SIBLING_NEEDED:
case STATE_DELEGATE_PARENT_NEEDED:
assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
break;
default:
assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
public XMLPersistenceMappingHandler(XMLResource xmlResource, XMLHelper helper, Map<?, ?> options) {
super(xmlResource, helper, options);
// set extended meta data
Object extendedMetaDataOption = options.get(XMLResource.OPTION_EXTENDED_META_DATA);
if (null != extendedMetaDataOption && extendedMetaDataOption instanceof XMLPersistenceMappingExtendedMetaData) {
xmlPersistenceMappingExtendedMetaData = (XMLPersistenceMappingExtendedMetaData) options.get(XMLResource.OPTION_EXTENDED_META_DATA);
extendedMetaData = xmlPersistenceMappingExtendedMetaData;
} else {
// default
xmlPersistenceMappingExtendedMetaData = xmlResource == null || xmlResource.getResourceSet() == null ? XMLPersistenceMappingExtendedMetaData.INSTANCE
: new XMLPersistenceMappingExtendedMetaDataImpl(xmlResource.getResourceSet().getPackageRegistry());
extendedMetaData = xmlPersistenceMappingExtendedMetaData;
}
helper.setExtendedMetaData(xmlPersistenceMappingExtendedMetaData);
// initialize progress monitor
Object progressMonitor = options.get(XMLPersistenceMappingResource.OPTION_PROGRESS_MONITOR);
if (progressMonitor instanceof IProgressMonitor) {
this.progressMonitor = (IProgressMonitor) progressMonitor;
} else {
// ignore
}
// get chunk size of xml parser, that is required for calculation of progress monitor ticks
Object parserPropertiesObject = options.get(XMLResource.OPTION_PARSER_PROPERTIES);
if (null != parserPropertiesObject && parserPropertiesObject instanceof Map<?, ?>) {
@SuppressWarnings("unchecked")
Map<String, Object> parserProperties = (Map<String, Object>) parserPropertiesObject;
Object bufferSizeObject = parserProperties.get(Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY);
if (bufferSizeObject instanceof Integer) {
progressMonitorChunkSize = (Integer) bufferSizeObject;
} else {
// use default;
}
} else {
// use default;
}
loadPatternStack = new MyStack<LoadPattern>();
xsiType = null;
// redefine href attribute since e.g.:
// xhtml.a.type/@href conflicts with this attribute and results in proxy resolution which can in turn
// result in long delays during load.
hrefAttribute = XMLPersistenceMappingResource.HREF;
// postconditions
assert null != xmlPersistenceMappingExtendedMetaData;
assert null != extendedMetaData;
}
/**
* Create an object based on the given feature and attributes.
*/
protected EObject createObjectFromNamespaceAndType(EObject peekObject, EStructuralFeature feature, String namespace, String typeXMLName) {
assert null != xmlPersistenceMappingExtendedMetaData;
assert null != peekObject;
assert null != feature;
assert null != namespace;
assert null != typeXMLName;
// Inform the progress monitor. As looking up the namespace can be slow (network),
// it will at least tell the user what's taking so long
if (progressMonitor != null && namespace != null && !progressReportedNamespaces.contains(namespace)) {
progressMonitor.subTask("Processing Namespace: " + namespace); //$NON-NLS-1$
progressReportedNamespaces.add(namespace);
}
// make sure, that information about feature is available for handleMissingPackage
contextFeature = feature;
EPackage ePackage = getPackageForURI(namespace);
contextFeature = null;
if (null != ePackage) {
EClassifier eClassifier;
if (xmlPersistenceMappingExtendedMetaData.demandedPackages().contains(ePackage)) {
// demand package requires demand type
eClassifier = xmlPersistenceMappingExtendedMetaData.demandType(namespace, typeXMLName);
} else {
eClassifier = xmlPersistenceMappingExtendedMetaData.getTypeByXMLName(namespace, typeXMLName, feature);
}
EFactory eFactory = ePackage.getEFactoryInstance();
if (null != eClassifier) {
EObject obj = createObject(eFactory, eClassifier, false);
obj = validateCreateObjectFromFactory(eFactory, typeXMLName, obj, feature);
if (obj != null) {
setFeatureValue(peekObject, feature, obj);
processObject(obj);
}
return obj;
} else {
error(new ClassNotFoundException(typeXMLName, eFactory, getLocation(), getLineNumber(), getColumnNumber()));
return null;
}
} else {
return null;
}
}
@Override
protected EObject validateCreateObjectFromFactory(EFactory factory, String typeName, EObject newObject, EStructuralFeature feature) {
if (newObject != null) {
if (extendedMetaData != null) {
Collection<EPackage> demandedPackages = extendedMetaData.demandedPackages();
if (!demandedPackages.isEmpty() && demandedPackages.contains(newObject.eClass().getEPackage())) {
if (xmlPersistenceMappingExtendedMetaData.isXMLPersistenceMappingEnabled(feature)) {
List<String> wildcards = xmlPersistenceMappingExtendedMetaData.getWildcards(feature);
if (xmlPersistenceMappingExtendedMetaData.matches(wildcards, newObject.eClass().getEPackage().getNsURI())) {
return newObject;
} else {
return null;
}
} else {
// the new object resulted from a demanded package
if (recordUnknownFeature) {
// recordUnknownFeature
EObject peekObject = objects.peekEObject();
if (!(peekObject instanceof AnyType)) {
AnyType anyType = getExtension(objects.peekEObject());
EStructuralFeature entryFeature = extendedMetaData.demandFeature(extendedMetaData.getNamespace(feature),
extendedMetaData.getName(feature), true);
anyType.getAny().add(entryFeature, newObject);
contextFeature = entryFeature;
}
return newObject;
} else {
// reportUnknowFeature
String namespace = extendedMetaData.getNamespace(feature);
String name = extendedMetaData.getName(feature);
EStructuralFeature wildcardFeature = extendedMetaData.getElementWildcardAffiliation(objects.peekEObject().eClass(),
namespace, name);
if (wildcardFeature != null) {
int processingKind = laxWildcardProcessing ? ExtendedMetaData.LAX_PROCESSING : extendedMetaData
.getProcessingKind(wildcardFeature);
switch (processingKind) {
case ExtendedMetaData.LAX_PROCESSING:
case ExtendedMetaData.SKIP_PROCESSING: {
return newObject;
}
}
}
}
newObject = null;
}
}
}
} else if (feature != null && factory != null && extendedMetaData != null) {
// processing unknown feature with xsi:type (xmi:type)
if (recordUnknownFeature || processAnyXML) {
EObject result = null;
String namespace = extendedMetaData.getNamespace(factory.getEPackage());
if (namespace == null) {
usedNullNamespacePackage = true;
}
EClassifier type = extendedMetaData.demandType(namespace, typeName);
result = createObject(type.getEPackage().getEFactoryInstance(), type, false);
EObject peekObject = objects.peekEObject();
if (!(peekObject instanceof AnyType)) {
// add as extension to an existing eobject
AnyType anyType = getExtension(peekObject);
EStructuralFeature entryFeature = extendedMetaData.demandFeature(extendedMetaData.getNamespace(feature),
extendedMetaData.getName(feature), true);
anyType.getAny().add(entryFeature, result);
contextFeature = entryFeature;
}
return result;
} else {
String namespace = extendedMetaData.getNamespace(feature);
String name = extendedMetaData.getName(feature);
EStructuralFeature wildcardFeature = extendedMetaData.getElementWildcardAffiliation(objects.peekEObject().eClass(), namespace, name);
if (wildcardFeature != null) {
int processingKind = laxWildcardProcessing ? ExtendedMetaData.LAX_PROCESSING : extendedMetaData
.getProcessingKind(wildcardFeature);
switch (processingKind) {
case ExtendedMetaData.LAX_PROCESSING:
case ExtendedMetaData.SKIP_PROCESSING: {
// EATM Demand create metadata; needs to depend on processing mode...
String factoryNamespace = extendedMetaData.getNamespace(factory.getEPackage());
if (factoryNamespace == null) {
usedNullNamespacePackage = true;
}
EClassifier type = extendedMetaData.demandType(factoryNamespace, typeName);
return createObject(type.getEPackage().getEFactoryInstance(), type, false);
}
}
}
}
}
validateCreateObjectFromFactory(factory, typeName, newObject);
return newObject;
}
@Override
public void characters(char[] ch, int start, int length) {
super.characters(ch, start, length);
if (null != progressMonitor) {
if (start < progressMonitorLastStartInChunk) {
progressMonitorChunksRead += 1;
}
if (progressMonitorChunksRead > progressMonitorNumberOfChunksPerUpdate) {
progressMonitor.worked(progressMonitorChunksRead);
progressMonitorChunksRead = 0;
}
progressMonitorLastStartInChunk = start;
}
}
@Override
public void endElement(String uri, String localName, String qName) {
if (null != xmlPersistenceMappingExtendedMetaData) {
elements.pop();
types.pop();
helper.popContext(prefixesToFactories);
// end from super.endElement
LoadPattern activeDeserializationRule = loadPatternStack.peek();
if (null != activeDeserializationRule) {
activeDeserializationRule.endElement(uri, localName);
if (activeDeserializationRule.needsDelegateParent()) {
loadPatternStack.pop();
activeDeserializationRule = loadPatternStack.peek();
if (null != activeDeserializationRule) {
// this happens if we return to the root object
activeDeserializationRule.endElement(uri, localName);
}
}
}
} else {
super.endElement(uri, localName, qName);
}
}
/**
* The XML element represents a feature. There are two cases to handle: 1. The feature has a type that is a
* datatype. 2. The feature has a type that is a class.
*/
@Override
protected void handleFeature(String prefix, String name) {
assert useNewMethods == true;
EObject peekObject = objects.peekEObject();
// This happens when processing an element with simple content that has elements content even though it
// shouldn't.
//
if (peekObject == null) {
types.push(ERROR_TYPE);
error(new FeatureNotFoundException(name, null, getLocation(), getLineNumber(), getColumnNumber()));
return;
}
if (null != xmlPersistenceMappingExtendedMetaData) {
String namespace = helper.getNamespaceURI(prefix);
LoadPattern activeDeserializationRule = loadPatternStack.peek();
if (null == activeDeserializationRule) {
activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
loadPatternStack.push(activeDeserializationRule);
}
if (null != activeDeserializationRule) {
activeDeserializationRule.startElement(namespace, name);
if (activeDeserializationRule.needsDelegateChild()) {
activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
loadPatternStack.push(activeDeserializationRule);
activeDeserializationRule.startElement(namespace, name);
} else if (activeDeserializationRule.needsDelegateSibling()) {
activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
loadPatternStack.pop();
loadPatternStack.push(activeDeserializationRule);
activeDeserializationRule.startElement(namespace, name);
} else {
// normal operation, no need for switching to another load pattern
}
}
} else {
EStructuralFeature feature = getFeature(peekObject, prefix, name, true);
if (feature != null) {
int kind = helper.getFeatureKind(feature);
if (kind == XMLHelper.DATATYPE_SINGLE || kind == XMLHelper.DATATYPE_IS_MANY) {
objects.push(null);
mixedTargets.push(null);
types.push(feature);
if (!isNull()) {
text = new StringBuffer();
}
} else if (extendedMetaData != null) {
EReference eReference = (EReference) feature;
boolean isContainment = eReference.isContainment();
if (!isContainment && !eReference.isResolveProxies()
&& extendedMetaData.getFeatureKind(feature) != ExtendedMetaData.UNSPECIFIED_FEATURE) {
isIDREF = true;
objects.push(null);
mixedTargets.push(null);
types.push(feature);
text = new StringBuffer();
} else {
createObject(peekObject, feature);
// child object is put on top of objects stack
// if an error occured, then types.peek is ERROR
//
EObject childObject = objects.peekEObject();
if (childObject != null) {
if (isContainment) {
EStructuralFeature simpleFeature = extendedMetaData.getSimpleFeature(childObject.eClass());
if (simpleFeature != null) {
isSimpleFeature = true;
isIDREF = simpleFeature instanceof EReference;
objects.push(null);
mixedTargets.push(null);
types.push(simpleFeature);
text = new StringBuffer();
}
} else if (!childObject.eIsProxy()) {
text = new StringBuffer();
}
}
}
} else {
createObject(peekObject, feature);
}
} else {
// Try to get a general-content feature.
// Use a pattern that's not possible any other way.
//
if (xmlMap != null && (feature = getFeature(peekObject, null, "", true)) != null) { //$NON-NLS-1$
EFactory eFactory = getFactoryForPrefix(prefix);
// This is for the case for a local unqualified element that has been bound.
//
if (eFactory == null) {
eFactory = feature.getEContainingClass().getEPackage().getEFactoryInstance();
}
EObject newObject = null;
newObject = createObject(eFactory, helper.getType(eFactory, name), false);
newObject = validateCreateObjectFromFactory(eFactory, name, newObject, feature);
if (newObject != null) {
setFeatureValue(peekObject, feature, newObject);
}
processObject(newObject);
} else {
// This handles the case of a substitution group.
//
if (xmlMap != null) {
EFactory eFactory = getFactoryForPrefix(prefix);
EObject newObject = createObjectFromFactory(eFactory, name);
validateCreateObjectFromFactory(eFactory, name, newObject);
if (newObject != null) {
for (EReference eReference : peekObject.eClass().getEAllReferences()) {
if (eReference.getEType().isInstance(newObject)) {
setFeatureValue(peekObject, eReference, newObject);
processObject(newObject);
return;
}
}
}
}
handleUnknownFeature(prefix, name, true, peekObject, null);
}
}
}
}
protected LoadPattern getLoadPattern(EObject eObject, String prefix, String name) {
assert null != xmlPersistenceMappingExtendedMetaData;
LoadPattern deserializationRule = null;
if (eObject instanceof AnyType) {
// handle any type using standard emf serialization
EStructuralFeature feature = super.getFeature(eObject, prefix, name, true);
deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
} else {
EStructuralFeature feature = getFeature(eObject, prefix, name, true);
if (null != feature) {
int featureSerializationStructure = xmlPersistenceMappingExtendedMetaData.getFeatureSerializationStructure(feature);
if (feature instanceof EReference) {
EReference reference = (EReference) feature;
if (reference.isContainment()) {
switch (featureSerializationStructure) {
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0001__CLASSIFIER_ELEMENT:
deserializationRule = new LoadPatternEReferenceContained0001Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0100__FEATURE_ELEMENT:
deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0101__FEATURE_ELEMENT__CLASSIFIER_ELEMENT:
deserializationRule = new LoadPatternEReferenceContained0101Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__1001__FEATURE_WRAPPER_ELEMENT__CLASSIFIER_ELEMENT:
deserializationRule = new LoadPatternEReferenceContained1001Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
break;
default:
deserializationRule = new LoadPatternEReferenceContained1001Impl(eObject, feature);
break;
}
} else {
switch (featureSerializationStructure) {
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0100__FEATURE_ELEMENT:
deserializationRule = new LoadPatternEReferenceReferenced0100Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0101__FEATURE_ELEMENT__CLASSIFIER_ELEMENT:
deserializationRule = new LoadPatternEReferenceReferenced0101Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__1001__FEATURE_WRAPPER_ELEMENT__CLASSIFIER_ELEMENT:
deserializationRule = new LoadPatternEReferenceReferenced1001Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
deserializationRule = new LoadPatternEReferenceReferenced0100Impl(eObject, feature);
break;
default:
deserializationRule = new LoadPatternEReferenceReferenced1001Impl(eObject, feature);
break;
}
}
} else {
// feature is an EAttribute
switch (featureSerializationStructure) {
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__0100__FEATURE_ELEMENT:
deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__1000__FEATURE_WRAPPER_ELEMENT:
deserializationRule = new LoadPatternEAttributeContained1000Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__1100__FEATURE_WRAPPER_ELEMENT__FEATURE_ELEMENT:
deserializationRule = new LoadPatternEAttributeContained1100Impl(eObject, feature);
break;
case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
break;
default:
deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
break;
}
}
} else {
deserializationRule = new LoadPatternUnknownImpl(eObject, feature);
}
}
assert null != deserializationRule : "getLoadPattern() should always return a LoadPattern (!=null)"; //$NON-NLS-1$
return deserializationRule;
}
@Override
protected EStructuralFeature getFeature(EObject object, String prefix, String name, boolean isElement) {
assert null != object;
assert null != name;
EStructuralFeature result = null;
if (isElement && null != xmlPersistenceMappingExtendedMetaData) {
String namespace = helper.getNamespaceURI(prefix);
result = xmlPersistenceMappingExtendedMetaData.getFeatureByXMLElementName(object.eClass(), namespace, name);
} else {
result = super.getFeature(object, prefix, name, isElement);
}
return result;
}
@Override
public void reset() {
super.reset();
loadPatternStack = null;
hrefAttribute = XMLPersistenceMappingResource.HREF;
};
@Override
public void prepare(XMLResource resource, XMLHelper helper, Map<?, ?> options) {
super.prepare(resource, helper, options);
loadPatternStack = new MyStack<LoadPattern>();
// enforce use of new methods
useNewMethods = true;
xsiType = null;
}
@Override
protected String getXSIType() {
if (xsiType != null) {
return xsiType;
} else {
return super.getXSIType();
}
}
protected void handleEndCreateObjectElement() {
if (text == null) {
objects.pop();
mixedTargets.pop();
} else {
EObject object = objects.popEObject();
if (mixedTargets.peek() != null
&& (object.eContainer() != null || suppressDocumentRoot || recordUnknownFeature
&& (eObjectToExtensionMap.containsValue(object) || ((InternalEObject) object).eDirectResource() != null))) {
handleMixedText();
mixedTargets.pop();
}
}
}
@Override
public void startDocument() {
super.startDocument();
// initialize the progress monitor
if (null != progressMonitor) {
progressMonitorChunksRead = 0;
progressMonitorLastStartInChunk = 0;
progressMonitor.beginTask("Reading resource '" + resourceURI + "'", getProgressMonitorTotalWork()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@Override
public void endDocument() {
super.endDocument();
// finalize the progress monitor
if (null != progressMonitor) {
progressMonitor.done();
}
}
protected int getProgressMonitorTotalWork() {
int totalWork = IProgressMonitor.UNKNOWN;
URI uri = xmlResource.getURI();
InputStream is = null;
try {
is = URIConverter.INSTANCE.createInputStream(uri);
totalWork = is.available() / progressMonitorChunkSize;
} catch (IOException ex) {
// NOP
} finally {
if (null != is) {
try {
is.close();
} catch (IOException ex) {
// NOP
}
}
}
return totalWork;
}
@Override
protected EPackage handleMissingPackage(String uriString) {
if (null != contextFeature && null != xmlPersistenceMappingExtendedMetaData
&& xmlPersistenceMappingExtendedMetaData.isXMLPersistenceMappingEnabled(contextFeature)) {
return xmlPersistenceMappingExtendedMetaData.demandPackage(uriString);
} else {
return super.handleMissingPackage(uriString);
}
}
}