blob: cd293a767ba4f75d44a15d2cdc3ecee6c1327ca6 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2012 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Petya Sabeva - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.jpt.jpadiagrameditor.ui.internal.feature;
import java.util.Set;
import org.eclipse.graphiti.features.IFeatureProvider;
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.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.context.Embeddable;
import org.eclipse.jpt.jpa.core.context.Entity;
import org.eclipse.jpt.jpa.core.context.MappedSuperclass;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.ReadOnlyPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.persistence.ClassRef;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.jpa2.MappingKeys2_0;
import org.eclipse.jpt.jpa.core.jpa2.resource.java.ElementCollection2_0Annotation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.propertypage.JPADiagramPropertyPage;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.JPAEditorImageProvider;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasCollectionReferenceRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasReferanceRelation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasReferanceRelation.HasReferenceType;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JpaArtifactFactory;
public class EmbedCollectionOfObjectsFeature extends AbstractCreateConnectionFeature {
private JavaPersistentType embeddingEntity;
public EmbedCollectionOfObjectsFeature(IFeatureProvider fp) {
this(fp, JPAEditorMessages.EmbedCollectionOfObjectsFeature_ElementCollectionFeatureName, JPAEditorMessages.EmbedCollectionOfObjectsFeature_ElementCollectionFeatureDescription);
}
public EmbedCollectionOfObjectsFeature(IFeatureProvider fp, String name,
String description) {
super(fp, name, description);
}
public boolean canCreate(ICreateConnectionContext context) {
JavaPersistentType embeddingEntity = (JavaPersistentType)getPersistentType(context.getSourceAnchor());
JavaPersistentType embeddable = (JavaPersistentType)getPersistentType(context.getTargetAnchor());
if ((embeddable == null) || (embeddingEntity == null))
return false;
if (!JpaArtifactFactory.instance().hasEmbeddableAnnotation(embeddable))
return false;
if(!JpaArtifactFactory.instance().hasEntityAnnotation(embeddingEntity) &&
!JpaArtifactFactory.instance().hasEmbeddableAnnotation(embeddingEntity))
return false;
if(isNotAllowed(embeddingEntity, embeddable)){
return false;
}
return true;
}
public Connection create(ICreateConnectionContext context) {
JavaPersistentType embeddingEntity = (JavaPersistentType)getPersistentType(context.getSourceAnchor());
JavaPersistentType embeddable = (JavaPersistentType)getPersistentType(context.getTargetAnchor());
boolean isMap = JPADiagramPropertyPage.isMapType(embeddingEntity.getJpaProject().getProject());
String mapKeyType = null;
if(isMap){
mapKeyType = "java.lang.String"; //$NON-NLS-1$
}
JavaPersistentAttribute embeddedAttribute = JPAEditorUtil.addAnnotatedAttribute(getFeatureProvider(), embeddingEntity, embeddable, true, mapKeyType);
embeddedAttribute.setMappingKey(MappingKeys2_0.ELEMENT_COLLECTION_ATTRIBUTE_MAPPING_KEY);
embeddedAttribute.getResourceAttribute().addAnnotation(ElementCollection2_0Annotation.ANNOTATION_NAME);
HasReferanceRelation rel = new HasCollectionReferenceRelation(embeddingEntity, embeddable);
rel.setEmbeddedAnnotatedAttribute(embeddedAttribute);
AddHasReferenceRelationFeature ft = new AddHasReferenceRelationFeature(getFeatureProvider());
AddConnectionContext cont = new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());
cont.setNewObject(rel);
Connection connection = (Connection) ft.add(cont);
return connection;
}
public boolean canStartConnection(ICreateConnectionContext context) {
embeddingEntity = (JavaPersistentType)getPersistentType(context.getSourceAnchor());
if (embeddingEntity == null)
return false;
return true;
}
public String getCreateImageId() {
return JPAEditorImageProvider.ICON_ELEMENT_COLLECTION;
}
protected PersistentType getPersistentType(Anchor anchor) {
if (anchor != null) {
Object refObject =
getBusinessObjectForPictogramElement(anchor.getParent());
if (refObject instanceof PersistentType) {
return (PersistentType) refObject;
}
}
return null;
}
/**
* Checks whether the given embeddable is already embedded as element collection in entity
* or it embed in itself an element collection of another embeddable.
* @param jpt - the given emebeddable
* @param isEmbedded - true if the embed connection is doing between entity and embeddable, false if the connection
* is trying to be done between two embeddables.
* @return true if the given emebddable is embedded as element collection in an entity or it embed in itself
* an element collection of another embeddable.
*/
private boolean isEmbeddableAlreadyEmbeddedAsElementCollection(JavaPersistentType jpt, boolean isEmbedded){
Set<HasReferanceRelation> refs = JpaArtifactFactory.instance().findAllHasReferenceRelationsByEmbeddable(jpt, getFeatureProvider());
if(!refs.isEmpty()){
for(HasReferanceRelation ref : refs){
if(ref.getReferenceType().equals(HasReferenceType.COLLECTION)){
if(!isEmbedded && ref.getEmbeddable().equals(jpt)){
return true;
} else if(isEmbedded && ref.getEmbeddingEntity().equals(jpt)){
return true;
}
}
}
}
return false;
}
/**
* Checks whether the connection is possible. If the source of the connection is embeddable and it already
* embeds in itself an element collection of another embeddable, or if the target of the connection is already
* embedded as an element connection in some entity, or the if the target embeddable contains an attribute with
* mapping element-collection, then the connection is not allowed by specification.
* @param embeddingEntity - the source entity of the connection
* @param embeddable - the target entity of the connection
* @return true if the connection is possible, false otherwise.
*/
private boolean isNotAllowed(JavaPersistentType embeddingEntity, JavaPersistentType embeddable){
boolean notAllowed = false;
if(JpaArtifactFactory.instance().hasEmbeddableAnnotation(embeddable)){
for(ReadOnlyPersistentAttribute attr : embeddable.getAllAttributes()){
if(attr.getMappingKey().equals(MappingKeys2_0.ELEMENT_COLLECTION_ATTRIBUTE_MAPPING_KEY)){
return true;
}
}
}
if(JpaArtifactFactory.instance().hasEmbeddableAnnotation(embeddingEntity)){
notAllowed = isEmbeddableAlreadyEmbeddedAsElementCollection(embeddingEntity, false);
} else if(JpaArtifactFactory.instance().hasEntityAnnotation(embeddingEntity)){
notAllowed = isEmbeddableAlreadyEmbeddedAsElementCollection(embeddable, true);
}
return notAllowed;
}
public IJPAEditorFeatureProvider getFeatureProvider() {
return (IJPAEditorFeatureProvider)super.getFeatureProvider();
}
@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();
disableAllMappedSuperclasses();
}
/**
* 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.getRootContextNode().getPersistenceXml().
getRoot().getPersistenceUnits().iterator().next();
if(JpaArtifactFactory.instance().hasEntityAnnotation(embeddingEntity)
|| JpaArtifactFactory.instance().hasEmbeddableAnnotation(embeddingEntity)){
disableAllNotEmbeddablesOrEmbedAsElementCollection(unit);
}
else if(JpaArtifactFactory.instance().hasMappedSuperclassAnnotation(embeddingEntity)){
disableAllPersistentType(unit);
}
}
/**
* Disable all {@link MappedSuperclass}es, {@link Entity}s and {@link Embeddable}s, which are part of
* element collection connection, registered in the persistence unit.
* @param unit
*/
private void disableAllNotEmbeddablesOrEmbedAsElementCollection(PersistenceUnit unit) {
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final JavaPersistentType jpt = classRef.getJavaPersistentType();
if(JpaArtifactFactory.instance().hasEntityAnnotation(jpt) || JpaArtifactFactory.instance().hasMappedSuperclassAnnotation(jpt)
|| embeddingEntity.equals(jpt) || isNotAllowed(embeddingEntity, jpt)){
getFeatureProvider().setGrayColor(jpt);
}
}
}
}
/**
* Disable (color in gray) all {@link JavaPersistentType}s registered in the
* persistence unit.
* @param unit
*/
private void disableAllPersistentType(PersistenceUnit unit) {
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final JavaPersistentType jpt = classRef.getJavaPersistentType();
getFeatureProvider().setGrayColor(jpt);
}
}
}
/**
* Disable all {@link MappedSuperclass}es
* registered in the persistence unit.
* @param unit
*/
private void disableAllMappedSuperclasses() {
Diagram d = getDiagram();
JpaProject project = ModelIntegrationUtil.getProjectByDiagram(d.getName());
PersistenceUnit unit = project.getRootContextNode().getPersistenceXml().
getRoot().getPersistenceUnits().iterator().next();
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
final JavaPersistentType jpt = classRef.getJavaPersistentType();
if(JpaArtifactFactory.instance().hasMappedSuperclassAnnotation(jpt)){
getFeatureProvider().setGrayColor(jpt);
}
}
}
}
}