/******************************************************************************* * Copyright (c) 2011, 2012 Red Hat, Inc. * All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.bpmn2.modeler.core.merrimac.clad; import java.util.ArrayList; import java.util.List; import org.eclipse.bpmn2.Definitions; import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesProvider; import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ModelSubclassSelectionDialog; import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime; import org.eclipse.bpmn2.modeler.core.utils.ModelUtil; import org.eclipse.dd.di.DiagramElement; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EObjectContainmentEList; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.dialogs.ListDialog; public class DefaultListComposite extends AbstractListComposite { protected EClass listItemClass; public DefaultListComposite(AbstractBpmn2PropertySection section, int style) { super(section, style); } public DefaultListComposite(AbstractBpmn2PropertySection section) { super(section); } public DefaultListComposite(Composite parent, int style) { super(parent, style); } /* (non-Javadoc) * @see org.eclipse.bpmn2.modeler.ui.property.AbstractListComposite#addListItem(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature) */ protected EObject addListItem(EObject object, EStructuralFeature feature) { EList<EObject> list = getItemList(); EClass listItemClass = getListItemClass(object,feature); EObject newItem = null; if (!(list instanceof EObjectContainmentEList)) { // this is not a containment list so we can't add it // because we don't know where the new object belongs String name = object.eClass().getName() + "." +feature.getName(); //$NON-NLS-1$ MessageDialog.openError(getShell(), Messages.DefaultListComposite_Internal_Error_Title, NLS.bind(Messages.DefaultListComposite_Error_Internal_Error_Message_No_List, name) ); return null; } else { if (listItemClass==null) { listItemClass = getListItemClassToAdd(listItemClass); if (listItemClass==null) return null; // user cancelled } newItem = getBusinessObjectDelegate().createFeature(object,feature,listItemClass); if (newItem==null) { MessageDialog.openError(getShell(), Messages.DefaultListComposite_Internal_Error_Title, NLS.bind(Messages.DefaultListComposite_Internal_Error_Message_No_Factory, listItemClass.getName()) ); } else if (!list.contains(newItem)) list.add(newItem); } return newItem; } /** * Find all subtypes of the given listItemClass EClass and display a selection * list if there are more than 1 subtypes. * * @param listItemClass * @return */ public EClass getListItemClassToAdd(EClass listItemClass) { EClass eclass = null; ModelSubclassSelectionDialog dialog = new ModelSubclassSelectionDialog(getDiagramEditor(), businessObject, feature); if (dialog.open()==Window.OK){ eclass = (EClass)dialog.getResult()[0]; } return eclass; } /* (non-Javadoc) * @see org.eclipse.bpmn2.modeler.ui.property.AbstractListComposite#createDetailComposite(org.eclipse.swt.widgets.Composite, java.lang.Class) */ public AbstractDetailComposite createDetailComposite(Class eClass, Composite parent, int style) { TargetRuntime rt = TargetRuntime.getRuntime(getDiagramEditor()); AbstractDetailComposite composite = PropertiesCompositeFactory.INSTANCE.createDetailComposite(eClass, parent, rt, SWT.NONE); return composite; } /* (non-Javadoc) * @see org.eclipse.bpmn2.modeler.ui.property.AbstractListComposite#editListItem(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature) */ protected EObject editListItem(EObject object, EStructuralFeature feature) { MessageDialog.openError(getShell(), Messages.DefaultListComposite_Internal_Error_Title, NLS.bind(Messages.DefaultListComposite_Internal_Error_Message_No_Editor, ExtendedPropertiesProvider.getTextValue(object, feature)) ); return null; } /* (non-Javadoc) * @see org.eclipse.bpmn2.modeler.ui.property.AbstractListComposite#removeListItem(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, int) */ protected Object removeListItem(EObject object, EStructuralFeature feature, int index) { EList<EObject> list = getItemList(); int[] map = buildIndexMap(object,feature); if (list instanceof EObjectContainmentEList) { if (!canDelete(list.get(map[index]))) return null; } EObject selected = null; if (index<map.length-1) selected = list.get(map[index+1]); EObject removed = list.get(map[index]); Diagram diagram = getDiagramEditor().getDiagramTypeProvider().getDiagram(); for (PictogramElement pe : Graphiti.getLinkService().getPictogramElements(diagram, removed)) { if (pe.getLink()!=null) { pe.getLink().getBusinessObjects().remove(removed); } } list.remove(map[index]); return selected; } protected Object deleteListItem(EObject object, EStructuralFeature feature, int index) { EList<EObject> list = getItemList(); int[] map = buildIndexMap(object,feature); EObject removed = list.get(map[index]); if (list instanceof EObjectContainmentEList) { if (!canDelete(removed)) return null; } EObject selected = null; if (index<map.length-1) selected = list.get(map[index+1]); EcoreUtil.delete(removed, true); return selected; } protected Object getListItem(EObject object, EStructuralFeature feature, int index) { EList<EObject> list = getItemList(); int[] map = buildIndexMap(object,feature); return list.get(map[index]); } protected Object moveListItemUp(EObject object, EStructuralFeature feature, int index) { EList<EObject> list = getItemList(); int[] map = buildIndexMap(object,feature); if (index>0) { list.move(map[index-1], map[index]); return list.get(map[index-1]); } return null; } protected Object moveListItemDown(EObject object, EStructuralFeature feature, int index) { EList<EObject> list = getItemList(); int[] map = buildIndexMap(object,feature); if (index<map.length-1) { list.move(map[index+1], map[index]); return list.get(map[index+1]); } return null; } public void setListItemClass(EClass clazz) { this.listItemClass = clazz; } public EClass getListItemClass(EObject object, EStructuralFeature feature) { return listItemClass; } protected boolean canDelete(EObject objectToDelete) { // make sure this object is not being referenced // anywhere else. If it is, we can't delete it! List<EObject> allDeleted = new ArrayList<EObject>(); allDeleted.add(objectToDelete); TreeIterator<EObject> iter = objectToDelete.eAllContents(); while (iter.hasNext()) { EObject o = iter.next(); allDeleted.add(o); } List<EObject> references = new ArrayList<EObject>(); Definitions definitions = ModelUtil.getDefinitions(objectToDelete); iter = definitions.eAllContents(); while (iter.hasNext()) { EObject o = iter.next(); for (EReference reference : o.eClass().getEAllReferences()) { if (!reference.isContainment() && !(o instanceof DiagramElement)) { if (reference.isMany()) { List refList = (List)o.eGet(reference); for (Object referencedObject : refList) { if (allDeleted.contains(referencedObject)) { references.add(o); break; } } } else { Object referencedObject = o.eGet(reference); if (allDeleted.contains(referencedObject)) { references.add(o); } } } } } if (references.size()>0) { ListDialog dlg = new ListDialog(getShell()); ReferencingObjectListProvider provider = new ReferencingObjectListProvider(references); dlg.setContentProvider(provider); dlg.setLabelProvider(provider); dlg.setInput(references); dlg.setMessage( NLS.bind(Messages.DefaultListComposite_Cannot_Delete_Message, ExtendedPropertiesProvider.getLabel(objectToDelete)) ); dlg.setAddCancelButton(false); dlg.setTitle(Messages.DefaultListComposite_Cannot_Delete_Title); dlg.open(); return false; } return true; } protected class ReferencingObjectListProvider implements IStructuredContentProvider, ILabelProvider { List<EObject> references; public ReferencingObjectListProvider(List<EObject> references) { this.references = references; } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // TODO Auto-generated method stub } @Override public void addListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } @Override public boolean isLabelProperty(Object element, String property) { // TODO Auto-generated method stub return false; } @Override public void removeListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } @Override public Image getImage(Object element) { // TODO Auto-generated method stub return null; } @Override public String getText(Object element) { String type = ModelUtil.getLabel(element); String name = ModelUtil.getTextValue(element); return type + ": " + name; //$NON-NLS-1$ } @Override public Object[] getElements(Object inputElement) { return references.toArray(); } } }