blob: 34f4218ac50b7d8b72a67c3a7c142b5d2b60f8a4 [file] [log] [blame]
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm.record;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.Marshaller;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathNode;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.w3c.dom.Node;
/**
* This class represents marshal record behaviour that is specific to the SAX
* platform.
*/
public interface MarshalRecord<
ABSTRACT_SESSION extends CoreAbstractSession,
FIELD extends CoreField,
MARSHALLER extends Marshaller,
NAMESPACE_RESOLVER extends NamespaceResolver> extends AbstractMarshalRecord<ABSTRACT_SESSION, FIELD, MARSHALLER, NAMESPACE_RESOLVER> {
void add(FIELD field, Object value);
void addGroupingElement(XPathNode holderXPathNode);
void afterContainmentMarshal(Object object, Object value);
@Override void attribute(String namespaceURI, String localPart,
String qualifiedName, String value);
void attribute(XPathFragment nextFragment,
NAMESPACE_RESOLVER namespaceResolver, Object fieldValue,
QName schemaType);
void attribute(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver, String value);
@Override void attributeWithoutQName(String namespaceURI,
String localName, String prefix, String value);
void beforeContainmentMarshal(Object value);
void cdata(String string);
void characters(QName schemaType, Object objectValue,
String mimeType, boolean b);
void characters(String c_id);
void closeStartElement();
void closeStartGroupingElements(XPathFragment groupingFragment);
void emptyAttribute(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
boolean emptyCollection(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver, boolean b);
void emptyComplex(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
void emptySimple(NAMESPACE_RESOLVER namespaceResolver);
void endCollection();
void endElement(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
void endPrefixMapping(String prefix);
void flush();
void forceValueWrapper();
CoreAttributeGroup getCurrentAttributeGroup();
CycleDetectionStack<Object> getCycleDetectionStack();
ArrayList<XPathNode> getGroupingElements();
XPathFragment getTextWrapperFragment();
String getValueToWrite(QName schemaType, Object fieldValue,
ConversionManager conversionManager);
@Override boolean hasCustomNamespaceMapper();
boolean isWrapperAsCollectionName();
@Override boolean isXOPPackage();
@Override void namespaceDeclaration(String generatedPrefix, String namespaceURI);
void nilComplex(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
void nilSimple(NAMESPACE_RESOLVER namespaceResolver);
void node(Node item, NAMESPACE_RESOLVER namespaceResolver);
void openStartElement(XPathFragment xPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
XPathFragment openStartGroupingElements(
NAMESPACE_RESOLVER namespaceResolver);
void popAttributeGroup();
void predicateAttribute(XPathFragment anXPathFragment,
NAMESPACE_RESOLVER namespaceResolver);
void pushAttributeGroup(CoreAttributeGroup group);
@Override void removeExtraNamespacesFromNamespaceResolver(List<Namespace> extraNamespaces, CoreAbstractSession session);
void removeGroupingElement(XPathNode holderXPathNode);
void setGroupingElement(ArrayList<XPathNode> object);
@Override void setLeafElementType(QName leafElementType);
@Override void setMarshaller(MARSHALLER marshaller);
void startCollection();
void startPrefixMapping(String prefix, String uri);
/**
* A Stack-like List, used to detect object cycles during marshal operations.
*/
class CycleDetectionStack<E> extends AbstractList<Object> {
private Object[] data = new Object[8];
int currentIndex = 0;
public void push(E item) {
if (currentIndex == data.length) {
growArray();
}
data[currentIndex] = item;
currentIndex++;
}
private void growArray() {
Object[] newArray = new Object[data.length * 2];
System.arraycopy(data, 0, newArray, 0, data.length);
data = newArray;
}
public Object pop() {
Object o = data[currentIndex - 1];
data[currentIndex - 1] = null;
currentIndex--;
return o;
}
public boolean contains(Object item, boolean equalsUsingIdentity) {
if (equalsUsingIdentity) {
for (int i = 0; i < currentIndex; i++) {
if (data[i] == item) {
return true;
}
}
} else {
for (int i = 0; i < currentIndex; i++) {
if (data[i] != null && data[i].equals(item)) {
return true;
}
}
}
return false;
}
public String getCycleString() {
StringBuilder sb = new StringBuilder();
int i = size() - 1;
Object obj = get(i);
sb.append(obj);
Object x;
do {
sb.append(" -> ");
x = get(--i);
sb.append(x);
} while (obj != x);
return sb.toString();
}
@Override
public Object get(int index) {
return data[index];
}
@Override
public int size() {
return currentIndex;
}
}
}