/*******************************************************************************
* Copyright © 2006, 2013 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package eglx.lang;
import java.lang.reflect.Field;
import org.eclipse.edt.javart.Constants;
import org.eclipse.edt.javart.TypeConstraints;
import org.eclipse.edt.javart.messages.Message;
import org.eclipse.edt.javart.util.JavartUtil;
public class AnyException extends RuntimeException implements eglx.lang.EAny {
private static final long serialVersionUID = Constants.SERIAL_VERSION_UID;
protected String message;
/**
* The message ID.
*/
protected String messageID;
public AnyException() {
this.message = "";
this.messageID = "";
ezeInitialize();
}
public AnyException(String id, String message) {
super( message );
this.message = message;
this.messageID = id;
ezeInitialize();
}
public Object clone() throws CloneNotSupportedException {
AnyException ezeClone = (AnyException) super.clone();
return ezeClone;
}
@Override
public void ezeInitialize() {}
@Override
public Object ezeGet(String name) throws AnyException {
try {
Field field = this.getClass().getField(name);
Object value = field.get(this);
return value;
}
catch (Exception e) {
DynamicAccessException dax = new DynamicAccessException();
dax.key = name;
dax.initCause( e );
throw dax.fillInMessage( Message.DYNAMIC_ACCESS_FAILED, name, ezeName() );
}
}
@Override
public Object ezeGet(int index) throws AnyException {
TypeCastException tcx = new TypeCastException();
tcx.castToName = "list";
Object unboxed = ezeUnbox();
tcx.actualTypeName = unboxed.getClass().getName();
throw tcx.fillInMessage( Message.CONVERSION_ERROR, unboxed, tcx.actualTypeName,
tcx.castToName );
}
@Override
public String ezeName() {
return this.getClass().getSimpleName();
}
@Override
public void ezeSet(String name, Object value) throws AnyException {
try {
Field field = this.getClass().getField(name);
field.set(this, value);
}
catch (Exception e) {
DynamicAccessException dax = new DynamicAccessException();
dax.key = name;
dax.initCause( e );
throw dax.fillInMessage( Message.DYNAMIC_ACCESS_FAILED, name, ezeName() );
}
}
@Override
public TypeConstraints ezeTypeConstraints(String fieldName) {
return null;
}
@Override
public String ezeTypeSignature() {
return this.getClass().getName();
}
public String toString() {
String msg = getMessage();
if (msg.length() == 0) {
return ezeTypeSignature();
} else {
String typeSig = ezeTypeSignature();
return new StringBuilder(typeSig.length() + 1 + msg.length()).append(typeSig).append(' ').append(msg).toString();
}
}
public void setMessage(String message) {
this.message = message;
}
/**
* Because the message is a non-nullable field of AnyException, this method
* never returns null. If there's no message, it returns the empty string.
*/
@Override
public String getMessage() {
if ( message != null && message.length() > 0 )
return message;
String superMessage = super.getMessage();
if ( superMessage != null && superMessage.length() > 0 )
return superMessage;
return "";
}
/**
* @return The ID of the error message.
*/
public String getMessageID()
{
return messageID;
}
public void setMessageID(String id) {
this.messageID = id;
}
@Override
public AnyException ezeUnbox() {
return this;
}
/**
* This method sets the ID and message of this exception. It's normally used
* after an exception is created and values are assigned to its fields, other
* than message and messageID. This exception is returned so that it may easily
* be thrown, as shown in the following example.
* <pre><code>
* DynamicAccessException dax = new DynamicAccessException();
* dax.key = name;
* throw dax.fillInMessage( Message.DYNAMIC_ACCESS_FAILED, name, ezeName() );
* </code></pre>
*
* @param id the message ID.
* @param inserts the inserts for the message, may be null.
* @return this exception.
*/
public AnyException fillInMessage( String id, Object... inserts )
{
setMessageID( id );
setMessage( JavartUtil.errorMessage( id, inserts ) );
return this;
}
/**
* The usual implementation of this method is VERY expensive. To improve
* performance, at the cost of losing stack traces from our exceptions, set
* the system property org.eclipse.edt.javart.StackTraces to false.
*
* @return this object.
*/
public Throwable fillInStackTrace()
{
if ( STACK_TRACES )
{
return super.fillInStackTrace();
}
return this;
}
/**
* Determines if fillInStackTrace is optimized or not.
*/
public static final boolean STACK_TRACES = !"false".equalsIgnoreCase( System.getProperty( "org.eclipse.edt.javart.StackTraces" ) );
}