signature:
public class BasicLTIUtil { /** * Check if the fields are properly signed
 * @ param postProp
 * @ param url
 * @ param method
 * @ param oauth _ consumer _ key
 * @ param oauth _ consumer _ secret
 * @ return */
public static boolean checkProperties ( Map < String , String > postProp , String url , String method , String oauth_consumer_key , String oauth_consumer_secret ) { } }

implementation: OAuthMessage oam = new OAuthMessage ( method , url , postProp . entrySet ( ) ) ; OAuthConsumer cons = new OAuthConsumer ( "about:blank" , oauth_consumer_key , oauth_consumer_secret , null ) ; OAuthValidator oav = new SimpleOAuthValidator ( ) ; OAuthAccessor acc = new OAuthAccessor ( cons ) ; String base_string = null ; try { base_string = OAuthSignatureMethod . getBaseString ( oam ) ; } catch ( Exception e ) { M_log . warning ( e . getLocalizedMessage ( ) ) ; base_string = null ; return false ; } try { oav . validateMessage ( oam , acc ) ; } catch ( Exception e ) { M_log . warning ( "Provider failed to validate message" ) ; M_log . warning ( e . getLocalizedMessage ( ) ) ; if ( base_string != null ) { M_log . warning ( base_string ) ; } return false ; } return true ;


signature:
public class BasicLTIUtil { /** * Create the HTML to render a POST form and then automatically submit it .
 * Make sure to call { @ link # cleanupProperties ( Properties ) } before signing .
 * @ deprecated Moved to { @ link # postLaunchHTML ( Map , String , boolean ) }
 * @ param cleanProperties Assumes you have called
 * { @ link # cleanupProperties ( Properties ) } beforehand .
 * @ param endpoint The LTI launch url .
 * @ param debug Useful for viewing the HTML before posting to end point .
 * @ return the HTML ready for IFRAME src = inclusion . */
public static String postLaunchHTML ( final Properties cleanProperties , String endpoint , boolean debug ) { } }

implementation: Map < String , String > map = convertToMap ( cleanProperties ) ; return postLaunchHTML ( map , endpoint , debug ) ;


signature:
public class BasicLTIUtil { /** * Create the HTML to render a POST form and then automatically submit it .
 * Make sure to call { @ link # cleanupProperties ( Properties ) } before signing .
 * @ param cleanProperties Assumes you have called
 * { @ link # cleanupProperties ( Properties ) } beforehand .
 * @ param endpoint The LTI launch url .
 * @ param debug Useful for viewing the HTML before posting to end point .
 * @ return the HTML ready for IFRAME src = inclusion . */
public static String postLaunchHTML ( final Map < String , String > cleanProperties , String endpoint , boolean debug ) { } }

implementation:
if ( cleanProperties == null || cleanProperties . isEmpty ( ) ) { throw new IllegalArgumentException ( "cleanProperties == null || cleanProperties.isEmpty()" ) ; } if ( endpoint == null ) { throw new IllegalArgumentException ( "endpoint == null" ) ; } Map < String , String > newMap = null ; if ( debug ) { // sort the properties for readability
newMap = new TreeMap < String , String > ( cleanProperties ) ; } else { newMap = cleanProperties ; } StringBuilder text = new StringBuilder ( ) ; // paint form
text . append ( "
\n" ) ; text . append ( "<form action=\"" ) ; text . append ( endpoint ) ; text . append ( "\" name=\"ltiLaunchForm\" id=\"ltiLaunchForm\" method=\"post\" " ) ; text . append ( " encType=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n" ) ; for ( Entry < String , String > entry : newMap . entrySet ( ) ) { String key = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( value == null ) { continue ; } // This will escape the contents pretty much - at least
// we will be safe and not generate dangerous HTML
key = htmlspecialchars ( key ) ; value = htmlspecialchars ( value ) ; if ( key . equals ( BASICLTI_SUBMIT ) ) { text . append ( "<input type=\"submit\" name=\"" ) ; } else { text . append ( "<input type=\"hidden\" name=\"" ) ; } text . append ( key ) ; text . append ( "\" value=\"" ) ; text . append ( value ) ; text . append ( "\"/>\n" ) ; } text . append ( "</form>\n" ) ; text . append ( "
\n" ) ; // Paint the auto - pop up if we are transitioning from https : to http :
// and are not already the top frame . . .
text . append ( "\n" ) ; // paint debug output
if ( debug ) { text . append ( "
\n" ) ; text . append ( "BasicLTI Endpoint\n" ) ; text . append ( endpoint ) ; text . append ( "\n\n" ) ; text . append ( "BasicLTI Parameters:\n" ) ; for ( Entry < String , String > entry : newMap . entrySet ( ) ) { String key = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( value == null ) { continue ; } text . append ( htmlspecialchars ( key ) ) ; text . append ( "=" ) ; text . append ( htmlspecialchars ( value ) ) ; text . append ( "\n" ) ; } text . append ( "
\n" ) ; } else { // paint auto submit script
text . append ( "  \n" ) ; } String htmltext = text . toString ( ) ; return htmltext ;


signature:
public class BasicLTIUtil { /** * Remove fields that should not be exported */
public static String prepareForExport ( String descriptor ) { } }

implementation: Map < String , Object > tm = null ; try { tm = XMLMap . getFullMap ( descriptor . trim ( ) ) ; } catch ( Exception e ) { M_log . warning ( "BasicLTIUtil exception parsing BasicLTI descriptor" + e . getMessage ( ) ) ; return null ; } if ( tm == null ) { M_log . warning ( "Unable to parse XML in prepareForExport" ) ; return null ; } XMLMap . removeSubMap ( tm , "/basic_lti_link/x-secure" ) ; String retval = XMLMap . getXML ( tm , true ) ; return retval ;


signature:
public class BasicLTIUtil { /** * The parameter name is mapped to lower case and any character that is
 * neither a number or letter is replaced with an " underscore " . So if a
 * custom entry was as follows :
 * { @ code < parameter name = " Vendor : Chapter " > 1.2.56 < / parameter > }
 * Would map to : custom _ vendor _ chapter = 1.2.56 */
public static String mapKeyName ( String keyname ) { } }

implementation: StringBuffer sb = new StringBuffer ( ) ; if ( keyname == null ) { return null ; } keyname = keyname . trim ( ) ; if ( keyname . length ( ) < 1 ) { return null ; } for ( int i = 0 ; i < keyname . length ( ) ; i ++ ) { Character ch = Character . toLowerCase ( keyname . charAt ( i ) ) ; if ( Character . isLetter ( ch ) || Character . isDigit ( ch ) ) { sb . append ( ch ) ; } else { sb . append ( '_' ) ; } } return sb . toString ( ) ;


signature:
public class BasicLTIUtil { /** * Mutates the passed { @ code Map < String , String > map } variable . Puts the key , value
 * into the Map if the value is not null and is not empty .
 * @ param map Variable is mutated by this method .
 * @ param key
 * @ param value */
public static void setProperty ( final Map < String , String > map , final String key , final String value ) { } }

implementation: if ( value != null && ! "" . equals ( value ) ) { map . put ( key , value ) ; }


signature:
public class BasicLTIUtil { /** * Mutates the passed Properties props variable . Puts the key , value into the
 * Map if the value is not null and is not empty .
 * @ deprecated See : { @ link # setProperty ( Map , String , String ) }
 * @ param props Variable is mutated by this method .
 * @ param key
 * @ param value */
public static void setProperty ( Properties props , String key , String value ) { } }

implementation: if ( value == null ) { return ; } if ( value . trim ( ) . length ( ) < 1 ) { return ; } props . setProperty ( key , value ) ;


signature:
public class BasicLTIUtil { /** * Basic utility to encode form text - handle the " safe cases " */
public static String htmlspecialchars ( String input ) { } }

implementation: if ( input == null ) { return null ; } String retval = input . replace ( "&" , "&" ) ; retval = retval . replace ( "\"" , """ ) ; retval = retval . replace ( "<" , "<" ) ; retval = retval . replace ( ">" , ">" ) ; retval = retval . replace ( ">" , ">" ) ; retval = retval . replace ( "=" , "=" ) ; return retval ;


signature:
public class BasicLTIUtil { /** * Simple utility method deal with a request that has the wrong URL when
 * behind a proxy .
 * @ param extUrl The url that the external world sees us as responding to .
 * This needs to be up to but not including the last slash like and not
 * include any path information http : / / www . sakaiproject . org - although we do
 * compensate for extra stuff at the end .
 * @ return The full path of the request with extUrl in place of whatever the
 * request thinks is the current URL . */
static public String getRealPath ( String servletUrl , String extUrl ) { } }

implementation:
Pattern pat = Pattern . compile ( "^https??://[^/]*" ) ; // Deal with potential bad extUrl formats
Matcher m = pat . matcher ( extUrl ) ; if ( m . find ( ) ) { extUrl = m . group ( 0 ) ; } String retval = pat . matcher ( servletUrl ) . replaceFirst ( extUrl ) ; return retval ;


signature:
public class BasicLTIUtil { /** * Simple utility method to help with the migration from { @ code Properties } to { @ code Map < String , String > } .
 * @ param properties
 * @ return */
@ SuppressWarnings ( { } }

implementation: "unchecked" , "rawtypes" } ) public static Map < String , String > convertToMap ( final Properties properties ) { final Map < String , String > map = new HashMap ( properties ) ; return map ;


signature:
public class BasicLTIUtil { /** * Simple utility method to help with the migration from { @ code Map < String , String > }
 * to { @ code Properties } .
 * @ deprecated Should migrate to { @ code Map < String , String > } signatures .
 * @ param map
 * @ return */
public static Properties convertToProperties ( final Map < String , String > map ) { } }

implementation: final Properties properties = new Properties ( ) ; if ( map != null ) { for ( Entry < String , String > entry : map . entrySet ( ) ) { properties . setProperty ( entry . getKey ( ) , entry . getValue ( ) ) ; } } return properties ;


signature:
public class LtiOauthVerifier { /** * This method verifies the signed HttpServletRequest
 * @ param request the HttpServletRequest that will be verified
 * @ param secret the secret to verify the properties with
 * @ return the result of the verification , along with contextual
 * information
 * @ throws LtiVerificationException */
@ Override public LtiVerificationResult verify ( HttpServletRequest request , String secret ) throws LtiVerificationException { } }

implementation: OAuthMessage oam = OAuthServlet . getMessage ( request , OAuthServlet . getRequestURL ( request ) ) ; String oauth_consumer_key = null ; try { oauth_consumer_key = oam . getConsumerKey ( ) ; } catch ( Exception e ) { return new LtiVerificationResult ( false , LtiError . BAD_REQUEST , "Unable to find consumer key in message" ) ; } OAuthValidator oav = new SimpleOAuthValidator ( ) ; OAuthConsumer cons = new OAuthConsumer ( null , oauth_consumer_key , secret , null ) ; OAuthAccessor acc = new OAuthAccessor ( cons ) ; try { oav . validateMessage ( oam , acc ) ; } catch ( Exception e ) { return new LtiVerificationResult ( false , LtiError . BAD_REQUEST , "Failed to validate: " + e . getLocalizedMessage ( ) ) ; } return new LtiVerificationResult ( true , new LtiLaunch ( request ) ) ;


signature:
public class LtiOauthVerifier { /** * This method will verify a collection of parameters
 * @ param parameters the parameters that will be verified . mapped by key & amp ; value
 * @ param url the url this request was made at
 * @ param method the method this url was requested with
 * @ param secret the secret to verify the propertihes with
 * @ return
 * @ throws LtiVerificationException */
@ Override public LtiVerificationResult verifyParameters ( Map < String , String > parameters , String url , String method , String secret ) throws LtiVerificationException { } }

implementation: OAuthMessage oam = new OAuthMessage ( method , url , parameters . entrySet ( ) ) ; OAuthConsumer cons = new OAuthConsumer ( null , parameters . get ( OAUTH_KEY_PARAMETER ) , secret , null ) ; OAuthValidator oav = new SimpleOAuthValidator ( ) ; OAuthAccessor acc = new OAuthAccessor ( cons ) ; try { oav . validateMessage ( oam , acc ) ; } catch ( Exception e ) { return new LtiVerificationResult ( false , LtiError . BAD_REQUEST , "Failed to validate: " + e . getLocalizedMessage ( ) + ", Parameters: " + Arrays . toString ( parameters . entrySet ( ) . toArray ( ) ) ) ; } return new LtiVerificationResult ( true , new LtiLaunch ( parameters ) ) ;


signature:
public class StandardServices { /** * " endpoint " : " http : / / lms . example . com / resources / Result / { sourcedId } " , */
public static ServiceOffered LTI2ResultItem ( String endpoint ) { } }

implementation:
ServiceOffered ret = new ServiceOffered ( ) ; ret . setEndpoint ( endpoint ) ; ret . set_id ( "tcp:Result.item" ) ; // TODO : Is this right see 5.6 in the docs
ret . set_type ( "RestService" ) ; ret . setFormat ( Arrays . asList ( RESULT_FORMAT ) ) ; ret . setAction ( Arrays . asList ( "GET" , "PUT" ) ) ; return ret ;


signature:
public class StandardServices { /** * " endpoint " : " http : / / lms . example . com / resources / ToolProxy / { tool _ proxy _ guid } / custom " , */
public static ServiceOffered LTI2ToolProxySettings ( String endpoint ) { } }

implementation: ServiceOffered ret = new ServiceOffered ( ) ; ret . setEndpoint ( endpoint ) ; ret . set_id ( "tcp:ToolProxySettings" ) ; ret . set_type ( "RestService" ) ; ret . setFormat ( Arrays . asList ( TOOLSETTINGS_FORMAT , TOOLSETTINGS_SIMPLE_FORMAT ) ) ; ret . setAction ( Arrays . asList ( "GET" , "PUT" ) ) ; return ret ;


signature:
public class IMSPOXRequest { /** * Load but do not check the authentication */
public void loadFromRequest ( HttpServletRequest request ) { } }

implementation: String contentType = request . getContentType ( ) ; if ( ! "application/xml" . equals ( contentType ) ) { errorMessage = "Content Type must be application/xml" ; Log . info ( errorMessage + "\n" + contentType ) ; return ; } setAuthHeader ( request . getHeader ( "Authorization" ) ) ; if ( oauth_body_hash == null ) { errorMessage = "Did not find oauth_body_hash" ; Log . info ( errorMessage + "\n" + header ) ; return ; } try { Reader in = request . getReader ( ) ; postBody = readPostBody ( in ) ; } catch ( Exception e ) { errorMessage = "Could not read message body:" + e . getMessage ( ) ; return ; } validatePostBody ( ) ; if ( errorMessage != null ) return ; parsePostBody ( ) ;


signature:
public class IMSPOXRequest { /** * Assumes data is all loaded */
public void validateRequest ( String oauth_consumer_key , String oauth_secret , HttpServletRequest request ) { } }

implementation: validateRequest ( oauth_consumer_key , oauth_secret , request , null ) ;


signature:
public class LTI2Servlet { /** * the profile and do a launch . */
@ SuppressWarnings ( "unused" ) protected void doLaunch ( HttpServletRequest request , HttpServletResponse response ) { } }

implementation:
String profile = PERSIST . get ( "profile" ) ; response . setContentType ( "text/html" ) ; String output = null ; if ( profile == null ) { output = "Missing profile" ; } else { JSONObject providerProfile = ( JSONObject ) JSONValue . parse ( profile ) ; List < Properties > profileTools = new ArrayList < Properties > ( ) ; Properties info = new Properties ( ) ; String retval = LTI2Util . parseToolProfile ( profileTools , info , providerProfile ) ; String launch = null ; String parameter = null ; for ( Properties profileTool : profileTools ) { launch = ( String ) profileTool . get ( "launch" ) ; parameter = ( String ) profileTool . get ( "parameter" ) ; } JSONObject security_contract = ( JSONObject ) providerProfile . get ( LTI2Constants . SECURITY_CONTRACT ) ; String shared_secret = ( String ) security_contract . get ( LTI2Constants . SHARED_SECRET ) ; System . out . println ( "launch=" + launch ) ; System . out . println ( "shared_secret=" + shared_secret ) ; Properties ltiProps = LTI2SampleData . getLaunch ( ) ; ltiProps . setProperty ( BasicLTIConstants . LTI_VERSION , BasicLTIConstants . LTI_VERSION_2 ) ; Properties lti2subst = LTI2SampleData . getSubstitution ( ) ; String settings_url = getServiceURL ( request ) + SVC_Settings + "/" ; lti2subst . setProperty ( "LtiLink.custom.url" , settings_url + LTI2Util . SCOPE_LtiLink + "/" + ltiProps . getProperty ( BasicLTIConstants . RESOURCE_LINK_ID ) ) ; lti2subst . setProperty ( "ToolProxyBinding.custom.url" , settings_url + LTI2Util . SCOPE_ToolProxyBinding + "/" + ltiProps . getProperty ( BasicLTIConstants . CONTEXT_ID ) ) ; lti2subst . setProperty ( "ToolProxy.custom.url" , settings_url + LTI2Util . SCOPE_ToolProxy + "/" + TEST_KEY ) ; lti2subst . setProperty ( "Result.url" , getServiceURL ( request ) + SVC_Result + "/" + ltiProps . getProperty ( BasicLTIConstants . RESOURCE_LINK_ID ) ) ; // Do the substitutions
Properties custom = new Properties ( ) ; LTI2Util . mergeLTI2Parameters ( custom , parameter ) ; LTI2Util . substituteCustom ( custom , lti2subst ) ; // Place the custom values into the launch
LTI2Util . addCustomToLaunch ( ltiProps , custom ) ; ltiProps = BasicLTIUtil . signProperties ( ltiProps , launch , "POST" , TEST_KEY , shared_secret , null , null , null ) ; boolean dodebug = true ; output = BasicLTIUtil . postLaunchHTML ( ltiProps , launch , dodebug ) ; } try { PrintWriter out = response . getWriter ( ) ; out . println ( output ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; }


signature:
public class LTI2Servlet { /** * it is always null and we allow everything */
protected ToolConsumer buildToolConsumerProfile ( HttpServletRequest request , Map < String , Object > deploy , String profile_id ) { } }

implementation:
// Load the configuration data
LTI2Config cnf = new org . imsglobal . lti2 . LTI2ConfigSample ( ) ; ToolConsumer consumer = new ToolConsumer ( profile_id , "LTI-2p0" , getServiceURL ( request ) , cnf ) ; // Normally we would check permissions before we offer capabilities
List < String > capabilities = consumer . getCapability_offered ( ) ; LTI2Util . allowEmail ( capabilities ) ; LTI2Util . allowName ( capabilities ) ; LTI2Util . allowSettings ( capabilities ) ; LTI2Util . allowResult ( capabilities ) ; // Normally we would check permissions before we offer services
List < ServiceOffered > services = consumer . getService_offered ( ) ; services . add ( StandardServices . LTI2Registration ( getServiceURL ( request ) + SVC_tc_registration + "/" + profile_id ) ) ; services . add ( StandardServices . LTI2ResultItem ( getServiceURL ( request ) + SVC_Result + "/{" + BasicLTIConstants . LIS_RESULT_SOURCEDID + "}" ) ) ; services . add ( StandardServices . LTI2LtiLinkSettings ( getServiceURL ( request ) + SVC_Settings + "/" + LTI2Util . SCOPE_LtiLink + "/{" + BasicLTIConstants . RESOURCE_LINK_ID + "}" ) ) ; services . add ( StandardServices . LTI2ToolProxySettings ( getServiceURL ( request ) + SVC_Settings + "/" + LTI2Util . SCOPE_ToolProxyBinding + "/{" + BasicLTIConstants . CONTEXT_ID + "}" ) ) ; services . add ( StandardServices . LTI2ToolProxySettings ( getServiceURL ( request ) + SVC_Settings + "/" + LTI2Util . SCOPE_ToolProxy + "/{" + LTI2Constants . TOOL_PROXY_GUID + "}" ) ) ; return consumer ;


signature:
public class LTI2Servlet { /** * So we write obtuse code . */
@ SuppressWarnings ( "unused" ) public void handleSettingsRequest ( HttpServletRequest request , HttpServletResponse response , String [ ] parts ) throws java . io . IOException { } }

implementation:
String URL = request . getRequestURL ( ) . toString ( ) ; System . out . println ( "URL=" + URL ) ; String scope = parts [ 4 ] ; System . out . println ( "scope=" + scope ) ; String acceptHdr = request . getHeader ( "Accept" ) ; String contentHdr = request . getContentType ( ) ; boolean acceptComplex = acceptHdr == null || acceptHdr . indexOf ( StandardServices . TOOLSETTINGS_FORMAT ) >= 0 ; System . out . println ( "accept=" + acceptHdr + " ac=" + acceptComplex ) ; // Check the JSON on PUT and check the oauth _ body _ hash
IMSJSONRequest jsonRequest = null ; JSONObject requestData = null ; if ( "PUT" . equals ( request . getMethod ( ) ) ) { try { jsonRequest = new IMSJSONRequest ( request ) ; requestData = ( JSONObject ) JSONValue . parse ( jsonRequest . getPostBody ( ) ) ; } catch ( Exception e ) { response . setStatus ( HttpServletResponse . SC_BAD_REQUEST ) ; doErrorJSON ( request , response , jsonRequest , "Could not parse JSON" , e ) ; return ; } } String consumer_key = TEST_KEY ; String profile = PERSIST . get ( "profile" ) ; JSONObject providerProfile = ( JSONObject ) JSONValue . parse ( profile ) ; JSONObject security_contract = ( JSONObject ) providerProfile . get ( LTI2Constants . SECURITY_CONTRACT ) ; String oauth_secret = ( String ) security_contract . get ( LTI2Constants . SHARED_SECRET ) ; // Validate the incoming message
LtiVerificationResult result = BasicLTIUtil . validateMessage ( request , URL , oauth_secret ) ; if ( ! result . getSuccess ( ) ) { response . setStatus ( HttpStatus . SC_FORBIDDEN ) ; doErrorJSON ( request , response , jsonRequest , result . getMessage ( ) , null ) ; return ; } // The URLs for the various settings resources
String settingsUrl = getServiceURL ( request ) + SVC_Settings ; String proxy_url = settingsUrl + "/" + LTI2Util . SCOPE_ToolProxy + "/" + consumer_key ; String binding_url = settingsUrl + "/" + LTI2Util . SCOPE_ToolProxyBinding + "/" + "TBD" ; String link_url = settingsUrl + "/" + LTI2Util . SCOPE_LtiLink + "/" + "TBD" ; // Load and parse the old settings . . .
JSONObject link_settings = LTI2Util . parseSettings ( PERSIST . get ( LTI2Util . SCOPE_LtiLink ) ) ; JSONObject binding_settings = LTI2Util . parseSettings ( PERSIST . get ( LTI2Util . SCOPE_ToolProxyBinding ) ) ; JSONObject proxy_settings = LTI2Util . parseSettings ( PERSIST . get ( LTI2Util . SCOPE_ToolProxy ) ) ; // For a GET request we depend on LTI2Util to do the GET logic
if ( "GET" . equals ( request . getMethod ( ) ) ) { Object obj = LTI2Util . getSettings ( request , scope , link_settings , binding_settings , proxy_settings , link_url , binding_url , proxy_url ) ; if ( obj instanceof String ) { response . setStatus ( HttpServletResponse . SC_BAD_REQUEST ) ; doErrorJSON ( request , response , jsonRequest , ( String ) obj , null ) ; return ; } if ( acceptComplex ) { response . setContentType ( StandardServices . TOOLSETTINGS_FORMAT ) ; } else { response . setContentType ( StandardServices . TOOLSETTINGS_SIMPLE_FORMAT ) ; } JSONObject jsonResponse = ( JSONObject ) obj ; response . setStatus ( HttpServletResponse . SC_OK ) ; PrintWriter out = response . getWriter ( ) ; System . out . println ( "jsonResponse=" + jsonResponse ) ; out . println ( jsonResponse . toString ( ) ) ; return ; } else if ( "PUT" . equals ( request . getMethod ( ) ) ) { // This is assuming the rule that a PUT of the complex settings
// format that there is only one entry in the graph and it is
// the same as our current URL . We parse without much checking .
String settings = null ; try { JSONArray graph = ( JSONArray ) requestData . get ( LTI2Constants . GRAPH ) ; if ( graph . size ( ) != 1 ) { response . setStatus ( HttpServletResponse . SC_BAD_REQUEST ) ; doErrorJSON ( request , response , jsonRequest , "Only one graph entry allowed" , null ) ; return ; } JSONObject firstChild = ( JSONObject ) graph . get ( 0 ) ; JSONObject custom = ( JSONObject ) firstChild . get ( LTI2Constants . CUSTOM ) ; settings = custom . toString ( ) ; } catch ( Exception e ) { settings = jsonRequest . getPostBody ( ) ; } PERSIST . put ( scope , settings ) ; System . out . println ( "Stored settings scope=" + scope ) ; System . out . println ( "settings=" + settings ) ; response . setStatus ( HttpServletResponse . SC_OK ) ; } else { response . setStatus ( HttpServletResponse . SC_BAD_REQUEST ) ; doErrorJSON ( request , response , jsonRequest , "Method not handled=" + request . getMethod ( ) , null ) ; }


signature:
public class LTI2Servlet { /** * / * IMS JSON version of Errors */
public void doErrorJSON ( HttpServletRequest request , HttpServletResponse response , IMSJSONRequest json , String message , Exception e ) throws java . io . IOException { } }

implementation: if ( e != null ) { M_log . log ( Level . WARNING , e . getLocalizedMessage ( ) , e ) ; } M_log . info ( message ) ; String output = IMSJSONRequest . doErrorJSON ( request , response , json , message , e ) ; System . out . println ( output ) ;


signature:
public class IMSJSONRequest { /** * Load but do not check the authentication */
@ SuppressWarnings ( "deprecation" ) public void loadFromRequest ( HttpServletRequest request ) { } }

implementation:
header = request . getHeader ( "Authorization" ) ; System . out . println ( "Header: " + header ) ; oauth_body_hash = null ; if ( header != null ) { if ( header . startsWith ( "OAuth " ) ) header = header . substring ( 5 ) ; String [ ] parms = header . split ( "," ) ; for ( String parm : parms ) { parm = parm . trim ( ) ; if ( parm . startsWith ( "oauth_body_hash=" ) ) { String [ ] pieces = parm . split ( "\"" ) ; if ( pieces . length == 2 ) oauth_body_hash = URLDecoder . decode ( pieces [ 1 ] ) ; } if ( parm . startsWith ( "oauth_consumer_key=" ) ) { String [ ] pieces = parm . split ( "\"" ) ; if ( pieces . length == 2 ) oauth_consumer_key = URLDecoder . decode ( pieces [ 1 ] ) ; } } } if ( oauth_body_hash == null ) { errorMessage = "Did not find oauth_body_hash" ; Log . info ( errorMessage + "\n" + header ) ; return ; } System . out . println ( "OBH=" + oauth_body_hash ) ; byte [ ] buf = new byte [ 1024 ] ; ByteArrayOutputStream bos = new ByteArrayOutputStream ( ) ; int chars = 0 ; try { ServletInputStream is = request . getInputStream ( ) ; int readNum ; do { readNum = is . read ( buf ) ; if ( readNum > 0 ) { bos . write ( buf , 0 , readNum ) ; chars = chars + readNum ; // We dont ' want a DOS
if ( chars > 10000000 ) { errorMessage = "Message body size exceeded" ; return ; } } } while ( readNum >= 0 ) ; } catch ( Exception e ) { errorMessage = "Could not read message body:" + e . getMessage ( ) ; return ; } byte [ ] bytes = bos . toByteArray ( ) ; try { postBody = new String ( bytes , "UTF-8" ) ; MessageDigest md = MessageDigest . getInstance ( "SHA1" ) ; md . update ( bytes ) ; byte [ ] output = Base64 . encodeBase64 ( md . digest ( ) ) ; String hash = new String ( output ) ; System . out . println ( "HASH=" + hash + " bytes=" + bytes . length ) ; if ( ! hash . equals ( oauth_body_hash ) ) { errorMessage = "Body hash does not match. bytes=" + bytes . length ; System . out . println ( postBody ) ; return ; } } catch ( Exception e ) { errorMessage = "Could not compute body hash.  bytes=" + bytes . length ; return ; } valid = true ; // So far we are valid


signature:
public class IMSJSONRequest { /** * / * IMS JSON version of Errors - does the complet request - returns the JSON in case
 * the code above us wants to log it . */
@ SuppressWarnings ( "static-access" ) public static String doErrorJSON ( HttpServletRequest request , HttpServletResponse response , IMSJSONRequest json , String message , Exception e ) throws java . io . IOException { } }

implementation: response . setContentType ( APPLICATION_JSON ) ; Map < String , Object > jsonResponse = new TreeMap < String , Object > ( ) ; Map < String , String > status = null ; if ( json == null ) { status = IMSJSONRequest . getStatusFailure ( message ) ; } else { status = json . getStatusFailure ( message ) ; if ( json . base_string != null ) { jsonResponse . put ( "base_string" , json . base_string ) ; } } jsonResponse . put ( IMSJSONRequest . STATUS , status ) ; if ( e != null ) { jsonResponse . put ( "exception" , e . getLocalizedMessage ( ) ) ; try { StringWriter sw = new StringWriter ( ) ; PrintWriter pw = new PrintWriter ( sw , true ) ; e . printStackTrace ( pw ) ; pw . flush ( ) ; sw . flush ( ) ; jsonResponse . put ( "traceback" , sw . toString ( ) ) ; } catch ( Exception f ) { jsonResponse . put ( "traceback" , f . getLocalizedMessage ( ) ) ; } } String jsonText = JSONValue . toJSONString ( jsonResponse ) ; PrintWriter out = response . getWriter ( ) ; out . println ( jsonText ) ; return jsonText ;


signature:
public class LTI2Util { /** * Validate the incoming tool _ services against a tool consumer */
public static String validateServices ( ToolConsumer consumer , JSONObject providerProfile ) { } }

implementation:
// Mostly to catch casting errors from bad JSON
try { JSONObject security_contract = ( JSONObject ) providerProfile . get ( LTI2Constants . SECURITY_CONTRACT ) ; if ( security_contract == null ) { return "JSON missing security_contract" ; } JSONArray tool_services = ( JSONArray ) security_contract . get ( LTI2Constants . TOOL_SERVICE ) ; List < ServiceOffered > services_offered = consumer . getService_offered ( ) ; if ( tool_services != null ) for ( Object o : tool_services ) { JSONObject tool_service = ( JSONObject ) o ; String json_service = ( String ) tool_service . get ( LTI2Constants . SERVICE ) ; boolean found = false ; for ( ServiceOffered service : services_offered ) { String service_endpoint = service . getEndpoint ( ) ; if ( service_endpoint . equals ( json_service ) ) { found = true ; break ; } } if ( ! found ) return "Service not allowed: " + json_service ; } return null ; } catch ( Exception e ) { return "Exception:" + e . getLocalizedMessage ( ) ; }


signature:
public class LTI2Util { /** * Validate incoming capabilities requested against out ToolConsumer */
public static String validateCapabilities ( ToolConsumer consumer , JSONObject providerProfile ) { } }

implementation:
List < Properties > theTools = new ArrayList < Properties > ( ) ; Properties info = new Properties ( ) ; // Mostly to catch casting errors from bad JSON
try { String retval = parseToolProfile ( theTools , info , providerProfile ) ; if ( retval != null ) return retval ; if ( theTools . size ( ) < 1 ) return "No tools found in profile" ; // Check all the capabilities requested by all the tools comparing against consumer
List < String > capabilities = consumer . getCapability_offered ( ) ; for ( Properties theTool : theTools ) { String ec = ( String ) theTool . get ( "enabled_capability" ) ; JSONArray enabled_capability = ( JSONArray ) JSONValue . parse ( ec ) ; if ( enabled_capability != null ) for ( Object o : enabled_capability ) { ec = ( String ) o ; if ( capabilities . contains ( ec ) ) continue ; return "Capability not permitted=" + ec ; } } return null ; } catch ( Exception e ) { return "Exception:" + e . getLocalizedMessage ( ) ; }


signature:
public class LTI2Util { /** * So we write obtuse code . */
@ SuppressWarnings ( { } }

implementation:
"unchecked" , "unused" } ) public static Object getSettings ( HttpServletRequest request , String scope , JSONObject link_settings , JSONObject binding_settings , JSONObject proxy_settings , String link_url , String binding_url , String proxy_url ) { // Check to see if we are doing the bubble
String bubbleStr = request . getParameter ( "bubble" ) ; String acceptHdr = request . getHeader ( "Accept" ) ; String contentHdr = request . getContentType ( ) ; if ( bubbleStr != null && bubbleStr . equals ( "all" ) && acceptHdr . indexOf ( StandardServices . TOOLSETTINGS_FORMAT ) < 0 ) { return "Simple format does not allow bubble=all" ; } if ( SCOPE_LtiLink . equals ( scope ) || SCOPE_ToolProxyBinding . equals ( scope ) || SCOPE_ToolProxy . equals ( scope ) ) { // All good
} else { return "Bad Setttings Scope=" + scope ; } boolean bubble = bubbleStr != null && "GET" . equals ( request . getMethod ( ) ) ; boolean distinct = bubbleStr != null && "distinct" . equals ( bubbleStr ) ; boolean bubbleAll = bubbleStr != null && "all" . equals ( bubbleStr ) ; // Check our output format
boolean acceptComplex = acceptHdr == null || acceptHdr . indexOf ( StandardServices . TOOLSETTINGS_FORMAT ) >= 0 ; if ( distinct && link_settings != null && scope . equals ( SCOPE_LtiLink ) ) { Iterator < String > i = link_settings . keySet ( ) . iterator ( ) ; while ( i . hasNext ( ) ) { String key = ( String ) i . next ( ) ; if ( binding_settings != null ) binding_settings . remove ( key ) ; if ( proxy_settings != null ) proxy_settings . remove ( key ) ; } } if ( distinct && binding_settings != null && scope . equals ( SCOPE_ToolProxyBinding ) ) { Iterator < String > i = binding_settings . keySet ( ) . iterator ( ) ; while ( i . hasNext ( ) ) { String key = ( String ) i . next ( ) ; if ( proxy_settings != null ) proxy_settings . remove ( key ) ; } } // Lets get this party started . . .
JSONObject jsonResponse = null ; if ( ( distinct || bubbleAll ) && acceptComplex ) { jsonResponse = new JSONObject ( ) ; jsonResponse . put ( LTI2Constants . CONTEXT , StandardServices . TOOLSETTINGS_CONTEXT ) ; JSONArray graph = new JSONArray ( ) ; boolean started = false ; if ( link_settings != null && SCOPE_LtiLink . equals ( scope ) ) { JSONObject cjson = new JSONObject ( ) ; cjson . put ( LTI2Constants . JSONLD_ID , link_url ) ; cjson . put ( LTI2Constants . TYPE , SCOPE_LtiLink ) ; cjson . put ( LTI2Constants . CUSTOM , link_settings ) ; graph . add ( cjson ) ; started = true ; } if ( binding_settings != null && ( started || SCOPE_ToolProxyBinding . equals ( scope ) ) ) { JSONObject cjson = new JSONObject ( ) ; cjson . put ( LTI2Constants . JSONLD_ID , binding_url ) ; cjson . put ( LTI2Constants . TYPE , SCOPE_ToolProxyBinding ) ; cjson . put ( LTI2Constants . CUSTOM , binding_settings ) ; graph . add ( cjson ) ; started = true ; } if ( proxy_settings != null && ( started || SCOPE_ToolProxy . equals ( scope ) ) ) { JSONObject cjson = new JSONObject ( ) ; cjson . put ( LTI2Constants . JSONLD_ID , proxy_url ) ; cjson . put ( LTI2Constants . TYPE , SCOPE_ToolProxy ) ; cjson . put ( LTI2Constants . CUSTOM , proxy_settings ) ; graph . add ( cjson ) ; } jsonResponse . put ( LTI2Constants . GRAPH , graph ) ; } else if ( distinct ) { // Simple format output
jsonResponse = proxy_settings ; if ( SCOPE_LtiLink . equals ( scope ) ) { jsonResponse . putAll ( binding_settings ) ; jsonResponse . putAll ( link_settings ) ; } else if ( SCOPE_ToolProxyBinding . equals ( scope ) ) { jsonResponse . putAll ( binding_settings ) ; } } else { // bubble not specified
jsonResponse = new JSONObject ( ) ; jsonResponse . put ( LTI2Constants . CONTEXT , StandardServices . TOOLSETTINGS_CONTEXT ) ; JSONObject theSettings = null ; String endpoint = null ; if ( SCOPE_LtiLink . equals ( scope ) ) { endpoint = link_url ; theSettings = link_settings ; } else if ( SCOPE_ToolProxyBinding . equals ( scope ) ) { endpoint = binding_url ; theSettings = binding_settings ; } if ( SCOPE_ToolProxy . equals ( scope ) ) { endpoint = proxy_url ; theSettings = proxy_settings ; } if ( acceptComplex ) { JSONArray graph = new JSONArray ( ) ; JSONObject cjson = new JSONObject ( ) ; cjson . put ( LTI2Constants . JSONLD_ID , endpoint ) ; cjson . put ( LTI2Constants . TYPE , scope ) ; cjson . put ( LTI2Constants . CUSTOM , theSettings ) ; graph . add ( cjson ) ; jsonResponse . put ( LTI2Constants . GRAPH , graph ) ; } else { jsonResponse = theSettings ; } } return jsonResponse ;


signature:
public class LTI2Util { /** * Parse a provider profile with lots of error checking . . . */
public static String parseToolProfile ( List < Properties > theTools , Properties info , JSONObject jsonObject ) { } }

implementation: try { return parseToolProfileInternal ( theTools , info , jsonObject ) ; } catch ( Exception e ) { M_log . warning ( "Internal error parsing tool proxy\n" + jsonObject . toString ( ) ) ; e . printStackTrace ( ) ; return "Internal error parsing tool proxy:" + e . getLocalizedMessage ( ) ; }


signature:
public class LTI2Util { /** * Parse a provider profile with lots of error checking . . . */
@ SuppressWarnings ( "unused" ) private static String parseToolProfileInternal ( List < Properties > theTools , Properties info , JSONObject jsonObject ) { } }

implementation:
Object o = null ; JSONObject tool_profile = ( JSONObject ) jsonObject . get ( "tool_profile" ) ; if ( tool_profile == null ) { return "JSON missing tool_profile" ; } JSONObject product_instance = ( JSONObject ) tool_profile . get ( "product_instance" ) ; if ( product_instance == null ) { return "JSON missing product_instance" ; } String instance_guid = ( String ) product_instance . get ( "guid" ) ; if ( instance_guid == null ) { return "JSON missing product_info / guid" ; } info . put ( "instance_guid" , instance_guid ) ; JSONObject product_info = ( JSONObject ) product_instance . get ( "product_info" ) ; if ( product_info == null ) { return "JSON missing product_info" ; } // Look for required fields
JSONObject product_name = product_info == null ? null : ( JSONObject ) product_info . get ( "product_name" ) ; String productTitle = product_name == null ? null : ( String ) product_name . get ( "default_value" ) ; JSONObject description = product_info == null ? null : ( JSONObject ) product_info . get ( "description" ) ; String productDescription = description == null ? null : ( String ) description . get ( "default_value" ) ; JSONObject product_family = product_info == null ? null : ( JSONObject ) product_info . get ( "product_family" ) ; String productCode = product_family == null ? null : ( String ) product_family . get ( "code" ) ; JSONObject product_vendor = product_family == null ? null : ( JSONObject ) product_family . get ( "vendor" ) ; description = product_vendor == null ? null : ( JSONObject ) product_vendor . get ( "description" ) ; String vendorDescription = description == null ? null : ( String ) description . get ( "default_value" ) ; String vendorCode = product_vendor == null ? null : ( String ) product_vendor . get ( "code" ) ; if ( productTitle == null || productDescription == null ) { return "JSON missing product_name or description " ; } if ( productCode == null || vendorCode == null || vendorDescription == null ) { return "JSON missing product code, vendor code or description" ; } info . put ( "product_name" , productTitle ) ; info . put ( "description" , productDescription ) ; // Backwards compatibility
info . put ( "product_description" , productDescription ) ; info . put ( "product_code" , productCode ) ; info . put ( "vendor_code" , vendorCode ) ; info . put ( "vendor_description" , vendorDescription ) ; o = tool_profile . get ( "base_url_choice" ) ; if ( ! ( o instanceof JSONArray ) || o == null ) { return "JSON missing base_url_choices" ; } JSONArray base_url_choices = ( JSONArray ) o ; String secure_base_url = null ; String default_base_url = null ; for ( Object i : base_url_choices ) { JSONObject url_choice = ( JSONObject ) i ; secure_base_url = ( String ) url_choice . get ( "secure_base_url" ) ; default_base_url = ( String ) url_choice . get ( "default_base_url" ) ; } String launch_url = secure_base_url ; if ( launch_url == null ) launch_url = default_base_url ; if ( launch_url == null ) { return "Unable to determine launch URL" ; } o = ( JSONArray ) tool_profile . get ( "resource_handler" ) ; if ( ! ( o instanceof JSONArray ) || o == null ) { return "JSON missing resource_handlers" ; } JSONArray resource_handlers = ( JSONArray ) o ; // Loop through resource handlers , read , and check for errors
for ( Object i : resource_handlers ) { JSONObject resource_handler = ( JSONObject ) i ; JSONObject resource_type_json = ( JSONObject ) resource_handler . get ( "resource_type" ) ; String resource_type_code = ( String ) resource_type_json . get ( "code" ) ; if ( resource_type_code == null ) { return "JSON missing resource_type code" ; } o = ( JSONArray ) resource_handler . get ( "message" ) ; if ( ! ( o instanceof JSONArray ) || o == null ) { return "JSON missing resource_handler / message" ; } JSONArray messages = ( JSONArray ) o ; JSONObject titleObject = ( JSONObject ) resource_handler . get ( "name" ) ; String title = titleObject == null ? null : ( String ) titleObject . get ( "default_value" ) ; if ( title == null || titleObject == null ) { return "JSON missing resource_handler / name / default_value" ; } JSONObject buttonObject = ( JSONObject ) resource_handler . get ( "short_name" ) ; String button = buttonObject == null ? null : ( String ) buttonObject . get ( "default_value" ) ; JSONObject descObject = ( JSONObject ) resource_handler . get ( "description" ) ; String resourceDescription = descObject == null ? null : ( String ) descObject . get ( "default_value" ) ; String path = null ; JSONArray parameter = null ; JSONArray enabled_capability = null ; for ( Object m : messages ) { JSONObject message = ( JSONObject ) m ; String message_type = ( String ) message . get ( "message_type" ) ; if ( ! "basic-lti-launch-request" . equals ( message_type ) ) continue ; if ( path != null ) { return "A resource_handler cannot have more than one basic-lti-launch-request message RT=" + resource_type_code ; } path = ( String ) message . get ( "path" ) ; if ( path == null ) { return "A basic-lti-launch-request message must have a path RT=" + resource_type_code ; } o = ( JSONArray ) message . get ( "parameter" ) ; if ( ! ( o instanceof JSONArray ) ) { return "Must be an array: parameter RT=" + resource_type_code ; } parameter = ( JSONArray ) o ; o = ( JSONArray ) message . get ( "enabled_capability" ) ; if ( ! ( o instanceof JSONArray ) ) { return "Must be an array: enabled_capability RT=" + resource_type_code ; } enabled_capability = ( JSONArray ) o ; } // Ignore everything except launch handlers
if ( path == null ) continue ; // Check the URI
String thisLaunch = launch_url ; if ( ! thisLaunch . endsWith ( "/" ) && ! path . startsWith ( "/" ) ) thisLaunch = thisLaunch + "/" ; thisLaunch = thisLaunch + path ; try { URL url = new URL ( thisLaunch ) ; } catch ( Exception e ) { return "Bad launch URL=" + thisLaunch ; } // Passed all the tests . . . Lets keep it . . .
Properties theTool = new Properties ( ) ; theTool . put ( "resource_type" , resource_type_code ) ; // Backwards compatibility
theTool . put ( "resource_type_code" , resource_type_code ) ; if ( title == null ) title = productTitle ; if ( title != null ) theTool . put ( "title" , title ) ; if ( button != null ) theTool . put ( "button" , button ) ; if ( resourceDescription == null ) resourceDescription = productDescription ; if ( resourceDescription != null ) theTool . put ( "description" , resourceDescription ) ; if ( parameter != null ) theTool . put ( "parameter" , parameter . toString ( ) ) ; if ( enabled_capability != null ) theTool . put ( "enabled_capability" , enabled_capability . toString ( ) ) ; theTool . put ( "launch" , thisLaunch ) ; theTools . add ( theTool ) ; } return null ; // All good


signature:
public class LTI2Util { /** * / * Two possible formats :
 * key = val ; key2 = val2;
 * key = val
 * key2 = val2 */
public static boolean mergeLTI1Custom ( Properties custom , String customstr ) { } }

implementation: if ( customstr == null || customstr . length ( ) < 1 ) return true ; String [ ] params = customstr . split ( "[\n;]" ) ; for ( int i = 0 ; i < params . length ; i ++ ) { String param = params [ i ] ; if ( param == null ) continue ; if ( param . length ( ) < 1 ) continue ; int pos = param . indexOf ( "=" ) ; if ( pos < 1 ) continue ; if ( pos + 1 > param . length ( ) ) continue ; String key = mapKeyName ( param . substring ( 0 , pos ) ) ; if ( key == null ) continue ; if ( custom . containsKey ( key ) ) continue ; String value = param . substring ( pos + 1 ) ; if ( value == null ) continue ; value = value . trim ( ) ; if ( value . length ( ) < 1 ) continue ; setProperty ( custom , key , value ) ; } return true ;


signature:
public class LTI2Util { /** * " custom " :
 * " isbn " : " 978-0321558145 " ,
 * " style " : " jazzy " */
public static boolean mergeLTI2Custom ( Properties custom , String customstr ) { } }

implementation:
if ( customstr == null || customstr . length ( ) < 1 ) return true ; JSONObject json = null ; try { json = ( JSONObject ) JSONValue . parse ( customstr . trim ( ) ) ; } catch ( Exception e ) { M_log . warning ( "mergeLTI2Custom could not parse\n" + customstr ) ; M_log . warning ( e . getLocalizedMessage ( ) ) ; return false ; } // This could happen if the old settings service was used
// on an LTI 2 . x placement to put in settings that are not
// JSON - we just ignore it .
if ( json == null ) return false ; Iterator < ? > keys = json . keySet ( ) . iterator ( ) ; while ( keys . hasNext ( ) ) { String key = ( String ) keys . next ( ) ; if ( custom . containsKey ( key ) ) continue ; Object value = json . get ( key ) ; if ( value instanceof String ) { setProperty ( custom , key , ( String ) value ) ; } } return true ;


signature:
public class LTI2Util { /** * " parameter " :
 * { " name " : " result _ url " ,
 * " variable " : " Result . url "
 * { " name " : " discipline " ,
 * " fixed " : " chemistry " */
public static boolean mergeLTI2Parameters ( Properties custom , String customstr ) { } }

implementation: if ( customstr == null || customstr . length ( ) < 1 ) return true ; JSONArray json = null ; try { json = ( JSONArray ) JSONValue . parse ( customstr . trim ( ) ) ; } catch ( Exception e ) { M_log . warning ( "mergeLTI2Parameters could not parse\n" + customstr ) ; M_log . warning ( e . getLocalizedMessage ( ) ) ; return false ; } Iterator < ? > parameters = json . iterator ( ) ; while ( parameters . hasNext ( ) ) { Object o = parameters . next ( ) ; JSONObject parameter = null ; try { parameter = ( JSONObject ) o ; } catch ( Exception e ) { M_log . warning ( "mergeLTI2Parameters did not find list of objects\n" + customstr ) ; M_log . warning ( e . getLocalizedMessage ( ) ) ; return false ; } String name = ( String ) parameter . get ( "name" ) ; if ( name == null ) continue ; if ( custom . containsKey ( name ) ) continue ; String fixed = ( String ) parameter . get ( "fixed" ) ; String variable = ( String ) parameter . get ( "variable" ) ; if ( variable != null ) { setProperty ( custom , name , variable ) ; continue ; } if ( fixed != null ) { setProperty ( custom , name , fixed ) ; } } return true ;


signature:
public class LTI2Util { /** * Place the custom values into the launch */
public static void addCustomToLaunch ( Properties ltiProps , Properties custom ) { } }

implementation: Enumeration < ? > e = custom . propertyNames ( ) ; while ( e . hasMoreElements ( ) ) { String keyStr = ( String ) e . nextElement ( ) ; String value = custom . getProperty ( keyStr ) ; setProperty ( ltiProps , "custom_" + keyStr , value ) ; }


signature:
public class ListBuddiesLayout { /** * Each time we touch the opposite ListView than the last one we have selected
 * we need to activate it as the enable one */
private void toogleListView ( View v ) { } }

implementation: if ( mLastViewTouchId != v . getId ( ) ) { if ( mLastViewTouchId == mListViewLeft . getId ( ) ) { isLeftListEnabled = true ; isRightListEnabled = false ; } else { isLeftListEnabled = false ; isRightListEnabled = true ; } }


signature:
public class ListBuddiesLayout { /** * Receives the distance scroll on listView . */
@ Override public void onListScroll ( View view , float deltaY ) { } }

implementation: int speed ; if ( view . getId ( ) == mListViewLeft . getId ( ) && ! isLeftListEnabled ) { speed = getSpeed ( false , deltaY ) ; mListViewRight . smoothScrollBy ( speed , 0 ) ; } else if ( view . getId ( ) == mListViewRight . getId ( ) && ! isRightListEnabled ) { speed = getSpeed ( true , deltaY ) ; mListViewLeft . smoothScrollBy ( speed , 0 ) ; }


signature:
public class SafeUrls { /** * Serializes a SafeUrl into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a SafeUrl using
 * { @ link # fromProto ( SafeUrlProto ) } . */
public static SafeUrlProto toProto ( SafeUrl url ) { } }

implementation: return SafeUrlProto . newBuilder ( ) . setPrivateDoNotAccessOrElseSafeUrlWrappedValue ( url . getSafeUrlString ( ) ) . build ( ) ;


signature:
public class SafeUrls { /** * Creates a SafeUrl object from the given { @ code url } , validating that the input string matches
 * a pattern of commonly used safe URLs . If { @ code url } fails validation , this method returns a
 * SafeUrl , { @ link SafeUrl # INNOCUOUS } , which contains an innocuous string ,
 * { @ link SafeUrl # INNOCUOUS _ STRING } .
 * < p > { @ code url } is sanitized as in { @ link # sanitize ( String ) } , additionally permitting the
 * custom schemes listed in { @ code extraAllowedSchemes } . */
public static SafeUrl sanitize ( String url , Set < CustomSafeUrlScheme > extraAllowedSchemes ) { } }

implementation: if ( ! isSafeUrl ( url , extraAllowedSchemes ) ) { return SafeUrl . INNOCUOUS ; } return create ( url ) ;


signature:
public class SafeUrls { /** * Sanitizes the given { @ code url } , validating that the input string matches a pattern of commonly
 * used safe URLs . If { @ code url } fails validation , this method returns
 * { @ code about : invalid # identifier } , with the given { @ code identifier } . The identifier allows
 * users to trace a sanitized value to the library that performed the sanitization and hence
 * should be a unique string like " zLibraryNamez " .
 * < p > Specifically , { @ code url } may be a URL with any of the default safe schemes ( http , https ,
 * ftp , mailto ) , or a relative URL ( i . e . , a URL without a scheme ; specifically , a scheme - relative ,
 * absolute - path - relative , or path - relative URL ) .
 * @ see http : / / url . spec . whatwg . org / # concept - relative - url */
public static String sanitizeAsString ( String url , @ CompileTimeConstant final String identifier ) { } }

implementation: if ( ! isSafeUrl ( url , EMPTY_CUSTOM_SCHEMES ) ) { return "about:invalid#" + identifier ; } return url ;


signature:
public class SafeUrls { /** * Creates a { @ code data : text / html } URL whose content is populated from the given
 * { @ code SafeHtml } object .
 * < p > The resulting { @ code data } - scheme URL ' s content is UTF - 8 - encoded , but the
 * encoding of non - ASCII characters is done using the standard % xx hex encoding .
 * @ see http : / / tools . ietf . org / html / rfc2397
 * @ see https : / / developer . mozilla . org / en - US / docs / Web / HTTP / data _ URIs */
public static SafeUrl createHtmlDataUrl ( SafeHtml html ) { } }

implementation:
// Use urlPathSegmentEscaper because all other Escapers convert spaces to " + " instead of " % 20 " ,
// which are rendered as normal " + " s in the browser instead of being rendered as spaces .
String dataUrl = "data:text/html;charset=UTF-8," + UrlEscapers . urlPathSegmentEscaper ( ) . escape ( html . getSafeHtmlString ( ) ) ; return create ( dataUrl ) ;


signature:
public class SafeUrls { /** * Creates a { @ code data : text / html } URL whose content is populated from the given
 * { @ code SafeHtml } object .
 * < p > The resulting { @ code data } - scheme URL ' s content is UTF - 8 - encoded , and further encoded using
 * base - 64 transfer encoding .
 * @ see http : / / tools . ietf . org / html / rfc2397
 * @ see https : / / developer . mozilla . org / en - US / docs / Web / HTTP / data _ URIs */
public static SafeUrl createHtmlDataUrlBase64 ( SafeHtml html ) { } }

implementation:
try { String dataUrl = "data:text/html;charset=UTF-8;base64," + BaseEncoding . base64 ( ) . encode ( html . getSafeHtmlString ( ) . getBytes ( "UTF-8" ) ) ; return create ( dataUrl ) ; } catch ( UnsupportedEncodingException e ) { // Should never happen . We use getBytes ( String ) instead of getBytes ( CharSet ) because
// there ' s no java . nio . charset . StandardCharsets in older Android SDKs .
throw new RuntimeException ( e ) ; }


signature:
public class SafeStyleBuilder { /** * Appends { @ code values } to the { @ code background - attachment } property . Values will be comma
 * separated .
 * < p > The values must consist of only ASCII alphabetic or ' - ' characters . A non - conforming value
 * will be replaced with { @ link # INNOCUOUS _ PROPERTY _ STRING } .
 * @ see " https : / / developer . mozilla . org / en - US / docs / Web / CSS / background - attachment " */
public SafeStyleBuilder backgroundAttachmentAppend ( String value , String ... otherValues ) { } }

implementation: appendToProperty ( "background-attachment" , sanitizeAndJoinEnumValues ( value , otherValues ) ) ; return this ;


signature:
public class SafeStyleBuilder { /** * Appends a { @ code url } value to the { @ code background - image } property , if necessary inserting
 * a leading comma . The { @ code url } value will be inserted inside a { @ code url } function call .
 * < p > The { @ code url } is validated as safe , as determined by { @ link SafeUrls # sanitize ( String ) } .
 * It also percent - encoded to prevent it from interefering with the structure of the surrounding
 * CSS .
 * < p > TODO ( mlourenco ) : The right thing to do would be to CSS - escape but percent - encoding is
 * easier for now because we don ' t have a CSS - escaper . As URLs in CSS are likely to point to
 * domains we control it seems extremely unlikely that this will break anything .
 * @ see " http : / / dev . w3 . org / csswg / css - backgrounds / # background - image " */
public SafeStyleBuilder backgroundImageAppendUrl ( String url ) { } }

implementation:
url = SafeUrls . sanitize ( url ) . getSafeUrlString ( ) ; try { url = ESCAPER_BACKGROUND_IMAGE . escape ( url ) ; } catch ( IllegalArgumentException e ) { // Happens if url contains invalid surrogate sequences .
url = INNOCUOUS_PROPERTY_STRING ; } String urlValue = "url(" + url + ")" ; appendToProperty ( "background-image" , urlValue ) ; return this ;


signature:
public class SafeStyleBuilder { /** * Appends { @ code values } to the { @ code background - size } property . Values will be comma
 * separated .
 * < p > All values must contain only whitelisted characters ; those are alphanumerics , space ,
 * tab , and the set { @ code [ + - . ! # % _ / * ] } . In addition , comment markers - { @ code / / } , { @ code / * } ,
 * and < code > * & # 47 ; < / code > - are disallowed too . Non - conforming values are replaced with
 * { @ link # INNOCUOUS _ PROPERTY _ STRING } .
 * @ see " https : / / developer . mozilla . org / en - US / docs / Web / CSS / background - size " */
public SafeStyleBuilder backgroundSizeAppend ( String value , String ... otherValues ) { } }

implementation: appendToProperty ( "background-size" , sanitizeAndJoinRegularValues ( value , otherValues ) ) ; return this ;


signature:
public class SafeStyleBuilder { /** * Appends { @ code values } to the { @ code font - family } property . Values will be comma separated .
 * < p > If a value consists only of only ASCII alphabetic or ' - ' characters , it is appended as is ,
 * since it might be a generic font family ( like { @ code serif } ) which must not be quoted . If a
 * value contains other characters it will be quoted , since quoting might be required ( for
 * example , if the font name contains a space ) and unnecessary quoting is allowed .
 * < p > Values must contain only whitelisted characters ; those are alphanumerics , space ,
 * tab , and the set { @ code [ + - . ! # % _ / * ] } . In addition , comment markers - { @ code / / } , { @ code / * } ,
 * and < code > * & # 47 ; < / code > - are disallowed too . Non - conforming values are replaced with
 * { @ link # INNOCUOUS _ PROPERTY _ STRING } .
 * @ see " https : / / developer . mozilla . org / en - US / docs / Web / CSS / font - family " */
public SafeStyleBuilder fontFamilyAppend ( String value , String ... otherValues ) { } }

implementation: sanitizeAndAppendToFontFamily ( value ) ; for ( String otherValue : otherValues ) { sanitizeAndAppendToFontFamily ( otherValue ) ; } return this ;


signature:
public class SafeStyleBuilder { /** * Throws IllegalArgumentException if { @ code value } contains any of a few blacklisted characters
 * which would change the syntactic structure of the CSS or entirely break out of the HTML style
 * attribute . */
private static String checkConstantValue ( @ CompileTimeConstant final String value ) { } }

implementation: for ( int i = 0 ; i < value . length ( ) ; i ++ ) { char c = value . charAt ( i ) ; if ( c == '<' || c == '>' || c == '"' || c == '\'' || c == ';' ) { throw new IllegalArgumentException ( "Value contains HTML/CSS meta-characters ([<>\"';]): " + value ) ; } else if ( value . startsWith ( "/*" , i ) || value . startsWith ( "*/" , i ) || value . startsWith ( "//" , i ) ) { throw new IllegalArgumentException ( "Value contains CSS comment marker (/*, */ or //): " + value ) ; } } return value ;


signature:
public class SafeStyleBuilder { /** * Sanitizes and joins string varargs where each value is subjected to sanitization via
 * { @ link # sanitizeEnumValue ( String ) } . */
private static String sanitizeAndJoinEnumValues ( String value , String [ ] otherValues ) { } }

implementation: StringBuilder sb = new StringBuilder ( sanitizeEnumValue ( value ) ) ; for ( int i = 0 ; i < otherValues . length ; i ++ ) { sb . append ( ',' ) . append ( sanitizeEnumValue ( otherValues [ i ] ) ) ; } return sb . toString ( ) ;


signature:
public class SafeStyleBuilder { /** * Sanitizes and joins string varargs where each value is subjected to sanitization via
 * { @ link # sanitizeRegularValue ( String ) } . */
private static String sanitizeAndJoinRegularValues ( String value , String [ ] otherValues ) { } }

implementation: StringBuilder sb = new StringBuilder ( sanitizeRegularValue ( value ) ) ; for ( int i = 0 ; i < otherValues . length ; i ++ ) { sb . append ( ',' ) . append ( sanitizeRegularValue ( otherValues [ i ] ) ) ; } return sb . toString ( ) ;


signature:
public class SafeStyles { /** * Creates a SafeStyle from the given compile - time constant string { @ code style } .
 * < p > { @ code style } should be in the format { @ code name : value ; [ name : value ; . . . ] } and must
 * not have any & lt ; or & gt ; characters in it . This is so that SafeStyle ' s contract is preserved ,
 * allowing the SafeStyle to correctly be interpreted as a sequence of CSS declarations and
 * without affecting the syntactic structure of any surrounding CSS and HTML .
 * < p > This method performs basic sanity checks on the format of { @ code style } but does not
 * constrain the format of { @ code name } and { @ code value } , except for disallowing tag characters .
 * @ throws IllegalArgumentException if some of the constraints of the format specified above
 * are not met */
public static SafeStyle fromConstant ( @ CompileTimeConstant final String style ) { } }

implementation: if ( style . length ( ) == 0 ) { return SafeStyle . EMPTY ; } for ( int i = 0 ; i < style . length ( ) ; i ++ ) { if ( style . charAt ( i ) == '<' || style . charAt ( i ) == '>' ) { throw new IllegalArgumentException ( "Forbidden characters in style string: " + style ) ; } } if ( style . charAt ( style . length ( ) - 1 ) != ';' ) { throw new IllegalArgumentException ( "Last character of style string is not ';': " + style ) ; } if ( ! style . contains ( ":" ) ) { throw new IllegalArgumentException ( "Style string must contain at least one ':', to " + "specify a \"name: value\" pair: " + style ) ; } return create ( style ) ;


signature:
public class SafeStyles { /** * Serializes a SafeStyle into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a SafeStyle using
 * { @ link # fromProto ( SafeStyleProto ) } . */
public static SafeStyleProto toProto ( SafeStyle style ) { } }

implementation: return SafeStyleProto . newBuilder ( ) . setPrivateDoNotAccessOrElseSafeStyleWrappedValue ( style . getSafeStyleString ( ) ) . build ( ) ;


signature:
public class SafeScripts { /** * Creates a SafeScript from the given compile - time constant string { @ code script } . */
public static SafeScript fromConstant ( @ CompileTimeConstant final String script ) { } }

implementation: if ( script . length ( ) == 0 ) { return SafeScript . EMPTY ; } return create ( script ) ;


signature:
public class SafeScripts { /** * Serializes a SafeScript into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a SafeScript using
 * { @ link # fromProto ( SafeScriptProto ) } . */
public static SafeScriptProto toProto ( SafeScript script ) { } }

implementation: return SafeScriptProto . newBuilder ( ) . setPrivateDoNotAccessOrElseSafeScriptWrappedValue ( script . getSafeScriptString ( ) ) . build ( ) ;


signature:
public class SafeStyleSheets { /** * Creates a SafeStyleSheet from the given compile - time constant string { @ code style } .
 * < p > { @ code styleSheet } must not have any & lt ; characters in it so that the syntactic
 * structure of any surrounding CSS and HTML is not affected .
 * @ throws IllegalArgumentException if { @ code styleSheet } contains & lt ; */
public static SafeStyleSheet fromConstant ( @ CompileTimeConstant final String styleSheet ) { } }

implementation: if ( styleSheet . length ( ) == 0 ) { return SafeStyleSheet . EMPTY ; } for ( int i = 0 ; i < styleSheet . length ( ) ; i ++ ) { if ( styleSheet . charAt ( i ) == '<' ) { throw new IllegalArgumentException ( "Forbidden '<' character in style sheet string: " + styleSheet ) ; } } return create ( styleSheet ) ;


signature:
public class SafeStyleSheets { /** * Creates a SafeStyleSheet from the given compile - time constant { @ code resourceName } using
 * the given { @ code charset } .
 * < p > This performs ZERO VALIDATION of the data . We assume that resources should be safe because
 * they are part of the binary , and therefore not attacker controlled .
 * @ param contextClass Class relative to which to load the resource . */
@ GwtIncompatible ( "Resources" ) public static SafeStyleSheet fromResource ( Class < ? > contextClass , @ CompileTimeConstant final String resourceName , Charset charset ) throws IOException { } }

implementation: return create ( Resources . toString ( Resources . getResource ( contextClass , resourceName ) , charset ) ) ;


signature:
public class SafeStyleSheets { /** * Serializes a SafeStyleSheet into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a SafeStyleSheet using
 * { @ link # fromProto ( SafeStyleSheetProto ) } . */
public static SafeStyleSheetProto toProto ( SafeStyleSheet style ) { } }

implementation: return SafeStyleSheetProto . newBuilder ( ) . setPrivateDoNotAccessOrElseSafeStyleSheetWrappedValue ( style . getSafeStyleSheetString ( ) ) . build ( ) ;


signature:
public class SafeStyleSheets { /** * Creates a new SafeStyleSheet which contains , in order , the string representations of the given
 * { @ code stylesheets } . */
public static SafeStyleSheet concat ( Iterable < SafeStyleSheet > stylesheets ) { } }

implementation: int concatLength = 0 ; for ( SafeStyleSheet stylesheet : stylesheets ) { concatLength += stylesheet . getSafeStyleSheetString ( ) . length ( ) ; } StringBuilder result = new StringBuilder ( concatLength ) ; for ( SafeStyleSheet stylesheet : stylesheets ) { result . append ( stylesheet . getSafeStyleSheetString ( ) ) ; } return create ( result . toString ( ) ) ;


signature:
public class TrustedResourceUrls { /** * Serializes a TrustedResourceUrl into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a TrustedResourceUrl using
 * { @ link # fromProto ( TrustedResourceUrlProto ) } . */
public static TrustedResourceUrlProto toProto ( TrustedResourceUrl url ) { } }

implementation: return TrustedResourceUrlProto . newBuilder ( ) . setPrivateDoNotAccessOrElseTrustedResourceUrlWrappedValue ( url . getTrustedResourceUrlString ( ) ) . build ( ) ;


signature:
public class TrustedResourceUrls { /** * Creates a { @ link TrustedResourceUrl } from the value of an environment variable . In a server
 * setting , environment variables are part of the application ' s deployment configuration and are
 * hence considered application - controlled . If the variable is not defined returns null .
 * < p > No runtime validation or sanitization is performed on the value of the environment variable ;
 * being under application control , it is simply assumed to comply with the TrustedResourceUrl
 * contract .
 * @ throws SecurityException if a security manager exists and its checkPermission method doesn ' t
 * allow access to the environment variable name */
@ GwtIncompatible ( "System.getEnv" ) @ Nullable public static TrustedResourceUrl fromEnvironmentVariable ( @ CompileTimeConstant final String variableName ) { } }

implementation: String var = System . getenv ( variableName ) ; if ( var == null ) { return null ; } return create ( var ) ;


signature:
public class SafeHtmls { /** * Wraps a SafeScript inside a & lt ; script type = " text / javascript " & gt ; tag .
 * The tag has a nonce attribute populated from the provided CSP nonce value . */
public static SafeHtml fromScriptWithCspNonce ( SafeScript script , String cspNonce ) { } }

implementation: return create ( "<script type=\"text/javascript\" nonce=\"" + htmlEscapeInternal ( cspNonce ) + "\">" + script . getSafeScriptString ( ) + "</script>" ) ;


signature:
public class SafeHtmls { /** * Creates a & lt ; script type = " text / javascript " src = " < i > url < / i > " & gt ; & lt ; script & gt ; where the
 * { @ code src } attribute points to the given { @ code trustedResourceUrl } . */
public static SafeHtml fromScriptUrl ( TrustedResourceUrl trustedResourceUrl ) { } }

implementation: String escapedUrl = htmlEscapeInternal ( trustedResourceUrl . getTrustedResourceUrlString ( ) ) ; return create ( "<script type=\"text/javascript\" src=\"" + escapedUrl + "\"></script>" ) ;


signature:
public class SafeHtmls { /** * Creates a & lt ; script type = " text / javascript " src = " < i > url < / i > " & gt ; & lt ; script & gt ; where the
 * { @ code src } attribute points to the given { @ code trustedResourceUrl } .
 * The tag has a nonce attribute populated from the provided CSP nonce value . */
public static SafeHtml fromScriptUrlWithCspNonce ( TrustedResourceUrl trustedResourceUrl , String cspNonce ) { } }

implementation: String escapedUrl = htmlEscapeInternal ( trustedResourceUrl . getTrustedResourceUrlString ( ) ) ; return create ( "<script type=\"text/javascript\" nonce=\"" + htmlEscapeInternal ( cspNonce ) + "\" src=\"" + escapedUrl + "\"></script>" ) ;


signature:
public class SafeHtmls { /** * Wraps a SafeStyleSheet inside a & lt ; style type = " text / css " & gt ; tag . */
public static SafeHtml fromStyleSheet ( SafeStyleSheet safeStyleSheet ) { } }

implementation: Preconditions . checkArgument ( ! safeStyleSheet . getSafeStyleSheetString ( ) . contains ( "<" ) ) ; return create ( "<style type=\"text/css\">" + safeStyleSheet . getSafeStyleSheetString ( ) + "</style>" ) ;


signature:
public class SafeHtmls { /** * Serializes a SafeHtml into its opaque protocol message representation .
 * < p > Protocol message forms of this type are intended to be opaque . The fields of the returned
 * protocol message should be considered encapsulated and are not intended for direct inspection
 * or manipulation . Protocol messages can be converted back into a SafeHtml using
 * { @ link # fromProto ( SafeHtmlProto ) } . */
public static SafeHtmlProto toProto ( SafeHtml safeHtml ) { } }

implementation: return SafeHtmlProto . newBuilder ( ) . setPrivateDoNotAccessOrElseSafeHtmlWrappedValue ( safeHtml . getSafeHtmlString ( ) ) . build ( ) ;


signature:
public class SafeHtmls { /** * Creates a new SafeHtml which contains , in order , the string representations of the given
 * { @ code htmls } . */
public static SafeHtml concat ( Iterable < SafeHtml > htmls ) { } }

implementation: int concatLength = 0 ; for ( SafeHtml html : htmls ) { concatLength += html . getSafeHtmlString ( ) . length ( ) ; } StringBuilder result = new StringBuilder ( concatLength ) ; for ( SafeHtml html : htmls ) { result . append ( html . getSafeHtmlString ( ) ) ; } return create ( result . toString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code action } attribute for this element .
 * < p > The attribute { @ code action } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code form }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code action } attribute with a { @ code SafeUrl } value
 * is not allowed on this element */
public SafeHtmlBuilder setAction ( SafeUrl value ) { } }

implementation: if ( ! ACTION_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"action\" with a SafeUrl value can only be used " + "by one of the following elements: " + ACTION_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "action" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code cite } attribute for this element .
 * < p > The attribute { @ code cite } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code blockquote }
 * < li > { @ code del }
 * < li > { @ code ins }
 * < li > { @ code q }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code cite } attribute with a { @ code SafeUrl } value is
 * not allowed on this element */
public SafeHtmlBuilder setCite ( SafeUrl value ) { } }

implementation: if ( ! CITE_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"cite\" with a SafeUrl value can only be used " + "by one of the following elements: " + CITE_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "cite" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code formaction } attribute for this element .
 * < p > The attribute { @ code formaction } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code button }
 * < li > { @ code input }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code formaction } attribute with a { @ code SafeUrl }
 * value is not allowed on this element */
public SafeHtmlBuilder setFormaction ( SafeUrl value ) { } }

implementation: if ( ! FORMACTION_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"formaction\" with a SafeUrl value can only be used " + "by one of the following elements: " + FORMACTION_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "formaction" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code formmethod } attribute for this element .
 * < p > The attribute { @ code formmethod } with a { @ code String } value is allowed on these elements :
 * < ul >
 * < li > { @ code button }
 * < li > { @ code input }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code formmethod } attribute with a { @ code String }
 * value is not allowed on this element */
public SafeHtmlBuilder setFormmethod ( String value ) { } }

implementation: if ( ! FORMMETHOD_STRING_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"formmethod\" with a String value can only be used " + "by one of the following elements: " + FORMMETHOD_STRING_ELEMENT_WHITELIST ) ; } return setAttribute ( "formmethod" , value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code href } attribute for this element .
 * < p > The attribute { @ code href } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code a }
 * < li > { @ code area }
 * < li > { @ code link }
 * < / ul >
 * < p > On { @ code link } elements , { @ code href } may only be set to a SafeUrl value if { @ code rel } is
 * one of the following values :
 * < ul >
 * < li > { @ code alternate }
 * < li > { @ code author }
 * < li > { @ code bookmark }
 * < li > { @ code canonical }
 * < li > { @ code cite }
 * < li > { @ code help }
 * < li > { @ code icon }
 * < li > { @ code license }
 * < li > { @ code next }
 * < li > { @ code prefetch }
 * < li > { @ code prerender }
 * < li > { @ code prev }
 * < li > { @ code search }
 * < li > { @ code subresource }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code href } attribute with a { @ code SafeUrl } value is
 * not allowed on this element
 * @ throws IllegalArgumentException if this a { @ code link } element and the value of { @ code rel }
 * does not allow the SafeUrl contract on { @ code href } */
public SafeHtmlBuilder setHref ( SafeUrl value ) { } }

implementation: if ( ! HREF_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) && ! elementName . equals ( "link" ) ) { throw new IllegalArgumentException ( "Attribute \"href\" with a SafeUrl value can only be used " + "by one of the following elements: " + HREF_SAFE_URL_ELEMENT_WHITELIST ) ; } if ( elementName . equals ( "link" ) ) { checkLinkDependentAttributes ( attributes . get ( "rel" ) , AttributeContract . SAFE_URL ) ; } hrefValueContract = AttributeContract . SAFE_URL ; return setAttribute ( "href" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code href } attribute for this element . */
public SafeHtmlBuilder setHref ( TrustedResourceUrl value ) { } }

implementation: hrefValueContract = AttributeContract . TRUSTED_RESOURCE_URL ; return setAttribute ( "href" , value . getTrustedResourceUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code icon } attribute for this element .
 * < p > The attribute { @ code icon } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code menuitem }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code icon } attribute with a { @ code SafeUrl } value is
 * not allowed on this element */
public SafeHtmlBuilder setIcon ( SafeUrl value ) { } }

implementation: if ( ! ICON_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"icon\" with a SafeUrl value can only be used " + "by one of the following elements: " + ICON_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "icon" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code list } attribute for this element to a { @ link CompileTimeConstant } { @ code
 * prefix } and a { @ code value } joined by a hyphen .
 * @ throws IllegalArgumentException if { @ code prefix } is an empty string */
public SafeHtmlBuilder setListWithPrefix ( @ CompileTimeConstant final String prefix , String value ) { } }

implementation: if ( prefix . trim ( ) . length ( ) == 0 ) { throw new IllegalArgumentException ( "Prefix cannot be empty string" ) ; } return setAttribute ( "list" , prefix + "-" + value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code media } attribute for this element .
 * < p > The attribute { @ code media } with a { @ code String } value is allowed on these elements :
 * < ul >
 * < li > { @ code link }
 * < li > { @ code source }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code media } attribute with a { @ code String } value is
 * not allowed on this element */
public SafeHtmlBuilder setMedia ( String value ) { } }

implementation: if ( ! MEDIA_STRING_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"media\" with a String value can only be used " + "by one of the following elements: " + MEDIA_STRING_ELEMENT_WHITELIST ) ; } return setAttribute ( "media" , value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code method } attribute for this element .
 * < p > The attribute { @ code method } with a { @ code String } value is allowed on these elements :
 * < ul >
 * < li > { @ code form }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code method } attribute with a { @ code String } value is
 * not allowed on this element */
public SafeHtmlBuilder setMethod ( String value ) { } }

implementation: if ( ! METHOD_STRING_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"method\" with a String value can only be used " + "by one of the following elements: " + METHOD_STRING_ELEMENT_WHITELIST ) ; } return setAttribute ( "method" , value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code pattern } attribute for this element .
 * < p > The attribute { @ code pattern } with a { @ code String } value is allowed on these elements :
 * < ul >
 * < li > { @ code input }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code pattern } attribute with a { @ code String } value
 * is not allowed on this element */
public SafeHtmlBuilder setPattern ( String value ) { } }

implementation: if ( ! PATTERN_STRING_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"pattern\" with a String value can only be used " + "by one of the following elements: " + PATTERN_STRING_ELEMENT_WHITELIST ) ; } return setAttribute ( "pattern" , value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code poster } attribute for this element .
 * < p > The attribute { @ code poster } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code video }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code poster } attribute with a { @ code SafeUrl } value
 * is not allowed on this element */
public SafeHtmlBuilder setPoster ( SafeUrl value ) { } }

implementation: if ( ! POSTER_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"poster\" with a SafeUrl value can only be used " + "by one of the following elements: " + POSTER_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "poster" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code src } attribute for this element .
 * < p > The attribute { @ code src } with a { @ code SafeUrl } value is allowed on these elements :
 * < ul >
 * < li > { @ code audio }
 * < li > { @ code img }
 * < li > { @ code input }
 * < li > { @ code source }
 * < li > { @ code video }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code src } attribute with a { @ code SafeUrl } value is
 * not allowed on this element */
public SafeHtmlBuilder setSrc ( SafeUrl value ) { } }

implementation: if ( ! SRC_SAFE_URL_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"src\" with a SafeUrl value can only be used " + "by one of the following elements: " + SRC_SAFE_URL_ELEMENT_WHITELIST ) ; } return setAttribute ( "src" , value . getSafeUrlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code srcdoc } attribute for this element .
 * < p > The attribute { @ code srcdoc } with a { @ code SafeHtml } value is allowed on these elements :
 * < ul >
 * < li > { @ code iframe }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code srcdoc } attribute with a { @ code SafeHtml } value
 * is not allowed on this element */
public SafeHtmlBuilder setSrcdoc ( SafeHtml value ) { } }

implementation: if ( ! SRCDOC_SAFE_HTML_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"srcdoc\" with a SafeHtml value can only be used " + "by one of the following elements: " + SRCDOC_SAFE_HTML_ELEMENT_WHITELIST ) ; } return setAttribute ( "srcdoc" , value . getSafeHtmlString ( ) ) ;


signature:
public class SafeHtmlBuilder { /** * Sets the { @ code type } attribute for this element .
 * < p > The attribute { @ code type } with a { @ code String } value is allowed on these elements :
 * < ul >
 * < li > { @ code button }
 * < li > { @ code command }
 * < li > { @ code input }
 * < li > { @ code li }
 * < li > { @ code link }
 * < li > { @ code ol }
 * < / ul >
 * @ throws IllegalArgumentException if the { @ code type } attribute with a { @ code String } value is
 * not allowed on this element */
public SafeHtmlBuilder setType ( String value ) { } }

implementation: if ( ! TYPE_STRING_ELEMENT_WHITELIST . contains ( elementName ) ) { throw new IllegalArgumentException ( "Attribute \"type\" with a String value can only be used " + "by one of the following elements: " + TYPE_STRING_ELEMENT_WHITELIST ) ; } return setAttribute ( "type" , value ) ;


signature:
public class SafeHtmlBuilder { /** * Sets a custom data attribute , { @ code name } , to { @ code value } for this element . { @ code value }
 * must consist only of letters and { @ code - } .
 * @ param name including the " data - " prefix , e . g . " data - tooltip "
 * @ throws IllegalArgumentException if the attribute name isn ' t valid
 * @ see
 * http : / / www . w3 . org / TR / html5 / dom . html # embedding - custom - non - visible - data - with - the - data - * - attributes */
public SafeHtmlBuilder setDataAttribute ( @ CompileTimeConstant final String name , String value ) { } }

implementation: if ( ! name . matches ( VALID_DATA_ATTRIBUTES_REGEXP ) ) { throw new IllegalArgumentException ( "Invalid data attribute name \"" + name + "\"." + "Name must start with \"data-\" and be followed by letters and '-'." ) ; } return setAttribute ( name , value ) ;


signature:
public class SafeHtmlBuilder { /** * Appends the given { @ code htmls } as this element ' s content , in the sequence the Iterable returns
 * them .
 * @ throws IllegalStateException if this builder represents a void element */
public SafeHtmlBuilder appendContent ( Iterable < SafeHtml > htmls ) { } }

implementation: checkNotVoidElement ( ) ; for ( SafeHtml html : htmls ) { contents . add ( html ) ; } return this ;


signature:
public class SafeHtmlBuilder { /** * Appends the given { @ code htmls } as this element ' s content , in the sequence the Iterator returns
 * them .
 * @ throws IllegalStateException if this builder represents a void element */
public SafeHtmlBuilder appendContent ( Iterator < SafeHtml > htmls ) { } }

implementation: checkNotVoidElement ( ) ; while ( htmls . hasNext ( ) ) { contents . add ( htmls . next ( ) ) ; } return this ;


signature:
public class SafeHtmlBuilder { /** * Checks that this combination of rel value and href contract is safe .
 * @ param relValue is the value of rel or null if rel isn ' t present .
 * @ throws IllegalArgumentException if this value and contract combination is not allowed . */
private static void checkLinkDependentAttributes ( @ Nullable String relValue , AttributeContract hrefValueContract ) { } }

implementation: if ( hrefValueContract . equals ( AttributeContract . SAFE_URL ) && relValue != null && ! LINK_HREF_SAFE_URL_REL_WHITELIST . contains ( relValue . toLowerCase ( Locale . ENGLISH ) ) ) { throw new IllegalArgumentException ( "SafeUrl values for the href attribute are not allowed on <link rel=" + relValue + ">. Did you intend to use a TrustedResourceUrl?" ) ; }


signature:
public class FilterUtils { /** * Parse a String to a boolean .
 * " true " : true
 * " false " : false
 * null : false
 * Anything else : logException ( IllegalArgumentException ) .
 * This is a stateless static method .
 * This method is an implementation detail and is not exposed API .
 * This method is only non - private to allow JUnit testing .
 * @ param stringToParse a String to parse to a boolean as specified
 * @ return true or false
 * @ throws IllegalArgumentException if the String is not true , false , or null . */
public static boolean parseStringToBooleanDefaultingToFalse ( final String stringToParse ) { } }

implementation: if ( "true" . equals ( stringToParse ) ) { return true ; } else if ( "false" . equals ( stringToParse ) ) { return false ; } else if ( null == stringToParse ) { return false ; } logException ( LOGGER , new IllegalArgumentException ( "String [" + stringToParse + "] could not parse to a boolean because it was not precisely 'true' or 'false'." ) ) ; return false ;


signature:
public class ResponseHeadersEnforcementFilter { /** * Examines the Filter init parameter names and throws ServletException if they contain an unrecognized
 * init parameter name .
 * This is a stateless static method .
 * This method is an implementation detail and is not exposed API .
 * This method is only non - private to allow JUnit testing .
 * @ param initParamNames init param names , in practice as read from the FilterConfig . */
static void throwIfUnrecognizedParamName ( final Enumeration initParamNames ) { } }

implementation: final Set < String > recognizedParameterNames = new HashSet < String > ( ) ; recognizedParameterNames . add ( INIT_PARAM_ENABLE_CACHE_CONTROL ) ; recognizedParameterNames . add ( INIT_PARAM_ENABLE_XCONTENT_OPTIONS ) ; recognizedParameterNames . add ( INIT_PARAM_ENABLE_STRICT_TRANSPORT_SECURITY ) ; recognizedParameterNames . add ( INIT_PARAM_ENABLE_STRICT_XFRAME_OPTIONS ) ; recognizedParameterNames . add ( INIT_PARAM_STRICT_XFRAME_OPTIONS ) ; recognizedParameterNames . add ( INIT_PARAM_CONTENT_SECURITY_POLICY ) ; recognizedParameterNames . add ( LOGGER_HANDLER_CLASS_NAME ) ; recognizedParameterNames . add ( INIT_PARAM_ENABLE_XSS_PROTECTION ) ; recognizedParameterNames . add ( INIT_PARAM_XSS_PROTECTION ) ; while ( initParamNames . hasMoreElements ( ) ) { final String initParamName = ( String ) initParamNames . nextElement ( ) ; if ( ! recognizedParameterNames . contains ( initParamName ) ) { FilterUtils . logException ( LOGGER , new ServletException ( "Unrecognized init parameter [" + initParamName + "].  Failing safe.  Typo" + " in the web.xml configuration? " + " Misunderstanding about the configuration " + RequestParameterPolicyEnforcementFilter . class . getSimpleName ( ) + " expects?" ) ) ; } }


signature:
public class RequestParameterPolicyEnforcementFilter { /** * Examines the Filter init parameter names and throws ServletException if they contain an unrecognized
 * init parameter name .
 * This is a stateless static method .
 * This method is an implementation detail and is not exposed API .
 * This method is only non - private to allow JUnit testing .
 * @ param initParamNames init param names , in practice as read from the FilterConfig .
 * @ throws ServletException if unrecognized parameter name is present */
static void throwIfUnrecognizedParamName ( Enumeration initParamNames ) throws ServletException { } }

implementation: final Set < String > recognizedParameterNames = new HashSet < String > ( ) ; recognizedParameterNames . add ( ALLOW_MULTI_VALUED_PARAMETERS ) ; recognizedParameterNames . add ( PARAMETERS_TO_CHECK ) ; recognizedParameterNames . add ( ONLY_POST_PARAMETERS ) ; recognizedParameterNames . add ( CHARACTERS_TO_FORBID ) ; recognizedParameterNames . add ( LOGGER_HANDLER_CLASS_NAME ) ; while ( initParamNames . hasMoreElements ( ) ) { final String initParamName = ( String ) initParamNames . nextElement ( ) ; if ( ! recognizedParameterNames . contains ( initParamName ) ) { FilterUtils . logException ( LOGGER , new ServletException ( "Unrecognized init parameter [" + initParamName + "].  Failing safe.  Typo" + " in the web.xml configuration? " + " Misunderstanding about the configuration " + RequestParameterPolicyEnforcementFilter . class . getSimpleName ( ) + " expects?" ) ) ; } }


signature:
public class RequestParameterPolicyEnforcementFilter { /** * Parse the whitespace delimited String of parameters to check .
 * If the String is null , return the empty set .
 * If the whitespace delimited String contains no tokens , throw IllegalArgumentException .
 * If the sole token is an asterisk , return the empty set .
 * If the asterisk token is encountered among other tokens , throw IllegalArgumentException .
 * This method returning an empty Set has the special meaning of " check all parameters " .
 * This is a stateless static method .
 * This method is an implementation detail and is not exposed API .
 * This method is only non - private to allow JUnit testing .
 * @ param initParamValue null , or a non - blank whitespace delimited list of parameters to check
 * @ param allowWildcard whether a wildcard is allowed instead of the parameters list
 * @ return a Set of String names of parameters to check , or an empty set representing check - them - all .
 * @ throws IllegalArgumentException when the init param value is out of spec */
static Set < String > parseParametersList ( final String initParamValue , final boolean allowWildcard ) { } }

implementation: final Set < String > parameterNames = new HashSet < String > ( ) ; if ( null == initParamValue ) { return parameterNames ; } final String [ ] tokens = initParamValue . split ( "\\s+" ) ; if ( 0 == tokens . length ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( "[" + initParamValue + "] had no tokens but should have had at least one token." ) ) ; } if ( 1 == tokens . length && "*" . equals ( tokens [ 0 ] ) && allowWildcard ) { return parameterNames ; } for ( final String parameterName : tokens ) { if ( "*" . equals ( parameterName ) ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( "Star token encountered among other tokens in parsing [" + initParamValue + "]" ) ) ; } parameterNames . add ( parameterName ) ; } return parameterNames ;


signature:
public class RequestParameterPolicyEnforcementFilter { /** * Parse a whitespace delimited set of Characters from a String .
 * If the String is null ( init param was not set ) default to DEFAULT _ CHARACTERS _ BLOCKED .
 * If the String is " none " parse to empty set meaning block no characters .
 * If the String is empty throw , to avoid configurer accidentally configuring not to block any characters .
 * @ param paramValue value of the init param to parse
 * @ return non - null Set of zero or more Characters to block */
static Set < Character > parseCharactersToForbid ( String paramValue ) { } }

implementation: final Set < Character > charactersToForbid = new HashSet < Character > ( ) ; if ( null == paramValue ) { paramValue = DEFAULT_CHARACTERS_BLOCKED ; } if ( "none" . equals ( paramValue ) ) { return charactersToForbid ; } final String [ ] tokens = paramValue . split ( "\\s+" ) ; if ( 0 == tokens . length ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( "Expected tokens when parsing [" + paramValue + "] but found no tokens." + " If you really want to configure no characters, use the magic value 'none'." ) ) ; } for ( final String token : tokens ) { if ( token . length ( ) > 1 ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( "Expected tokens of length 1 but found [" + token + "] when " + "parsing [" + paramValue + "]" ) ) ; } final Character character = token . charAt ( 0 ) ; charactersToForbid . add ( character ) ; } return charactersToForbid ;


signature:
public class RequestParameterPolicyEnforcementFilter { /** * For each parameter to check , for each value of that parameter , check that the value does not contain
 * forbidden characters .
 * This is a stateless static method .
 * This method is an implementation detail and is not exposed API .
 * This method is only non - private to allow JUnit testing .
 * @ param parametersToCheck Set of String request parameter names to look for
 * @ param charactersToForbid Set of Character characters to forbid
 * @ param parameterMap String - - > String [ ] Map , in practice as read from ServletRequest */
static void enforceParameterContentCharacterRestrictions ( final Set < String > parametersToCheck , final Set < Character > charactersToForbid , final Map parameterMap ) { } }

implementation:
if ( charactersToForbid . isEmpty ( ) ) { // short circuit
return ; } for ( final String parameterToCheck : parametersToCheck ) { final String [ ] parameterValues = ( String [ ] ) parameterMap . get ( parameterToCheck ) ; if ( null != parameterValues ) { for ( final String parameterValue : parameterValues ) { for ( final Character forbiddenCharacter : charactersToForbid ) { final StringBuilder characterAsStringBuilder = new StringBuilder ( ) ; characterAsStringBuilder . append ( forbiddenCharacter ) ; if ( parameterValue . contains ( characterAsStringBuilder ) ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( "Disallowed character [" + forbiddenCharacter + "] found in value [" + parameterValue + "] of parameter named [" + parameterToCheck + "]" ) ) ; } // that forbiddenCharacter was not in this parameterValue
} // none of the charactersToForbid were in this parameterValue
} // none of the values of this parameterToCheck had a forbidden character
} // or this parameterToCheck had null value
} // none of the values of any of the parametersToCheck had a forbidden character
// hurray ! allow flow to continue without throwing an Exception .


signature:
public class RequestParameterPolicyEnforcementFilter { /** * Check that some parameters should only be in POST requests ( according to the configuration ) .
 * @ param method the method of the request
 * @ param parameterMap all the request parameters
 * @ param onlyPostParameters parameters that should only be in POST requests */
static void checkOnlyPostParameters ( final String method , final Map parameterMap , final Set < String > onlyPostParameters ) { } }

implementation: if ( ! "POST" . equals ( method ) ) { Set < String > names = parameterMap . keySet ( ) ; for ( String onlyPostParameter : onlyPostParameters ) { if ( names . contains ( onlyPostParameter ) ) { FilterUtils . logException ( LOGGER , new IllegalArgumentException ( onlyPostParameter + " parameter should only be used in POST requests" ) ) ; } } }


signature:
public class Vector2f { /** * Gets the direction vector of a certain angle in radians .
 * @ param angle in radians
 * @ return the direction vector */
public static Vector2f createDirectionRad ( float angle ) { } }

implementation: return new Vector2f ( TrigMath . cos ( angle ) , TrigMath . sin ( angle ) ) ;


signature:
public class Vector3f { /** * Gets the direction vector of a random pitch and yaw using the random specified .
 * @ param random to use
 * @ return the random direction vector */
public static Vector3f createRandomDirection ( Random random ) { } }

implementation: return createDirectionRad ( random . nextFloat ( ) * ( float ) TrigMath . TWO_PI , random . nextFloat ( ) * ( float ) TrigMath . TWO_PI ) ;


signature:
public class Vector3f { /** * Gets the direction vector of a certain theta and phi in degrees . This uses the standard math spherical coordinate system .
 * @ param theta in degrees
 * @ param phi in degrees
 * @ return the direction vector */
public static Vector3f createDirectionDeg ( float theta , float phi ) { } }

implementation: return createDirectionRad ( ( float ) Math . toRadians ( theta ) , ( float ) Math . toRadians ( phi ) ) ;


signature:
public class Vector3f { /** * Gets the direction vector of a certain theta and phi in radians . This uses the standard math spherical coordinate system .
 * @ param theta in radians
 * @ param phi in radians
 * @ return the direction vector */
public static Vector3f createDirectionRad ( float theta , float phi ) { } }

implementation: final float f = TrigMath . sin ( phi ) ; return new Vector3f ( f * TrigMath . cos ( theta ) , f * TrigMath . sin ( theta ) , TrigMath . cos ( phi ) ) ;


signature:
public class GenericMath { /** * Wraps the radian between - PI and PI
 * @ param angle to wrap
 * @ return - PI < radian < = PI */
public static double wrapAngleRad ( double angle ) { } }

implementation: angle %= TrigMath . TWO_PI ; if ( angle <= - TrigMath . PI ) { return angle + TrigMath . TWO_PI ; } if ( angle > TrigMath . PI ) { return angle - TrigMath . TWO_PI ; } return angle ;


signature:
public class GenericMath { /** * Rounds a number to the amount of decimals specified
 * @ param input to round
 * @ param decimals to round to
 * @ return the rounded number */
public static double round ( double input , int decimals ) { } }

implementation: final double p = Math . pow ( 10 , decimals ) ; return Math . round ( input * p ) / p ;


signature:
public class GenericMath { /** * Calculates the linear interpolation between a and b with the given percent
 * @ param a The first know value
 * @ param b The second know value
 * @ param percent The percent
 * @ return the interpolated vector */
public static Vector3f lerp ( Vector3f a , Vector3f b , float percent ) { } }

implementation: return a . mul ( 1 - percent ) . add ( b . mul ( percent ) ) ;


signature:
public class GenericMath { /** * Calculates the linear interpolation between a and b with the given percent
 * @ param a The first know value
 * @ param b The second know value
 * @ param percent The percent
 * @ return the interpolated vector */
public static Vector3d lerp ( Vector3d a , Vector3d b , double percent ) { } }


signature:
public class GenericMath { /** * Calculates the linear interpolation between a and b with the given percent
 * @ param a The first know value
 * @ param b The second know value
 * @ param percent The percent
 * @ return the interpolated vector */
public static Vector2f lerp ( Vector2f a , Vector2f b , float percent ) { } }


signature:
public class GenericMath { /** * Calculates the linear interpolation between a and b with the given percent
 * @ param a The first know value
 * @ param b The second know value
 * @ param percent The percent
 * @ return the interpolated vector */
public static Vector2d lerp ( Vector2d a , Vector2d b , double percent ) { } }


signature:
public class GenericMath { /** * Calculates the value at x using linear interpolation
 * @ param x the X coord of the value to interpolate
 * @ param x1 the X coord of q0
 * @ param x2 the X coord of q1
 * @ param q0 the first known value ( x1)
 * @ param q1 the second known value ( x2)
 * @ return the interpolated value */
public static double lerp ( double x , double x1 , double x2 , double q0 , double q1 ) { } }


signature:
public class GenericMath { /** * Calculates the linear interpolation between a and b with the given percent
 * @ param a The first know value
 * @ param b The second know value
 * @ param percent The percent
 * @ return Color */
public static Color lerp ( Color a , Color b , float percent ) { } }

implementation: int red = ( int ) lerp ( a . getRed ( ) , b . getRed ( ) , percent ) ; int blue = ( int ) lerp ( a . getBlue ( ) , b . getBlue ( ) , percent ) ; int green = ( int ) lerp ( a . getGreen ( ) , b . getGreen ( ) , percent ) ; int alpha = ( int ) lerp ( a . getAlpha ( ) , b . getAlpha ( ) , percent ) ; return new Color ( red , green , blue , alpha ) ;