package com.perforce.client.api; class P4Error { //================================// // // PACKAGE // //================================// long instance = 0; // the native perr instance of the error /** * Makes a ClientUser object. * * @return XXX. * **/ String fmt() { return nFmt(this.instance); } /** * Test to see if there was an error made. * * @return if there is an error or not. * **/ boolean test() { return nTest(this.instance); } P4Error() { this.instance = nNewInstance(); javaCreatedTheInstance = true; } /** * Make a new P4Error that will just bind to an already * existing native Error. * * @param instance a native peer to bind this to. * @return the java interface. * **/ static P4Error makeJavaPeer(long instance) { return new P4Error(instance); } /** * Take a P4ClientException, and make sure that the * error on the native side is set. * * <p>You would call this when you've caught a P4ClientException * and want to convey that to the native side</p> * * @param err the exception that we use to see what to set. * **/ void convertException(P4ClientException err) { // // We can get a unique name for this exception // String kind = exceptionToName(err); // // If we got one (and we always should) // if (kind != null) { // // Get the native ErrorId and set it on the native side // long ptr = nameToPtr(kind); nSetErrorId(this.instance, ptr); } else { // // By default, just set a message // nSetMessage(this.instance, err.toString()); } } /** * Given a P4Error, see if there was an exception on the native side. * If so, throw the corresponding P4ClientException. * * <p>You would use this if you wanted to convert from P4's Error * handling system to a more java-like exception mechanism.</p> * * @throws the corresponding P4ClientException that matches the Error * but only if one needs to be thrown. * **/ void checkException() throws P4ClientException { // // Check to see if there was an error. // if (test()) { // // There was, so get the native one and, as best we // can, throw the corresponding exception. // P4ClientException exp = fmtToException(fmt()); if (exp != null) { throw exp; } } } //================================// // // PROTECTED // //================================// protected void finalize() { // // If this instance was create to pass to the native side, // then a native pointer was allocated and we need to clean // that up, otherwise, this was created as a face to an // Error that was created outside of Java and we do not want // to clean that up. // if (javaCreatedTheInstance) { nDeleteInstance(this.instance); } } //================================// // // PRIVATE // //================================// // to track if we created this or the native side did // private boolean javaCreatedTheInstance; // // tables we can use to map exceptions to their // native error types and vice-versa. // // "names" are an agreement between the native and // java side as a way to identify ErroIds. // Identifiers that begin with "ERRNAME_" are the Strings // that represent that agreement. // // "fmts" are the output of the fmt() method for // each error identified with a name. This is used // as the only way to map from a native error to a // java exception. // // "ptrs" are actual c ptrs that point to instances // of ErrorIds for each name. // private static String[] names = nGetErrorIdNames(); private static String[] fmts = nGetErrorIdFmts(); private static long[] ptrs = nGetErrorIdPtrs(); // // methods to create and dispose of native Error pointers. // private static native long nNewInstance(); private static native void nDeleteInstance(long instance); // // the names that are agreed upon by both the native // and java side to identify ErrorIds. // private static final String ERRNAME_CANTEDIT = "CantEdit"; private static final String ERRNAME_BADFLAG = "BadFlag"; private static final String ERRNAME_CANTFINDAPP = "CantFindApp"; private static final String ERRNAME_CLOBBERFILE = "ClobberFile"; private static final String ERRNAME_CONNECT = "Connect"; private static final String ERRNAME_MKDIR = "MkDir"; private static final String ERRNAME_NOMERGER = "NoMerger"; /** * Make a P4Error to use as a "face" to an actual, pre-existing * native Error instance. * * @param instance the pre-existing native instance. * **/ private P4Error(long instance) { this.instance = instance; javaCreatedTheInstance = false; } /** * Given a name of an ErrorId, get the pointer to it from * the "ptrs" table. * * @param name the name of the ErrorId. * @return the ptr to the native ErrorId instance or 0 if not found. * **/ private static long nameToPtr(String name) { int i = nameToIndex(name); return (i == -1) ? 0 : ptrs[i]; } /** * Given a name of an ErrorId, get the index of it * in the "names" table. * * @param name the name of the ErrorId. * @return the index in the "names" table or -1 if not found. * **/ private static int nameToIndex(String name) { int i = 0; for (i = 0; i < names.length; i++) { if (names[i].equals(name)) return i; } return -1; } /** * Given fmt from the <tt>fmt()</tt> method, get the index of it * in the "fmts" table. * * @param fmt the result of the <tt>fmt()</tt> method. * @return the index in the "fmts" table or -1 if not found. * **/ private static int fmtToIndex(String fmt) { int i = 0; for (i = 0; i < fmts.length; i++) { if (fmts[i].equals(fmt)) return i; } return -1; } /** * Given fmt from the <tt>fmt()</tt> method, guess as best * as we can as to what the Exception would be. * * @param fmt the result of the <tt>fmt()</tt> method. * @return the best guess as to what that exception was or null if not found. * **/ private static P4ClientException fmtToException(String fmt) { int i = fmtToIndex(fmt); if (i != -1) { return nameToException(names[i]); } return null; } /** * Given fmt from the <tt>fmt()</tt> method, guess as best * as we can as to what the Exception would be. * * @param fmt the result of the <tt>fmt()</tt> method. * @return the best guess as to what that exception was or null if not found. * **/ private static String exceptionToName(P4ClientException err) { if (err instanceof P4CantEditException) { return ERRNAME_CANTEDIT; } else if (err instanceof P4BadFlagException) { return ERRNAME_BADFLAG; } else if (err instanceof P4CantFindAppException) { return ERRNAME_CANTFINDAPP; } else if (err instanceof P4ClobberFileException) { return ERRNAME_CLOBBERFILE; } else if (err instanceof P4ConnectException) { return ERRNAME_CONNECT; } else if (err instanceof P4MkDirException) { return ERRNAME_MKDIR; } else if (err instanceof P4NoMergerException) { return ERRNAME_NOMERGER; } else { return null; } } private static P4ClientException nameToException(String name) { if (name.equals(ERRNAME_CANTEDIT)) { return new P4CantEditException(); } else if (name.equals(ERRNAME_BADFLAG)) { return new P4BadFlagException(); } else if (name.equals(ERRNAME_CANTFINDAPP)) { return new P4CantFindAppException(); } else if (name.equals(ERRNAME_CLOBBERFILE)) { return new P4ClobberFileException(); } else if (name.equals(ERRNAME_CONNECT)) { return new P4ConnectException(); } else if (name.equals(ERRNAME_MKDIR)) { return new P4MkDirException(); } else if (name.equals(ERRNAME_NOMERGER)) { return new P4NoMergerException(); } else { return null; } } //================================// // // NATIVE // //================================// private static native String[] nGetErrorIdNames(); private static native String[] nGetErrorIdFmts(); private static native long[] nGetErrorIdPtrs(); private static native void nSetErrorId(long errInstance, long errorrIDInstance); private static native void nSetMessage(long errInstance, String message); private static native boolean nTest(long instance); private static native String nFmt(long instance); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#9 | 4181 | Paul Krause |
Rename //guest/paul_krause/perforce/api/java/wcvm/com/... //guest/paul_krause/perforce/api/java/wcvm/javax/... To //guest/paul_krause/perforce/api/java/wcvm/src-15/... |
||
#8 | 4177 | Paul Krause | parameterize container types - requires tiger or pizza | ||
#7 | 4173 | Paul Krause | add serialVersionUID | ||
#6 | 4129 | Paul Krause | use msgclient.h in place of old errclient.h | ||
#5 | 4107 | Paul Krause | fix JNI sigs for ErrorId | ||
#4 | 4103 | Paul Krause | ditch clienterror.h | ||
#3 | 4100 | Paul Krause | fix type problems | ||
#2 | 4097 | Paul Krause | remove support for unimplemented abort() function | ||
#1 | 4073 | Paul Krause | branch com.perforce.api package from michael_bishop | ||
//guest/michael_bishop/P4APIForJava/java/com/perforce/client/api/P4Error.java | |||||
#1 | 430 | Michael Bishop |
Initial checkin. Seems to work. Not very much testing. Not very much documentation. Some more commenting needs to take place. But, it's there to experiment with. |