/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.compare.ui.structure;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.HistoryItem;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.ResourceNode;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.compare.DifferenceProcessor;
import org.teiid.designer.compare.DifferenceReport;
import org.teiid.designer.compare.ModelerComparePlugin;
import org.teiid.designer.compare.ui.UiConstants;
import org.teiid.designer.compare.ui.tree.DifferenceReportsPanel;
import org.teiid.designer.compare.ui.tree.MappingTreeContentProvider;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.workspace.ModelFolder;
import org.teiid.designer.core.workspace.ModelFolderImpl;
import org.teiid.designer.core.workspace.ModelFolderInfo;
import org.teiid.designer.core.workspace.ModelProject;
import org.teiid.designer.core.workspace.ModelProjectInfo;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelResourceImpl;
import org.teiid.designer.core.workspace.ModelUtil;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.core.workspace.ModelWorkspaceItem;
import org.teiid.designer.core.workspace.ModelWorkspaceItemImpl;
/**
* @since 8.0
*/
public class ModelObjectStructureViewer extends StructuredViewer /*StructureDiffViewer*/{
/*
* jh notes
* 0. what is the earliest ancestor class this viewer can be to fit in with the immediate
* parent class CompareViewerSwitchingPane (see EditionSelectionDialog)?
* Answer: StructuredViewer.
* 1. This viewer will be defined as a "structureViewers" extension in the CompareUi plugin.zml,
* associated with the ".xmi" file type extension.
* 2. The structure creator 'ModelObjectStructureCreator' will be explicitly used in this
* class and will therefore not need to be defined as a "structureCreators" extension
* in the plugin.xml.
* 3. At this point it is not clear how much, if any, of StructureDiffViewer this class will
* need to override, but having it serves as a useful way to control our implementation and
* allow it to grow if/as needed.
*
*/
private Composite cmpParent;
// private ModelObjectStructureCreator fStructureCreator;
private DifferenceProcessor dpProcessor;
private DifferenceReport drReport;
private DifferenceReportsPanel pnlDifferenceReport;
private HistoryItem hiRight;
private ResourceNode rnLeft;
private ResourceNode rnRight;
private int iCompareType = -1;
private static final int RESOURCE_NODE_TO_INPUT_STREAM = 1;
private static final int RESOURCE_NODE_TO_RESOURCE_NODE = 2;
private final static String EMPTY_STRING = ""; //$NON-NLS-1$
private int iTerminology = DifferenceReportsPanel.USE_OLD_NEW_TERMINOLOGY;
private static final String DIALOG_TITLE = UiConstants.Util.getString("ModelObjectStructureViewer.dialogTitle"); //$NON-NLS-1$
private static final String TREE_TITLE = UiConstants.Util.getString("ModelObjectStructureViewer.treeTitle"); //$NON-NLS-1$
private static final String DIFF_DESCRIPTOR_TITLE = UiConstants.Util.getString("ModelObjectStructureViewer.diffDescriptorTitle"); //$NON-NLS-1$
/**
* @param parent
* @param configuration
* @since 4.2
*/
public ModelObjectStructureViewer( Composite parent,
CompareConfiguration configuration ) {
super();
this.cmpParent = parent;
this.setContentProvider(new MappingTreeContentProvider());
getContentProvider();
// fStructureCreator = new ModelObjectStructureCreator();
// System.out.println("[ModelObjectStructureViewer.ctor #2] BOT"); //$NON-NLS-1$
}
@Override
protected void inputChanged( Object input,
Object oldInput ) {
// System.out.println("[ModelObjectStructureViewer.inputChanged] TOP"); //$NON-NLS-1$
// input might be null...
if (input == null) {
return;
}
InputStream isRight = null;
IPath pathRight = null;
IResource resLeft = null;
IResource resRight = null;
// capture the ResourceNode
DiffNode node = (DiffNode)input;
// get ModelResource for Left
ITypedElement teLeft = node.getLeft();
if (teLeft instanceof ResourceNode) {
rnLeft = (ResourceNode)teLeft;
resLeft = rnLeft.getResource();
}
// get ModelResource for Right
ITypedElement teRight = node.getRight();
if (teRight instanceof ResourceNode) {
iCompareType = RESOURCE_NODE_TO_RESOURCE_NODE;
rnRight = (ResourceNode)teRight;
resRight = rnRight.getResource();
} else
// or get InputStream for right
if (teRight instanceof HistoryItem) {
iCompareType = RESOURCE_NODE_TO_INPUT_STREAM;
rnRight = null;
hiRight = (HistoryItem)teRight;
pathRight = new Path(hiRight.getName());
try {
isRight = hiRight.getContents();
} catch (CoreException ce) {
UiConstants.Util.log(ce);
}
}
// create the processor from two resources
if (iCompareType == RESOURCE_NODE_TO_RESOURCE_NODE) {
try {
ModelResource mrLeft = findModelResource(resLeft, true);
ModelResource mrRight = findModelResource(resRight, true);
// System.out.println("[ModelObjectStructureViewer.inputChanged] resLeft: " + resLeft.getName() ); //$NON-NLS-1$
// System.out.println("[ModelObjectStructureViewer.inputChanged] resRight: " + resRight.getName() ); //$NON-NLS-1$
dpProcessor = ModelerComparePlugin.createDifferenceProcessor(mrLeft, mrRight);
} catch (ModelWorkspaceException mwe) {
UiConstants.Util.log(mwe);
}
} else {
// OR, create the processor from a resource and an input stream
IProject project = null;
if(resLeft!=null) {
project = resLeft.getProject();
}
if ((project != null) && project.isOpen() && ModelerCore.hasModelNature(project)
&& (resLeft.getType() == IResource.FILE)) {
try {
ModelResource mrLeft = findModelResource(resLeft, true);
if (mrLeft != null) {
dpProcessor = ModelerComparePlugin.createDifferenceProcessor(isRight,
pathRight,
mrLeft,
mrLeft.getDescription());
}
} catch (ModelWorkspaceException mwe) {
UiConstants.Util.log(mwe);
}
}
}
// run the processor
// IStatus status =
dpProcessor.execute(new NullProgressMonitor());
// System.out.println("[ModelObjectStructureViewer.inputChanged] status after processor.execute is: " + status.getCode() ); //$NON-NLS-1$
drReport = dpProcessor.getDifferenceReport();
// System.out.println("[ModelObjectStructureViewer.inputChanged] drReport.getTotalAdditions(): " + drReport.getTotalAdditions() ); //$NON-NLS-1$
// System.out.println("[ModelObjectStructureViewer.inputChanged] drReport.getTotalChanges(): " + drReport.getTotalChanges() ); //$NON-NLS-1$
// System.out.println("[ModelObjectStructureViewer.inputChanged] drReport.getTotalDeletions(): " + drReport.getTotalDeletions() ); //$NON-NLS-1$
getDifferenceReportsPanel().setTerminologyStyle(getTerminologyStyle(iCompareType));
getDifferenceReportsPanel().setDifferenceReports(Collections.singletonList(drReport));
if (iCompareType == RESOURCE_NODE_TO_RESOURCE_NODE) {
getDifferenceReportsPanel().setObjectNames(getLeftObjectName(), getRightObjectName());
} else if (iCompareType == RESOURCE_NODE_TO_INPUT_STREAM) {
getDifferenceReportsPanel().setObjectNames(getRightObjectName(), getLeftObjectName());
}
if( isRight != null ) {
try {
isRight.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private int getTerminologyStyle( int iCompareType ) {
int iTerminology = DifferenceReportsPanel.USE_OLD_NEW_TERMINOLOGY;
// determine terminology setting
if (iCompareType == ModelObjectStructureViewer.RESOURCE_NODE_TO_INPUT_STREAM) {
iTerminology = DifferenceReportsPanel.USE_OLD_NEW_TERMINOLOGY;
} else if (iCompareType == ModelObjectStructureViewer.RESOURCE_NODE_TO_RESOURCE_NODE) {
iTerminology = DifferenceReportsPanel.USE_FIRST_SECOND_TERMINOLOGY;
}
return iTerminology;
}
public ModelResource findModelResource( final IResource resource,
final boolean createIfRequired ) throws ModelWorkspaceException {
CoreArgCheck.isNotNull(resource);
// Get the project and the path of the model file relative to the project ...
final IProject proj = resource.getProject();
// check if this is a model project
if (!ModelerCore.hasModelNature(proj)) {
return null;
}
final IPath pathInWorkspace = resource.getProjectRelativePath();
// Find the ModelProject
final ModelProject modelProject = ModelerCore.getModelWorkspace().getModelProject(proj);
ModelUtil.getModelResource((IFile)resource, false);
// Iterate over the segments, finding the corresponding model folder(s) and model resource
ModelWorkspaceItem parent = modelProject;
int numFolders = pathInWorkspace.segmentCount(); // should be at least 1
if (resource instanceof IFile) {
// See if the file is a model ...
if (!ModelUtil.isModelFile(resource) && !ModelUtil.isVdbArchiveFile(resource)) {
return null; // it's a non-model resource
}
--numFolders;
}
for (int i = 0; i < numFolders; ++i) {
final String folderName = pathInWorkspace.segment(i);
final ModelWorkspaceItem child = parent.getChild(folderName);
if (child == null) {
// get the workspace resource
final IFolder underlyingFolder = proj.getFolder(folderName);
CoreArgCheck.isNotNull(underlyingFolder);
final ModelFolder newFolder = new ModelFolderImpl(underlyingFolder, parent);
final Object parentInfo = ((ModelWorkspaceItemImpl)parent).getItemInfo();
if (parentInfo instanceof ModelFolderInfo) {
((ModelFolderInfo)parentInfo).addChild(newFolder);
parent = newFolder;
} else if (parentInfo instanceof ModelProjectInfo) {
((ModelProjectInfo)parentInfo).addChild(newFolder);
parent = newFolder;
}
} else {
parent = child;
}
}
if (resource instanceof IFile) {
// Get the ModelResource ...
ModelWorkspaceItem result = parent.getChild(resource);
if (result == null && createIfRequired) {
final String name = resource.getName();
result = new ModelResourceImpl(parent, name);
}
return (ModelResource)result;
}
// else return the folder
return (ModelResource)parent;
}
private DifferenceReportsPanel getDifferenceReportsPanel() {
if (pnlDifferenceReport == null) {
// determine terminology setting
if (iCompareType == ModelObjectStructureViewer.RESOURCE_NODE_TO_INPUT_STREAM) {
iTerminology = DifferenceReportsPanel.USE_OLD_NEW_TERMINOLOGY;
} else if (iCompareType == ModelObjectStructureViewer.RESOURCE_NODE_TO_RESOURCE_NODE) {
iTerminology = DifferenceReportsPanel.USE_FIRST_SECOND_TERMINOLOGY;
}
// in this case, 'drReport' is probably null
pnlDifferenceReport = new DifferenceReportsPanel(cmpParent, TREE_TITLE, DIFF_DESCRIPTOR_TITLE, false, false, false,
drReport, iTerminology);
}
// refresh the title
String sTitle = DIALOG_TITLE;
// but will they pick up this change after the panel has been created?
pnlDifferenceReport.setData(CompareUI.COMPARE_VIEWER_TITLE, sTitle);
return pnlDifferenceReport;
}
private String getRightObjectName() {
String sResult = EMPTY_STRING;
if (iCompareType == RESOURCE_NODE_TO_RESOURCE_NODE) {
sResult = rnRight.getResource().getFullPath().toString();
} else {
sResult = hiRight.getName() + " - " //$NON-NLS-1$
+ DateFormat.getDateTimeInstance().format(new Date(hiRight.getModificationDate()));
}
return sResult;
}
private String getLeftObjectName() {
return rnLeft.getResource().getFullPath().toString();
}
// ====================================
@Override
public Widget doFindInputItem( Object o ) {
return null;
}
@Override
public Widget doFindItem( Object o ) {
return null;
}
@Override
public void doUpdateItem( Widget w,
Object o,
boolean b ) {
}
@Override
public List getSelectionFromWidget() {
return null;
}
@Override
public void internalRefresh( Object o ) {
}
@Override
public void reveal( Object o ) {
}
@Override
public void setSelectionToWidget( List l,
boolean b ) {
}
@Override
public Control getControl() {
// this temp version must return a DifferenceReportsPanel
return getDifferenceReportsPanel();
}
}