blob: ca2539421e8d13c9f4fd2b6631e4d823b727a1c7 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2013 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Stefan Dimov - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.jpt.jpadiagrameditor.ui.internal.feature;
import java.util.Set;
import org.eclipse.graphiti.features.context.ICreateConnectionContext;
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
import org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.context.Embeddable;
import org.eclipse.jpt.jpa.core.context.MappedSuperclass;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.persistence.ClassRef;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.AbstractRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasReferanceRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JpaArtifactFactory;
abstract public class CreateRelationFeature extends AbstractCreateConnectionFeature {
protected PersistentType owner;
protected boolean isDerivedIdFeature;
public CreateRelationFeature(IJPAEditorFeatureProvider fp, String name, String description, boolean isDerivedIdFeature) {
super(fp, name, description);
this.isDerivedIdFeature = isDerivedIdFeature;
}
public boolean canCreate(ICreateConnectionContext context) {
owner = getPersistentType(context.getSourceAnchor());
PersistentType inverse = getPersistentType(context.getTargetAnchor());
if ((owner == null) || (inverse == null))
return false;
if (JpaArtifactFactory.instance().isMappedSuperclass(inverse)
|| JpaArtifactFactory.instance().isEmbeddable(inverse))
return false;
if(JpaArtifactFactory.instance().isEmbeddable(owner)) {
if(!isRelationshipPossible() || isParentEntity(inverse)
|| JPAEditorUtil.checkJPAFacetVersion(owner.getJpaProject(), JPAEditorUtil.JPA_PROJECT_FACET_10))
return false;
}
if ((this instanceof ICreateBiDirRelationFeature) &&
(JpaArtifactFactory.instance().isMappedSuperclass(owner)))
return false;
if(isDerivedIdFeature && (!JpaArtifactFactory.instance().isEntity(owner)
|| !JpaArtifactFactory.instance().isEntity(inverse))){
return false;
}
return true;
}
public boolean canStartConnection(ICreateConnectionContext context) {
owner = getPersistentType(context.getSourceAnchor());
if (owner == null)
return false;
return true;
}
public Connection create(ICreateConnectionContext context) {
Connection newConnection = null;
PersistentType owner = getPersistentType(context.getSourceAnchor());
PersistentType inverse = getPersistentType(context.getTargetAnchor());
if (owner != null && inverse != null) {
// List<PersistentType> embeddingEntities = new ArrayList<PersistentType>();
if(JpaArtifactFactory.instance().isEmbeddable(owner) && (this instanceof ICreateBiDirRelationFeature)){
Set<HasReferanceRelation> refs = JpaArtifactFactory.instance().findAllHasReferenceRelationsByEmbeddable(owner, getFeatureProvider());
// if(refs.size()>1){
// SelectEmbeddingEntitiesDialog dlg = new SelectEmbeddingEntitiesDialog(owner, getFeatureProvider());
// List<PersistentType> selectedJPTs = dlg.selectInverseRelationshipEntities();
// if(selectedJPTs == null || selectedJPTs.isEmpty()){
// return null;
// }
// embeddingEntities.addAll(selectedJPTs);
// } else {
// embeddingEntities.add(refs.iterator().next().getEmbeddingEntity());
// }
// for(PersistentType embeddingJPT : embeddingEntities) {
newConnection = makeRelation(context, refs.iterator().next().getEmbeddingEntity());
// }
} else {
newConnection = makeRelation(context, null);
}
}
return newConnection;
}
private Connection makeRelation(ICreateConnectionContext context,
PersistentType embeddingJPT) {
Connection newConnection;
AbstractRelation rel = createRelation(getFeatureProvider(), context.getSourceAnchor().getParent(),
context.getTargetAnchor().getParent(), embeddingJPT);
AddConnectionContext addContext =
new AddConnectionContext(context.getSourceAnchor(), context
.getTargetAnchor());
addContext.setNewObject(rel);
newConnection =
(Connection) getFeatureProvider().addIfPossible(addContext);
return newConnection;
}
/**
* Returns the PersistentType class belonging to the anchor, or null if not available.
*/
protected PersistentType getPersistentType(Anchor anchor) {
if (anchor != null) {
Object refObject =
getBusinessObjectForPictogramElement(anchor.getParent());
if (refObject instanceof PersistentType) {
return (PersistentType) refObject;
}
}
return null;
}
/**
* Creates a new OneToOneRelation between two PersistentType classes.
*/
abstract protected AbstractRelation createRelation(IJPAEditorFeatureProvider fp, PictogramElement source,
PictogramElement target, PersistentType type);
@Override
public IJPAEditorFeatureProvider getFeatureProvider() {
return (IJPAEditorFeatureProvider)super.getFeatureProvider();
}
/**
* If the relationship is between an embeddable class and an entity and if the embeddable has an
* element collection to another entity, then the relationships of type one-to-many and
* many-to-many must not be allowed (by spec).
* @return true, if the relationship is allowed, false otherwise.
*/
abstract protected boolean isRelationshipPossible();
@Override
public void attachedToSource(ICreateConnectionContext context) {
super.attachedToSource(context);
getFeatureProvider().setOriginalPersistentTypeColor();
disableUnvalidRelationTargets();
}
@Override
public void endConnecting() {
super.endConnecting();
getFeatureProvider().setOriginalPersistentTypeColor();
}
@Override
public void startConnecting() {
super.startConnecting();
disableAllEmbeddables();
}
/**
* For each unvalid relationship's target, change the color of the respective
* java persistent type in gray to simulate disability of the persistent type.
*/
private void disableUnvalidRelationTargets(){
Diagram d = getDiagram();
JpaProject project = ModelIntegrationUtil.getProjectByDiagram(d.getName());
PersistenceUnit unit = project.getContextRoot().getPersistenceXml().
getRoot().getPersistenceUnits().iterator().next();
if(JpaArtifactFactory.instance().isEntity(owner)){
disableAllJPTsThatAreNotEntities(unit);
}
else if(JpaArtifactFactory.instance().isMappedSuperclass(owner)){
if (isDerivedIdFeature || (this instanceof ICreateBiDirRelationFeature)){
disableAllPersistentTypes(unit);
} else {
disableAllJPTsThatAreNotEntities(unit);
}
}
else if(JpaArtifactFactory.instance().isEmbeddable(owner)) {
if(isDerivedIdFeature || !isRelationshipPossible() || JPAEditorUtil.checkJPAFacetVersion(owner.getJpaProject(), JPAEditorUtil.JPA_PROJECT_FACET_10)) {
disableAllPersistentTypes(unit);
} else {
disableAllJPTsThatAreNotEntities(unit);
}
}
}
/**
* Disable all {@link MappedSuperclass}es and {@link Embeddable}s
* registered in the persistence unit.
* @param unit
*/
private void disableAllJPTsThatAreNotEntities(PersistenceUnit unit) {
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final PersistentType jpt = classRef.getJavaPersistentType();
if(JpaArtifactFactory.instance().isEmbeddable(jpt) || JpaArtifactFactory.instance().isMappedSuperclass(jpt) || isParentEntity(jpt)){
getFeatureProvider().setGrayColor(jpt);
}
}
}
}
/**
* Disable (color in gray) all {@link PersistentType}s registered in the
* persistence unit.
* @param unit
*/
private void disableAllPersistentTypes(PersistenceUnit unit) {
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final PersistentType jpt = classRef.getJavaPersistentType();
getFeatureProvider().setGrayColor(jpt);
}
}
}
/**
* Disable all {@link Embeddable}s
* registered in the persistence unit.
* @param unit
*/
private void disableAllEmbeddables() {
Diagram d = getDiagram();
JpaProject project = ModelIntegrationUtil.getProjectByDiagram(d.getName());
PersistenceUnit unit = project.getContextRoot().getPersistenceXml().
getRoot().getPersistenceUnits().iterator().next();
boolean isJPA10Project = JPAEditorUtil.checkJPAFacetVersion(ModelIntegrationUtil.getProjectByDiagram(getDiagram().getName()), JPAEditorUtil.JPA_PROJECT_FACET_10);
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final PersistentType jpt = classRef.getJavaPersistentType();
if((isJPA10Project && JpaArtifactFactory.instance().isEmbeddable(jpt))
|| (isDerivedIdFeature && !JpaArtifactFactory.instance().isEntity(jpt))){
getFeatureProvider().setGrayColor(jpt);
}
}
}
}
private boolean isParentEntity(PersistentType jpt) {
if(JpaArtifactFactory.instance().isEntity(jpt)){
Set<HasReferanceRelation> refs = JpaArtifactFactory.instance().findAllHasReferenceRelationsByEmbeddable(owner, getFeatureProvider());
if(!refs.isEmpty()){
for(HasReferanceRelation ref : refs){
if(ref.getEmbeddingEntity().getName().equals(jpt.getName())){
return true;
}
}
}
}
return false;
}
}