org.eclipse.persistence.eis.EISDescriptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2023 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:
// Oracle - initial API and implementation from Oracle TopLink
// 14/05/2012-2.4 Guy Pelletier
// - 376603: Provide for table per tenant support for multitenant applications
package org.eclipse.persistence.eis;
import java.util.List;
import java.util.Vector;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.eis.mappings.EISCompositeCollectionMapping;
import org.eclipse.persistence.eis.mappings.EISCompositeDirectCollectionMapping;
import org.eclipse.persistence.eis.mappings.EISCompositeObjectMapping;
import org.eclipse.persistence.eis.mappings.EISDirectMapping;
import org.eclipse.persistence.eis.mappings.EISOneToManyMapping;
import org.eclipse.persistence.eis.mappings.EISOneToOneMapping;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.expressions.SQLStatement;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.oxm.QNameInheritancePolicy;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.queries.DatabaseQuery;
/**
*
* An EISDescriptor
defines the mapping from a JCA data
* structure to a Java object. There are two types of EIS descriptors:
*
* - Root - indicates to the EclipseLink runtime that the EIS descriptor's
* reference class is a parent class: no other class will reference it by way of
* a composite object mapping or composite collection mapping. For an EIS root
* descriptor, EIS interactions can be defined to invoke methods on an EIS
*
- Composite - indicates to the EclipseLink runtime that the EIS descriptor's
* reference class may be referenced by a composite object mapping or composite
* collection mapping
*
*
* @see org.eclipse.persistence.eis.interactions.EISInteraction
* @see org.eclipse.persistence.eis.mappings.EISMapping
*
* @author James
* @since OracleAS TopLink 10g (10.0.3)
*/
public class EISDescriptor extends ClassDescriptor {
/** Define the type of data the descriptor maps to. */
protected String dataFormat;
/** Define the valid data formats that the descriptor can map to. */
public static final String MAPPED = "mapped";
public static final String INDEXED = "indexed";
public static final String XML = "xml";
/** Allow namespaces to be specified for XML type descriptors. */
protected NamespaceResolver namespaceResolver;
/**
* Default constructor.
*/
public EISDescriptor() {
super();
this.shouldOrderMappings = false;
this.dataFormat = XML;
}
@Override
protected void validateMappingType(DatabaseMapping mapping) {
if (!(mapping.isEISMapping())) {
throw DescriptorException.invalidMappingType(mapping);
}
}
/**
* PUBLIC:
* Specify the data type name for the class of objects the descriptor maps.
* This may be the XML schema complex type name, or the JCA record name for the type being mapped.
*/
public void setDataTypeName(String dataTypeName) throws DescriptorException {
this.setTableName(dataTypeName);
}
/**
* PUBLIC:
* Return the XML namespace resolver.
* XML type EIS descriptor can use a namespace resolver to support XML schema namespaces.
*/
public NamespaceResolver getNamespaceResolver() {
return namespaceResolver;
}
/**
* PUBLIC:
* The inheritance policy is used to define how a descriptor takes part in inheritance.
* All inheritance properties for both child and parent classes is configured in inheritance policy.
* Caution must be used in using this method as it lazy initializes an inheritance policy.
* Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.
*/
@Override
public InheritancePolicy getInheritancePolicy() {
if (inheritancePolicy == null) {
if(isXMLFormat()) {
// Lazy initialize to conserve space in non-inherited classes.
setInheritancePolicy(new org.eclipse.persistence.internal.oxm.QNameInheritancePolicy(this));
} else {
setInheritancePolicy(new InheritancePolicy(this));
}
}
return inheritancePolicy;
}
/**
* PUBLIC:
* Set the XML namespace resolver.
* XML type EIS descriptor can use a namespace resolver to support XML schema namespaces.
*/
public void setNamespaceResolver(NamespaceResolver namespaceResolver) {
this.namespaceResolver = namespaceResolver;
}
/**
* INTERNAL:
* Avoid SDK initialization.
*/
@Override
public void setQueryManager(DescriptorQueryManager queryManager) {
this.queryManager = queryManager;
if (queryManager != null) {
queryManager.setDescriptor(this);
}
}
/**
* INTERNAL:
* Configure the object builder for the correct dataFormat.
*/
@Override
public void preInitialize(AbstractSession session) {
// Must not initialize if already done.
if (isInitialized(PREINITIALIZED)) {
return;
}
if (isXMLFormat()) {
setObjectBuilder(new XMLObjectBuilder(this));
if(this.hasInheritance()) {
((QNameInheritancePolicy)getInheritancePolicy()).setNamespaceResolver(this.namespaceResolver);
}
}
// initializeQueryManager();
super.preInitialize(session);
}
/**
* INTERNAL:
* Initialize the query manager specific to the descriptor type.
* Allow the platform to initialize the CRUD queries to defaults.
*/
@Override
public void initialize(DescriptorQueryManager queryManager, AbstractSession session) {
((DatasourcePlatform)session.getDatasourcePlatform()).initializeDefaultQueries(queryManager, session);
super.initialize(queryManager, session);
}
public boolean isXMLFormat() {
return this.dataFormat.equals(XML);
}
public boolean isMappedFormat() {
return this.dataFormat.equals(MAPPED);
}
public boolean isIndexedFormat() {
return this.dataFormat.equals(INDEXED);
}
/**
* PUBLIC:
* Return the data format that the descriptor maps to.
*/
public String getDataFormat() {
return dataFormat;
}
/**
* PUBLIC:
* Specify the data type name for the class of objects the descriptor maps.
* This may be the XML schema complex type name, or the JCA record name for the type being mapped.
*/
public String getDataTypeName() throws DescriptorException {
return this.getTableName();
}
/**
* PUBLIC:
* Configure the data format that the descriptor maps to.
*/
public void setDataFormat(String dataFormat) {
this.dataFormat = dataFormat;
}
/**
* PUBLIC:
* Configure the data format to use mapped records.
*/
public void useMappedRecordFormat() {
setDataFormat(MAPPED);
}
/**
* PUBLIC:
* Configure the data format to use indexed records.
*/
public void useIndexedRecordFormat() {
setDataFormat(INDEXED);
}
/**
* PUBLIC:
* Configure the data format to use xml records.
*/
public void useXMLRecordFormat() {
setDataFormat(XML);
}
/**
* INTERNAL:
* Build the nested row.
*/
@Override
public AbstractRecord buildNestedRowFromFieldValue(Object fieldValue) {
if (fieldValue instanceof AbstractRecord) {
return (AbstractRecord)fieldValue;
}
// BUG#2667762 if the tag was empty this could be a string of whitespace.
if (!(fieldValue instanceof List)) {
return getObjectBuilder().createRecord(0, null);
}
List> nestedRows = (List>)fieldValue;
if (nestedRows.isEmpty()) {
return getObjectBuilder().createRecord(0, null);
} else {
// BUG#2667762 if the tag was empty this could be a string of whitespace.
if (!(nestedRows.get(0) instanceof AbstractRecord)) {
return getObjectBuilder().createRecord(0, null);
}
return (AbstractRecord)nestedRows.get(0);
}
}
/**
* INTERNAL:
* Build the nested rows.
*/
@Override
public Vector buildNestedRowsFromFieldValue(Object fieldValue, AbstractSession session) {
if (!isXMLFormat()) {
if (!(fieldValue instanceof List)) {
return new Vector<>();
}
return new Vector<>((List>)fieldValue);
}
// BUG#2667762 if the tag was empty this could be a string of whitespace.
if (!(fieldValue instanceof Vector)) {
return new Vector<>(0);
}
return (Vector)fieldValue;
}
/**
* INTERNAL:
* Extract the direct values from the specified field value.
* Return them in a vector.
* The field value could be a vector or could be a text value if only a single value.
*/
@Override
public Vector buildDirectValuesFromFieldValue(Object fieldValue) {
if (!(fieldValue instanceof Vector)) {
Vector