/*******************************************************************************
* Copyright (c) 2008 Conselleria de Infraestructuras y Transporte,
* Generalitat de la Comunitat Valenciana .
* 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: Francisco Javier Cano Muñoz (Prodevelop) - initial API implementation
*
******************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.part;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.core.DiagramEditingDomainFactory;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocumentProvider;
import org.eclipse.papyrus.uml.diagram.common.util.MDTUtil;
import org.eclipse.papyrus.uml.diagram.common.util.PathsUtil;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
// TODO: Auto-generated Javadoc
/**
* The Class EditingDomainRegistry.
*
* @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Muñoz</a>
*/
public class EditingDomainRegistry extends HashMap<String, TransactionalEditingDomain> implements IPartListener2 {
/** The instance. */
private static EditingDomainRegistry instance = null;
/** The listening. */
private boolean listening = false;
/** The changing cached editors. */
private boolean changingCachedEditors = false;
/**
* Instantiates a new editing domain registry.
*/
private EditingDomainRegistry() {
return;
}
/**
* Gets the single instance of EditingDomainRegistry.
*
* @return single instance of EditingDomainRegistry
*/
public static EditingDomainRegistry getInstance() {
if(instance == null) {
instance = new EditingDomainRegistry();
}
return instance;
}
/**
* Start listening.
*/
private void startListening() {
if(listening) {
return;
}
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(instance);
listening = true;
} catch (NullPointerException e) {
;
}
}
// //
/**
* Calculate key.
*
* @param editorID
* the editor id
* @param uri
* the uri
*
* @return the string
*/
protected String calculateKey(String editorID, String uri) {
uri = PathsUtil.fromAbsoluteFileSystemToAbsoluteWorkspace(uri);
String key = ((uri != null) ? (editorID + uri) : editorID);
return key;
}
/**
* Gets the.
*
* @param editorID
* the editor id
* @param uri
* the uri
*
* @return the transactional editing domain
*/
public TransactionalEditingDomain get(String editorID, String uri) {
// we need to listen to editors closing
startListening();
// new get method
String key = calculateKey(editorID, uri);
TransactionalEditingDomain oldDomain = null;
TransactionalEditingDomain newDomain = null;
if(containsKey(key)) {
oldDomain = super.get(key);
oldDomain.getCommandStack().flush();
return oldDomain;
}
newDomain = DiagramEditingDomainFactory.getInstance().createEditingDomain();
newDomain.setID(editorID);
final NotificationFilter diagramResourceModifiedFilter = NotificationFilter.createNotifierFilter(newDomain.getResourceSet()).and(NotificationFilter.createEventTypeFilter(Notification.ADD)).and(NotificationFilter.createFeatureFilter(ResourceSet.class, ResourceSet.RESOURCE_SET__RESOURCES));
newDomain.getResourceSet().eAdapters().add(new Adapter() {
private Notifier myTarget;
public Notifier getTarget() {
return myTarget;
}
public boolean isAdapterForType(Object type) {
return false;
}
public void notifyChanged(Notification notification) {
if(diagramResourceModifiedFilter.matches(notification)) {
Object value = notification.getNewValue();
if(value instanceof Resource) {
((Resource)value).setTrackingModification(true);
}
}
}
public void setTarget(Notifier newTarget) {
myTarget = newTarget;
}
});
put(key, newDomain);
return newDomain;
}
/*
* (non-Javadoc)
*
* @see java.util.HashMap#get(java.lang.Object)
*/
@Override
public TransactionalEditingDomain get(Object okey) {
if(okey == null || okey instanceof String == false) {
return null;
}
return get((String)okey, null);
}
/**
* Gets the uri from i editor input.
*
* @param input
* the input
*
* @return the uri from i editor input
*/
private String getUriFromIEditorInput(IEditorInput input) {
String uri = null;
if(input instanceof FileEditorInput) {
uri = ((FileEditorInput)input).getPath().toString();
uri = MDTUtil.fullFilePathToResourceURI(uri).toString();
} else if(input instanceof URIEditorInput) {
uri = ((URIEditorInput)input).getURI().trimFragment().toString();
}
return uri;
}
/**
* Gets the iD from editor.
*
* @param editor
* the editor
*
* @return the iD from editor
*/
private String getIDFromEditor(IEditorPart editor) {
if(editor instanceof CachedResourcesDiagramEditor) {
IDocumentProvider documentProvider = ((CachedResourcesDiagramEditor)editor).getDocumentProvider();
if(documentProvider instanceof CachedResourcesDocumentProvider) {
return ((CachedResourcesDocumentProvider)documentProvider).getEditingDomainID();
}
}
return null;
}
/**
* Clean registry.
*
* @param partReference
* the part reference
*/
private void cleanRegistry(IWorkbenchPartReference partReference) {
if(isChangingCachedEditors()) {
return;
}
if(partReference instanceof IEditorReference) {
List<IEditorReference> editors = new ArrayList<IEditorReference>();
for(IEditorReference editorReference : partReference.getPage().getEditorReferences()) {
editors.add(editorReference);
}
// editors.add((IEditorReference) partReference);
cleanRegistry(editors);
}
}
/**
* Clean registry.
*
* @param editors
* the editors
*/
private void cleanRegistry(List<IEditorReference> editors) {
// get keys list from open editors
List<String> keys = new ArrayList<String>();
for(IEditorReference editor : editors) {
IEditorPart editorPart = editor.getEditor(false);
if(editorPart != null) {
String uri = getUriFromIEditorInput(editorPart.getEditorInput());
String id = getIDFromEditor(editorPart);
String key = calculateKey(id, uri);
keys.add(key);
}
}
// find keys that are no longer in use
List<String> keysToRemove = new ArrayList<String>();
for(String key : keySet()) {
if(keys.contains(key) == false) {
keysToRemove.add(key);
}
}
// remove unused keys
for(Entry<String, TransactionalEditingDomain> entry : entrySet()) {
if(keysToRemove.contains(entry.getKey())) {
entry.getValue().dispose();
}
}
for(String key : keysToRemove) {
remove(key);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partActivated(IWorkbenchPartReference partRef) {
// nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partBroughtToTop(IWorkbenchPartReference partRef) {
// nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partClosed(IWorkbenchPartReference partRef) {
cleanRegistry(partRef);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partDeactivated(IWorkbenchPartReference partRef) {
// nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partHidden(IWorkbenchPartReference partRef) {
// nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partInputChanged(IWorkbenchPartReference partRef) {
cleanRegistry(partRef);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partOpened(IWorkbenchPartReference partRef) {
// nothing to do
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void partVisible(IWorkbenchPartReference partRef) {
// nothing to do
}
/**
* Checks if is changing cached editors.
*
* @return true, if is changing cached editors
*/
public boolean isChangingCachedEditors() {
return changingCachedEditors;
}
/**
* Sets the changing cached editors.
*
* @param changingCachedEditors
* the new changing cached editors
*/
public void setChangingCachedEditors(boolean changingCachedEditors) {
this.changingCachedEditors = changingCachedEditors;
}
}