001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: UMSException.java,v 1.5 2009/01/28 05:34:51 ww203982 Exp $ 026 * 027 */ 028 029/** 030 * Portions Copyrighted [2011] [ForgeRock AS] 031 */ 032package com.iplanet.ums; 033 034import java.io.PrintWriter; 035import java.io.StringWriter; 036import java.util.ResourceBundle; 037 038import com.sun.identity.shared.ldap.LDAPException; 039 040/** 041 * <PRE> 042 * 043 * This class is the super-class for all UMS <B>checked</B> exceptions. 044 * 045 * 046 * Some Exception throwing guidelines: ------------------------------------- 047 * 048 * <B> Checked exceptions </B> are sub-classes of java.lang.Exception; methods 049 * throwing this type of exception are forced to define a throws clause in the 050 * method signature and client programmers need to catch and handle the 051 * exception with a try/catch block or declare the throws clause in their 052 * methods. <B> Unchecked exceptions </B> are sub-classes of 053 * java.lang.RuntimeException. Client programmers don't have to deal with the 054 * exception using a try/catch block and the method throwing it does not have to 055 * define it in its signature. 056 * - If your method encounters an abnormal condition which causes it to be 057 * unable to fulfill its contract, or throw a checked or unchecked exception 058 * (either UMSException or RuntimeException). 059 * - If your method discovers that a client has breached its contract, for 060 * example, passing a null as a parameter where a non-null value is required, 061 * throw an unchecked exception (RuntimeException). 062 * - If your method is unable to fulfill its contract and you feel client 063 * programmers should consciously decide how to handle, throw checked exceptions 064 * (UMSException). 065 * 066 * 067 * Embedded/Nested Exceptions: -------------------------- 068 * 069 * An exception of type UMSException can embed any exception of type Throwable. 070 * Embedded exceptions ensure traceability of errors in a multi-tiered 071 * application. For example, in a simple 3- Tier model - presentation/client 072 * tier, middle/domain tier and database/persistence tier - the real cause of 073 * error might be lost by the time control, which is passed back from the 074 * persistence tier to the client tier. To ensure tracking info, the constructor 075 * UMSException(message,Throwable) should be used while throwing the exception. 076 * Normally, the first object at each tier/module will have generic exceptions 077 * defined, for example, LDAPException, RelationalDBException, 078 * ConfigManagerException. Client programs can then invoke the #getRootCause() 079 * method to get the underlying cause. 080 * 081 * Exception hierarchy should be defined: ------------------------------------- 082 * An exception for each abnormal cause should be created. For example, 083 * LDAPSearchException, LDAPArchiveException, etc. UMSException should probably 084 * be thrown only by external API's. Even these should have embedded exceptions 085 * from lower level tiers. For example, UMSException will have LDAPException 086 * embedded in it, LDAPException will have LDAPSearchException nested, and so 087 * on. Every package should define its own exception hierarchies specific to its 088 * context, for example, policy-related exceptions should be defined in the 089 * policy package. 090 * 091 * Localizing Error Messages ------------------------- The java resource bundle 092 * mechanism is used to implement localization. The ResourceSet and 093 * ResourceSetManager classes are used to implement localization. 094 * 095 * Steps for creating UMSException Sub-classes and messages 096 * ------------------------------------------------------ 097 * 098 * 1. Identify the package this exception will belong to. A policy-related 099 * exception, PolicyNotFoundException, should be part of the policy package. 100 * 101 * 2. Each package should have its own properties file to store error messages. 102 * For example policy.properties in package policy #policy.properties # 103 * Resources for com.iplanet.ums.policy policy-nopolicyfound=Cannot find this 104 * Policy 105 * 106 * 3. Create a sub-class of UMSException and override the constructors. 107 * 108 * public class PolicyNotFoundException extends UMSException { public 109 * PolicyNotFoundException() { super(); } public PolicyNotFoundException(String 110 * msg) { super(msg); } public PolicyNotFoundExceptin(String msg, Throwable t) { 111 * super(msg,t); } 112 * 113 * 114 * Throwing/Catching Exception Examples: ------------------------------------ 115 * 116 * 1. Throwing a non-nested Exception <B>(not recommended, use Ex. 3 below)</B> 117 * UMSException ux = new UMSException("Some weird error!..."); throw ux; 118 * 119 * 2. Throwing a nested Exception <B>(not recommended, use Ex. 3 below)</B> 120 * try { ....... ....... } catch (LDAPException le) { UMSException ux = new 121 * UMSException("Some weird error!...", le); throw ux; } 122 * 123 * 3. Throwing an Exception using the ResourceSetManager 124 * 125 * ...... ...... public static final String PKG = 126 * "com.iplanet.ums.policy.policy"; public static final String PREFIX = 127 * "policy"; public static final String NO_POLICY_DOMAIN = "nopolicydomain"; 128 * public static final String POLICY_NOT_FOUND = "nopolicyfound"; ...... ...... 129 * if( policyDomainName == null || policyDomainName.length() == 0) { 130 * String msg = ResourceSetManager.getString( PKG, PREFIX, NO_POLICY_DOMAIN ); 131 * // RuntimeException 132 * throw new IllegalArgumentException( msg ); } ...... ...... 133 * if (policy not found ) { String msg = ResourceSetManager.getString( PKG, 134 * PREFIX, POLICY_NOT_FOUND); // RuntimeException throw new 135 * InvalidPolicyException(msg); } 136 * 137 * 138 * The properties file (com/iplanet/ums/policy/policy.properties) looks like 139 * this: # Resources for com.iplanet.ums.policy policy-nopolicydomain=Policy 140 * Domain name cannot be null or blank policy-nopolicyfound=Cannot find this 141 * Policy 142 * 143 * - Logging/Dealing with an Exception, inclunding all nested exceptions try { 144 * ....... ....... } catch (UMSException ux) { 145 * 146 * if (ux.getRootCause() instanceof LDAPException) { PrintWriter pw = new 147 * PrintWriter(<some file stream>); ux.log(pw); } else { 148 * System.out.println(ux.getMessage()); } 149 * } 150 * 151 * </PRE> 152 * 153 * @see #UMSException(String, Throwable) 154 * @see #getRootCause() 155 * @see java.lang.Exception 156 * @see java.lang.RuntimeException 157 * @supported.api 158 */ 159public class UMSException extends java.lang.Exception { 160 161 private static final long serialVersionUID = -7043204896844472780L; 162 163 static ResourceBundle xcptMsgs = null; 164 165 protected String xcptMessage; 166 167 protected Throwable rootCause; 168 169 /** 170 * Constructs a UMSException with a detailed message. 171 * 172 * @param message 173 * Detailed message for this exception. 174 * @supported.api 175 */ 176 public UMSException(String message) { 177 super(message); 178 xcptMessage = message; 179 } 180 181 /** 182 * Constructs a UMSException with a message and an embedded exception. 183 * 184 * @param message 185 * Detailed message for this exception. 186 * @param rootCause 187 * An embedded exception 188 * @supported.api 189 */ 190 public UMSException(String message, Throwable rootCause) { 191 super(message); 192 xcptMessage = message; 193 this.rootCause = rootCause; 194 } 195 196 /** 197 * Constructs a UMSException with no details. 198 */ 199 protected UMSException() { 200 super(); 201 xcptMessage = null; 202 } 203 204 /** 205 * Returns the detail message of this exception and all embedded exceptions. 206 * @supported.api 207 */ 208 public String getMessage() { 209 210 // if there's no nested exception, 211 // return the main message 212 if (getRootCause() == null) 213 return xcptMessage; 214 215 StringBuilder theMsg = new StringBuilder(); 216 217 // get the root cause message 218 String nestedMsg; 219 if (rootCause instanceof LDAPException) { 220 nestedMsg = ((LDAPException) rootCause).getLDAPErrorMessage(); 221 } else { 222 nestedMsg = rootCause.getMessage(); 223 } 224 225 if (xcptMessage != null) 226 theMsg.append(xcptMessage).append("::").append(nestedMsg); 227 else 228 theMsg.append(nestedMsg); 229 230 return theMsg.toString(); 231 } 232 233 /** 234 * Returns the embedded exception. 235 * @supported.api 236 */ 237 public Throwable getRootCause() { 238 return rootCause; 239 } 240 241 /** 242 * Format this UMSException to a PrintWriter. 243 * 244 * @param out 245 * PrintWriter to write exception to. 246 * 247 * @return The out parameter passed in. 248 * @see java.io.PrintWriter 249 * @supported.api 250 */ 251 public PrintWriter log(PrintWriter out) { 252 return log(this, out); 253 } 254 255 /** 256 * A utility method to format an Exception to a PrintWriter. 257 * 258 * @param xcpt 259 * Exception to log. 260 * @param out 261 * PrintWriter to write exception to. 262 * 263 * @return The out parameter passed in. 264 * @see java.io.PrintWriter 265 * @supported.api 266 */ 267 static public PrintWriter log(Throwable xcpt, PrintWriter out) { 268 269 out.println("-----------"); 270 out.println(xcpt.toString()); 271 out.println("Stack Trace:"); 272 out.print(getStackTrace(xcpt)); 273 out.println("-----------"); 274 out.flush(); 275 return out; 276 } 277 278 /** 279 * Formats a UMSException exception message; includes embedded exceptions. 280 * @supported.api 281 */ 282 public String toString() { 283 284 StringBuilder buf = new StringBuilder(); 285 buf.append("--------------------------------------"); 286 buf.append("Got UMS Exception\n"); 287 288 String msg = getMessage(); 289 if (msg != null && msg.length() > 0) { 290 buf.append("Message: ").append(getMessage()); 291 } 292 293 // Invoke toString() of rootCause first 294 if (rootCause != null) { 295 buf.append("\nLower level exception: "); 296 buf.append(getRootCause()); 297 } 298 299 return buf.toString(); 300 } 301 302 /** 303 * Prints this exception's stack trace to <tt>System.err</tt>. If this 304 * exception has a root exception; the stack trace of the root exception is 305 * printed to <tt>System.err</tt> instead. 306 * @supported.api 307 */ 308 public void printStackTrace() { 309 printStackTrace(System.err); 310 } 311 312 /** 313 * Prints this exception's stack trace to a print stream. If this exception 314 * has a root exception, the stack trace of the root exception is printed to 315 * the print stream instead. 316 * 317 * @param ps 318 * The non-null print stream to which to print. 319 * @supported.api 320 */ 321 public void printStackTrace(java.io.PrintStream ps) { 322 if (rootCause != null) { 323 String superString = super.toString(); 324 synchronized (ps) { 325 ps.print(superString + (superString.endsWith(".") ? "" : ".") 326 + " Root exception is "); 327 rootCause.printStackTrace(ps); 328 } 329 } else { 330 super.printStackTrace(ps); 331 } 332 } 333 334 /** 335 * Prints this exception's stack trace to a print writer. If this exception 336 * has a root exception; the stack trace of the root exception is printed to 337 * the print writer instead. 338 * 339 * @param pw The non-null print writer to which to print. 340 * @supported.api 341 */ 342 public void printStackTrace(java.io.PrintWriter pw) { 343 if (rootCause != null) { 344 String superString = super.toString(); 345 synchronized (pw) { 346 pw.print(superString + (superString.endsWith(".") ? "" : ".") 347 + " Root exception is "); 348 rootCause.printStackTrace(pw); 349 } 350 } else { 351 super.printStackTrace(pw); 352 } 353 } 354 355 /** 356 * Get exception stack trace as a string. 357 * 358 * java.lang.Throwable java.lang.Exception UMSException <name of exception 359 * being thrown> 360 */ 361 static private String getStackTrace(Throwable xcpt) { 362 StringWriter sw = new StringWriter(); 363 PrintWriter pw = new PrintWriter(sw); 364 365 xcpt.printStackTrace(pw); 366 367 return sw.toString(); 368 } 369}
Copyright © 2010-2017, ForgeRock All Rights Reserved.