001/* A notification exception used only to terminate a process. 002 003 Copyright (c) 1997-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.actor.process; 029 030import ptolemy.kernel.util.Nameable; 031 032/////////////////////////////////////////////////////////////////// 033//// TerminateProcessException 034 035/** 036 This exception is thrown to terminate a process. This is only a 037 notification exception that a ProcessDirector uses to terminate all the 038 processes gracefully. It is not an exception that indicates an error in 039 the code or model. 040 <p> 041 In the process domains (PN and CSP for example), a simulation is 042 terminated only when a deadlock is detected. During a deadlock, the 043 threads corresponding to actors are normally blocked on a method call to 044 the receiver. This exception is normally thrown from these methods, so 045 that the threads can return from the call and terminate themselves. 046 <p> 047 This class is a standalone class and not derived from the Ptolemy 048 Runtime exceptions as those exceptions indicate an error in the model, 049 while this exception is used for passing of information to the threads. 050 051 @author Neil Smyth, Mudit Goel 052 @version $Id$ 053 @since Ptolemy II 0.2 054 @Pt.ProposedRating Green (mudit) 055 @Pt.AcceptedRating Yellow (mudit) 056 */ 057@SuppressWarnings("serial") 058public class TerminateProcessException extends RuntimeException { 059 // NOTE: This class has much duplicated code with KernelException, 060 // but because it needs to be a RuntimeException, there seemed to 061 // be no way to avoid this. Should there be an interface defined 062 // for the commonality? 063 064 /** Constructs an Exception with only a detail message. 065 * @param detail The message. 066 */ 067 public TerminateProcessException(String detail) { 068 this(null, null, detail); 069 } 070 071 /** Constructs an Exception with a detail message that includes the 072 * name of the first argument and the second argument string. 073 * @param object The object. 074 * @param detail The message. 075 */ 076 public TerminateProcessException(Nameable object, String detail) { 077 this(object, null, detail); 078 } 079 080 /** Constructs an Exception with a detail message that includes the 081 * names of the first two arguments plus the third argument string. 082 * @param object1 The first object. 083 * @param object2 The second object. 084 * @param detail The message. 085 */ 086 public TerminateProcessException(Nameable object1, Nameable object2, 087 String detail) { 088 String object1String = _getFullName(object1); 089 String object2String = _getFullName(object2); 090 String prefix; 091 092 if (!object1String.equals("")) { 093 if (!object2String.equals("")) { 094 prefix = object1String + " and " + object2String; 095 } else { 096 prefix = object1String; 097 } 098 } else { 099 prefix = object2String; 100 } 101 102 _setMessage(prefix); 103 104 if (detail != null) { 105 if (!detail.equals("")) { 106 if (!prefix.equals("")) { 107 _setMessage(prefix + ": " + detail); 108 } else { 109 _setMessage(detail); 110 } 111 } 112 } 113 } 114 115 /////////////////////////////////////////////////////////////////// 116 //// public methods //// 117 118 /** Get the detail message. */ 119 @Override 120 public String getMessage() { 121 return _message; 122 } 123 124 /////////////////////////////////////////////////////////////////// 125 //// protected methods //// 126 127 /** Get the name of a Nameable object. This method attempts to use 128 * getFullName(), if it is defined, and resorts to getName() if it is 129 * not. If the argument is a null reference, return an empty string. 130 * @param object An object with a full name. 131 * @return The full name of the argument. 132 */ 133 protected String _getFullName(Nameable object) { 134 String name; 135 136 if (object == null) { 137 return ""; 138 } else { 139 try { 140 name = object.getFullName(); 141 } catch (TerminateProcessException ex) { 142 name = object.getName(); 143 } 144 } 145 146 return name; 147 } 148 149 /** Get the name of a Nameable object. 150 * If the argument is a null reference, return an empty string. 151 * @param object An object with a name. 152 * @return The name of the argument. 153 */ 154 protected String _getName(Nameable object) { 155 String name; 156 157 if (object == null) { 158 return ""; 159 } else { 160 name = object.getName(); 161 162 if (name.equals("")) { 163 name = "<Unnamed Object>"; 164 } 165 } 166 167 return name; 168 } 169 170 /** Sets the error message to the specified string. 171 * @param message The message. 172 */ 173 protected void _setMessage(String message) { 174 _message = message; 175 } 176 177 /////////////////////////////////////////////////////////////////// 178 //// private variables //// 179 // The detail message. 180 private String _message; 181}