/*******************************************************************************
* Copyright (c) 2008-2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* 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:
******************************************************************************/
package org.eclipse.emf.emfstore.client.ui.views.scm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.emfstore.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.client.ui.views.changes.ChangePackageVisualizationHelper;
import org.eclipse.emf.emfstore.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.server.model.versioning.ChangePackage;
import org.eclipse.emf.emfstore.server.model.versioning.HistoryInfo;
import org.eclipse.emf.emfstore.server.model.versioning.operations.AbstractOperation;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
/**
* Content provider for the scm views.
*
* @author Shterev
*/
public abstract class SCMContentProvider implements ITreeContentProvider {
private static ChangePackageVisualizationHelper changePackageVisualizationHelper;
private boolean showRootNodes = true;
private boolean reverseNodes = true;
private AdapterFactoryContentProvider contentProvider;
private ProjectSpace projectSpace;
private ComposedAdapterFactory adapterFactory;
/**
* Default constructor.
*
* @param treeViewer
* the tree viewer. the project.
*/
protected SCMContentProvider(TreeViewer treeViewer) {
adapterFactory = new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
contentProvider = new AdapterFactoryContentProvider(adapterFactory);
}
/**
* Sets the flag to reverse the order of the nodes. Default value is true -
* i.e. the more recent operations are on top.
*
* @param reverseNodes
* the new value
*/
public void setReverseNodes(boolean reverseNodes) {
this.reverseNodes = reverseNodes;
}
/**
* Returns if the nodes should be reversed.
*
* @return true if the nodes should be reversed in order
*/
public boolean isReverseNodes() {
return reverseNodes;
}
/**
* {@inheritDoc}
*/
public Object[] getChildren(Object node) {
Object element = node;
if (element instanceof HistoryInfo) {
if (((HistoryInfo) element).getChangePackage() == null) {
return new Object[0];
} else {
return getChildrenOfChangePackage(((HistoryInfo) element).getChangePackage());
}
} else if (node instanceof AbstractOperation) {
return Arrays.asList(contentProvider.getChildren(node)).toArray();
} else if (node instanceof ChangePackage) {
return getChildrenOfChangePackage(((ChangePackage) element));
} else if (element instanceof EObject) {
// EObject me = (EObject) element;
// show only model element that are contained in a project and have an ID
// ModelElementId modelElementId = projectSpace.getProject().getModelElementId(me);
// if (modelElementId != null) {
// return getChildren(me);
// }
Object[] children = contentProvider.getChildren(element);
return children;
}
return Arrays.asList(contentProvider.getChildren(element)).toArray();
}
private Object[] getChildrenOfChangePackage(ChangePackage changePackage) {
EList<AbstractOperation> operations = changePackage.getOperations();
if (isReverseNodes()) {
ECollections.reverse(operations);
}
return operations.toArray();
}
/**
* @param visualizationHelper
* the visualizationHelper to set.
*/
public void setChangePackageVisualizationHelper(
ChangePackageVisualizationHelper visualizationHelper) {
changePackageVisualizationHelper = visualizationHelper;
}
/**
* {@inheritDoc}
*/
public boolean hasChildren(Object element) {
return true;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Object[] getElements(Object inputElement) {
if (inputElement instanceof ChangePackage) {
return Arrays.asList((ChangePackage) inputElement).toArray();
}
if (!(inputElement instanceof List) || ((List) inputElement).isEmpty()) {
return new Object[0];
}
List inputList = (List) inputElement;
Object firstElement = inputList.get(0);
if (firstElement == null) {
return new Object[0];
}
if (firstElement instanceof ChangePackage) {
if (showRootNodes) {
return inputList.toArray();
} else {
ArrayList<Object> elements = new ArrayList<Object>();
List<ChangePackage> changePackages = inputList;
for (ChangePackage cp : changePackages) {
elements.addAll(Arrays.asList(getChildren(cp)));
}
return elements.toArray();
}
} else if (firstElement instanceof HistoryInfo) {
List<HistoryInfo> historyInfos = (List<HistoryInfo>) inputElement;
if (showRootNodes) {
return historyInfos.toArray();
} else {
ArrayList<Object> elements = new ArrayList<Object>();
for (HistoryInfo hi : historyInfos) {
if (hi.getChangePackage() != null) {
elements.addAll(Arrays.asList(getChildren(hi)));
}
}
return elements.toArray();
}
}
return new Object[0];
}
/**
* {@inheritDoc}
*/
// TODO: inspect & review
public Object getParent(Object element) {
if (element instanceof HistoryInfo) {
return ((HistoryInfo) element).getPrimerySpec();
} else if (element instanceof ChangePackage) {
// TODO: use bidirectional references?
return ((ChangePackage) element).eContainer();
} else if (element instanceof AbstractOperation) {
return ((ChangePackage) element).eContainer();
}
return null;
}
/**
* {@inheritDoc}
*/
public void dispose() {
if (adapterFactory != null) {
adapterFactory.dispose();
}
if (changePackageVisualizationHelper != null) {
changePackageVisualizationHelper.dispose();
}
}
/**
* {@inheritDoc}
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
/**
* @return if the root nodes should be shown.
*/
public boolean showRootNodes() {
return showRootNodes;
}
/**
* Sets if the root nodes should be shown.
*
* @param show
* the new value.
*/
public void setShowRootNodes(boolean show) {
showRootNodes = show;
}
/**
* Content provider displaying the scm item in the following order:
* HistoryInfo > ChangePackage > Operation(s) > ModelElement(s).
*
* @author Shterev
*/
public static class Detailed extends SCMContentProvider {
/**
* Default constructor.
*
* @param viewer
* the viewer.
* @param project
*/
public Detailed(TreeViewer viewer) {
super(viewer);
}
/**
* {@inheritDoc}
*
* @return an array of {@link AbstractOperation}s
*/
protected Object[] getChildren(ChangePackage changePackage) {
EList<AbstractOperation> operations = changePackage.getOperations();
if (isReverseNodes()) {
ECollections.reverse(operations);
}
return operations.toArray();
}
/**
* {@inheritDoc}
*
* @return an empty array
*/
protected Object[] getChildren(EObject modelElement) {
Object[] children = super.contentProvider.getChildren(modelElement);
return children;
}
}
/**
* {@inheritDoc}
*
* @return an array of {@link EObject}s
*/
protected Object[] getChildren(AbstractOperation op) {
return Arrays.asList(contentProvider.getChildren(op)).toArray();
}
/**
* Content provider displaying the scm item in the following order:
* HistoryInfo > ChangePackage > ModelElement(s) > Operation(s).
*
* @author Shterev
*/
public static class Compact extends SCMContentProvider {
/**
* Default constructor.
*
* @param viewer
* the viewer.
*/
public Compact(TreeViewer viewer) {
super(viewer);
}
/**
* {@inheritDoc}
*
* @return an array of {@link EObject}s
*/
protected Object[] getChildren(ChangePackage changePackage) {
ArrayList<EObject> modelElements = changePackageVisualizationHelper.getModelElements(
changePackage.getAllInvolvedModelElements(), new ArrayList<EObject>());
return modelElements.toArray();
}
/**
* {@inheritDoc}
*
* @return an array of {@link AbstractOperation}s
*/
protected Object[] getChildren(EObject modelElement) {
ChangePackage changePackage;
if (getParent(modelElement) instanceof HistoryInfo) {
HistoryInfo historyInfo = (HistoryInfo) getParent(modelElement);
changePackage = historyInfo.getChangePackage();
} else if (getParent(modelElement) instanceof ChangePackage) {
changePackage = (ChangePackage) getParent(modelElement);
} else {
return new Object[0];
}
// TODO: code duplication, see getChildren method above
List<AbstractOperation> operations = changePackage.getTouchingOperations(ModelUtil.getProject(modelElement)
.getModelElementId(modelElement));
if (isReverseNodes()) {
Collections.reverse(operations);
}
return operations.toArray();
}
}
/**
* Sets the ProjectSpace.
*
* @param projectSpace
* the projectspace
*/
public void setProjectSpace(ProjectSpace projectSpace) {
this.projectSpace = projectSpace;
}
}