/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.rubypeople.rdt.internal.core;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyModelStatus;
import org.rubypeople.rdt.core.IRubyModelStatusConstants;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.internal.core.util.Messages;
/**
* @see IRubyModelStatus
*/
public class RubyModelStatus extends Status implements IRubyModelStatus, IRubyModelStatusConstants, IResourceStatus {
/**
* The elements related to the failure, or <code>null</code>
* if no elements are involved.
*/
protected IRubyElement[] elements = new IRubyElement[0];
/**
* The path related to the failure, or <code>null</code>
* if no path is involved.
*/
protected IPath path;
/**
* The <code>String</code> related to the failure, or <code>null</code>
* if no <code>String</code> is involved.
*/
protected String string;
/**
* Empty children
*/
protected final static IStatus[] NO_CHILDREN = new IStatus[] {};
protected IStatus[] children= NO_CHILDREN;
/**
* Singleton OK object
*/
public static final IRubyModelStatus VERIFIED_OK = new RubyModelStatus(OK, OK, Messages.bind(Messages.status_OK));
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus() {
// no code for an multi-status
super(ERROR, RubyCore.PLUGIN_ID, 0, "RubyModelStatus", null); //$NON-NLS-1$
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(int code) {
super(ERROR, RubyCore.PLUGIN_ID, code, "RubyModelStatus", null); //$NON-NLS-1$
this.elements= RubyElement.NO_ELEMENTS;
}
/**
* Constructs an Ruby model status with the given corresponding
* elements.
*/
public RubyModelStatus(int code, IRubyElement[] elements) {
super(ERROR, RubyCore.PLUGIN_ID, code, "RubyModelStatus", null); //$NON-NLS-1$
this.elements= elements;
this.path= null;
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(int code, String string) {
this(ERROR, code, string);
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(int severity, int code, String string) {
super(severity, RubyCore.PLUGIN_ID, code, "RubyModelStatus", null); //$NON-NLS-1$
this.elements= RubyElement.NO_ELEMENTS;
this.path= null;
this.string = string;
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(int code, Throwable throwable) {
super(ERROR, RubyCore.PLUGIN_ID, code, "RubyModelStatus", throwable); //$NON-NLS-1$
this.elements= RubyElement.NO_ELEMENTS;
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(int code, IPath path) {
super(ERROR, RubyCore.PLUGIN_ID, code, "RubyModelStatus", null); //$NON-NLS-1$
this.elements= RubyElement.NO_ELEMENTS;
this.path= path;
}
/**
* Constructs an Ruby model status with the given corresponding
* element.
*/
public RubyModelStatus(int code, IRubyElement element) {
this(code, new IRubyElement[]{element});
}
/**
* Constructs an Ruby model status with the given corresponding
* element and string
*/
public RubyModelStatus(int code, IRubyElement element, String string) {
this(code, new IRubyElement[]{element});
this.string = string;
}
/**
* Constructs an Ruby model status with the given corresponding
* element and path
*/
public RubyModelStatus(int code, IRubyElement element, IPath path) {
this(code, new IRubyElement[]{element});
this.path = path;
}
/**
* Constructs an Ruby model status with the given corresponding
* element, path and string
*/
public RubyModelStatus(int code, IRubyElement element, IPath path, String string) {
this(code, new IRubyElement[]{element});
this.path = path;
this.string = string;
}
/**
* Constructs an Ruby model status with no corresponding elements.
*/
public RubyModelStatus(CoreException coreException) {
super(ERROR, RubyCore.PLUGIN_ID, CORE_EXCEPTION, "RubyModelStatus", coreException); //$NON-NLS-1$
elements= RubyElement.NO_ELEMENTS;
}
protected int getBits() {
int severity = 1 << (getCode() % 100 / 33);
int category = 1 << ((getCode() / 100) + 3);
return severity | category;
}
/**
* @see IStatus
*/
public IStatus[] getChildren() {
return children;
}
/**
* @see IRubyModelStatus
*/
public IRubyElement[] getElements() {
return elements;
}
/**
* Returns the message that is relevant to the code of this status.
*/
public String getMessage() {
Throwable exception = getException();
if (exception == null) {
switch (getCode()) {
case CORE_EXCEPTION :
return Messages.bind(Messages.status_coreException);
case BUILDER_INITIALIZATION_ERROR:
return Messages.bind(Messages.build_initializationError);
case BUILDER_SERIALIZATION_ERROR:
return Messages.bind(Messages.build_serializationError);
case DEVICE_PATH:
return Messages.bind(Messages.status_cannotUseDeviceOnPath, getPath().toString());
case DOM_EXCEPTION:
return Messages.bind(Messages.status_JDOMError);
case ELEMENT_DOES_NOT_EXIST:
return Messages.bind(Messages.element_doesNotExist,((RubyElement)elements[0]).toStringWithAncestors());
case ELEMENT_NOT_ON_CLASSPATH:
return Messages.bind(Messages.element_notOnClasspath,((RubyElement)elements[0]).toStringWithAncestors());
case EVALUATION_ERROR:
return Messages.bind(Messages.status_evaluationError, string);
case INDEX_OUT_OF_BOUNDS:
return Messages.bind(Messages.status_indexOutOfBounds);
case INVALID_CONTENTS:
return Messages.bind(Messages.status_invalidContents);
case INVALID_DESTINATION:
return Messages.bind(Messages.status_invalidDestination, ((RubyElement)elements[0]).toStringWithAncestors());
case INVALID_ELEMENT_TYPES:
StringBuffer buff= new StringBuffer(Messages.bind(Messages.operation_notSupported));
for (int i= 0; i < elements.length; i++) {
if (i > 0) {
buff.append(", "); //$NON-NLS-1$
}
buff.append(((RubyElement)elements[i]).toStringWithAncestors());
}
return buff.toString();
case INVALID_NAME:
return Messages.bind(Messages.status_invalidName, string);
case INVALID_PACKAGE:
return Messages.bind(Messages.status_invalidPackage, string);
case INVALID_PATH:
if (string != null) {
return string;
}
return Messages.bind(Messages.status_invalidPath, getPath() == null ? "null" : getPath().toString()); //$NON-NLS-1$
case INVALID_PROJECT:
return Messages.bind(Messages.status_invalidProject, string);
case INVALID_RESOURCE:
return Messages.bind(Messages.status_invalidResource, string);
case INVALID_RESOURCE_TYPE:
return Messages.bind(Messages.status_invalidResourceType, string);
case INVALID_SIBLING:
if (string != null) {
return Messages.bind(Messages.status_invalidSibling, string);
}
return Messages.bind(Messages.status_invalidSibling, ((RubyElement)elements[0]).toStringWithAncestors());
case IO_EXCEPTION:
return Messages.bind(Messages.status_IOException);
case NAME_COLLISION:
if (string != null) {
return string;
}
return Messages.bind(Messages.status_nameCollision, ""); //$NON-NLS-1$
case NO_ELEMENTS_TO_PROCESS:
return Messages.bind(Messages.operation_needElements);
case NULL_NAME:
return Messages.bind(Messages.operation_needName);
case NULL_PATH:
return Messages.bind(Messages.operation_needPath);
case NULL_STRING:
return Messages.bind(Messages.operation_needString);
case PATH_OUTSIDE_PROJECT:
return Messages.bind(Messages.operation_pathOutsideProject, string, ((RubyElement)elements[0]).toStringWithAncestors());
case READ_ONLY:
IRubyElement element = elements[0];
String name = element.getElementName();
return Messages.bind(Messages.status_readOnly, name);
case RELATIVE_PATH:
return Messages.bind(Messages.operation_needAbsolutePath, getPath().toString());
case TARGET_EXCEPTION:
return Messages.bind(Messages.status_targetException);
case UPDATE_CONFLICT:
return Messages.bind(Messages.status_updateConflict);
case NO_LOCAL_CONTENTS :
return Messages.bind(Messages.status_noLocalContents, getPath().toString());
case CP_VARIABLE_PATH_UNBOUND:
IRubyProject javaProject = (IRubyProject)elements[0];
return Messages.bind(Messages.classpath_unboundVariablePath, path.makeRelative().toString(), javaProject.getElementName());
case CLASSPATH_CYCLE:
javaProject = (IRubyProject)elements[0];
return Messages.bind(Messages.classpath_cycle, javaProject.getElementName());
case DISABLED_CP_EXCLUSION_PATTERNS:
javaProject = (IRubyProject)elements[0];
String projectName = javaProject.getElementName();
IPath newPath = path;
if (path.segment(0).toString().equals(projectName)) {
newPath = path.removeFirstSegments(1);
}
return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, newPath.makeRelative().toString(), projectName);
case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS:
javaProject = (IRubyProject)elements[0];
projectName = javaProject.getElementName();
newPath = path;
if (path.segment(0).toString().equals(projectName)) {
newPath = path.removeFirstSegments(1);
}
return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, newPath.makeRelative().toString(), projectName);
case PROJECT_HAS_NO_RUBY_NATURE:
javaProject = (IRubyProject)elements[0];
projectName = javaProject.getElementName();
return Messages.bind(Messages.project_has_no_ruby_nature, projectName);
}
if (string != null) {
return string;
}
return ""; // //$NON-NLS-1$
}
String message = exception.getMessage();
if (message != null) {
return message;
}
return exception.toString();
}
/**
* @see IRubyModelStatus#getPath()
*/
public IPath getPath() {
return path;
}
/**
* @see IStatus#getSeverity()
*/
public int getSeverity() {
if (children == NO_CHILDREN) return super.getSeverity();
int severity = -1;
for (int i = 0, max = children.length; i < max; i++) {
int childrenSeverity = children[i].getSeverity();
if (childrenSeverity > severity) {
severity = childrenSeverity;
}
}
return severity;
}
/**
* @see IRubyModelStatus#getString()
* @deprecated
*/
public String getString() {
return string;
}
/**
* @see IRubyModelStatus#isDoesNotExist()
*/
public boolean isDoesNotExist() {
int code = getCode();
return code == ELEMENT_DOES_NOT_EXIST || code == ELEMENT_NOT_ON_CLASSPATH;
}
/**
* @see IStatus#isMultiStatus()
*/
public boolean isMultiStatus() {
return children != NO_CHILDREN;
}
/**
* @see IStatus#isOK()
*/
public boolean isOK() {
return getCode() == OK;
}
/**
* @see IStatus#matches(int)
*/
public boolean matches(int mask) {
if (! isMultiStatus()) {
return matches(this, mask);
}
for (int i = 0, max = children.length; i < max; i++) {
if (matches((RubyModelStatus) children[i], mask))
return true;
}
return false;
}
/**
* Helper for matches(int).
*/
protected boolean matches(RubyModelStatus status, int mask) {
int severityMask = mask & 0x7;
int categoryMask = mask & ~0x7;
int bits = status.getBits();
return ((severityMask == 0) || (bits & severityMask) != 0) && ((categoryMask == 0) || (bits & categoryMask) != 0);
}
/**
* Creates and returns a new <code>IRubyModelStatus</code> that is a
* a multi-status status.
*
* @see IStatus#isMultiStatus()
*/
public static IRubyModelStatus newMultiStatus(IRubyModelStatus[] children) {
RubyModelStatus jms = new RubyModelStatus();
jms.children = children;
return jms;
}
/**
* Returns a printable representation of this exception for debugging
* purposes.
*/
public String toString() {
if (this == VERIFIED_OK){
return "RubyModelStatus[OK]"; //$NON-NLS-1$
}
StringBuffer buffer = new StringBuffer();
buffer.append("Ruby Model Status ["); //$NON-NLS-1$
buffer.append(getMessage());
buffer.append("]"); //$NON-NLS-1$
return buffer.toString();
}
}