/*******************************************************************************
* Copyright (c) 2004, 2006
* Thomas Hallgren, Kenneth Olwing, Mitch Sonies
* Pontus Rydin, Nils Unden, Peer Torngren
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the individual
* copyright holders listed above, as Initial Contributors under such license.
* The text of such license is available at www.eclipse.org.
*******************************************************************************/
package org.eclipse.buckminster.manifest.commands;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.List;
import org.eclipse.buckminster.cmdline.AbstractCommand;
import org.eclipse.buckminster.cmdline.Option;
import org.eclipse.buckminster.cmdline.OptionDescriptor;
import org.eclipse.buckminster.cmdline.OptionValueType;
import org.eclipse.buckminster.cmdline.SimpleErrorExitException;
import org.eclipse.buckminster.cmdline.UsageException;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.helpers.TextUtils;
import org.eclipse.buckminster.manifest.Difference;
import org.eclipse.buckminster.manifest.Manifest;
import org.eclipse.buckminster.runtime.MonitorUtils;
import org.eclipse.core.runtime.IProgressMonitor;
public class DiffManifest extends AbstractCommand
{
static private final OptionDescriptor ALGORITHM_DESCRIPTOR = new OptionDescriptor('a', "algorithm",
OptionValueType.REQUIRED);
static private final OptionDescriptor ASSUMEDLINESEPARATOR_DESCRIPTOR = new OptionDescriptor('l',
"assumedlineseparator", OptionValueType.REQUIRED);
static private final OptionDescriptor REPORT_DESCRIPTOR = new OptionDescriptor('r', "report", OptionValueType.NONE);
static private final OptionDescriptor DIFFERENCESONLY_DESCRIPTOR = new OptionDescriptor('d', "differencesonly",
OptionValueType.NONE);
static private final OptionDescriptor SETSTATUS_DESCRIPTOR = new OptionDescriptor('s', "setstatus",
OptionValueType.NONE);
private String m_algorithm = null;
private String m_assumedLineSep = null;
private boolean m_report = false;
private boolean m_differencesOnly = false;
private boolean m_setStatus = false;
private File m_left = null;
private File m_right = null;
@Override
protected void getOptionDescriptors(List<OptionDescriptor> appendHere) throws Exception
{
appendHere.add(ALGORITHM_DESCRIPTOR);
appendHere.add(ASSUMEDLINESEPARATOR_DESCRIPTOR);
appendHere.add(REPORT_DESCRIPTOR);
appendHere.add(DIFFERENCESONLY_DESCRIPTOR);
appendHere.add(SETSTATUS_DESCRIPTOR);
}
@Override
protected void handleOption(Option option) throws Exception
{
if(option.is(ALGORITHM_DESCRIPTOR))
m_algorithm = option.getValue();
else if(option.is(ASSUMEDLINESEPARATOR_DESCRIPTOR))
m_assumedLineSep = this.convertToRealLineSep(option.getValue());
else if(option.is(REPORT_DESCRIPTOR))
m_report = true;
else if(option.is(DIFFERENCESONLY_DESCRIPTOR))
m_differencesOnly = true;
else if(option.is(SETSTATUS_DESCRIPTOR))
m_setStatus = true;
}
@Override
protected void handleUnparsed(String[] unparsed) throws Exception
{
if(unparsed.length > 2)
throw new UsageException("Too many arguments.");
if(unparsed.length > 0)
m_left = new File(unparsed[0]);
if(unparsed.length > 1)
m_right = new File(unparsed[1]);
}
@Override
protected int run(IProgressMonitor monitor) throws Exception
{
if(m_left == null || m_right == null)
throw new SimpleErrorExitException("No left/right root or manifest given");
if(!m_left.exists() || !m_right.exists())
throw new SimpleErrorExitException("Both left and right must exist as either file or directory");
Difference d = null;
Difference.RESULT r = null;
try
{
monitor.beginTask(null, 4);
Manifest lmf = m_left.isFile()
? Manifest.fromBufferedReader(new BufferedReader(new FileReader(m_left)), null)
: Manifest.create(m_left, m_algorithm, m_assumedLineSep, null, MonitorUtils.subMonitor(monitor, 1));
MonitorUtils.testCancelStatus(monitor);
Manifest rmf = m_right.isFile()
? Manifest.fromBufferedReader(new BufferedReader(new FileReader(m_right)), null)
: Manifest.create(m_right, m_algorithm, m_assumedLineSep, null, MonitorUtils.subMonitor(monitor, 1));
MonitorUtils.testCancelStatus(monitor);
d = lmf.getDifference(rmf);
CorePlugin.getLogger().info(d.toString());
MonitorUtils.worked(monitor, 1);
r = d.getResult();
MonitorUtils.worked(monitor, 1);
}
finally
{
monitor.done();
}
int status = 0;
switch(r)
{
case EQUAL:
System.out.println("Manifests are equal.");
break;
case MATCHING:
System.out.println("Manifests are not equal, but matches and can be merged.");
status = 1;
break;
case MERGABLE_NONMATCHING:
System.out.println("Manifests are not equal and do not match, but can be merged.");
status = 2;
break;
case NONMATCHING:
System.out.println("Manifests do not match.");
status = 3;
break;
default:
throw new InternalError("Unexpected diff result: " + r);
}
if(m_report)
d.report(new PrintWriter(System.out, true), m_differencesOnly);
return m_setStatus
? status
: 0;
}
private String convertToRealLineSep(String symbolicLineSep)
{
if(symbolicLineSep.equalsIgnoreCase("crlf"))
return "\r\n";
else if(symbolicLineSep.equalsIgnoreCase("cr"))
return "\r";
else if(symbolicLineSep.equalsIgnoreCase("lf"))
return "\n";
else
return new String(TextUtils.makeByteArrayFromHexString(symbolicLineSep));
}
}