/*****************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.buckminster.core.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.buckminster.cmdline.Option;
import org.eclipse.buckminster.cmdline.OptionDescriptor;
import org.eclipse.buckminster.cmdline.OptionValueType;
import org.eclipse.buckminster.cmdline.UsageException;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.Messages;
import org.eclipse.buckminster.core.actor.IPerformManager;
import org.eclipse.buckminster.core.cspec.model.Attribute;
import org.eclipse.buckminster.core.cspec.model.CSpec;
import org.eclipse.buckminster.core.cspec.model.ComponentIdentifier;
import org.eclipse.buckminster.core.metadata.WorkspaceInfo;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
public class Perform extends WorkspaceCommand {
static private final OptionDescriptor FORCED_DESCRIPTOR = new OptionDescriptor('F', "force", OptionValueType.NONE); //$NON-NLS-1$
static private final OptionDescriptor QUIET_DESCRIPTOR = new OptionDescriptor('Q', "quiet", OptionValueType.NONE); //$NON-NLS-1$
static private final OptionDescriptor MAXWARNINGS_DESCRIPTOR = new OptionDescriptor('W', "maxWarnings", //$NON-NLS-1$
OptionValueType.REQUIRED);
private final List<Attribute> attributes = new ArrayList<Attribute>();
private boolean forced = false;
private int maxWarnings = -1;
private boolean quiet;
public void addAttribute(Attribute attribute) {
attributes.add(attribute);
}
public boolean isQuiet() {
return quiet;
}
public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
@Override
protected void getOptionDescriptors(List<OptionDescriptor> appendHere) throws Exception {
appendHere.add(MAXWARNINGS_DESCRIPTOR);
appendHere.add(FORCED_DESCRIPTOR);
appendHere.add(QUIET_DESCRIPTOR);
super.getOptionDescriptors(appendHere);
}
@Override
protected void handleOption(Option option) throws Exception {
if (option.is(MAXWARNINGS_DESCRIPTOR))
maxWarnings = Integer.parseInt(option.getValue());
else if (option.is(FORCED_DESCRIPTOR))
forced = true;
else if (option.is(QUIET_DESCRIPTOR))
quiet = true;
else
super.handleOption(option);
}
@Override
protected void handleUnparsed(String[] unparsed) throws Exception {
for (String s : unparsed) {
String component = null;
String attribute = null;
int splitIdx = s.lastIndexOf('#');
if (splitIdx > 0) {
attribute = s.substring(splitIdx + 1).trim();
if (attribute.length() == 0)
attribute = null;
component = s.substring(0, splitIdx).trim();
if (component.length() == 0)
component = null;
}
if (component == null || attribute == null)
throw new UsageException(Messages.Attribute_names_must_be_in_the_form_component_name_attribute_name);
CSpec cspec = WorkspaceInfo.getResolution(ComponentIdentifier.parse(component)).getCSpec();
addAttribute(cspec.getRequiredAttribute(attribute));
}
}
@Override
protected int internalRun(IProgressMonitor monitor) throws Exception {
if (attributes.isEmpty())
throw new UsageException(Messages.No_attributes_specified);
IPerformManager pm = CorePlugin.getPerformManager();
IStatus status = pm.perform(attributes, null, forced, quiet, monitor).getStatus();
if (status.isOK())
return 0;
// Get all problem markers. Sort them by timestamp
//
IMarker[] markers = ResourcesPlugin.getWorkspace().getRoot().findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
if (markers.length == 0)
return 0;
if (isQuiet()) {
for (IMarker problem : markers)
if (problem.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR)
return 1;
return 0;
}
Map<Long, IMarker> problems = new TreeMap<Long, IMarker>();
for (IMarker problem : markers)
problems.put(Long.valueOf(problem.getCreationTime()), problem);
int warnings = 0;
int errors = 0;
int exitValue = 0;
for (IMarker problem : problems.values()) {
switch (problem.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO)) {
case IMarker.SEVERITY_ERROR:
exitValue = 1;
errors++;
System.err.println(formatMarkerMessage("Error", problem)); //$NON-NLS-1$
break;
case IMarker.SEVERITY_WARNING:
warnings++;
System.err.println(formatMarkerMessage("Warning", problem)); //$NON-NLS-1$
break;
case IMarker.SEVERITY_INFO:
System.out.println(formatMarkerMessage("Info", problem)); //$NON-NLS-1$
}
}
if (warnings + errors > 0) {
StringBuilder bld = new StringBuilder();
bld.append(Messages.Found);
if (errors > 0) {
bld.append(errors);
bld.append(Messages.Errors);
if (warnings > 0)
bld.append(Messages.And);
}
if (warnings > 0) {
bld.append(warnings);
bld.append(Messages.Warnings);
}
System.err.println(bld.toString());
}
if (maxWarnings != -1 && warnings > maxWarnings) {
System.err.println(Messages.Too_many_warnings_Exiting_with_error_status);
exitValue = 1;
}
if (exitValue > 0)
System.err.println(Messages.Build_failed);
return exitValue;
}
private String formatMarkerMessage(String type, IMarker problem) {
StringBuilder bld = new StringBuilder();
bld.append(type);
bld.append(": file "); //$NON-NLS-1$
bld.append(problem.getResource().getLocation().toOSString());
int line = problem.getAttribute(IMarker.LINE_NUMBER, -1);
if (line > 0) {
bld.append(", line "); //$NON-NLS-1$
bld.append(line);
}
bld.append(": "); //$NON-NLS-1$
bld.append(problem.getAttribute(IMarker.MESSAGE, "")); //$NON-NLS-1$
return bld.toString();
}
}