/*******************************************************************************
* Copyright (c) 2010 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:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.ui.v2;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.DefaultOperationHistory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.wst.sse.sieditor.command.common.AbstractNotificationOperation;
import org.eclipse.wst.sse.sieditor.command.emf.common.BaseNewTypeCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewElementTypeCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewElementTypeWithAddSchemaCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewSimpleTypeCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewSimpleTypeWithAddSchemaCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewStructureTypeCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.NewStructureTypeWithAddSchemaCompositeCommand;
import org.eclipse.wst.sse.sieditor.command.emf.common.setcommandbuilder.DefaultSetTypeCommandBuilder;
import org.eclipse.wst.sse.sieditor.command.emf.common.setcommandbuilder.ISetTypeCommandBuilder;
import org.eclipse.wst.sse.sieditor.command.emf.wsdl.SetDocumentationCommand;
import org.eclipse.wst.sse.sieditor.core.common.Logger;
import org.eclipse.wst.sse.sieditor.model.api.IModelObject;
import org.eclipse.wst.sse.sieditor.model.api.IModelRoot;
import org.eclipse.wst.sse.sieditor.model.api.IWsdlModelRoot;
import org.eclipse.wst.sse.sieditor.model.api.IXSDModelRoot;
import org.eclipse.wst.sse.sieditor.model.utils.EmfWsdlUtils;
import org.eclipse.wst.sse.sieditor.model.utils.ResourceUtils;
import org.eclipse.wst.sse.sieditor.model.utils.StatusUtils;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IDescription;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IFault;
import org.eclipse.wst.sse.sieditor.model.xsd.api.IElement;
import org.eclipse.wst.sse.sieditor.model.xsd.api.ISchema;
import org.eclipse.wst.sse.sieditor.model.xsd.api.IType;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.Facet;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.StructureType;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.UnresolvedType;
import org.eclipse.wst.sse.sieditor.ui.Activator;
import org.eclipse.wst.sse.sieditor.ui.DataTypesEditor;
import org.eclipse.wst.sse.sieditor.ui.ServiceInterfaceEditor;
import org.eclipse.wst.sse.sieditor.ui.i18n.Messages;
import org.eclipse.wst.sse.sieditor.ui.preedit.PreEditService;
import org.eclipse.wst.sse.sieditor.ui.preferences.ServiceInterfaceEditorPreferencePage;
import org.eclipse.wst.sse.sieditor.ui.v2.common.BuiltinTypesHelper;
import org.eclipse.wst.sse.sieditor.ui.v2.common.TypeSearchDialog;
import org.eclipse.wst.sse.sieditor.ui.v2.dt.nodes.impl.ImportedTypesNode;
import org.eclipse.wst.sse.sieditor.ui.v2.eventing.ISIEvent;
import org.eclipse.wst.sse.sieditor.ui.v2.eventing.ISIEventListener;
import org.eclipse.wst.sse.sieditor.ui.v2.eventing.SIEvent;
import org.eclipse.wst.sse.sieditor.ui.v2.factory.TreeNodeMapper;
import org.eclipse.wst.sse.sieditor.ui.v2.nodes.ITreeNode;
import org.eclipse.wst.sse.sieditor.ui.v2.propertyeditor.TypePropertyEditor;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.ISIComponentSearchListProvider;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.ITypeResolver;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.ITypeSelectionDialogDelegate;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.SIEditorSearchListProvider;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.TypeResolverFactory;
import org.eclipse.wst.sse.sieditor.ui.v2.typeselect.TypeSelectionDialogDelegate;
import org.eclipse.wst.sse.sieditor.ui.v2.utils.UIUtils;
import org.eclipse.wst.sse.sieditor.ui.v2.wsdltree.nodes.ImportedServicesNode;
public abstract class AbstractFormPageController implements IFormPageController {
protected IModelRoot model;
protected boolean readOnly; // TODO - the multi page stores that data - get
// it from there from now on?
protected final TreeNodeMapper treeNodeMapper;
protected ArrayList<ISIEventListener> eventListeners;
/**
* This class is providing the common functionality for a Service Interface
* Form Page controller. <br>
* - {@link TreeNodeMapper} instance<br>
* - readOnly state persistence & getter<br>
* - event listeners management and convenience methods for firing events<br>
* - checks if an model object, treeNode or the model it self are able for
* edit<br>
* - provides the list and mapping between the names most common used
* primitive types and them actually<br>
* - used to open the {@link TypeSearchDialog}
*
* @param model
* the model which the Controller will be operating upon
* @param readOnly
* the flag determining if the model is enabled for edit or not
*/
public AbstractFormPageController(final IModelRoot model, final boolean readOnly) {
this.model = model;
this.readOnly = readOnly;
eventListeners = new ArrayList<ISIEventListener>();
treeNodeMapper = new TreeNodeMapper();
}
/**
* Called to determine if the editor is opened with a readOnly resource
*
* @return the read only state of the editor page
*/
public boolean isResourceReadOnly() {
return readOnly;
}
/**
* Method make the controller operate on a new model
*
* @param model
* the model with which the controller will be operating
* @param readOnly
* the mode of access to the model
*/
public void setNewModel(final IModelRoot model, final boolean readOnly) {
this.model = model;
this.readOnly = readOnly;
treeNodeMapper.clearAllNodesFromMap();
final ISIEvent refreshEvent = new SIEvent(ISIEvent.ID_REFRESH_INPUT, null);
// ISIEvent selectEvent = new SIEvent(ISIEvent.ID_SELECT_TREENODE, new
// Object[0]);
for (final ISIEventListener eventListener : eventListeners) {
eventListener.notifyEvent(refreshEvent);
// eventListener.notifyEvent(selectEvent);
}
}
/**
*
* @return The node mapper used to map Model Objects to Tree Nodes
*/
public TreeNodeMapper getTreeNodeMapper() {
return treeNodeMapper;
}
/**
* Adds an FormPage event listener - Listens for errors in SI and errors and
* updates of TreeNodes
*
* @param listener
* the listener
*/
public void addEventListener(final ISIEventListener listener) {
eventListeners.add(listener);
}
/**
* Removes the listener from the list. If not existing in the first place -
* nothing will happen
*
* @param listener
*/
public void removeEventListener(final ISIEventListener listener) {
eventListeners.remove(listener);
}
/**
* Called to notify all registered listeners that the given ITreeNode object
* should be selected
*
* @param treeNode
* the tree node to be selected
*/
protected void fireTreeNodeSelectionEvent(final ITreeNode treeNode) {
final ISIEvent event = new SIEvent(ISIEvent.ID_SELECT_TREENODE, new Object[] { treeNode });
for (final ISIEventListener eventListener : eventListeners) {
eventListener.notifyEvent(event);
}
}
protected void fireTreeNodeSelectionEvent(final IModelObject modelObject) {
final ITreeNode treeNode = getTreeNodeMapper().getTreeNode(modelObject);
fireTreeNodeSelectionEvent(treeNode);
}
protected void fireTreeNodeExpandEvent(final IModelObject modelObject) {
final ITreeNode treeNode = getTreeNodeMapper().getTreeNode(modelObject);
fireTreeNodeExpandEvent(treeNode);
}
protected void fireTreeNodeEditEvent(final IModelObject modelObject) {
final ITreeNode treeNode = getTreeNodeMapper().getTreeNode(modelObject);
fireTreeNodeEditEvent(treeNode);
}
private void fireTreeNodeEditEvent(final ITreeNode treeNode) {
fireEvent(ISIEvent.ID_EDIT_TREENODE, treeNode);
}
/**
* notifies all registered listener that the given ITreeNode should be
* expanded
*
* @param treeNode
*/
protected void fireTreeNodeExpandEvent(final ITreeNode treeNode) {
fireEvent(ISIEvent.ID_TREE_NODE_EXPAND, treeNode);
}
public void fireShowErrorMsgEvent(final String message) {
fireEvent(ISIEvent.ID_ERROR_MSG, message);
}
private void fireEvent(final int eventType, final Object parameter) {
final ISIEvent event = new SIEvent(eventType, new Object[] { parameter });
for (final ISIEventListener eventListener : eventListeners) {
eventListener.notifyEvent(event);
}
}
/**
* Called in order to determine if the provided object is an editable one.<br>
* The original implementation is not using the individual objects and
* directly using the model root,<br>
* due to the problem of incorrect object being passed and for dtr pre-edit
* case for wsdl,<br>
* object level change means a file level change.
*
* @param editedObject
* the object for which the check will be done
* @return true if edit is allowed, false otherwise.
*/
protected boolean isEditAllowed(final Object editedObject) {
// not using the individual objects and directly using the model root
// due to the problem of incorrect object being passed
// and for dtr pre-edit case for wsdl, object level change means a file
// level change
return !isResourceReadOnly() && PreEditService.getInstance().startEdit(model);
}
/**
* Called in order to determine if the provided object can be deleted.<br>
* The original implementation is not using the individual objects and
* directly using the model root,<br>
* due to the problem of incorrect object being passed and for dtr pre-edit
* case for wsdl,<br>
* object level change means a file level change.
*
* @param editedObject
* the object for which the check will be done
* @return true if delete is allowed, false otherwise.
*/
protected boolean isDeleteAllowed(final Object editedObject) {
// not using the individual objects and directly using the model root
// due to the problem of incorrect object being passed
// and for dtr pre-edit case for wsdl, object level change means a file
// level change
return !isResourceReadOnly() && PreEditService.getInstance().startDelete(model);
}
// TODO - refactor this one, it's going to be used?
/**
* Determines if the model object that the treeNode is representing is an
* editable one
*
* @return true if it is editable, false otherwise
*/
public boolean canEdit(final ITreeNode node) {
if (null == node || null == node.getModelObject()) { // TODO is this
// check necessary
return false;
}
return isEditAllowed(node.getModelObject());
}
/**
* Used to retrieve a list of most often used type names
*
* @return the list of type names
*/
@Override
public String[] getCommonTypesDropDownList() {
final String[] primTypes = BuiltinTypesHelper.getInstance().getCommonlyUsedTypeNames();
final String[] ret = new String[primTypes.length + 1];
ret[0] = Messages.TypePropertyEditor_browse_button;
for (int i = 0, j = 1; i < primTypes.length; i++, j++) {
ret[j] = primTypes[i];
}
return ret;
}
public void editDocumentation(final ITreeNode treeNode, final String text) {
// TODO do some checks only if necessary
AbstractNotificationOperation command = null;
final IModelObject modelObject = treeNode.getModelObject();
if (modelObject instanceof Facet) {
// do nothing
return;
}
if (model instanceof IWsdlModelRoot) {
command = new SetDocumentationCommand(model, modelObject, ((WSDLElement) modelObject.getComponent()).getElement(),
text);
} else if (model instanceof IXSDModelRoot) {
command = new org.eclipse.wst.sse.sieditor.command.emf.xsd.SetDocumentationCommand(model, modelObject, text);
} else {
Logger
.log(new Status(
IStatus.ERROR,
Activator.PLUGIN_ID,
"Failed to edit element documentation " + treeNode.getDisplayName() + " override set documentation to use the correct command")); //$NON-NLS-1$//$NON-NLS-2$
}
try {
final IStatus status = model.getEnv().execute(command);
if (!StatusUtils.canContinue(status)) {
StatusUtils.showStatusDialog(Messages.SIFormPageController_dlg_title_edit_documentation,
Messages.SIFormPageController_msg_failure_edit_documentation, status);
return;
}
} catch (final ExecutionException e) {
Logger.log(Activator.PLUGIN_ID, IStatus.ERROR, "Failed to edit element documentation " + treeNode.getDisplayName(), //$NON-NLS-1$
e);
}
}
private IEditorInput editorInput;
public void setEditorInput(final IEditorInput editorInput) {
this.editorInput = editorInput;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.wst.sse.sieditor.ui.v2.IFormPageController#openTypesDialog
* ()
*/
public IType openTypesDialog() {
return openTypesDialog(Messages.AbstractFormPageController_type_wizard_display_text, null, true);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.wst.sse.sieditor.ui.v2.IFormPageController#openTypesDialog
* (java.lang.String, boolean)
*/
public IType openTypesDialog(final String displayText, final IModelObject selectedModelObject, final boolean showComplexTypes) {
// could be null
final IFile editorFile = (IFile) editorInput.getAdapter(IFile.class);
IType result = null;
final IModelObject modelObject = getModelObject();
final ITypeResolver typeResolver = TypeResolverFactory.getInstance().createTypeResolver(modelObject);
final XSDSchema[] schemas = typeResolver.getLocalSchemas();
final ITypeSelectionDialogDelegate dialog = createTypeSelectionDialog(editorFile, schemas, displayText,
selectedModelObject, showComplexTypes);
final boolean[] bool = { false };
final AbstractEMFOperation op = new AbstractEMFOperation(model.getEnv().getEditingDomain(), "Load selected types") { //$NON-NLS-1$
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
bool[0] = dialog.open();
return Status.OK_STATUS;
}
};
try {
new DefaultOperationHistory().execute(op, null, null);
} catch (final ExecutionException e) {
Logger.logError(e.getMessage(), e);
return UnresolvedType.instance();
}
if (bool[0]) {
final Object selectedObject = dialog.getSelectedObject();
if (selectedObject instanceof XSDNamedComponent) {
result = typeResolver.resolveType((XSDNamedComponent) selectedObject);
}
if (result == null) {
final String name = dialog.getSelectedTypeName();
final String namespace = dialog.getSelectedTypeNamespace();
final IFile file = dialog.getSelectedTypeFile();
if (file != null) {
result = typeResolver.resolveType(name, namespace, file);
} else {
throw new IllegalStateException("Cannot find XSD type " + new QName(namespace, name)); //$NON-NLS-1$
}
}
}
return result;
// old logic
// return
// TypesDialogCreator.getInstance().openTypesDialog(getModelObject());
}
/*
* For mocking
*/
protected ITypeSelectionDialogDelegate createTypeSelectionDialog(final IFile editorFile, final XSDSchema[] schemas,
final String displayText, final IModelObject selectedModelObject, final boolean showComplexTypes) {
final TypeSelectionDialogDelegate typeSelectionDialog = new TypeSelectionDialogDelegate(editorFile, schemas);
final Shell shell = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
typeSelectionDialog.create(shell, displayText, createSearchListProvider(selectedModelObject, editorFile, schemas,
showComplexTypes));
return typeSelectionDialog;
}
/**
* Template method used to create the list provider for the type search
* dialog. The type search dialog could be created in a couple of different
* fashions: Showing complex types or not, showing global elements or not,
* and filterin out one type.
*
* @param selectedModelObject
* the selected model object according to which the custom
* content of the list should be defined. In the Default
* implementation - the type to be filtered and the existance ot
* complex types and global elements in the list isdefined by
* this parameter
* @param contextFile
* the file needed to create the provider
* @param schemas
* the schemas included
* @return the newly created provider
*/
protected ISIComponentSearchListProvider createSearchListProvider(final IModelObject selectedModelObject,
final IFile contextFile, final XSDSchema[] schemas, boolean showComplexTypes) {
IType typeToFilter = null;
boolean localShowComplexTypes = false;
boolean showElements = false;
boolean showSimpleTypes = true;
if (selectedModelObject instanceof IFault) {
showSimpleTypes = false;
localShowComplexTypes = false;
showElements = true;
} else if (selectedModelObject instanceof IElement) {
if (!((IElement) selectedModelObject).isAttribute()) {
localShowComplexTypes = true;
showElements = true;
}
} else if (selectedModelObject instanceof IType) {
typeToFilter = (IType) selectedModelObject;
if (typeToFilter instanceof StructureType) {
localShowComplexTypes = true;
if (!((StructureType) typeToFilter).isElement()) {
showElements = false;
}
}
}
// consider the PropertyEditor's opinion
showComplexTypes &= localShowComplexTypes;
final SIEditorSearchListProvider searchListProvider = new SIEditorSearchListProvider(contextFile, schemas, showElements,
showComplexTypes, showSimpleTypes);
searchListProvider.setTypeToFilter(typeToFilter);
return searchListProvider;
}
protected abstract IModelObject getModelObject();
protected abstract String getEditorID();
abstract protected ITreeNode getNextTreeNode(final ITreeNode selectedTreeNode);
protected ITreeNode getNextSiblingTreeNode(final ITreeNode selectedTreeNode, final Object[] siblings) {
int index = 0;
// getting the index of the current node
for (int i = 0; i < siblings.length; i++) {
if (selectedTreeNode.equals(siblings[i])) {
index = i;
break;
}
}
if (index == siblings.length - 1) {
if (siblings.length == 1) { // returning the parent node
return selectedTreeNode.getParent();
}
return (ITreeNode) siblings[index - 1]; // returning the
// previous node
}
return (ITreeNode) siblings[index + 1]; // returning the next node
}
@Override
public boolean areAllItemsPartOfEditedDocument(final List<? extends ITreeNode> items) {
if (items == null) {
return true;
}
if (items.size() == 1 && (items.get(0) instanceof ImportedTypesNode || items.get(0) instanceof ImportedServicesNode)) {
return true;
}
for (final ITreeNode item : items) {
if ((item.getCategories() & ITreeNode.CATEGORY_IMPORTED) == ITreeNode.CATEGORY_IMPORTED) {
return false;
}
}
return true;
}
public boolean isPartOfEdittedDocument(final IModelObject modelObject) {
return EmfWsdlUtils.isModelObjectPartOfModelRoot(model, modelObject);
}
public void openInNewEditor(final ITreeNode node) {
if (node == null) {
return;
}
IPath rootPath = null;
String importedLocation = null;
final IModelObject modelObject = node.getModelObject();
final IDescription referredDescription = EmfWsdlUtils.getReferredDescription(modelObject);
final ISchema referedSchema = EmfWsdlUtils.getReferredSchema(modelObject);
if (referredDescription != null) {
final IDescription rootDescription = ((IWsdlModelRoot) referredDescription.getModelRoot()).getDescription();
rootPath = new Path(rootDescription.getLocation());
rootPath = rootPath.removeLastSegments(1);
importedLocation = referredDescription.getLocation();
} else if (referedSchema != null) {
final ISchema rootSchema = ((IXSDModelRoot) referedSchema.getModelRoot()).getSchema();
rootPath = new Path(rootSchema.getLocation());
rootPath = rootPath.removeLastSegments(1);
importedLocation = referedSchema.getLocation();
}
if (importedLocation != null) {
final IPath path = new Path(rootPath.toOSString() + File.separator + importedLocation);
openInNewEditor(path, getEditorID());
}
}
public void openInNewEditor(final IType type) {
if (type == null) {
return;
}
// do not use type.getSchema(), because it has relative URI
// Construct full path
final ISchema importedSchema = type.getParent();
String rootPathString = null;
if (importedSchema.getParent() instanceof IDescription) {
rootPathString = ((IWsdlModelRoot) importedSchema.getParent().getModelRoot()).getDescription().getLocation();
} else {
rootPathString = ((IXSDModelRoot) importedSchema.getModelRoot()).getSchema().getLocation();
}
IPath rootPath = new Path(rootPathString);
rootPath = rootPath.removeLastSegments(1);
final String importedLocation = importedSchema.getLocation();
final IPath path = new Path(rootPath.toOSString() + File.separator + importedLocation);
final String editorID = importedSchema.getParent() instanceof IDescription ? ServiceInterfaceEditor.EDITOR_ID
: DataTypesEditor.EDITOR_ID;
openInNewEditor(path, editorID);
}
public boolean isOpenInNewEditorEnabled(final ITreeNode iTreeNode) {
final IModelObject modelObject = iTreeNode.getModelObject();
if (modelObject == null) {
return false;
}
return !EmfWsdlUtils.isModelObjectPartOfModelRoot(modelObject.getModelRoot(), modelObject);
}
private void openInNewEditor(final IPath path, final String editorID) {
final IFile file = ResourceUtils.getWorkSpaceFile(path);
boolean hasError = file == null;
if (file != null) {
try {
final IWorkbenchWindow window = getActiveWorkbenchWindow();
final FileEditorInput eInput = new FileEditorInput(file);
final IWorkbenchPage workbenchActivePage = window.getActivePage();
final IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();
final String doNotShow = preferenceStore
.getString(ServiceInterfaceEditorPreferencePage.EDIT_REFERENCED_POPUP_NOT_SHOW_AGAIN);
if (UIConstants.EMPTY_STRING.equals(doNotShow)) {
showWarningMessage(window, preferenceStore);
}
workbenchActivePage.openEditor(eInput, editorID);
} catch (final PartInitException e) {
Logger.log(Activator.PLUGIN_ID, IStatus.ERROR, "Can not open editor for file: " //$NON-NLS-1$
+ file.getFullPath().toString(), e);
hasError = true;
}
}
if (hasError) {
final IStatus statusToShow = new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(
Messages.AbstractFormPageController_4, path.toString()));
StatusUtils.showStatusDialog(Messages.AbstractFormPageController_5, statusToShow);
}
}
protected IWorkbenchWindow getActiveWorkbenchWindow() {
return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
}
protected void showWarningMessage(final IWorkbenchWindow window, final IPreferenceStore preferenceStore) {
MessageDialogWithToggle.openWarning(window.getShell(), Messages.AbstractFormPageController_0,
Messages.AbstractFormPageController_1, Messages.AbstractFormPageController_2, false, preferenceStore,
ServiceInterfaceEditorPreferencePage.EDIT_REFERENCED_POPUP_NOT_SHOW_AGAIN);
}
// ===========================================================
// new type command execution helpers
// ===========================================================
@Override
public void newElementType(final String name, final ISchema schema, final TypePropertyEditor propertyEditor) {
final ISetTypeCommandBuilder setTypeCommandBuilder = createNewTypeSetTypeCommandBuilder(propertyEditor);
BaseNewTypeCompositeCommand command = null;
if (schema == null) {
command = new NewElementTypeWithAddSchemaCompositeCommand(getModelObject().getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_element_type, setTypeCommandBuilder, name);
} else {
command = new NewElementTypeCompositeCommand(schema.getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_element_type, schema, name, setTypeCommandBuilder);
}
executeNewTypeCommand(command, name);
postExecuteNewTypeCommand(command.getType(), propertyEditor.getInput().getModelObject());
}
@Override
public void newSimpleType(final String name, final ISchema schema, final TypePropertyEditor propertyEditor) {
final ISetTypeCommandBuilder setTypeCommandBuilder = createNewTypeSetTypeCommandBuilder(propertyEditor);
BaseNewTypeCompositeCommand command = null;
if (schema == null) {
command = new NewSimpleTypeWithAddSchemaCompositeCommand(getModelObject().getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_simple_type, setTypeCommandBuilder, name);
} else {
command = new NewSimpleTypeCompositeCommand(schema.getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_simple_type, schema, name, setTypeCommandBuilder);
}
executeNewTypeCommand(command, name);
postExecuteNewTypeCommand(command.getType(), propertyEditor.getInput().getModelObject());
}
@Override
public void newStructureType(final String name, final ISchema schema, final TypePropertyEditor propertyEditor) {
final ISetTypeCommandBuilder setTypeCommandBuilder = createNewTypeSetTypeCommandBuilder(propertyEditor);
BaseNewTypeCompositeCommand command = null;
if (schema == null) {
command = new NewStructureTypeWithAddSchemaCompositeCommand(getModelObject().getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_structure_type, setTypeCommandBuilder, name);
} else {
command = new NewStructureTypeCompositeCommand(schema.getModelRoot(), getModelObject(),
Messages.AbstractFormPageController_cmd_label_new_structure_type, schema, name, setTypeCommandBuilder);
}
executeNewTypeCommand(command, name);
postExecuteNewTypeCommand(command.getType(), propertyEditor.getInput().getModelObject());
}
/**
* Utility method. Notifies the listeners that the g
*
* @param newModelObject
*/
protected void postExecuteNewTypeCommand(final IModelObject newModelObject, final IModelObject sourceModelObject) {
fireTreeNodeExpandEvent(newModelObject);
if (sourceModelObject != null && newModelObject.getModelRoot() != sourceModelObject.getModelRoot()) {
fireTreeNodeSelectionEvent(sourceModelObject);
} else {
fireTreeNodeSelectionEvent(newModelObject);
}
}
/**
* utility method. creates the set type command builder for the new element
* type
*
* @param propertyEditor
* - the {@link TypePropertyEditor} from which the method call is
* issued
* @return the created set type command builder for the new element type
*/
protected ISetTypeCommandBuilder createNewTypeSetTypeCommandBuilder(final TypePropertyEditor propertyEditor) {
if (propertyEditor.getInput().getModelObject().getModelRoot() instanceof IWsdlModelRoot) {
final IModelObject modelObject = UIUtils.instance().getParameterFromUINode(propertyEditor.getInput());
return new DefaultSetTypeCommandBuilder(modelObject);
}
if (propertyEditor.getInput().getModelObject().getModelRoot() instanceof IXSDModelRoot) {
return new DefaultSetTypeCommandBuilder(propertyEditor.getInput().getModelObject());
}
return null;
}
/**
* Utility method. Executes the {@link AbstractNewTypeCommand} command. Logs
* any {@link ExecutionException}s. Displays error dialog if the execution
* status was not {@link IStatus#OK}
*
* @param command
* - the command to execute
* @param typeName
* - the name of the new type (for display purposes only)
*/
protected void executeNewTypeCommand(final BaseNewTypeCompositeCommand command, final String typeName) {
try {
final IStatus status = getModelObject().getModelRoot().getEnv().execute(command);
if (!status.isOK()) {
StatusUtils.showStatusDialog(Messages.AbstractFormPageController_dlg_title_new_type, MessageFormat.format(
Messages.AbstractFormPageController_dlg_err_msg_new_type, typeName), status);
}
} catch (final ExecutionException e) {
Logger.log(Activator.PLUGIN_ID, IStatus.ERROR, "Failed to create new type", e); //$NON-NLS-1$
}
}
}