/*******************************************************************************
* Copyright (c) 1998, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
* 05/16/2008-1.0M8 Guy Pelletier
* - 218084: Implement metadata merging functionality between mapping files
******************************************************************************/
package org.eclipse.persistence.internal.jpa.metadata.accessors.mappings;
import java.lang.annotation.Annotation;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAccessibleObject;
import org.eclipse.persistence.mappings.ManyToManyMapping;
/**
* INTERNAL:
* A many to many relationship accessor.
*
* @author Guy Pelletier
* @since TopLink EJB 3.0 Reference Implementation
*/
public class ManyToManyAccessor extends CollectionAccessor {
/**
* INTERNAL:
* Used for OX mapping.
*/
public ManyToManyAccessor() {
super("<many-to-many>");
}
/**
* INTERNAL:
*/
public ManyToManyAccessor(Annotation manyToMany, MetadataAccessibleObject accessibleObject, ClassAccessor classAccessor) {
super(manyToMany, accessibleObject, classAccessor);
setMappedBy((String) MetadataHelper.invokeMethod("mappedBy", manyToMany));
}
/**
* INTERNAL:
* Return the logging context for this accessor.
*/
protected String getLoggingContext() {
return MetadataLogger.MANY_TO_MANY_MAPPING_REFERENCE_CLASS;
}
/**
* INTERNAL:
*/
@Override
public boolean isManyToMany() {
return true;
}
/**
* INTERNAL:
* A PrivateOwned setting on a ManyToMany is ignored. A log warning is
* issued.
*/
@Override
public boolean isPrivateOwned() {
if (super.isPrivateOwned()) {
getLogger().logWarningMessage(MetadataLogger.IGNORE_PRIVATE_OWNED_ANNOTATION, this);
}
return false;
}
/**
* INTERNAL:
* Process a many to many metadata accessor into a EclipseLink
* ManyToManyMapping.
*/
@Override
public void process() {
super.process();
// Create a M-M mapping and process common collection mapping metadata.
ManyToManyMapping mapping = new ManyToManyMapping();
process(mapping);
if (getMappedBy() == null || getMappedBy().equals("")) {
// Processing the owning side of a M-M that is process a join table.
processJoinTable(mapping);
} else {
// We are processing the a non-owning side of a M-M. Must set the
// mapping read-only.
mapping.setIsReadOnly(true);
// Get the owning mapping from the reference descriptor metadata.
ManyToManyMapping ownerMapping = null;
if (getOwningMapping(getMappedBy()).isManyToManyMapping()){
ownerMapping = (ManyToManyMapping)getOwningMapping(getMappedBy());
} else {
// If improper mapping encountered, throw an exception.
throw ValidationException.invalidMapping(getJavaClass(), getReferenceClass());
}
// Set the relation table name from the owner.
mapping.setRelationTable(ownerMapping.getRelationTable());
// Add all the source foreign keys we found on the owner.
mapping.setSourceKeyFields(ownerMapping.getTargetKeyFields());
mapping.setSourceRelationKeyFields(ownerMapping.getTargetRelationKeyFields());
// Add all the target foreign keys we found on the owner.
mapping.setTargetKeyFields(ownerMapping.getSourceKeyFields());
mapping.setTargetRelationKeyFields(ownerMapping.getSourceRelationKeyFields());
}
// Process properties
processProperties(mapping);
// Add the mapping to the descriptor.
getDescriptor().addMapping(mapping);
}
}