| /* |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Florian Pirchner - Initial implementation |
| * Loetz GmbH&Co.KG |
| * |
| */ |
| package org.eclipse.osbp.vaadin.emf.data; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.provider.IChangeNotifier; |
| import org.eclipse.emf.edit.provider.IItemLabelProvider; |
| import org.eclipse.emf.edit.provider.INotifyChangedListener; |
| import org.eclipse.emf.edit.provider.ITreeItemContentProvider; |
| import org.eclipse.xtext.common.types.JvmDeclaredType; |
| import org.eclipse.xtext.common.types.JvmGenericType; |
| import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider; |
| import org.eclipse.osbp.vaadin.emf.api.IModelingContext; |
| import org.eclipse.osbp.vaadin.emf.data.JvmTypeProperties.Info; |
| import org.eclipse.osbp.vaadin.emf.views.UiSync; |
| |
| import com.vaadin.data.Item; |
| import com.vaadin.data.util.HierarchicalContainer; |
| import com.vaadin.server.Resource; |
| |
| // TODO: Auto-generated Javadoc |
| /** |
| * The base container to provide all properties for a given JvmType. |
| * <p> |
| * ATTENTION: This container MUST be disposed! |
| */ |
| @SuppressWarnings("serial") |
| public class JvmTypePropertiesTreeContainer extends HierarchicalContainer { |
| |
| /** The Constant ICON. */ |
| private static final String ICON = "icon"; |
| |
| /** The Constant LABEL. */ |
| private static final String LABEL = "label"; |
| |
| /** The root element. */ |
| private EObject rootElement; |
| |
| /** The editing domain. */ |
| @SuppressWarnings("unused") |
| private final EditingDomain editingDomain; |
| |
| /** The adapter factory. */ |
| private final AdapterFactory adapterFactory; |
| |
| /** The ui sync. */ |
| private final UiSync uiSync; |
| |
| /** The resolved. */ |
| private Set<Object> resolved = new HashSet<Object>(); |
| |
| /** The resource provider. */ |
| private IResourceProvider resourceProvider; |
| |
| /** The change listener. */ |
| private INotifyChangedListener changeListener; |
| |
| /** |
| * Instantiates a new jvm type properties tree container. |
| * |
| * @param modelingContext |
| * the modeling context |
| * @param resourceProvider |
| * the resource provider |
| * @param uiSync |
| * the ui sync |
| */ |
| public JvmTypePropertiesTreeContainer(IModelingContext modelingContext, |
| IResourceProvider resourceProvider, UiSync uiSync) { |
| this.resourceProvider = resourceProvider; |
| this.editingDomain = modelingContext.getEditingDomain(); |
| this.adapterFactory = modelingContext.getAdapterFactory(); |
| this.uiSync = uiSync; |
| |
| addContainerProperty(LABEL, String.class, ""); |
| addContainerProperty(ICON, Resource.class, null); |
| |
| // IChangeNotifier notifier = (IChangeNotifier) modelingContext |
| // .getAdapterFactory(); |
| // notifier.addListener(getModelChangeListener()); |
| } |
| |
| /** |
| * Gets the root element. |
| * |
| * @return the root element |
| */ |
| public EObject getRootElement() { |
| return rootElement; |
| } |
| |
| /** |
| * Sets the root element. |
| * |
| * @param rootElement |
| * the new root element |
| */ |
| public void setRootElement(JvmGenericType rootElement) { |
| if (this.rootElement == rootElement) { |
| return; |
| } |
| |
| removeAllItems(); |
| resolved.clear(); |
| |
| this.rootElement = rootElement; |
| |
| loadRootElements(); |
| } |
| |
| /** |
| * Load root elements. |
| */ |
| private void loadRootElements() { |
| if (rootElement != null) { |
| doAddItem(null, rootElement, -1); |
| resolveChildren(rootElement); |
| } |
| } |
| |
| /** |
| * Resolve children. |
| * |
| * @param itemId |
| * the item id |
| */ |
| public void resolveChildren(Object itemId) { |
| // if children are allowed and they have not been resolved so far |
| if (areChildrenAllowed(itemId) |
| && (getChildren(itemId) == null || getChildren(itemId) |
| .isEmpty())) { |
| resolved.add(itemId); |
| |
| // resolve children |
| if (itemId instanceof JvmDeclaredType) { |
| List<Info> children = createPropertyInfos((JvmDeclaredType) itemId); |
| for (Info newChild : children) { |
| doAddItem(itemId, newChild, -1); |
| } |
| } else { |
| JvmTypeProperties.Info info = (Info) itemId; |
| List<Info> children = createPropertyInfos(info); |
| for (Info newChild : children) { |
| doAddItem(info, newChild, -1); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates the property infos. |
| * |
| * @param type |
| * the type |
| * @return the list |
| */ |
| private List<JvmTypeProperties.Info> createPropertyInfos( |
| JvmDeclaredType type) { |
| List<JvmTypeProperties.Info> result = new ArrayList<JvmTypeProperties.Info>( |
| JvmTypeProperties.getOperationInfos(type).values()); |
| Collections.sort(result); |
| return result; |
| } |
| |
| /** |
| * Creates the property infos. |
| * |
| * @param info |
| * the info |
| * @return the list |
| */ |
| private List<JvmTypeProperties.Info> createPropertyInfos( |
| JvmTypeProperties.Info info) { |
| List<JvmTypeProperties.Info> result = new ArrayList<JvmTypeProperties.Info>( |
| JvmTypeProperties.getOperationInfos(info).values()); |
| Collections.sort(result); |
| return result; |
| } |
| |
| /** |
| * Refreshes the given node. |
| * |
| * @param itemId |
| * the item id |
| */ |
| public void refreshNode(Object itemId) { |
| for (Object child : new ArrayList<>(getChildren(itemId))) { |
| removeItemRecursively(child); |
| } |
| resolved.remove(itemId); |
| resolveChildren(itemId); |
| } |
| |
| /** |
| * Adds a new item. |
| * |
| * @param parent |
| * the parent |
| * @param newChild |
| * the new child |
| * @param index |
| * pass -1 for last index |
| */ |
| @SuppressWarnings("unchecked") |
| private void doAddItem(Object parent, EObject newChild, int index) { |
| if (newChild == null) { |
| return; |
| } |
| Item item; |
| if (index >= 0) { |
| item = addItemAt(index, newChild); |
| } else { |
| item = addItem(newChild); |
| } |
| IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory |
| .adapt(newChild, IItemLabelProvider.class); |
| item.getItemProperty(LABEL).setValue(labelProvider.getText(newChild)); |
| |
| // parse the platform uri |
| item.getItemProperty(ICON) |
| .setValue( |
| resourceProvider |
| .getResource("platform:/plugin/org.eclipse.osbp.vaadin.emf/images/class_obj.gif")); |
| |
| // if the newChild is not root and the container is available in the |
| // tree |
| if (parent != null && containsId(parent)) { |
| setParent(newChild, parent); |
| // the new parent may have children again |
| // setChildrenAllowed(newChild.eContainer(), true); |
| } |
| } |
| |
| /** |
| * Adds a new item. |
| * |
| * @param parent |
| * the parent |
| * @param newChild |
| * the new child |
| * @param index |
| * pass -1 for last index |
| */ |
| @SuppressWarnings("unchecked") |
| private void doAddItem(Object parent, JvmTypeProperties.Info newChild, |
| int index) { |
| if (newChild == null) { |
| return; |
| } |
| Item item; |
| if (index >= 0) { |
| item = addItemAt(index, newChild); |
| } else { |
| item = addItem(newChild); |
| } |
| |
| item.getItemProperty(LABEL).setValue(getText(newChild)); |
| item.getItemProperty(ICON) |
| .setValue( |
| resourceProvider |
| .getResource("platform:/plugin/org.eclipse.osbp.vaadin.emf/images/field_public_obj.gif")); |
| |
| // if the newChild is not root and the container is available in the |
| // tree |
| if (parent != null && containsId(parent)) { |
| setParent(newChild, parent); |
| } |
| } |
| |
| /** |
| * Gets the text. |
| * |
| * @param newChild |
| * the new child |
| * @return the text |
| */ |
| private String getText(Info newChild) { |
| String result = newChild.getName(); |
| |
| if (newChild.getType() != null) { |
| if (newChild.isMany()) { |
| result += "[*]"; |
| result += " : "; |
| if (newChild.getParameterizedType() != null) { |
| result += newChild.getParameterizedType() |
| .getQualifiedName(); |
| } |
| } else { |
| result += " : "; |
| result += newChild.getType().getQualifiedName(); |
| } |
| } |
| |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see com.vaadin.data.util.HierarchicalContainer#hasChildren(java.lang.Object) |
| */ |
| @Override |
| public boolean hasChildren(Object itemId) { |
| boolean result = super.hasChildren(itemId); |
| if (!result) { |
| if (itemId instanceof EObject) { |
| // calculate children allowed |
| ITreeItemContentProvider treeProvider = (ITreeItemContentProvider) adapterFactory |
| .adapt(itemId, ITreeItemContentProvider.class); |
| result = treeProvider.hasChildren(itemId); |
| } else { |
| JvmTypeProperties.Info info = (Info) itemId; |
| return !info.isMany() && !info.isPrimitive(); |
| } |
| } |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see com.vaadin.data.util.HierarchicalContainer#areChildrenAllowed(java.lang.Object) |
| */ |
| @Override |
| public boolean areChildrenAllowed(Object itemId) { |
| // calculate children allowed |
| |
| if (itemId instanceof EObject) { |
| ITreeItemContentProvider treeProvider = (ITreeItemContentProvider) adapterFactory |
| .adapt(itemId, ITreeItemContentProvider.class); |
| return treeProvider.hasChildren(itemId); |
| } else { |
| JvmTypeProperties.Info info = (Info) itemId; |
| try { |
| return !info.isMany() && !info.isPrimitive(); |
| } catch (Exception e) { |
| System.out.println(""); |
| } |
| return false; |
| } |
| } |
| |
| // private INotifyChangedListener getModelChangeListener() { |
| // this.changeListener = e -> handleNotification(e); |
| // return changeListener; |
| // } |
| |
| // /** |
| // * Refreshes the item with the given eObject. |
| // * |
| // * @param eObject |
| // */ |
| // protected void handleNotification(Notification notification) { |
| // if (notification.isTouch()) { |
| // return; |
| // } |
| // |
| // switch (notification.getEventType()) { |
| // case Notification.ADD: |
| // uiSync.sync(new Runnable() { |
| // @Override |
| // public void run() { |
| // if (notification.getNewValue() instanceof EObject) { |
| // EObject addItem = (EObject) notification.getNewValue(); |
| // doAddItem(addItem, notification.getPosition()); |
| // } |
| // } |
| // }); |
| // break; |
| // case Notification.REMOVE: |
| // uiSync.sync(new Runnable() { |
| // @Override |
| // public void run() { |
| // if (notification.getOldValue() instanceof EObject) { |
| // EObject removeItem = (EObject) notification |
| // .getOldValue(); |
| // removeItemRecursively(removeItem); |
| // } |
| // } |
| // }); |
| // break; |
| // case Notification.MOVE: |
| // EObject moveItem = (EObject) notification.getNewValue(); |
| // EStructuralFeature feature = moveItem.eContainingFeature(); |
| // if (feature.isMany()) { |
| // EObject container = moveItem.eContainer(); |
| // // if the parent is not visible, then leave |
| // if (!containsId(container)) { |
| // return; |
| // } |
| // uiSync.sync(new Runnable() { |
| // @SuppressWarnings("unchecked") |
| // @Override |
| // public void run() { |
| // List<EObject> eObjects = (List<EObject>) container |
| // .eGet(feature); |
| // EObject previousSibling = null; |
| // if (notification.getPosition() > 0) { |
| // previousSibling = eObjects.get(notification |
| // .getPosition() - 1); |
| // moveAfterSibling(moveItem, previousSibling); |
| // } |
| // } |
| // }); |
| // } |
| // break; |
| // case Notification.SET: |
| // // update the property with the changed value |
| // uiSync.sync(new Runnable() { |
| // @Override |
| // public void run() { |
| // EObject notifier = (EObject) notification.getNotifier(); |
| // if (notification.getNewValue() instanceof EObject) { |
| // EObject itemId = (EObject) notification.getNewValue(); |
| // // the containment reference was set |
| // if (itemId.eContainingFeature() == notification |
| // .getFeature()) { |
| // removeItem(itemId); |
| // doAddItem(itemId, -1); |
| // } else { |
| // refreshLabel(notifier); |
| // } |
| // } else { |
| // refreshLabel(notifier); |
| // } |
| // } |
| // |
| // @SuppressWarnings({ "unchecked" }) |
| // private void refreshLabel(EObject notifier) { |
| // Item item = getItem(notifier); |
| // if (item != null) { |
| // IItemLabelProvider labelProvider = (IItemLabelProvider) adapterFactory |
| // .adapt(notifier, IItemLabelProvider.class); |
| // item.getItemProperty(LABEL).setValue( |
| // labelProvider.getText(notifier)); |
| // } |
| // } |
| // }); |
| // break; |
| // case Notification.ADD_MANY: |
| // uiSync.sync(new Runnable() { |
| // @SuppressWarnings("unchecked") |
| // @Override |
| // public void run() { |
| // if (notification.getOldValue() instanceof Collection) { |
| // Collection<Object> elements = (Collection<Object>) notification |
| // .getNewValue(); |
| // for (Object element : elements) { |
| // EObject addItem = (EObject) element; |
| // doAddItem(addItem, notification.getPosition()); |
| // } |
| // } |
| // } |
| // }); |
| // break; |
| // case Notification.REMOVE_MANY: |
| // uiSync.sync(new Runnable() { |
| // @SuppressWarnings("unchecked") |
| // @Override |
| // public void run() { |
| // if (notification.getOldValue() instanceof Collection) { |
| // Collection<Object> elements = (Collection<Object>) notification |
| // .getOldValue(); |
| // for (Object element : elements) { |
| // EObject removeItem = (EObject) element; |
| // removeItemRecursively(removeItem); |
| // } |
| // } |
| // } |
| // }); |
| // break; |
| // } |
| // } |
| |
| /** |
| * This container MUST be disposed!. |
| */ |
| public void dispose() { |
| IChangeNotifier notifier = (IChangeNotifier) adapterFactory; |
| notifier.removeListener(changeListener); |
| } |
| |
| } |