package com.perforce.client.api; class P4Error { //================================// // // PACKAGE // //================================// int 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 ); } /** * XX. * * **/ void abort() { nAbort( 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( int 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 // int 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 int[] ptrs = nGetErrorIdPtrs(); // // methods to create and dispose of native Error pointers. // private static native int nNewInstance(); private static native void nDeleteInstance( int 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( int 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 int 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 int[] nGetErrorIdPtrs(); private static native void nSetErrorId( int errInstance, int errorrIDInstance ); private static native void nSetMessage( int errInstance, String message ); private static native boolean nTest( int instance ); private static native String nFmt( int instance ); private static native void nAbort( int instance ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 783 | paul_hammant |
First cut of P4 Soap API. Uses Glue, can't work yet as DLLs missing. |
||
//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. |