tikhomirov@215: /* tikhomirov@394: * Copyright (c) 2011-2012 TMate Software Ltd tikhomirov@215: * tikhomirov@215: * This program is free software; you can redistribute it and/or modify tikhomirov@215: * it under the terms of the GNU General Public License as published by tikhomirov@215: * the Free Software Foundation; version 2 of the License. tikhomirov@215: * tikhomirov@215: * This program is distributed in the hope that it will be useful, tikhomirov@215: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@215: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@215: * GNU General Public License for more details. tikhomirov@215: * tikhomirov@215: * For information on how to redistribute this software under tikhomirov@215: * the terms of a license other than GNU General Public License tikhomirov@215: * contact TMate Software at support@hg4j.com tikhomirov@215: */ tikhomirov@215: package org.tmatesoft.hg.core; tikhomirov@215: tikhomirov@423: import org.tmatesoft.hg.internal.ExceptionInfo; tikhomirov@275: import org.tmatesoft.hg.util.Path; tikhomirov@215: tikhomirov@275: tikhomirov@215: tikhomirov@215: /** tikhomirov@423: * Checked exception that client supplied callback code can use to indicates its own errors. tikhomirov@370: * tikhomirov@423: *

Generally, client need to pass own error information/exceptions from within implementations of the callback methods they supply. tikhomirov@370: * However, there's no straightforward way to alter throws clause for these methods, and alternatives like generic {@link Exception} or tikhomirov@370: * library's own {@link HgException} are rather obscure. Suggested approach is to wrap whatever exception user code produces with tikhomirov@423: * {@link HgCallbackTargetException}, the only checked exception allowed out from a callback. tikhomirov@370: * tikhomirov@427: *

It's intentionally not a subclass of {@link HgException} to avoid get mixed with library own errors and be processed separately. tikhomirov@423: * tikhomirov@427: *

Top-level API handlers ({@link HgStatusHandler}, {@link HgManifestHandler}, {@link HgChangesetHandler}, etc) allow to throw tikhomirov@557: * HgCallbackTargetException from their methods. Exceptions thrown this way are not handled in corresponding commands, except for tikhomirov@557: * revision or file name specification, unless already set. Then, these exceptions go straight to the command caller. tikhomirov@215: * tikhomirov@215: * @author Artem Tikhomirov tikhomirov@215: * @author TMate Software Ltd. tikhomirov@215: */ tikhomirov@215: @SuppressWarnings("serial") tikhomirov@423: public class HgCallbackTargetException extends Exception { tikhomirov@423: tikhomirov@423: protected final ExceptionInfo details = new ExceptionInfo(this); tikhomirov@423: tikhomirov@215: /** tikhomirov@215: * @param cause can't be null tikhomirov@215: */ tikhomirov@215: public HgCallbackTargetException(Throwable cause) { tikhomirov@216: super((String) null); tikhomirov@215: if (cause == null) { tikhomirov@215: throw new IllegalArgumentException(); tikhomirov@215: } tikhomirov@423: initCause(cause); tikhomirov@215: } tikhomirov@215: tikhomirov@215: @SuppressWarnings("unchecked") tikhomirov@423: public T getTargetException() { tikhomirov@215: return (T) getCause(); tikhomirov@215: } tikhomirov@215: tikhomirov@215: /** tikhomirov@215: * Despite this exception is merely a way to give users access to their own exceptions, it may still supply tikhomirov@215: * valuable debugging information about what led to the error. tikhomirov@215: */ tikhomirov@215: @Override tikhomirov@215: public String getMessage() { tikhomirov@215: StringBuilder sb = new StringBuilder(); tikhomirov@423: sb.append("Error from callback. Original exception thrown: "); tikhomirov@320: sb.append(getCause().getClass().getName()); tikhomirov@320: sb.append(" at "); tikhomirov@423: details.appendDetails(sb); tikhomirov@215: return sb.toString(); tikhomirov@215: } tikhomirov@215: tikhomirov@275: public HgCallbackTargetException setRevision(Nodeid r) { tikhomirov@423: return details.setRevision(r); tikhomirov@275: } tikhomirov@275: tikhomirov@423: public HgCallbackTargetException setRevisionIndex(int rev) { tikhomirov@423: return details.setRevisionIndex(rev); tikhomirov@423: } tikhomirov@215: tikhomirov@423: public HgCallbackTargetException setFileName(Path name) { tikhomirov@423: return details.setFileName(name); tikhomirov@215: } tikhomirov@215: }