// ============================================================================
//
// Copyright (C) 2006-2016 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package com.amalto.workbench.actions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Event;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDIdentityConstraintCategory;
import org.eclipse.xsd.XSDIdentityConstraintDefinition;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDXPathDefinition;
import org.eclipse.xsd.XSDXPathVariety;
import org.eclipse.xsd.impl.XSDElementDeclarationImpl;
import com.amalto.workbench.editors.DataModelMainPage;
import com.amalto.workbench.i18n.Messages;
import com.amalto.workbench.image.EImage;
import com.amalto.workbench.image.ImageCache;
import com.amalto.workbench.providers.datamodel.SchemaTreeContentProvider;
import com.amalto.workbench.utils.Util;
public class XSDDeleteConceptWrapAction extends UndoAction {
private static Log log = LogFactory.getLog(XSDDeleteConceptWrapAction.class);
private TreeViewer viewer = null;
private XSDDeleteConceptAction deleteConceptAction = null;
private List<XSDConcreteComponent> delObjs = new ArrayList<XSDConcreteComponent>();
private Map<Class, UndoAction> clsAction = new HashMap<Class, UndoAction>();
private List<Class> extraClsToDel = new ArrayList<Class>();
public XSDDeleteConceptWrapAction(DataModelMainPage page) {
super(page);
viewer = page.getTreeViewer();
setImageDescriptor(ImageCache.getImage(EImage.DELETE_OBJ.getPath()));
}
public void regisDelAction(Class cls, UndoAction action) {
clsAction.put(cls, action);
}
public void regisExtraClassToDel(Class cls) {
extraClsToDel.add(cls);
}
public void clearExtraClassToDel() {
extraClsToDel.clear();
}
@Override
public IStatus doAction() {
List<IStatus> results = new ArrayList<IStatus>();
try {
IStructuredSelection selection = (IStructuredSelection) page.getTreeViewer().getSelection();
if (delObjs.isEmpty()) {
return Status.CANCEL_STATUS;
} else {
boolean sameType = checkInSameClassType(delObjs.toArray(), delObjs.get(0).getClass());
String deleteLabel = Messages.DelLabel1;
String elemDesc = ((Action) clsAction.get(delObjs.get(0).getClass())).getText();
int backPos = elemDesc.indexOf(" "); //$NON-NLS-1$
if (delObjs.size() > 1) {
deleteLabel += elemDesc.substring(0, backPos) + Messages.DelLabel2 + delObjs.size() + Messages.DelLabel2A
+ (!sameType ? Messages.DelLabel2B : elemDesc.substring(backPos + 1));
if (deleteLabel.endsWith("y")) {//$NON-NLS-1$
deleteLabel = deleteLabel.substring(0, deleteLabel.length() - 1) + Messages.DelLabel3;
} else {
deleteLabel = deleteLabel + Messages.XSDDeleteXX_DelLabel4;
}
} else {
deleteLabel += elemDesc.substring(0, backPos) + Messages.XSDDeleteXX_DelLabel5
+ (!sameType ? Messages.XSDDeleteXX_DelLabel5A : elemDesc.substring(backPos + 1));
}
if (!MessageDialog.openConfirm(page.getSite().getShell(), Messages.XSDDeleteXX_DialogTitle, deleteLabel)) {
return Status.CANCEL_STATUS;
}
}
for (Iterator iterator = delObjs.iterator(); iterator.hasNext();) {
Object toDel = iterator.next();
UndoAction delExecute = null;
boolean isElem = true;
if (toDel instanceof XSDElementDeclaration) {
XSDElementDeclaration decl = (XSDElementDeclaration) toDel;
EList l = decl.getIdentityConstraintDefinitions();
for (Iterator iter = l.iterator(); iter.hasNext();) {
XSDIdentityConstraintDefinition icd = (XSDIdentityConstraintDefinition) iter.next();
if (icd.getIdentityConstraintCategory().equals(XSDIdentityConstraintCategory.UNIQUE_LITERAL)) {
isElem = false;
break;
}
}
}
if (toDel instanceof XSDXPathDefinition) {
XSDXPathDefinition xpath = (XSDXPathDefinition) toDel;
if (!xpath.getVariety().equals(XSDXPathVariety.FIELD_LITERAL)) {
continue;
}
}
delExecute = clsAction.get(toDel.getClass());
if (isElem && toDel instanceof XSDElementDeclaration) {
delExecute = clsAction.get(null);
}
if (delExecute instanceof XSDDeleteConceptAction && toDel instanceof XSDElementDeclaration) {
((XSDDeleteConceptAction) delExecute).setXSDTODel((XSDElementDeclaration) toDel);
} else if (delExecute instanceof XSDDeleteElementAction && toDel instanceof XSDElementDeclaration) {
((XSDDeleteElementAction) delExecute).setXSDTODel((XSDElementDeclaration) toDel);
} else if (delExecute instanceof XSDDeleteParticleAction && toDel instanceof XSDParticle) {
((XSDDeleteParticleAction) delExecute).setXSDTODel((XSDParticle) toDel);
} else if (delExecute instanceof XSDDeleteXPathAction && toDel instanceof XSDXPathDefinition) {
((XSDDeleteXPathAction) delExecute).setXSDTODel((XSDXPathDefinition) toDel);
} else if (delExecute instanceof XSDDeleteIdentityConstraintAction
&& toDel instanceof XSDIdentityConstraintDefinition) {
((XSDDeleteIdentityConstraintAction) delExecute).setXSDTODel((XSDIdentityConstraintDefinition) toDel);
} else if (delExecute instanceof XSDDeleteTypeDefinition && toDel instanceof XSDComplexTypeDefinition) {
((XSDDeleteTypeDefinition) delExecute).setXSDTODel((XSDComplexTypeDefinition) toDel);
} else if (delExecute instanceof XSDDeleteTypeDefinition && toDel instanceof XSDSimpleTypeDefinition) {
((XSDDeleteTypeDefinition) delExecute).setXSDTODel((XSDSimpleTypeDefinition) toDel);
} else if (delExecute instanceof XSDDeleteAttributeAction && toDel instanceof XSDAttributeUse) {
((XSDDeleteAttributeAction) delExecute).setXSDAttributeUse((XSDAttributeUse) toDel);
} else if (delExecute instanceof XSDDeleteAttributeAction && toDel instanceof XSDAttributeDeclaration) {
((XSDDeleteAttributeAction) delExecute).setXSDAttribute((XSDAttributeDeclaration) toDel);
} else {
return Status.CANCEL_STATUS;
}
results.add(delExecute.execute());
}
} catch (Exception e) {
log.error(e.getMessage(), e);
MessageDialog.openError(page.getSite().getShell(), Messages._Error,
Messages.bind(Messages.XSDDeleteXX_ErrorMsg, e.getLocalizedMessage()));
return (results.indexOf(Status.OK_STATUS) >= 0 ? Status.OK_STATUS : Status.CANCEL_STATUS);
}
return (results.indexOf(Status.OK_STATUS) >= 0 ? Status.OK_STATUS : Status.CANCEL_STATUS);
}
private void wrapDelObj(Object[] toDels) {
clearDelData();
for (Object del : toDels) {
if (((XSDConcreteComponent) del).getSchema().getTargetNamespace() == null
&& !Util.IsAImporedElement((XSDConcreteComponent) del, page.reConfigureXSDSchema(false))) {
delObjs.add((XSDConcreteComponent) del);
} else {
delObjs.clear();
break;
}
}
if (delObjs != null) {
refreshAction();
}
}
/**
* author: Fliu it is meant to support multiple deletions on data modules on key press
*
* @param selections: tree node picking up in the data module view
*/
public void prepareToDelSelectedItems(IStructuredSelection selections, TreeViewer treeView) {
viewer = treeView;
Object[] objs = selections.toArray();
objs = filterSelectedItemsToDel(selections);
wrapDelObj(objs);
}
/**
* Author: Fliu this fun is to filter out all the children listed in the selections, all left is the top parent
* level ones in the selections
*
* @param selections
* @return all parent array with no corresponding children in the selection list
*/
private Object[] filterSelectedItemsToDel(IStructuredSelection selections) {
Object[] objs = selections.toArray();
List lst = new ArrayList();
for (Object obj : objs) {
if (obj instanceof XSDElementDeclarationImpl) {
continue;
}
for (Object objOther : objs) {
if (obj == objOther) {
continue;
}
Object[] offsprings = populateAllOffspring(objOther, new ArrayList());
for (Object offspring : offsprings) {
if (offspring == obj) {
if (lst.indexOf(obj) < 0) {
lst.add(obj);
}
}
}
}
}
for (Object ca : objs) {
if (lst.indexOf(ca) >= 0) {
lst.remove(ca);
} else {
lst.add(ca);
}
}
return lst.toArray();
}
/**
* Author: Fliu this fun is to populate all offsprings for a specific object
*/
private Object[] populateAllOffspring(Object obj, ArrayList offspringList) {
SchemaTreeContentProvider provider = (SchemaTreeContentProvider) viewer.getContentProvider();
Object[] offersprings = provider.getChildren(obj);
for (Object subObj : offersprings) {
if (!offspringList.contains(subObj)) {
offspringList.add(subObj);
if (provider.hasChildren(subObj)) {
populateAllOffspring(subObj, offspringList);
}
} else {
continue;
}
}
return offspringList.toArray();
}
private void refreshAction() {
if (delObjs.isEmpty()) {
return;
}
XSDConcreteComponent comp = delObjs.get(0);
if (checkInSameClassType(delObjs.toArray(), comp.getClass())) {
String actionTxt = clsAction.get(comp.getClass()).getText();
if (delObjs.size() > 1) {
if (actionTxt.endsWith("y")) {//$NON-NLS-1$
actionTxt = actionTxt.substring(0, actionTxt.length() - 1) + "ies";//$NON-NLS-1$
}
else {
actionTxt = actionTxt + "s";//$NON-NLS-1$
}
}
setText(actionTxt);
} else {
setText(Messages.XSDDeleteXX_DeleteObjects);
}
setToolTipText(Messages.XSDDeleteXX_DeleteEntities);
}
private void clearDelData() {
delObjs.clear();
}
private boolean checkInSameClassType(Object[] selects, Class type) {
for (Object obj : selects) {
if (obj.getClass() != type) {
return false;
}
}
if (selects[0] instanceof XSDElementDeclaration) {
boolean isConcept = Util.checkConcept((XSDElementDeclaration) selects[0]);
for (Object obj : selects) {
if (Util.checkConcept((XSDElementDeclaration) obj) != isConcept) {
return false;
}
}
}
return true;
}
public boolean checkInDeletableType(Object[] selects) {
clearDelData();
for (Object obj : selects) {
if (obj instanceof XSDElementDeclaration || obj instanceof XSDParticle
|| obj instanceof XSDIdentityConstraintDefinition || obj instanceof XSDAttributeUse
|| obj instanceof XSDAttributeDeclaration) {
continue;
} else if (obj instanceof XSDXPathDefinition) {
XSDXPathDefinition xpath = (XSDXPathDefinition) obj;
if (xpath.getVariety().equals(XSDXPathVariety.FIELD_LITERAL)) {
continue;
} else {
return false;
}
} else if (extraClsToDel.indexOf(obj.getClass()) < 0) {
return false;
}
}
return true;
}
public boolean checkInAllElementType(Object[] selects) {
if (selects.length == 0) {
return false;
}
for (Object obj : selects) {
if (!(obj instanceof XSDElementDeclaration)) {
return false;
}
}
return true;
}
public boolean checkOutAllConcept(Object[] selections) {
for (Object obj : selections) {
if (!(obj instanceof XSDElementDeclaration)) {
return false;
}
if (!Util.checkConcept((XSDElementDeclaration) obj)) {
return false;
}
}
return true;
}
public Action outPutDeleteActions() {
if (delObjs.size() == 0) {
return null;
}
return this;
}
@Override
public void runWithEvent(Event event) {
super.runWithEvent(event);
}
}