/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.diagram.ui.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.teiid.core.designer.event.EventObjectListener;
import org.teiid.core.designer.event.EventSourceException;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.diagram.ui.DiagramUiConstants;
import org.teiid.designer.metamodels.diagram.AbstractDiagramEntity;
import org.teiid.designer.metamodels.diagram.Diagram;
import org.teiid.designer.runtime.spi.ITeiidServer;
import org.teiid.designer.runtime.spi.ITeiidServerVersionListener;
import org.teiid.designer.runtime.version.spi.ITeiidServerVersion;
import org.teiid.designer.ui.UiPlugin;
import org.teiid.designer.ui.event.ModelResourceEvent;
import org.teiid.designer.ui.viewsupport.ModelObjectUtilities;
/**
* @author BLaFond
*
* This class contains static utility methods which cashe the diagramEntity-eObject maps and
* allow quick access to find DE's, instead of interating through the lists.
*
* @since 8.0
*/
public class DiagramEntityManager {
private static HashMap diagramMap;
private static final String MMUUID = "mmuuid"; //$NON-NLS-1$
private static boolean clearingStaleDiagrams = false;
private static EventObjectListener eventObjectListener;
private static ITeiidServerVersionListener teiidServerVersionListener;
private static boolean debugPrint = false;
static {
// Need to register a new listener here.
eventObjectListener = new EventObjectListener() {
@Override
public void processEvent(EventObject event) {
DiagramEntityManager.processEvent(event);
}
};
try {
UiPlugin.getDefault().getEventBroker().addListener(ModelResourceEvent.class, eventObjectListener);
} catch (EventSourceException e) {
DiagramUiConstants.Util.log(IStatus.ERROR, e, e.getMessage());
}
teiidServerVersionListener = new ITeiidServerVersionListener() {
@Override
public void serverChanged(ITeiidServer server) {
// Nothing to do
}
@Override
public void versionChanged(ITeiidServerVersion version) {
// Clear the diagram cache since the diagrams are invalid given the server version
if (diagramMap != null)
diagramMap.clear();
}
};
ModelerCore.addTeiidServerVersionListener(teiidServerVersionListener);
}
public static void addDiagram(Diagram diagram) {
if( diagramMap == null ) {
diagramMap = new HashMap();
}
String diagramUuid = getDiagramURI(diagram);
// Now we check to see if diagram already has map
if( diagramUuid != null && diagramMap.get(diagramUuid) == null ) {
HashMap newMap = new HashMap();
List diagramChildren = diagram.eContents();
if (diagramChildren != null && !diagramChildren.isEmpty()) {
AbstractDiagramEntity nextDE = null;
String uuid = null;
Iterator iter = diagramChildren.iterator();
while (iter.hasNext() ) {
nextDE = (AbstractDiagramEntity)iter.next();
EObject someDEMO = nextDE.getModelObject();
if( someDEMO != null ) {
uuid = ModelObjectUtilities.getFullUuid(someDEMO);
if( isValidURI(uuid) ) {
if( debugPrint )
System.out.println(" DEM.addEntity() Adding Entity to Map. EObject = " + nextDE); //$NON-NLS-1$
newMap.put(uuid, nextDE);
}
}
}
}
if( debugPrint )
System.out.println(" DEM.addDiagram() Add Diagram To Map = " + diagram); //$NON-NLS-1$
diagramMap.put(diagramUuid, newMap);
}
}
public static void removeDiagram(Diagram diagram) {
if( diagramMap != null ) {
String diagramUuid = getDiagramURI(diagram);
if( diagramUuid != null ) {
HashMap existingMap = (HashMap)diagramMap.get(diagramUuid);
if( existingMap != null ) {
diagramMap.remove(diagramUuid);
if( debugPrint )
System.out.println(" DEM.removeDiagram() Removing Diagram From Map = " + diagram); //$NON-NLS-1$
}
}
}
}
public static void addEntity(Diagram diagram, AbstractDiagramEntity entity, EObject eObject) {
if( diagramMap != null ) {
String diagramUuid = getDiagramURI(diagram);
if( diagramUuid != null ) {
HashMap dMap = (HashMap)diagramMap.get(diagramUuid);
if( dMap != null ) {
String uuid = ModelObjectUtilities.getFullUuid(eObject);
if( isValidURI(uuid) ) {
Object existingDE = dMap.get(uuid);
if( existingDE == null ) {
if( debugPrint )
System.out.println(" DEM.addEntity() Adding Entity to Map. EObject = " + eObject); //$NON-NLS-1$
dMap.put(uuid, entity);
}
}
}
}
}
}
public static void removeEntity(Diagram diagram, EObject eObject) {
if( diagramMap != null ) {
String diagramUuid = getDiagramURI(diagram);
if( diagramUuid != null ) {
HashMap dMap = (HashMap)diagramMap.get(diagramUuid);
if( dMap != null ) {
String uuid = ModelObjectUtilities.getFullUuid(eObject);
if( isValidURI(uuid) ) {
Object existingDE = dMap.get(uuid);
if( existingDE != null ) {
if( debugPrint )
System.out.println(" DEM.removeEntity() Removing Entity From Map. EObject = " + eObject); //$NON-NLS-1$
dMap.remove(uuid);
}
}
}
}
}
}
public static AbstractDiagramEntity getEntity(Diagram diagram, EObject eObject) {
AbstractDiagramEntity existingDE = null;
if( diagramMap != null ) {
String diagramUuid = getDiagramURI(diagram);
if( diagramUuid != null ) {
HashMap dMap = (HashMap)diagramMap.get(diagramUuid);
if( dMap != null ) {
String uuid = ModelObjectUtilities.getFullUuid(eObject);
if( isValidURI(uuid) )
existingDE = (AbstractDiagramEntity)dMap.get(uuid);
}
}
}
return existingDE;
}
public static void cleanDiagramEntities(Diagram diagram) {
String diagramUuid = getDiagramURI(diagram);
if( diagramMap == null ) {
return;
}
HashMap dMap = (HashMap)diagramMap.get(diagramUuid);
if( dMap != null ) {
List deleteList = new ArrayList();
Collection keys = new ArrayList(dMap.keySet());
Iterator iter = keys.iterator();
AbstractDiagramEntity de = null;
String nextKey = null;
Object someRef = null;
while( iter.hasNext() ) {
nextKey = (String)iter.next();
de = (AbstractDiagramEntity)dMap.get(nextKey);
someRef = de.getModelObject();
if( someRef != null && someRef instanceof EObject ) {
EObject realEObject = ModelObjectUtilities.getRealEObject((EObject)someRef);
EObject resolvedEObject = getEObject(nextKey);
if( realEObject == null || resolvedEObject == null ) {
dMap.remove(nextKey);
if( debugPrint )
System.out.println(" DEM.cleanDiagramEntities() Removing Stale Entity From Map. EObject = " + someRef); //$NON-NLS-1$
deleteList.add(de);
continue;
}
// One more check for FULL UUID's that could have changed via refactor/rename
String currentUUID = ModelObjectUtilities.getFullUuid(realEObject);
if( ! currentUUID.equals(nextKey) ) {
dMap.remove(nextKey);
if( debugPrint )
System.out.println(" DEM.cleanDiagramEntities() Removing Stale Entity From Map. EObject = " + someRef); //$NON-NLS-1$
deleteList.add(de);
}
} else {
dMap.remove(nextKey);
deleteList.add(de);
}
}
if( !deleteList.isEmpty() ) {
ModelObjectUtilities.delete(deleteList, false, false, diagram);
}
}
}
public static void cleanUpDiagram(Diagram diagram) {
if( diagram != null ) {
List deleteList = new ArrayList();
Iterator iter = diagram.eContents().iterator();
AbstractDiagramEntity de = null;
Object someRef = null;
while( iter.hasNext() ) {
de = (AbstractDiagramEntity)iter.next();
someRef = de.getModelObject();
if( someRef != null && someRef instanceof EObject ) {
EObject realEObject = ModelObjectUtilities.getRealEObject((EObject)someRef);
if( realEObject == null ) {
deleteList.add(de);
}
} else {
deleteList.add(de);
}
}
if( !deleteList.isEmpty() ) {
ModelObjectUtilities.delete(deleteList, false, false, diagram, false);
}
}
}
private static EObject getEObject(String uri) {
EObject target = null;
if( isValidURI(uri) ) {
URI theURI = URI.createURI(uri);
if( theURI != null ) {
try {
target = ModelerCore.getModelContainer().getEObject(theURI, false);
// Need to
} catch (CoreException e1) {
e1.printStackTrace();
}
}
}
return target;
}
private static String getDiagramURI(Diagram diagram) {
if( diagram.eContainer() != null ) {
String diagramURI = ModelerCore.getModelEditor().getUri(diagram).toString();
if( isValidURI(diagramURI) )
return diagramURI;
}
return null;
}
private static boolean isValidURI(String uri) {
if( uri == null || uri.length() <=6 || uri.indexOf(MMUUID) < 0 )
return false;
return true;
}
//*******************************
public static void processEvent(EventObject obj) {
ModelResourceEvent event = (ModelResourceEvent) obj;
// Return if event concerns closed resource, otherwise subsequent call to checkValidity will cause resource to be
// re-opened
final int eventType = event.getType();
IResource resource = event.getResource();
if( resource != null ) {
switch(eventType) {
case ModelResourceEvent.CLOSED:
case ModelResourceEvent.RELOADED:
case ModelResourceEvent.REMOVED:
case ModelResourceEvent.MOVED:
{
while( !clearingStaleDiagrams ) {
clearStaleDiagrams();
}
clearingStaleDiagrams = false;
} break;
default:
break;
}
}
}
public static void clearStaleDiagrams() {
clearingStaleDiagrams = true;
// Access the Map
// Walk through the list, get each diagram and check for eResource() == NULL
// Add to remove list and the remove them all
if( diagramMap != null ) {
Collection staleKeys = new ArrayList();
Object nextKey = null;
int keyId = 0;
for(Iterator iter = diagramMap.keySet().iterator(); iter.hasNext(); keyId++) {
nextKey = iter.next();
if( nextKey != null ) {
// we need see if the KEY still exists?
EObject eObj = getEObject((String)nextKey);
if( eObj == null || eObj.eIsProxy() || eObj.eResource() == null ) {
if( debugPrint )
System.out.println(" DEM.clearStaleDiagrams() Removing Stale Diagram = " + nextKey); //$NON-NLS-1$
staleKeys.add(nextKey);
}
}
}
if( !staleKeys.isEmpty() ) {
for (Iterator iter = staleKeys.iterator(); iter.hasNext(); ) {
diagramMap.remove(iter.next());
}
}
}
}
}