+ "(Container is '" + _current + "').",
_currentExternalEntity(), _getLineNumber(),
_getColumnNumber());
}
CompositeEntity container = (CompositeEntity) _current;
ComponentEntity previous = _searchForEntity(entityName, _current);
Class newClass = null;
ComponentEntity reference = null;
if (className != null) {
// A class name is given.
reference = searchForClass(className, source);
// If no source is specified and no reference was found,
// search for a class definition in context.
if ((reference == null) && (source == null)) {
// Allow the class name to be local in the current context
// or defined in scope. Search for a class definition that
// matches in the current context.
reference = _searchForClassInContext(className, /* source*/
null);
}
if (reference == null) {
// No previously defined class with this name.
// First attempt to instantiate a Java class.
// If we throw an error or exception be sure to save the
// original error message before we go off and try to fix the
// error. Sometimes, the original error message is the true
// cause of the problem, and we should always provide the user
// with the cause of the original error in the unlikely event
// that our error correction fails
try {
newClass = Class.forName(className, true, _classLoader);
} catch (Exception ex) {
// NOTE: Java sometimes throws ClassNotFoundException
// and sometimes NullPointerException when the class
// does not exist. Hence the broad catch here.
try {
reference = _attemptToFindMoMLClass(className, source);
} catch (Exception ex2) {
// If we are running inside an applet, then
// we may end up getting a SecurityException,
// so we want to be sure to not throw away ex2
throw new IllegalActionException(null, ex2,
"Cannot find class: " + className);
}
} catch (Error error) {
// Java might throw a ClassFormatError, but
// we usually get and XmlException
// NOTE: The following error message is for
// the programmer, not for the user. EAL
StringBuffer errorMessage = new StringBuffer();
if (error instanceof ExceptionInInitializerError) {
// Running a Python applet may cause
// an ExceptionInInitializerError
// There was a problem in the initializer, but
// we can get the original exception that was
// thrown.
Throwable staticThrowable = ((ExceptionInInitializerError) error)
.getCause();
// I think we should report the cause and a stack
// trace for all the exceptions thrown here,
// but it sure makes the output ugly.
// Instead, I just debug from here -cxh
errorMessage.append("ExceptionInInitializerError: "
+ "Caused by:\n "
+ KernelException
.stackTraceToString(staticThrowable));
} else {
// If there is a class format error in the
// code generator, then we may end up obscuring
// that error, requiring debugging here.
// We use error.toString() here instead of
// error.getMessage() so that the name of the
// actual class that caused the error is reported.
// This is critical if the problem is a class not
// found error. If we use error.getMessage()
// and try to open up
// actor/lib/comm/demo/SerialPort/SerialPort.xml
// when the Java Serial Comm API is not installed,
// we get
// Error encounted in:
// <entity name="SerialComm" class="ptolemy.actor.lib...
// -- ptolemy.actor.lib.comm.SerialComm:
// javax/comm/SerialPortEventListener
// ptolemy.actor.lib.comm.SerialComm: XmlException:
// Could not find 'ptolemy/actor/lib/comm/SerialComm.xml'..
// If we use toString(), we get:
// Error encounted in:
// <entity name="SerialComm" class="ptolemy.actor.lib..
// -- ptolemy.actor.lib.comm.SerialComm:
// java.lang.NoClassDefFoundError: javax/comm/SerialPortEventListener
// ptolemy.actor.lib.comm.SerialComm: XmlException:
// Could not find 'ptolemy/actor/lib/comm/SerialComm.xml'..
// It is critical that the error include the
// NoClassDefFoundError string -cxh
errorMessage.append(className + ": \n "
+ error.toString() + "\n");
}
try {
reference = _attemptToFindMoMLClass(className, source);
} catch (XmlException ex2) {
throw new Exception("-- " + errorMessage.toString()
+ className + ": XmlException:\n"
+ ex2.getMessage());
} catch (ClassFormatError ex3) {
throw new Exception("-- :" + errorMessage.toString()
+ className + ": ClassFormatError: "
+ "found invalid Java class file.\n"
+ ex3.getMessage());
} catch (Exception ex4) {
throw new Exception("-- " + errorMessage.toString()
+ className + ": Exception:\n"
+ ex4.getMessage());
}
}
}
}
if (previous != null) {
if (newClass != null) {
_checkClass(previous, newClass, "entity named \"" + entityName
+ "\" exists and is not an instance of " + className);
}
return previous;
}
// No previous entity. Class name is required.
_checkForNull(className, "Cannot create entity without a class name.");
// Next check to see whether the class extends a named entity.
if (reference == null) {
// Not a named entity. Instantiate a Java class.
if (_current != null) {
// Not a top-level entity.
// First check that there will be no name collision
// when this is propagated. Note that we need to
// include all derived objects, irrespective of whether
// they are locally changed.
List derivedList = container.getDerivedList();
Iterator derivedObjects = derivedList.iterator();
while (derivedObjects.hasNext()) {
CompositeEntity derived = (CompositeEntity) derivedObjects
.next();
if (derived.getEntity(entityName) != null) {
throw new IllegalActionException(
container,
"Cannot create entity because a subclass or instance "
+ "contains an entity with the same name: "
+ derived.getEntity(entityName)
.getFullName());
}
}
_checkClass(_current, CompositeEntity.class,
"Cannot create an entity inside an element that "
+ "is not a CompositeEntity. It is: "
+ _current);
Object[] arguments = new Object[2];
arguments[0] = _current;
arguments[1] = entityName;
NamedObj newEntity = _createInstance(newClass, arguments);
newEntity.propagateExistence();
_loadIconForClass(className, newEntity);
_addParamsToParamsToParse(newEntity);
return newEntity;
} else {
// Top-level entity. Instantiate in the workspace.
// Note that there cannot possibly be any propagation here.
Object[] arguments = new Object[1];
arguments[0] = _workspace;
NamedObj result = _createInstance(newClass, arguments);
result.setName(entityName);
_loadIconForClass(className, result);
return result;
}
} else {
// Extending a previously defined entity. Check to see that
// it was defined to be a class definition.
if (!reference.isClassDefinition()) {
throw new MissingClassException(
"Attempt to extend an entity that "
+ "is not a class: " + reference.getFullName(),
reference.getFullName(), _currentExternalEntity(),
_getLineNumber(), _getColumnNumber());
}
// First check that there will be no name collision
// when this is propagated. Note that we need to
// include all derived objects, irrespective of whether
// they are locally changed.
// If the container is null, then we can't possibly get
// a name collision.
List derivedList = null;
if (container != null) {
derivedList = container.getDerivedList();
Iterator derivedObjects = derivedList.iterator();
while (derivedObjects.hasNext()) {
CompositeEntity derived = (CompositeEntity) derivedObjects
.next();
if (derived.getEntity(entityName) != null) {
throw new IllegalActionException(
container,
"Cannot create entity because a subclass or instance "
+ "contains an entity with the same name: "
+ derived.getEntity(entityName)
.getFullName());
}
}
}