/*
* 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.core.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.core.ModelerCore;
/** The NewModelObjectHelperManager collects all extensions of this type and provides the hooks to do the work.
*
* The <code>INewModelObjectHelper</code> interface provides plugins the capability to contribute to the creation of new objects
* The primary use case lies in creating virtual tables. Defect 18433 pointed out that the user could
* not UNDO the creation with one undo. There were other symptoms, but the reality was, some additional work
* was being performed (Creating transformation roots and helpers) by notification listeners, etc. This interface
* allows the work to be done up-front and creates a more concrete set of work.
* To generically contribute an implementation of this interface, use the org.teiid.designer.ui.newModelObjectHelper
* extension point ID.
*
* @since 8.0
*/
public abstract class NewModelObjectHelperManager {
private static final String ID = "newModelObjectHelper"; //$NON-NLS-1$
private static final String CLASS = "class"; //$NON-NLS-1$
private static final String CLASSNAME = "name"; //$NON-NLS-1$
private static List helpersCache;
private static boolean helpersLoaded = false;
public static INewModelObjectHelper[] getHelpers(Object newObject) {
CoreArgCheck.isNotNull(newObject);
HashSet helpers = new HashSet();
if( !helpersLoaded )
loadHelperExtensions();
if( helpersCache != null ) {
// walk through the helpers and ask
INewModelObjectHelper nextHelper = null;
for( Iterator iter = helpersCache.iterator(); iter.hasNext(); ) {
nextHelper = (INewModelObjectHelper)iter.next();
if( nextHelper.canHelpCreate(newObject) ) {
helpers.add(nextHelper);
}
}
}
return (INewModelObjectHelper[])helpers.toArray(new INewModelObjectHelper[helpers.size()]);
}
private static void loadHelperExtensions() {
helpersCache = new ArrayList();
helpersLoaded = true;
// get the NewChildAction extension point from the plugin class
IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(ModelerCore.PLUGIN_ID, ID);
// get the all extensions to the NewChildAction extension point
IExtension[] extensions = extensionPoint.getExtensions();
// walk through the extensions and find all INewChildAction implementations
for ( int i=0 ; i<extensions.length ; ++i ) {
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
try {
// first, find the content provider instance and add it to the instance list
for ( int j=0 ; j<elements.length ; ++j ) {
if ( elements[j].getName().equals(CLASS)) {
Object helper = elements[j].createExecutableExtension(CLASSNAME);
if ( helper instanceof INewModelObjectHelper ) {
helpersCache.add(helper);
}
}
}
} catch (Exception e) {
// catch any Exception that occurred obtaining the configuration and log it
String message = ModelerCore.Util.getString("NewModelObjectHelperManager.loadHelperExtensionsErrorMessage", //$NON-NLS-1$
extensions[i].getUniqueIdentifier());
ModelerCore.Util.log(IStatus.ERROR, e, message);
}
}
}
public static boolean helpCreate(Object newObject, Map properties, List<EObject> references) throws ModelerCoreException {
CoreArgCheck.isNotNull(newObject);
// Set default behavior to undoable. This is the behavior of the UnitOfWorkImpl.
boolean canUndo = true;
// Defect 18433 - BML 8/31/05 - Added this manager and INewModelObjectHelper interface to give arbitary
// plugins the change to contribute more work following the creation of a new object
// In the case of a Virtual Group, we needed to create the transformation for that table so it didn't
// get lazily created as another "Undo" event. (i.e. TransformationNotificationListener, EditAction,, etc.)
// If Helper exists, ask for helpCreate(newObj)
// The helper also has the opportunity to change/override the "Undo" state of the transaction
// Get all applicable helpers
INewModelObjectHelper[] helpers = getHelpers(newObject);
boolean undoHelp = true;
// Walk through each and ask to help create additional objects
for( int i=0; i<helpers.length; i++ ) {
undoHelp = helpers[i].helpCreate(newObject, properties, references);
// if any helper says it can't undo the work, then we set the canUndo for the entire operation
if( !undoHelp && canUndo )
canUndo = false;
}
return canUndo;
}
public static boolean helpCreate(Object newObject, Map properties) throws ModelerCoreException {
CoreArgCheck.isNotNull(newObject);
// Set default behavior to undoable. This is the behavior of the UnitOfWorkImpl.
boolean canUndo = true;
// Defect 18433 - BML 8/31/05 - Added this manager and INewModelObjectHelper interface to give arbitary
// plugins the change to contribute more work following the creation of a new object
// In the case of a Virtual Group, we needed to create the transformation for that table so it didn't
// get lazily created as another "Undo" event. (i.e. TransformationNotificationListener, EditAction,, etc.)
// If Helper exists, ask for helpCreate(newObj)
// The helper also has the opportunity to change/override the "Undo" state of the transaction
// Get all applicable helpers
INewModelObjectHelper[] helpers = getHelpers(newObject);
boolean undoHelp = true;
// Walk through each and ask to help create additional objects
for( int i=0; i<helpers.length; i++ ) {
undoHelp = helpers[i].helpCreate(newObject, properties, null);
// if any helper says it can't undo the work, then we set the canUndo for the entire operation
if( !undoHelp && canUndo )
canUndo = false;
}
return canUndo;
}
}