blob: 8642eca2e72f6fc57575a603b34336f45d85b994 [file] [log] [blame]
/*
*
* 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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);
}
}