All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.mappings.querykeys;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.expressions.DataExpression;
import org.eclipse.persistence.internal.expressions.ExpressionIterator;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.TableExpression;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;

/**
 * 

* Purpose: Define an alias to a foreign object. *

* Responsibilities: *

    *
  • Define the reference class of the foreign object. *
*/ public class ForeignReferenceQueryKey extends QueryKey { protected Class referenceClass; protected String referenceClassName; protected Expression joinCriteria; /** * INTERNAL: * Convert all the class-name-based settings in this project to actual class-based * settings */ @Override public void convertClassNamesToClasses(ClassLoader classLoader){ Class referenceClass = null; try{ if (referenceClassName != null){ if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ try { referenceClass = AccessController.doPrivileged(new PrivilegedClassForName<>(referenceClassName, true, classLoader)); } catch (PrivilegedActionException exception) { throw ValidationException.classNotFoundWhileConvertingClassNames(referenceClassName, exception.getException()); } } else { referenceClass = PrivilegedAccessHelper.getClassForName(referenceClassName, true, classLoader); } } setReferenceClass(referenceClass); } catch (ClassNotFoundException exc){ throw ValidationException.classNotFoundWhileConvertingClassNames(referenceClassName, exc); } } /** * PUBLIC: * Return the join expression for the relationship defined by the query key. */ public Expression getJoinCriteria() { return joinCriteria; } /** * PUBLIC: * Return the reference class of the relationship. */ public Class getReferenceClass() { return referenceClass; } /** * PUBLIC: * Return the reference class name of the relationship. */ public String getReferenceClassName() { if (referenceClassName == null && referenceClass != null){ referenceClassName = referenceClass.getName(); } return referenceClassName; } /** * INTERNAL: * override the isForeignReferenceQueryKey() method in the superclass to return true. * @return boolean */ @Override public boolean isForeignReferenceQueryKey() { return true; } /** * PUBLIC: * Set the join expression for the relationship defined by the query key. *

Example: *

     *     builder.getField("ADDRESS.ADDRESS_ID").equal(builder.getParameter("EMPLOYEE.ADDR_ID");
     * 
*/ public void setJoinCriteria(Expression joinCriteria) { this.joinCriteria = joinCriteria; } /** * PUBLIC: * Set the reference class of the relationship. * This is not required for direct collection query keys. */ public void setReferenceClass(Class referenceClass) { this.referenceClass = referenceClass; } /** * PUBLIC: * Set the reference class name for this relationship * This is used when projects are built without using classes */ public void setReferenceClassName(String referenceClassName) { this.referenceClassName = referenceClassName; } /** * PUBLIC: * Returns the source table. */ public DatabaseTable getSourceTable() { // TODO: Should extract the target table from joinCriteria (if it's not null), // like ManyToManyQueryKey.getRelationTable does. return this.descriptor.getTables().firstElement(); } /** * PUBLIC: * Returns the reference table. */ public DatabaseTable getReferenceTable(ClassDescriptor desc) { // TODO: This won't work for direct collection. // Should extract the target table from joinCriteria (if it's not null), // like ManyToManyQueryKey.getRelationTable does. return desc.getTables().firstElement(); } /** * PUBLIC: * Returns the relation table. * Currently only ManyToMany and OneToOne may have relation table. * The method is overridden to return null for other subclasses. * The returned relationTable still could be null. */ public DatabaseTable getRelationTable(ClassDescriptor referenceDescriptor) { ExpressionIterator expIterator = new ExpressionIterator() { @Override public void iterate(Expression each) { if(each.isTableExpression()) { ((Collection)this.getResult()).add(((TableExpression)each).getTable()); } else if(each.isDataExpression()) { DatabaseField field = ((DataExpression)each).getField(); if(field != null && field.hasTableName()) { ((Collection)this.getResult()).add(field.getTable()); } } else if(each.isParameterExpression()) { DatabaseField field = ((ParameterExpression)each).getField(); if(field != null && field.hasTableName()) { ((Collection)this.getResult()).add(field.getTable()); } } } }; expIterator.setResult(new HashSet()); expIterator.iterateOn(this.joinCriteria); HashSet tables = (HashSet)expIterator.getResult(); DatabaseTable relationTable = null; Iterator it = tables.iterator(); while(it.hasNext()) { DatabaseTable table = it.next(); // neither source nor reference descriptor contains table - must be relationTable if(!descriptor.getTables().contains(table) && !referenceDescriptor.getTables().contains(table)) { relationTable = table; break; } } return relationTable; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy