blob: d89265d328704ee8397a2af8915c6eabe95b7f7a [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2011 SAP AG.
* 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:
* Stefan Dimov - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.jpt.jpadiagrameditor.ui.internal.provider;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.dt.AbstractDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.context.impl.CustomContext;
import org.eclipse.graphiti.features.context.impl.RemoveContext;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.platform.IDiagramEditor;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.tb.IToolBehaviorProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.MappingKeys;
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.jpadiagrameditor.ui.internal.JPADiagramEditor;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.facade.EclipseFacade;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.AddAllEntitiesFeature;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.AddJPAEntityFeature;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.RemoveRelationFeature;
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.util.EntitiesCoordinatesXML;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPACheckSum;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorConstants;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPASolver;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JpaArtifactFactory;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.SizePosition;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
public class JPAEditorDiagramTypeProvider extends AbstractDiagramTypeProvider {
private IToolBehaviorProvider[] toolBehaviorProviders;
public final static String ID = "org.eclipse.jpt.jpadiagrameditor.ui.provider.JPAEditorDiagramTypeProvider"; //$NON-NLS-1$
boolean isDisposed = false;
boolean readOnly = false;
public JPAEditorDiagramTypeProvider() {
IFeatureProvider fp = new JPAEditorFeatureProvider(this, new JPASolver());
setFeatureProvider(fp);
}
@Override
public void init(Diagram diagram, IDiagramEditor diagramEditor) {
super.init(diagram, diagramEditor);
if (getTargetJPAProject() == null)
closeEditor();
JPAEditorDiagramTypeProvider provider = ModelIntegrationUtil.getProviderByDiagram(diagram.getName());
if ((provider != null) && provider.isAlive())
provider.getDiagramEditor().getSite().getWorkbenchWindow().getActivePage().closeEditor(provider.getDiagramEditor(), true);
}
@Override
public IToolBehaviorProvider[] getAvailableToolBehaviorProviders() {
if (toolBehaviorProviders == null) {
toolBehaviorProviders =
new IToolBehaviorProvider[] { new JPAEditorToolBehaviorProvider(this, EclipseFacade.INSTANCE) };
}
return toolBehaviorProviders;
}
@Override
public JPAEditorFeatureProvider getFeatureProvider() {
return (JPAEditorFeatureProvider)super.getFeatureProvider();
}
@SuppressWarnings("restriction")
public boolean hasToAdd() {
JpaProject project = getTargetJPAProject();
PersistenceUnit unit = project.getRootContextNode().getPersistenceXml().
getPersistence().getPersistenceUnits().iterator().next();
for (ClassRef classRef : unit.getClassRefs()) {
if (classRef.getJavaPersistentType() != null) {
JavaPersistentType jpt = classRef.getJavaPersistentType();
if (jpt.getMappingKey() == MappingKeys.ENTITY_TYPE_MAPPING_KEY) {
PictogramElement pe = getFeatureProvider().getPictogramElementForBusinessObject(jpt);
if (pe == null)
return true;
}
}
}
return false;
}
@Override
public void postInit() {
final String jptName = getDiagramEditor().getPartProperty(JPAEditorConstants.OPEN_WHOLE_PERSISTENCE_UNIT_EDITOR_PROPERTY);
if (jptName != null) {
boolean hasToAdd = hasToAdd();
boolean readOnly = openPersistedDiagram(hasToAdd);
if (hasToAdd && !readOnly)
addRemainingEntities();
} else
try {
openPersistedDiagram(false);
} catch (NullPointerException e) {
return;
}
}
private void addRemainingEntities() {
final AddAllEntitiesFeature feature = new AddAllEntitiesFeature(getFeatureProvider());
final CustomContext context = new CustomContext();
TransactionalEditingDomain ted = ModelIntegrationUtil.getTransactionalEditingDomain(feature.getFeatureProvider().getDiagramTypeProvider().getDiagram());
ted.getCommandStack().execute(new RecordingCommand(ted) {
@Override
protected void doExecute() {
feature.execute(context);
}
});
}
private void closeEditor() {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
page.closeEditor(getDiagramEditor(), false);
}
});
}
private boolean openPersistedDiagram(boolean hasToAdd) {
final JpaProject proj = getTargetJPAProject();
IProject project = proj.getProject();
final Diagram diagram = getDiagram();
ModelIntegrationUtil.putProjectToDiagram(project, diagram);
PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(proj);
String diagramName = pu.getName();
IPath path = ModelIntegrationUtil.getDiagramsFolderPath(project).append(diagramName).addFileExtension(ModelIntegrationUtil.DIAGRAM_FILE_EXTENSION);
final IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
boolean readOnly = (f != null) && f.exists() && f.isReadOnly();
if (readOnly) {
if (JPACheckSum.INSTANCE().isModelDifferentFromDiagram(diagram, proj) || hasToAdd) {
String message = hasToAdd ? JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyHasToAddMsg :
JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyMsg;
MessageDialog dialog = new MessageDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyTitle, null, message,
MessageDialog.INFORMATION, new String[] {JPAEditorMessages.BTN_OK, JPAEditorMessages.BTN_CANCEL}, 0) {
@Override
protected int getShellStyle() {
return SWT.TITLE | SWT.BORDER
| SWT.APPLICATION_MODAL
| getDefaultOrientation();
}
};
if (dialog.open() == 1) {
closeEditor();
return true;
} else {
IStatus stat = ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{f}, null);
if (!stat.isOK()) {
message = NLS.bind(JPAEditorMessages.JPAEditorDiagramTypeProvider_cantMakeDiagramWritableMsg,
stat.getMessage());;
dialog = new MessageDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
JPAEditorMessages.JPAEditorDiagramTypeProvider_cantMakeDiagramWritableTitle, null, message,
MessageDialog.CANCEL, new String[] {JPAEditorMessages.BTN_OK}, 0) {
@Override
protected int getShellStyle() {
return SWT.CLOSE | SWT.TITLE | SWT.BORDER
| SWT.APPLICATION_MODAL
| getDefaultOrientation();
}
};
dialog.open();
closeEditor();
return true;
} else {
readOnly = false;
}
}
} else {
return readOnly;
}
}
removeConnections();
final Hashtable<String, SizePosition> marks = new Hashtable<String, SizePosition>();
EntitiesCoordinatesXML xml = new EntitiesCoordinatesXML(project.getName());
xml.load(marks);
xml.clean();
List<Shape> picts = diagram.getChildren();
Iterator<Shape> it = picts.iterator();
HashSet<Shape> toDelete = new HashSet<Shape>();
// collecting data from the saved pictograms
while (it.hasNext()) {
Shape pict = it.next();
toDelete.add(pict);
}
final Iterator<Shape> iter = toDelete.iterator();
TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
ted.getCommandStack().execute(new RecordingCommand(ted) {
@Override
protected void doExecute() {
while (iter.hasNext())
Graphiti.getPeService().deletePictogramElement(iter.next());
Collection<Connection> cns = diagram.getConnections();
Iterator<Connection> itera = cns.iterator();
Set<Connection> toDel = new HashSet<Connection>();
while (itera.hasNext())
toDel.add(itera.next());
itera = toDel.iterator();
while (itera.hasNext())
Graphiti.getPeService().deletePictogramElement(itera.next());
Enumeration<String> itr = marks.keys();
// create new pictograms
while (itr.hasMoreElements()) {
String entityName = itr.nextElement();
JavaPersistentType jpt = JpaArtifactFactory.instance().getContextPersistentType(proj, entityName);
if (jpt != null) {
SizePosition sp = marks.get(entityName);
AddContext ctx = new AddEntityContext(sp.primaryCollapsed,
sp.relationCollapsed, sp.basicCollapsed);
ctx.setNewObject(jpt);
ctx.setTargetContainer(getDiagram());
ctx.setWidth(sp.getWidth());
ctx.setHeight(sp.getHeight());
ctx.setX(sp.getX());
ctx.setY(sp.getY());
AddJPAEntityFeature ft = new AddJPAEntityFeature(getFeatureProvider());
ft.add(ctx);
}
}
}
});
getDiagramEditor().saveWithoutEntities(new NullProgressMonitor());
// delete old pictograms
return false;
}
private void removeConnections() {
Collection<org.eclipse.graphiti.mm.pictograms.Connection> cons = getDiagram().getConnections();
Iterator<org.eclipse.graphiti.mm.pictograms.Connection> consIt = cons.iterator();
Collection<org.eclipse.graphiti.mm.pictograms.Connection> allCons = new HashSet<org.eclipse.graphiti.mm.pictograms.Connection>();
while (consIt.hasNext()) {
org.eclipse.graphiti.mm.pictograms.Connection con = consIt.next();
allCons.add(con);
}
consIt = allCons.iterator();
while (consIt.hasNext()) {
org.eclipse.graphiti.mm.pictograms.Connection con = consIt.next();
RemoveContext ctx = new RemoveContext(con);
RemoveRelationFeature ft = new RemoveRelationFeature(getFeatureProvider());
ft.remove(ctx);
}
}
@Override
public JPADiagramEditor getDiagramEditor() {
return (JPADiagramEditor)super.getDiagramEditor();
}
private JpaProject getTargetJPAProject() {
return ModelIntegrationUtil.getProjectByDiagram(getDiagram().getName());
}
public boolean isAlive() {
return !isDisposed;
}
@Override
public void dispose() {
super.dispose();
setFeatureProvider(null);
isDisposed = true;
}
}