signature:
public class TaskScheduler { /** * Schedule a list of task requests by using any newly - added resource leases in addition to any
 * previously - unused leases . This is the main scheduling method that attempts to assign resources to task
 * requests . Resource leases are associated with a host name . A host can have zero or more leases . Leases
 * that the scheduler does not use in this scheduling run it stores for later use until they expire .
 * You cannot add a lease object with an Id equal to that of a stored lease object ; { @ code scheduleOnce ( ) }
 * will throw an { @ code IllegalStateException } . Upon throwing this exception , if you provided multiple
 * leases in the { @ code newLeases } argument , the state of internally maintained list of unused leases will
 * be in an indeterminate state - some of the leases may have been successfully added .
 * The task scheduler rejects any expired leases before scheduling begins . Then , it combines all leases of a
 * host to determine the total available resources on the host . The scheduler then tries each task request ,
 * in the order that they appear in the given list , for assignment against the available hosts until
 * successful . For each task the scheduler returns either a successful assignment result , or , a set of
 * assignment failures .
 * After the scheduler evaluates all assignments , it will reject remaining leases if they are unused and
 * their offer time is further in the past than lease expiration interval . This prevents the scheduler from
 * hoarding leases . If you provided an autoscaler , the scheduler then launches autoscale evaluation to run
 * asynchronously , which runs each registered autoscale rule based on its policy .
 * The successful assignments contain hosts to which tasks have been successfully assigned and the offers for that
 * host that were used for the assignments . Fenzo removes those offers from its internal state . Normally , you
 * would use those offers to launch the tasks . For any reason if you do not launch those tasks , you must either
 * reject the offers to Mesos , or , re - add them to Fenzo with the next call to { @ link # scheduleOnce ( List , List ) } .
 * Otherwise , those offers would be " leaked out " .
 * Unexpected exceptions may arise during scheduling , for example , due to uncaught exceptions in user provided
 * plugins . The scheduling routine stops upon catching any unexpected exceptions . These exceptions are surfaced to
 * you in one or both of two ways .
 * < UL >
 * < li > The returned result object will contain the exceptions encountered in
 * { @ link SchedulingResult # getExceptions ( ) } . In this case , no assignments would have been made . < / li >
 * < li > This method may throw { @ code IllegalStateException } with its cause set to the uncaught exception . In this
 * case the internal state of Fenzo will be undefined . < / li >
 * < / UL >
 * If there are exceptions , the internal state of Fenzo may be corrupt with no way to undo any partial effects .
 * @ param requests a list of task requests to match with resources , in their given order
 * @ param newLeases new resource leases from hosts that the scheduler can use along with any previously
 * ununsed leases
 * @ return a { @ link SchedulingResult } object that contains a task assignment results map and other summaries
 * @ throws IllegalStateException if you call this method concurrently , or , if you try to add an existing lease
 * again , or , if there was unexpected exception during the scheduling iteration , or , if using
 * { @ link TaskSchedulingService } , which will instead invoke scheduling from within . Unexpected exceptions
 * can arise from uncaught exceptions in user defined plugins . It is also thrown if the scheduler has been shutdown
 * via the { @ link # shutdown ( ) } method . */
public SchedulingResult scheduleOnce ( List < ? extends TaskRequest > requests , List < VirtualMachineLease > newLeases ) throws IllegalStateException { } }

implementation: if ( usingSchedulingService ) { throw new IllegalStateException ( usingSchedSvcMesg ) ; } final Iterator < ? extends TaskRequest > iterator = requests != null ? requests . iterator ( ) : Collections . < TaskRequest > emptyIterator ( ) ; TaskIterator taskIterator = ( ) -> { if ( iterator . hasNext ( ) ) { return Assignable . success ( iterator . next ( ) ) ; } return null ; } ; return scheduleOnce ( taskIterator , newLeases ) ;


signature:
public class TaskScheduler { /** * / * package */
SchedulingResult scheduleOnce ( TaskIterator taskIterator , List < VirtualMachineLease > newLeases ) throws IllegalStateException { } }

implementation: checkIfShutdown ( ) ; try ( AutoCloseable ignored = stateMonitor . enter ( ) ) { return doScheduling ( taskIterator , newLeases ) ; } catch ( Exception e ) { logger . error ( "Error with scheduling run: " + e . getMessage ( ) , e ) ; if ( e instanceof IllegalStateException ) { throw ( IllegalStateException ) e ; } else { logger . warn ( "Unexpected exception: " + e . getMessage ( ) ) ; throw new IllegalStateException ( "Unexpected exception during scheduling run: " + e . getMessage ( ) , e ) ; } }


signature:
public class TaskScheduler { /** * / * package */
Map < String , List < String > > createPseudoHosts ( Map < String , Integer > groupCounts ) { } }

implementation: return assignableVMs . createPseudoHosts ( groupCounts , autoScaler == null ? name -> null : autoScaler :: getRule ) ;


signature:
public class TaskScheduler { /** * Returns the state of resources on all known hosts . You can use this for debugging or informational
 * purposes ( occasionally ) . This method obtains and holds a lock for the duration of creating the state
 * information . Scheduling runs are blocked around the lock .
 * @ return a Map of state information with the hostname as the key and a Map of resource state as the value .
 * The resource state Map contains a resource as the key and a two element Double array - the first
 * element of which contains the amount of the resource used and the second element contains the
 * amount still available ( available does not include used ) .
 * @ throws IllegalStateException if called concurrently with { @ link # scheduleOnce ( List , List ) } or if called when
 * using a { @ link TaskSchedulingService } .
 * @ see < a href = " https : / / github . com / Netflix / Fenzo / wiki / Insights # how - to - learn - which - resources - are - available - on - which - hosts " > How to Learn Which Resources Are Available on Which Hosts < / a > */
public Map < String , Map < VMResource , Double [ ] > > getResourceStatus ( ) throws IllegalStateException { } }

implementation: if ( usingSchedulingService ) { throw new IllegalStateException ( usingSchedSvcMesg ) ; } return getResourceStatusIntl ( ) ;


signature:
public class TaskScheduler { /** * / * package */
Map < String , Map < VMResource , Double [ ] > > getResourceStatusIntl ( ) { } }

implementation: try ( AutoCloseable ignored = stateMonitor . enter ( ) ) { return assignableVMs . getResourceStatus ( ) ; } catch ( Exception e ) { logger . error ( "Unexpected error from state monitor: " + e . getMessage ( ) ) ; throw new RuntimeException ( e ) ; }


signature:
public class TaskScheduler { /** * / * package */
List < VirtualMachineCurrentState > getVmCurrentStatesIntl ( ) throws IllegalStateException { } }

implementation: try ( AutoCloseable ignored = stateMonitor . enter ( ) ) { return assignableVMs . getVmCurrentStates ( ) ; } catch ( Exception e ) { logger . error ( "Unexpected error from state monitor: " + e . getMessage ( ) , e ) ; throw new IllegalStateException ( e ) ; }


signature:
public class TaskScheduler { /** * Call this method to instruct the task scheduler to reject all of the unused offers it is currently
 * holding that concern resources offered by the host with the ID , { @ code vmId } .
 * @ param vmId the ID of the host whose leases you want to expire
 * @ return { @ code true } if the given ID matches a known host , { @ code false } otherwise .
 * @ throws IllegalStateException if the scheduler is shutdown via the { @ link # isShutdown } method . */
public boolean expireAllLeasesByVMId ( String vmId ) throws IllegalStateException { } }

implementation: final String hostname = assignableVMs . getHostnameFromVMId ( vmId ) ; if ( hostname == null ) { return false ; } expireAllLeases ( hostname ) ; return true ;


signature:
public class TaskScheduler { /** * / * package */
Action2 < TaskRequest , String > getTaskAssignerIntl ( ) throws IllegalStateException { } }

implementation: return ( request , hostname ) -> { try ( AutoCloseable ignored = stateMonitor . enter ( ) ) { assignableVMs . setTaskAssigned ( request , hostname ) ; } catch ( Exception e ) { logger . error ( "Unexpected error from state monitor: " + e . getMessage ( ) , e ) ; throw new IllegalStateException ( e ) ; } } ;


signature:
public class TaskScheduler { /** * Disable the virtual machine with the specified hostname . The scheduler will not use disabled hosts for
 * allocating resources to tasks .
 * @ param hostname the name of the host to disable
 * @ param durationMillis the length of time , starting from now , in milliseconds , during which the host will
 * be disabled
 * @ throws IllegalStateException if the scheduler is shutdown via the { @ link # isShutdown } method . */
public void disableVM ( String hostname , long durationMillis ) throws IllegalStateException { } }

implementation: logger . debug ( "Disable VM " + hostname + " for " + durationMillis + " millis" ) ; assignableVMs . disableUntil ( hostname , System . currentTimeMillis ( ) + durationMillis ) ;


signature:
public class TaskScheduler { /** * Disable the virtual machine with the specified ID . The scheduler will not use disabled hosts for allocating
 * resources to tasks .
 * @ param vmID the ID of the host to disable
 * @ param durationMillis the length of time , starting from now , in milliseconds , during which the host will
 * be disabled
 * @ return { @ code true } if the ID matches a known VM , { @ code false } otherwise .
 * @ throws IllegalStateException if the scheduler is shutdown via the { @ link # isShutdown } method . */
public boolean disableVMByVMId ( String vmID , long durationMillis ) throws IllegalStateException { } }

implementation: final String hostname = assignableVMs . getHostnameFromVMId ( vmID ) ; if ( hostname == null ) { return false ; } disableVM ( hostname , durationMillis ) ; return true ;


signature:
public class TaskScheduler { /** * Enable the VM with the specified host name . Hosts start in an enabled state , so you only need to call
 * this method if you have previously explicitly disabled the host .
 * @ param hostname the name of the host to enable
 * @ throws IllegalStateException if the scheduler is shutdown via the { @ link # isShutdown } method . */
public void enableVM ( String hostname ) throws IllegalStateException { } }

implementation: logger . debug ( "Enabling VM " + hostname ) ; assignableVMs . enableVM ( hostname ) ;


signature:
public class TaskScheduler { /** * Mark task scheduler as shutdown and shutdown any thread pool executors created . */
public void shutdown ( ) { } }

implementation: if ( isShutdown . compareAndSet ( false , true ) ) { executorService . shutdown ( ) ; if ( autoScaler != null ) { autoScaler . shutdown ( ) ; } }


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ param group
 * @ param id
 * @ param type */
protected void create ( String group , String id , T type ) { } }

implementation: ConcurrentMap < String , T > subMap = new ConcurrentHashMap < String , T > ( ) ; subMap . put ( id , type ) ; Map existingTriggerMap = map . putIfAbsent ( group , subMap ) ; if ( existingTriggerMap != null ) { synchronized ( map ) { map . get ( group ) . put ( id , type ) ; } }


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ param group
 * @ param id
 * @ param type */
protected void update ( String group , String id , T type ) { } }

implementation: synchronized ( map ) { map . get ( group ) . put ( id , type ) ; }


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ param group
 * @ param id
 * @ return */
protected T read ( String group , String id ) { } }

implementation: ConcurrentMap < String , T > subMap = map . get ( group ) ; for ( Iterator < String > iterator2 = subMap . keySet ( ) . iterator ( ) ; iterator2 . hasNext ( ) ; ) { String storedId = iterator2 . next ( ) ; if ( id . equals ( storedId ) ) { return subMap . get ( id ) ; } } return null ;


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ param group
 * @ param id */
protected void delete ( String group , String id ) { } }

implementation: synchronized ( map ) { map . get ( group ) . remove ( id ) ; }


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ param group
 * @ param count
 * @ return */
protected List < T > list ( String group , int count ) { } }

implementation: List < T > items = list ( group ) ; return items . size ( ) > count ? items . subList ( 0 , count ) : items ;


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter group description missing
 * @ param group
 * @ return */
protected List < T > list ( String group ) { } }

implementation: return map . get ( group ) != null ? new ArrayList < T > ( map . get ( group ) . values ( ) ) : new ArrayList < T > ( ) ;


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ return */
protected List < T > list ( ) { } }

implementation: List < T > items = new ArrayList < > ( ) ; for ( Iterator < String > iterator = map . keySet ( ) . iterator ( ) ; iterator . hasNext ( ) ; ) { items . addAll ( map . get ( iterator . next ( ) ) . values ( ) ) ; } return items ;


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter descriptions missing
 * @ warn exception IllegalArgumentException description missing
 * @ param group
 * @ param id
 * @ return
 * @ throws IllegalArgumentException */
protected String createId ( String group , String id ) { } }

implementation: if ( group == null || id == null || group . contains ( idSeparator ) || id . contains ( idSeparator ) ) { throw new IllegalArgumentException ( String . format ( "Illegal arguments specified for column name creation (group = %s, id = %s)" , group , id ) ) ; } return String . format ( "%s%s%s" , group , idSeparator , id ) ;


signature:
public class AbstractInMemoryDao { /** * @ warn method description missing
 * @ warn parameter columnName description missing
 * @ warn exception IllegalArgumentException description missing
 * @ param columnName
 * @ return
 * @ throws IllegalArgumentException */
protected String extractGroupFromId ( String columnName ) { } }

implementation: if ( columnName == null || ! columnName . contains ( idSeparator ) ) return columnName ; String [ ] tokens = columnName . split ( idSeparator ) ; if ( tokens . length == 2 ) { return tokens [ 0 ] ; } else { throw new IllegalArgumentException ( String . format ( "Cannot extract row key from column name string: %s" , columnName ) ) ; }


signature:
public class AsSoftConstraint { /** * Returns a " soft " constraint , in the form of a { @ link VMTaskFitnessCalculator } , based on a specified " hard "
 * constraint , in the form of a { @ link ConstraintEvaluator } .
 * @ param c the " hard " constraint to convert
 * @ return a " soft " constraint version of { @ code c } */
public static VMTaskFitnessCalculator get ( final ConstraintEvaluator c ) { } }

implementation:
// This fitness calculator return 0 or 1 . This can possibly be improved upon by the ConstraintEvaluator using its
// own logic .
return new VMTaskFitnessCalculator ( ) { @ Override public String getName ( ) { return c . getName ( ) ; } @ Override public double calculateFitness ( TaskRequest taskRequest , VirtualMachineCurrentState targetVM , TaskTrackerState taskTrackerState ) { return c . evaluate ( taskRequest , targetVM , taskTrackerState ) . isSuccessful ( ) ? 1.0 : 0.0 ; } } ;


signature:
public class Entity { /** * Check if this entity contains all of the given properties .
 * @ param properties Names of the properties
 * @ return True , if and only if the given properties are present in this entity */
public boolean hasProperties ( String ... properties ) { } }

implementation: for ( String property : properties ) { if ( ! hasProperty ( property ) ) { return false ; } } return true ;


signature:
public class Clarity { /** * Retrieves summary - data from the given input source
 * @ param source the { @ code Source } providing the replay data
 * @ return the { @ code CDemoFileInfo } protobuf message
 * @ throws IOException if the given source is invalid
 * @ see Source */
public static Demo . CDemoFileInfo infoForSource ( final Source source ) throws IOException { } }

implementation: EngineType engineType = source . readEngineType ( ) ; source . setPosition ( source . readFixedInt32 ( ) ) ; PacketInstance < GeneratedMessage > pi = engineType . getNextPacketInstance ( source ) ; return ( Demo . CDemoFileInfo ) pi . parse ( ) ;


signature:
public class Clarity { /** * reads a metadata stream and returns it ' s contents
 * @ param stream an { @ code InputStream } , containing replay data , positioned at the beginning
 * @ return the { @ code CDOTAMatchMetadataFile } protobuf message
 * @ throws IOException if the given stream is invalid */
private static S2DotaMatchMetadata . CDOTAMatchMetadataFile metadataForStream ( InputStream stream ) throws IOException { } }

implementation: return Packet . parse ( S2DotaMatchMetadata . CDOTAMatchMetadataFile . class , ByteString . readFrom ( stream ) ) ;


signature:
public class CsGoEngineType { /** * alternative to 6 ? Similar to dota ? */
private byte [ ] readPacket ( Source source ) throws IOException { } }

implementation: int size = source . readFixedInt32 ( ) ; return packetReader . readFromSource ( source , size , false ) ;


signature:
public class Source { /** * reads a variable int32 from the current position
 * @ return the int
 * @ throws IOException if the data cannot be read , or is not a valid variable int32 */
public int readVarInt32 ( ) throws IOException { } }

implementation: byte tmp = readByte ( ) ; if ( tmp >= 0 ) { return tmp ; } int result = tmp & 0x7f ; if ( ( tmp = readByte ( ) ) >= 0 ) { result |= tmp << 7 ; } else { result |= ( tmp & 0x7f ) << 7 ; if ( ( tmp = readByte ( ) ) >= 0 ) { result |= tmp << 14 ; } else { result |= ( tmp & 0x7f ) << 14 ; if ( ( tmp = readByte ( ) ) >= 0 ) { result |= tmp << 21 ; } else { result |= ( tmp & 0x7f ) << 21 ; result |= ( tmp = readByte ( ) ) << 28 ; if ( tmp < 0 ) { throw new IOException ( "malformed varint detected" ) ; } } } } return result ;


signature:
public class Source { /** * reads a fixed int32 from the current position
 * @ return the int
 * @ throws IOException if the data cannot be read */
public int readFixedInt32 ( ) throws IOException { } }

implementation: return ByteBuffer . wrap ( readBytes ( 4 ) ) . order ( ByteOrder . LITTLE_ENDIAN ) . asIntBuffer ( ) . get ( ) ;


signature:
public class Source { /** * reads the magic of a demo file , identifying the engine type
 * @ throws IOException if there is not enough data or the if no valid magic was found */
public EngineType readEngineType ( ) throws IOException { } }

implementation: try { engineType = EngineId . typeForMagic ( new String ( readBytes ( 8 ) ) ) ; if ( engineType == null ) { throw new IOException ( ) ; } return engineType ; } catch ( IOException e ) { throw new IOException ( "given stream does not seem to contain a valid replay" ) ; }


signature:
public class ContainerTag { /** * Appends a DomContent - object to the end of this element
 * @ param child DomContent - object to be appended
 * @ return itself for easy chaining */
public ContainerTag with ( DomContent child ) { } }

implementation:
if ( this == child ) { throw new RuntimeException ( "Cannot append a tag to itself." ) ; } if ( child == null ) { return this ; // in some cases , like when using iff ( ) , we ignore null children
} children . add ( child ) ; return this ;


signature:
public class ContainerTag { /** * Appends a list of DomContent - objects to the end of this element
 * @ param children DomContent - objects to be appended
 * @ return itself for easy chaining */
public ContainerTag with ( Iterable < ? extends DomContent > children ) { } }

implementation: if ( children != null ) { for ( DomContent child : children ) { this . with ( child ) ; } } return this ;


signature:
public class TagCreator { /** * Generic if - expression to if ' ing inside method calls
 * @ param optional The item that may be present
 * @ param ifFunction The function that will be called if that optional is present
 * @ param < T > The derived generic parameter type
 * @ param < U > The supplying generic parameter type
 * @ return transformed value if condition is true , null otherwise */
@ SuppressWarnings ( "OptionalUsedAsFieldOrParameterType" ) public static < T , U > T iff ( Optional < U > optional , Function < U , T > ifFunction ) { } }

implementation: if ( Objects . nonNull ( optional ) && optional . isPresent ( ) ) { return optional . map ( ifFunction ) . orElse ( null ) ; } return null ;


signature:
public class TagCreator { /** * Like { @ link j2html . TagCreator # iff } , but returns else - value instead of null */
public static < T > T iffElse ( boolean condition , T ifValue , T elseValue ) { } }

implementation: return condition ? ifValue : elseValue ;


signature:
public class TagCreator { /** * Creates a DomContent object containing HTML using a mapping function on a collection
 * Intended usage : { @ literal each ( numbers , n - > li ( n . toString ( ) ) ) }
 * @ param < T > The derived generic parameter type
 * @ param collection the collection to iterate over , ex : a list of values " 1 , 2 , 3"
 * @ param mapper the mapping function , ex : { @ literal " n - > li ( n . toString ( ) ) " }
 * @ return DomContent containing mapped data { @ literal ( ex . docs : [ li ( 1 ) , li ( 2 ) , li ( 3 ) ] ) } */
public static < T > DomContent each ( Collection < T > collection , Function < ? super T , DomContent > mapper ) { } }

implementation: return tag ( null ) . with ( collection . stream ( ) . map ( mapper ) ) ;


signature:
public class TagCreator { /** * Creates a DomContent object containing HTML using a mapping function on a map
 * Intended usage : { @ literal each ( idsToNames , ( id , name ) - > li ( id + " " + name ) ) }
 * @ param < I > The type of the keys
 * @ param < T > The type of the values
 * @ param map the map to iterate over , ex : a map of values { 1 : " Tom " , 2 : " Dick " , 3 : " Harry " }
 * @ param mapper the mapping function , ex : { @ literal " ( id , name ) - > li ( id + " " + name ) " }
 * @ return DomContent containing mapped data { @ literal ( ex . docs : [ li ( 1 Tom ) , li ( 2 Dick ) , li ( 3 Harry ) ] ) } */
public static < I , T > DomContent each ( final Map < I , T > map , final BiFunction < I , T , DomContent > mapper ) { } }

implementation: return rawHtml ( map . entrySet ( ) . stream ( ) . map ( entry -> mapper . andThen ( DomContent :: render ) . apply ( entry . getKey ( ) , entry . getValue ( ) ) ) . collect ( Collectors . joining ( ) ) ) ;


signature:
public class TagCreator { /** * Filters a collection to a list , to be used with { @ link j2html . TagCreator # each }
 * Intended usage : { @ literal each ( filter ( numbers , n - > n % 2 = = 0 ) , n - > li ( n . toString ( ) ) ) }
 * @ param < T > The derived generic parameter type
 * @ param collection the collection to filter , ex : a list of values " 1 , 2 , 3"
 * @ param filter the filter predicate , { @ literal ex : " n - > n % 2 = = 0 " }
 * @ return the filtered collection as a list ( ex . docs : 2) */
public static < T > List < T > filter ( Collection < T > collection , Predicate < ? super T > filter ) { } }

implementation: return collection . stream ( ) . filter ( filter ) . collect ( Collectors . toList ( ) ) ;


signature:
public class TagCreator { /** * Return a complete html document string
 * @ param htmlTag the html content of a website
 * @ return document declaration and rendered html content */
public static String document ( ContainerTag htmlTag ) { } }

implementation: if ( htmlTag . getTagName ( ) . equals ( "html" ) ) { return document ( ) . render ( ) + htmlTag . render ( ) ; } throw new IllegalArgumentException ( "Only HTML-tag can follow document declaration" ) ;


signature:
public class Tag { /** * Sets an attribute on an element
 * @ param name the attribute
 * @ param value the attribute value */
boolean setAttribute ( String name , String value ) { } }

implementation:
if ( value == null ) { return attributes . add ( new Attribute ( name ) ) ; } for ( Attribute attribute : attributes ) { if ( attribute . getName ( ) . equals ( name ) ) { attribute . setValue ( value ) ; // update with new value
return true ; } } return attributes . add ( new Attribute ( name , value ) ) ;


signature:
public class Tag { /** * Sets a custom attribute
 * @ param attribute the attribute name
 * @ param value the attribute value
 * @ return itself for easy chaining */
public T attr ( String attribute , Object value ) { } }

implementation: setAttribute ( attribute , value == null ? null : String . valueOf ( value ) ) ; return ( T ) this ;


signature:
public class Tag { /** * Adds the specified attribute . If the Tag previously contained an attribute with the same name , the old attribute is replaced by the specified attribute .
 * @ param attribute the attribute
 * @ return itself for easy chaining */
public T attr ( Attribute attribute ) { } }

implementation:
Iterator < Attribute > iterator = attributes . iterator ( ) ; String name = attribute . getName ( ) ; if ( name != null ) { // name = = null is allowed , but those Attributes are not rendered . So we add them anyway .
while ( iterator . hasNext ( ) ) { Attribute existingAttribute = iterator . next ( ) ; if ( existingAttribute . getName ( ) . equals ( name ) ) { iterator . remove ( ) ; } } } attributes . add ( attribute ) ; return ( T ) this ;


signature:
public class Tag { /** * Call attr - method based on condition
 * { @ link # attr ( String attribute , Object value ) }
 * @ param condition the condition
 * @ param attribute the attribute name
 * @ param value the attribute value
 * @ return itself for easy chaining */
public T condAttr ( boolean condition , String attribute , String value ) { } }

implementation: return ( condition ? attr ( attribute , value ) : ( T ) this ) ;


signature:
public class Tag { /** * Convenience methods that call attr with predefined attributes
 * @ return itself for easy chaining */
public T withClasses ( String ... classes ) { } }

implementation: StringBuilder sb = new StringBuilder ( ) ; for ( String s : classes ) { sb . append ( s != null ? s : "" ) . append ( " " ) ; } return attr ( Attr . CLASS , sb . toString ( ) . trim ( ) ) ;


signature:
public class JSMin { /** * Compress a JS - string
 * @ param code the js - code you want to compress
 * @ return the compressed code */
public static String compressJs ( String code ) { } }

implementation: InputStream inStream = new ByteArrayInputStream ( code . getBytes ( ) ) ; ByteArrayOutputStream outStream = new ByteArrayOutputStream ( ) ; JSMin jsmin = new JSMin ( inStream , outStream ) ; try { jsmin . jsmin ( ) ; return outStream . toString ( ) . trim ( ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; return "" ; }


signature:
public class JSMin { /** * jsmin - - Copy the input to the output , deleting the characters which are
 * insignificant to JavaScript . Comments will be removed . Tabs will be
 * replaced with spaces . Carriage returns will be replaced with linefeeds .
 * Most spaces and linefeeds will be removed . */
public void jsmin ( ) throws IOException , UnterminatedRegExpLiteralException , UnterminatedCommentException , UnterminatedStringLiteralException { } }

implementation: theA = '\n' ; action ( 3 ) ; while ( theA != EOF ) { switch ( theA ) { case ' ' : if ( isAlphanum ( theB ) ) { action ( 1 ) ; } else { action ( 2 ) ; } break ; case '\n' : switch ( theB ) { case '{' : case '[' : case '(' : case '+' : case '-' : action ( 1 ) ; break ; case ' ' : action ( 3 ) ; break ; default : if ( isAlphanum ( theB ) ) { action ( 1 ) ; } else { action ( 2 ) ; } } break ; default : switch ( theB ) { case ' ' : if ( isAlphanum ( theA ) ) { action ( 1 ) ; break ; } action ( 3 ) ; break ; case '\n' : switch ( theA ) { case '}' : case ']' : case ')' : case '+' : case '-' : case '"' : case '\'' : action ( 1 ) ; break ; default : if ( isAlphanum ( theA ) ) { action ( 1 ) ; } else { action ( 3 ) ; } } break ; default : action ( 1 ) ; break ; } } } out . flush ( ) ;


signature:
public class CSSMin { /** * Minify supplied CSS .
 * @ param input the CSS
 * @ return the compressed version */
public static String compressCss ( String input ) { } }

implementation:
try { int k , j , // Number of open braces
n ; // Current position in stream
char curr ; BufferedReader br = new BufferedReader ( new StringReader ( input ) ) ; StringBuilder sb = new StringBuilder ( ) ; if ( debugLogging ) { LOG . info ( "Reading file into StringBuffer..." ) ; } String s ; while ( ( s = br . readLine ( ) ) != null ) { if ( s . trim ( ) . equals ( "" ) ) { continue ; } sb . append ( s ) ; } if ( debugLogging ) { LOG . info ( "Removing comments..." ) ; } // Find the start of the comment
n = 0 ; while ( ( n = sb . indexOf ( "/*" , n ) ) != - 1 ) { if ( sb . charAt ( n + 2 ) == '*' ) { // Retain special comments
n += 2 ; continue ; } k = sb . indexOf ( "*/" , n + 2 ) ; if ( k == - 1 ) { throw new UnterminatedCommentException ( ) ; } sb . delete ( n , k + 2 ) ; } if ( debugLogging ) { LOG . info ( sb . toString ( ) ) ; LOG . info ( "\n\n" ) ; } if ( debugLogging ) { LOG . info ( "Parsing and processing selectors..." ) ; } Vector < Selector > selectors = new Vector < > ( ) ; n = 0 ; j = 0 ; for ( int i = 0 ; i < sb . length ( ) ; i ++ ) { curr = sb . charAt ( i ) ; if ( j < 0 ) { throw new UnbalancedBracesException ( ) ; } if ( curr == '{' ) { j ++ ; } else if ( curr == '}' ) { j -- ; if ( j == 0 ) { try { selectors . addElement ( new Selector ( sb . substring ( n , i + 1 ) ) ) ; } catch ( UnterminatedSelectorException usex ) { LOG . warning ( "Unterminated selector: " + usex . getMessage ( ) ) ; } catch ( EmptySelectorBodyException ebex ) { if ( debugLogging ) { LOG . warning ( "Empty selector body: " + ebex . getMessage ( ) ) ; } } n = i + 1 ; } } } StringBuilder result = new StringBuilder ( ) ; for ( Selector selector : selectors ) { result . append ( selector ) ; } if ( debugLogging ) { LOG . info ( "Process completed successfully." ) ; } return result . toString ( ) ; } catch ( UnterminatedCommentException ucex ) { LOG . warning ( "Unterminated comment." ) ; } catch ( UnbalancedBracesException ubex ) { LOG . warning ( "Unbalanced braces." ) ; } catch ( Exception ex ) { LOG . warning ( ex . getMessage ( ) ) ; } return null ;


signature:
public class Selector { /** * Parses out the properties of a selector ' s body .
 * @ param contents The body ; for example , " border : solid 1px red ; color : blue ; "
 * @ return An array of properties parsed from this selector . */
private ArrayList < Property > parseProperties ( String contents ) { } }

implementation:
ArrayList < String > parts = new ArrayList < > ( ) ; boolean bInsideString = false , bInsideURL = false ; int j = 0 ; String substr ; for ( int i = 0 ; i < contents . length ( ) ; i ++ ) { if ( bInsideString ) { // If we ' re inside a string
bInsideString = ! ( contents . charAt ( i ) == '"' ) ; } else if ( bInsideURL ) { // If we ' re inside a URL
bInsideURL = ! ( contents . charAt ( i ) == ')' ) ; } else if ( contents . charAt ( i ) == '"' ) { bInsideString = true ; } else if ( contents . charAt ( i ) == '(' ) { if ( ( i - 3 ) > 0 && "url" . equals ( contents . substring ( i - 3 , i ) ) ) { bInsideURL = true ; } } else if ( contents . charAt ( i ) == ';' ) { substr = contents . substring ( j , i ) ; if ( ! ( substr . trim ( ) . equals ( "" ) ) ) { parts . add ( substr ) ; } j = i + 1 ; } } substr = contents . substring ( j , contents . length ( ) ) ; if ( ! ( substr . trim ( ) . equals ( "" ) ) ) { parts . add ( substr ) ; } ArrayList < Property > results = new ArrayList < > ( ) ; for ( String part : parts ) { try { results . add ( new Property ( part ) ) ; } catch ( IncompletePropertyException ipex ) { LOG . warning ( "Incomplete property in selector \"" + this . selector + "\": \"" + ipex . getMessage ( ) + "\"" ) ; } } return results ;


signature:
public class Property { /** * Parse the values out of a property .
 * @ param contents The property to parse
 * @ return An array of Parts */
private Part [ ] parseValues ( String contents ) { } }

implementation: String [ ] parts = contents . split ( "," ) ; Part [ ] results = new Part [ parts . length ] ; for ( int i = 0 ; i < parts . length ; i ++ ) { try { results [ i ] = new Part ( parts [ i ] , property ) ; } catch ( Exception e ) { LOG . warning ( e . getMessage ( ) ) ; results [ i ] = null ; } } return results ;


signature:
public class Property { /** * Convert rgb ( 51,102,153 ) to # 336699 ( this code largely based on YUI code ) */
private String simplifyRGBColours ( String contents ) { } }

implementation: StringBuffer newContents = new StringBuffer ( ) ; StringBuffer hexColour ; String [ ] rgbColours ; int colourValue ; Pattern pattern = Pattern . compile ( "rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)" ) ; Matcher matcher = pattern . matcher ( contents ) ; while ( matcher . find ( ) ) { hexColour = new StringBuffer ( "#" ) ; rgbColours = matcher . group ( 1 ) . split ( "," ) ; for ( String rgbColour : rgbColours ) { colourValue = Integer . parseInt ( rgbColour ) ; if ( colourValue < 16 ) { hexColour . append ( "0" ) ; } hexColour . append ( Integer . toHexString ( colourValue ) ) ; } matcher . appendReplacement ( newContents , hexColour . toString ( ) ) ; } matcher . appendTail ( newContents ) ; return newContents . toString ( ) ;


signature:
public class MenuView { /** * Resets the the view to fit into a new
 * available width .
 * < p > This clears and then re - inflates the menu items
 * , removes all of its associated action views , and re - creates
 * the menu and action items to fit in the new width . < / p >
 * @ param availWidth the width available for the menu to use . If
 * there is room , menu items that are flagged with
 * android : showAsAction = " ifRoom " or android : showAsAction = " always "
 * will show as actions . */
public void reset ( int menu , int availWidth ) { } }

implementation:
mMenu = menu ; if ( mMenu == - 1 ) { return ; } mActionShowAlwaysItems = new ArrayList < > ( ) ; mActionItems = new ArrayList < > ( ) ; mMenuItems = new ArrayList < > ( ) ; mMenuBuilder = new MenuBuilder ( getContext ( ) ) ; mMenuPopupHelper = new MenuPopupHelper ( getContext ( ) , mMenuBuilder , this ) ; // clean view and re - inflate
removeAllViews ( ) ; getMenuInflater ( ) . inflate ( mMenu , mMenuBuilder ) ; mMenuItems = mMenuBuilder . getActionItems ( ) ; mMenuItems . addAll ( mMenuBuilder . getNonActionItems ( ) ) ; Collections . sort ( mMenuItems , new Comparator < MenuItemImpl > ( ) { @ Override public int compare ( MenuItemImpl lhs , MenuItemImpl rhs ) { return ( ( Integer ) lhs . getOrder ( ) ) . compareTo ( rhs . getOrder ( ) ) ; } } ) ; List < MenuItemImpl > localActionItems = filter ( mMenuItems , new MenuItemImplPredicate ( ) { @ Override public boolean apply ( MenuItemImpl menuItem ) { return menuItem . getIcon ( ) != null && ( menuItem . requiresActionButton ( ) || menuItem . requestsActionButton ( ) ) ; } } ) ; int availItemRoom = availWidth / ( int ) ACTION_DIMENSION_PX ; // determine if to show overflow menu
boolean addOverflowAtTheEnd = false ; if ( ( ( localActionItems . size ( ) < mMenuItems . size ( ) ) || availItemRoom < localActionItems . size ( ) ) ) { addOverflowAtTheEnd = true ; availItemRoom -- ; } ArrayList < Integer > actionItemsIds = new ArrayList < > ( ) ; if ( availItemRoom > 0 ) { for ( int i = 0 ; i < localActionItems . size ( ) ; i ++ ) { final MenuItemImpl menuItem = localActionItems . get ( i ) ; if ( menuItem . getIcon ( ) != null ) { ImageView action = createActionView ( ) ; action . setContentDescription ( menuItem . getTitle ( ) ) ; action . setImageDrawable ( menuItem . getIcon ( ) ) ; Util . setIconColor ( action , mActionIconColor ) ; addView ( action ) ; mActionItems . add ( menuItem ) ; actionItemsIds . add ( menuItem . getItemId ( ) ) ; action . setOnClickListener ( new OnClickListener ( ) { @ Override public void onClick ( View v ) { if ( mMenuCallback != null ) { mMenuCallback . onMenuItemSelected ( mMenuBuilder , menuItem ) ; } } } ) ; availItemRoom -- ; if ( availItemRoom == 0 ) { break ; } } } } mHasOverflow = addOverflowAtTheEnd ; if ( addOverflowAtTheEnd ) { ImageView overflowAction = getOverflowActionView ( ) ; overflowAction . setImageResource ( R . drawable . ic_more_vert_black_24dp ) ; Util . setIconColor ( overflowAction , mOverflowIconColor ) ; addView ( overflowAction ) ; overflowAction . setOnClickListener ( new OnClickListener ( ) { @ Override public void onClick ( View v ) { mMenuPopupHelper . show ( ) ; } } ) ; mMenuBuilder . setCallback ( mMenuCallback ) ; } // remove all menu items that will be shown as icons ( the action items ) from the overflow menu
for ( int id : actionItemsIds ) { mMenuBuilder . removeItem ( id ) ; } actionItemsIds = null ; if ( mOnVisibleWidthChangedListener != null ) { mVisibleWidth = ( ( int ) ACTION_DIMENSION_PX * getChildCount ( ) ) - ( mHasOverflow ? Util . dpToPx ( 8 ) : 0 ) ; mOnVisibleWidthChangedListener . onItemsMenuVisibleWidthChanged ( mVisibleWidth ) ; }


signature:
public class MenuView { /** * Hides all the menu items flagged with " ifRoom "
 * @ param withAnim */
public void hideIfRoomItems ( boolean withAnim ) { } }

implementation:
if ( mMenu == - 1 ) { return ; } mActionShowAlwaysItems . clear ( ) ; cancelChildAnimListAndClear ( ) ; List < MenuItemImpl > showAlwaysActionItems = filter ( mMenuItems , new MenuItemImplPredicate ( ) { @ Override public boolean apply ( MenuItemImpl menuItem ) { return menuItem . getIcon ( ) != null && menuItem . requiresActionButton ( ) ; } } ) ; int actionItemIndex ; for ( actionItemIndex = 0 ; actionItemIndex < mActionItems . size ( ) && actionItemIndex < showAlwaysActionItems . size ( ) ; actionItemIndex ++ ) { final MenuItemImpl showAlwaysActionItem = showAlwaysActionItems . get ( actionItemIndex ) ; // reset action item image if needed
if ( mActionItems . get ( actionItemIndex ) . getItemId ( ) != showAlwaysActionItem . getItemId ( ) ) { ImageView action = ( ImageView ) getChildAt ( actionItemIndex ) ; action . setImageDrawable ( showAlwaysActionItem . getIcon ( ) ) ; Util . setIconColor ( action , mOverflowIconColor ) ; action . setOnClickListener ( new OnClickListener ( ) { @ Override public void onClick ( View v ) { if ( mMenuCallback != null ) { mMenuCallback . onMenuItemSelected ( mMenuBuilder , showAlwaysActionItem ) ; } } } ) ; } mActionShowAlwaysItems . add ( showAlwaysActionItem ) ; } final int diff = mActionItems . size ( ) - actionItemIndex + ( mHasOverflow ? 1 : 0 ) ; anims = new ArrayList < > ( ) ; // add anims for moving showAlwaysItem views to the right
for ( int i = 0 ; i < actionItemIndex ; i ++ ) { final View currentChild = getChildAt ( i ) ; final float destTransX = ( ACTION_DIMENSION_PX * diff ) - ( mHasOverflow ? Util . dpToPx ( 8 ) : 0 ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentChild ) . setDuration ( withAnim ? HIDE_IF_ROOM_ITEMS_ANIM_DURATION : 0 ) . setInterpolator ( new AccelerateInterpolator ( ) ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentChild . setTranslationX ( destTransX ) ; } } ) . translationXBy ( destTransX ) . get ( ) ) ; } // add anims for moving to right and / or zooming out previously shown items
for ( int i = actionItemIndex ; i < ( diff + actionItemIndex ) ; i ++ ) { final View currentView = getChildAt ( i ) ; currentView . setClickable ( false ) ; // move to right
if ( i != ( getChildCount ( ) - 1 ) ) { anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . setDuration ( withAnim ? HIDE_IF_ROOM_ITEMS_ANIM_DURATION : 0 ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setTranslationX ( ACTION_DIMENSION_PX ) ; } } ) . translationXBy ( ACTION_DIMENSION_PX ) . get ( ) ) ; } // scale and zoom out
anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . setDuration ( withAnim ? HIDE_IF_ROOM_ITEMS_ANIM_DURATION : 0 ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setScaleX ( 0.5f ) ; } } ) . scaleX ( .5f ) . get ( ) ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . setDuration ( withAnim ? HIDE_IF_ROOM_ITEMS_ANIM_DURATION : 0 ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setScaleY ( 0.5f ) ; } } ) . scaleY ( .5f ) . get ( ) ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . setDuration ( withAnim ? HIDE_IF_ROOM_ITEMS_ANIM_DURATION : 0 ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setAlpha ( 0.0f ) ; } } ) . alpha ( 0.0f ) . get ( ) ) ; } final int actionItemsCount = actionItemIndex ; // finally , run animation
if ( ! anims . isEmpty ( ) ) { AnimatorSet animSet = new AnimatorSet ( ) ; if ( ! withAnim ) { // temporary , from laziness
animSet . setDuration ( 0 ) ; } animSet . playTogether ( anims . toArray ( new ObjectAnimator [ anims . size ( ) ] ) ) ; animSet . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { if ( mOnVisibleWidthChangedListener != null ) { mVisibleWidth = ( ( int ) ACTION_DIMENSION_PX * actionItemsCount ) ; mOnVisibleWidthChangedListener . onItemsMenuVisibleWidthChanged ( mVisibleWidth ) ; } } } ) ; animSet . start ( ) ; }


signature:
public class MenuView { /** * Shows all the menu items that were hidden by hideIfRoomItems ( boolean withAnim )
 * @ param withAnim */
public void showIfRoomItems ( boolean withAnim ) { } }

implementation:
if ( mMenu == - 1 ) { return ; } cancelChildAnimListAndClear ( ) ; if ( mMenuItems . isEmpty ( ) ) { return ; } anims = new ArrayList < > ( ) ; for ( int i = 0 ; i < getChildCount ( ) ; i ++ ) { final View currentView = getChildAt ( i ) ; // reset all the action item views
if ( i < mActionItems . size ( ) ) { ImageView action = ( ImageView ) currentView ; final MenuItem actionItem = mActionItems . get ( i ) ; action . setImageDrawable ( actionItem . getIcon ( ) ) ; Util . setIconColor ( action , mActionIconColor ) ; action . setOnClickListener ( new OnClickListener ( ) { @ Override public void onClick ( View v ) { if ( mMenuCallback != null ) { mMenuCallback . onMenuItemSelected ( mMenuBuilder , actionItem ) ; } } } ) ; } Interpolator interpolator = new DecelerateInterpolator ( ) ; if ( i > ( mActionShowAlwaysItems . size ( ) - 1 ) ) { interpolator = new LinearInterpolator ( ) ; } currentView . setClickable ( true ) ; // simply animate all properties of all action item views back to their default / visible state
anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setTranslationX ( 0 ) ; } } ) . setInterpolator ( interpolator ) . translationX ( 0 ) . get ( ) ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setScaleX ( 1.0f ) ; } } ) . setInterpolator ( interpolator ) . scaleX ( 1.0f ) . get ( ) ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setScaleY ( 1.0f ) ; } } ) . setInterpolator ( interpolator ) . scaleY ( 1.0f ) . get ( ) ) ; anims . add ( ViewPropertyObjectAnimator . animate ( currentView ) . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { currentView . setAlpha ( 1.0f ) ; } } ) . setInterpolator ( interpolator ) . alpha ( 1.0f ) . get ( ) ) ; } if ( anims . isEmpty ( ) ) { return ; } AnimatorSet animSet = new AnimatorSet ( ) ; if ( ! withAnim ) { // temporary , from laziness
animSet . setDuration ( 0 ) ; } animSet . playTogether ( anims . toArray ( new ObjectAnimator [ anims . size ( ) ] ) ) ; animSet . addListener ( new AnimatorListenerAdapter ( ) { @ Override public void onAnimationEnd ( Animator animation ) { if ( mOnVisibleWidthChangedListener != null ) { mVisibleWidth = ( getChildCount ( ) * ( int ) ACTION_DIMENSION_PX ) - ( mHasOverflow ? Util . dpToPx ( 8 ) : 0 ) ; mOnVisibleWidthChangedListener . onItemsMenuVisibleWidthChanged ( mVisibleWidth ) ; } } } ) ; animSet . start ( ) ;


signature:
public class Util { /** * Gets a reference to a given drawable and prepares it for use with tinting through .
 * @ param resId the resource id for the given drawable
 * @ return a wrapped drawable ready fo use
 * with { @ link android . support . v4 . graphics . drawable . DrawableCompat } ' s tinting methods
 * @ throws Resources . NotFoundException */
public static Drawable getWrappedDrawable ( Context context , @ DrawableRes int resId ) throws Resources . NotFoundException { } }

implementation: return DrawableCompat . wrap ( ResourcesCompat . getDrawable ( context . getResources ( ) , resId , null ) ) ;


signature:
public class FloatingSearchView { /** * ensures that the end margin of the search input is according to Material specs */
private void handleOnVisibleMenuItemsWidthChanged ( int menuItemsWidth ) { } }

implementation: if ( menuItemsWidth == 0 ) { mClearButton . setTranslationX ( - Util . dpToPx ( 4 ) ) ; int paddingRight = Util . dpToPx ( 4 ) ; if ( mIsFocused ) { paddingRight += Util . dpToPx ( CLEAR_BTN_WIDTH_DP ) ; } else { paddingRight += Util . dpToPx ( 14 ) ; } mSearchInput . setPadding ( 0 , 0 , paddingRight , 0 ) ; } else { mClearButton . setTranslationX ( - menuItemsWidth ) ; int paddingRight = menuItemsWidth ; if ( mIsFocused ) { paddingRight += Util . dpToPx ( CLEAR_BTN_WIDTH_DP ) ; } mSearchInput . setPadding ( 0 , 0 , paddingRight , 0 ) ; }


signature:
public class FloatingSearchView { /** * Sets the menu button ' s color .
 * @ param color the color to be applied to the
 * left menu button . */
public void setLeftActionIconColor ( int color ) { } }

implementation: mLeftActionIconColor = color ; mMenuBtnDrawable . setColor ( color ) ; DrawableCompat . setTint ( mIconBackArrow , color ) ; DrawableCompat . setTint ( mIconSearch , color ) ;


signature:
public class FloatingSearchView { /** * Sets the background color of the search
 * view including the suggestions section .
 * @ param color the color to be applied to the search bar and
 * the suggestion section background . */
public void setBackgroundColor ( int color ) { } }

implementation: mBackgroundColor = color ; if ( mQuerySection != null && mSuggestionsList != null ) { mQuerySection . setCardBackgroundColor ( color ) ; mSuggestionsList . setBackgroundColor ( color ) ; }


signature:
public class FloatingSearchView { /** * Enables clients to directly manipulate
 * the menu icon ' s progress .
 * Useful for custom animation / behaviors .
 * @ param progress the desired progress of the menu
 * icon ' s rotation : 0.0 = = hamburger
 * shape , 1.0 = = back arrow shape */
public void setMenuIconProgress ( float progress ) { } }

implementation: mMenuBtnDrawable . setProgress ( progress ) ; if ( progress == 0 ) { closeMenu ( false ) ; } else if ( progress == 1.0 ) { openMenu ( false ) ; }


signature:
public class FloatingSearchView { /** * Mimics a menu click that opens the menu . Useful for navigation
 * drawers when they open as a result of dragging . */
public void openMenu ( boolean withAnim ) { } }

implementation: mMenuOpen = true ; openMenuDrawable ( mMenuBtnDrawable , withAnim ) ; if ( mOnMenuClickListener != null ) { mOnMenuClickListener . onMenuOpened ( ) ; }


signature:
public class FloatingSearchView { /** * Mimics a menu click that closes . Useful when fo navigation
 * drawers when they close as a result of selecting and item .
 * @ param withAnim true , will close the menu button with
 * the Material animation */
public void closeMenu ( boolean withAnim ) { } }

implementation: mMenuOpen = false ; closeMenuDrawable ( mMenuBtnDrawable , withAnim ) ; if ( mOnMenuClickListener != null ) { mOnMenuClickListener . onMenuClosed ( ) ; }


signature:
public class FloatingSearchView { /** * Shows a circular progress on top of the
 * menu action button .
 * Call hidProgress ( )
 * to change back to normal and make the menu
 * action visible . */
public void showProgress ( ) { } }

implementation: mLeftAction . setVisibility ( View . GONE ) ; mSearchProgress . setAlpha ( 0.0f ) ; mSearchProgress . setVisibility ( View . VISIBLE ) ; ObjectAnimator . ofFloat ( mSearchProgress , "alpha" , 0.0f , 1.0f ) . start ( ) ;


signature:
public class FloatingSearchView { /** * Hides the progress bar after
 * a prior call to showProgress ( ) */
public void hideProgress ( ) { } }

implementation: mSearchProgress . setVisibility ( View . GONE ) ; mLeftAction . setAlpha ( 0.0f ) ; mLeftAction . setVisibility ( View . VISIBLE ) ; ObjectAnimator . ofFloat ( mLeftAction , "alpha" , 0.0f , 1.0f ) . start ( ) ;


signature:
public class FloatingSearchView { /** * Inflates the menu items from
 * an xml resource .
 * @ param menuId a menu xml resource reference */
public void inflateOverflowMenu ( int menuId ) { } }

implementation: mMenuId = menuId ; mMenuView . reset ( menuId , actionMenuAvailWidth ( ) ) ; if ( mIsFocused ) { mMenuView . hideIfRoomItems ( false ) ; }


signature:
public class FloatingSearchView { /** * Set a hint that will appear in the
 * search input . Default hint is R . string . abc _ search _ hint
 * which is " search . . . " ( when device language is set to english )
 * @ param searchHint */
public void setSearchHint ( String searchHint ) { } }

implementation: mSearchHint = searchHint != null ? searchHint : getResources ( ) . getString ( R . string . abc_search_hint ) ; mSearchInput . setHint ( mSearchHint ) ;


signature:
public class FloatingSearchView { /** * Sets whether the the button with the search icon
 * will appear in the soft - keyboard or not .
 * @ param show to show the search button in
 * the soft - keyboard . */
public void setShowSearchKey ( boolean show ) { } }

implementation: mShowSearchKey = show ; if ( show ) { mSearchInput . setImeOptions ( EditorInfo . IME_ACTION_SEARCH ) ; } else { mSearchInput . setImeOptions ( EditorInfo . IME_ACTION_NONE ) ; }


signature:
public class FloatingSearchView { /** * Set whether a touch outside of the
 * search bar ' s bounds will cause the search bar to
 * loos focus .
 * @ param enable true to dismiss on outside touch , false otherwise . */
public void setDismissOnOutsideClick ( boolean enable ) { } }

implementation:
mDismissOnOutsideTouch = enable ; mSuggestionsSection . setOnTouchListener ( new OnTouchListener ( ) { @ Override public boolean onTouch ( View v , MotionEvent event ) { // todo check if this is called twice
if ( mDismissOnOutsideTouch && mIsFocused ) { setSearchFocusedInternal ( false ) ; } return true ; } } ) ;


signature:
public class FloatingSearchView { /** * Sets the title for the search bar .
 * Note that after the title is set , when
 * the search gains focus , the title will be replaced
 * by the search hint .
 * @ param title the title to be shown when search
 * is not focused */
public void setSearchBarTitle ( CharSequence title ) { } }

implementation: this . mTitleText = title . toString ( ) ; mIsTitleSet = true ; mSearchInput . setText ( title ) ;


signature:
public class FloatingSearchView { /** * Sets whether the search is focused or not .
 * @ param focused true , to set the search to be active / focused .
 * @ return true if the search was focused and will now become not focused . Useful for
 * calling supper . onBackPress ( ) in the hosting activity only if this method returns false */
public boolean setSearchFocused ( final boolean focused ) { } }

implementation: boolean updatedToNotFocused = ! focused && this . mIsFocused ; if ( ( focused != this . mIsFocused ) && mSuggestionSecHeightListener == null ) { if ( mIsSuggestionsSectionHeightSet ) { setSearchFocusedInternal ( focused ) ; } else { mSuggestionSecHeightListener = new OnSuggestionSecHeightSetListener ( ) { @ Override public void onSuggestionSecHeightSet ( ) { setSearchFocusedInternal ( focused ) ; mSuggestionSecHeightListener = null ; } } ; } } return updatedToNotFocused ;


signature:
public class FloatingSearchView { /** * returns true if the suggestion items occupy the full RecyclerView ' s height , false otherwise */
private boolean updateSuggestionsSectionHeight ( List < ? extends SearchSuggestion > newSearchSuggestions , boolean withAnim ) { } }

implementation:
final int cardTopBottomShadowPadding = Util . dpToPx ( CARD_VIEW_CORNERS_AND_TOP_BOTTOM_SHADOW_HEIGHT ) ; final int cardRadiusSize = Util . dpToPx ( CARD_VIEW_TOP_BOTTOM_SHADOW_HEIGHT ) ; int visibleSuggestionHeight = calculateSuggestionItemsHeight ( newSearchSuggestions , mSuggestionListContainer . getHeight ( ) ) ; int diff = mSuggestionListContainer . getHeight ( ) - visibleSuggestionHeight ; int addedTranslationYForShadowOffsets = ( diff <= cardTopBottomShadowPadding ) ? - ( cardTopBottomShadowPadding - diff ) : diff < ( mSuggestionListContainer . getHeight ( ) - cardTopBottomShadowPadding ) ? cardRadiusSize : 0 ; final float newTranslationY = - mSuggestionListContainer . getHeight ( ) + visibleSuggestionHeight + addedTranslationYForShadowOffsets ; // todo go over
final float fullyInvisibleTranslationY = - mSuggestionListContainer . getHeight ( ) + cardRadiusSize ; ViewCompat . animate ( mSuggestionListContainer ) . cancel ( ) ; if ( withAnim ) { ViewCompat . animate ( mSuggestionListContainer ) . setInterpolator ( SUGGEST_ITEM_ADD_ANIM_INTERPOLATOR ) . setDuration ( mSuggestionSectionAnimDuration ) . translationY ( newTranslationY ) . setUpdateListener ( new ViewPropertyAnimatorUpdateListener ( ) { @ Override public void onAnimationUpdate ( View view ) { if ( mOnSuggestionsListHeightChanged != null ) { float newSuggestionsHeight = Math . abs ( view . getTranslationY ( ) - fullyInvisibleTranslationY ) ; mOnSuggestionsListHeightChanged . onSuggestionsListHeightChanged ( newSuggestionsHeight ) ; } } } ) . setListener ( new ViewPropertyAnimatorListenerAdapter ( ) { @ Override public void onAnimationCancel ( View view ) { mSuggestionListContainer . setTranslationY ( newTranslationY ) ; } } ) . start ( ) ; } else { mSuggestionListContainer . setTranslationY ( newTranslationY ) ; if ( mOnSuggestionsListHeightChanged != null ) { float newSuggestionsHeight = Math . abs ( mSuggestionListContainer . getTranslationY ( ) - fullyInvisibleTranslationY ) ; mOnSuggestionsListHeightChanged . onSuggestionsListHeightChanged ( newSuggestionsHeight ) ; } } return mSuggestionListContainer . getHeight ( ) == visibleSuggestionHeight ;


signature:
public class FloatingSearchView { /** * results is > = max . The max option allows us to avoid doing unnecessary and potentially long calculations . */
private int calculateSuggestionItemsHeight ( List < ? extends SearchSuggestion > suggestions , int max ) { } }

implementation:
// todo
// ' i < suggestions . size ( ) ' in the below ' for ' seems unneeded , investigate if there is a use for it .
int visibleItemsHeight = 0 ; for ( int i = 0 ; i < suggestions . size ( ) && i < mSuggestionsList . getChildCount ( ) ; i ++ ) { visibleItemsHeight += mSuggestionsList . getChildAt ( i ) . getHeight ( ) ; if ( visibleItemsHeight > max ) { visibleItemsHeight = max ; break ; } } return visibleItemsHeight ;


signature:
public class FloatingSearchView { /** * Set a callback that will be called after each suggestion view in the suggestions recycler
 * list is bound . This allows for customized binding for specific items in the list .
 * @ param callback A callback to be called after a suggestion is bound by the suggestions list ' s
 * adapter . */
public void setOnBindSuggestionCallback ( SearchSuggestionsAdapter . OnBindSuggestionCallback callback ) { } }

implementation: this . mOnBindSuggestionCallback = callback ; if ( mSuggestionsAdapter != null ) { mSuggestionsAdapter . setOnBindSuggestionCallback ( mOnBindSuggestionCallback ) ; }


signature:
public class WeChatBot { /** * 根据名称发送消息
 * @ param name 备注或昵称 , 精确匹配
 * @ param msg 消息内容
 * @ return 发送是否成功 */
public boolean sendMsgByName ( String name , String msg ) { } }

implementation: Account account = api . getAccountByName ( name ) ; if ( null == account ) { log . warn ( "找不到用户: {}" , name ) ; return false ; } return this . api . sendText ( account . getUserName ( ) , msg ) ;


signature:
public class WeChatBot { /** * 根据名称发送图片消息
 * @ param name 备注或昵称 , 精确匹配
 * @ param imgPath 图片路径
 * @ return 发送是否成功 */
public boolean sendImgName ( String name , String imgPath ) { } }

implementation: Account account = api . getAccountByName ( name ) ; if ( null == account ) { log . warn ( "找不到用户: {}" , name ) ; return false ; } return this . api . sendImg ( account . getUserName ( ) , imgPath ) ;


signature:
public class WeChatBot { /** * 根据名称发送文件消息
 * @ param name 备注或昵称 , 精确匹配
 * @ param filePath 文件路径
 * @ return 发送是否成功 */
public boolean sendFileName ( String name , String filePath ) { } }

implementation: Account account = api . getAccountByName ( name ) ; if ( null == account ) { log . warn ( "找不到用户: {}" , name ) ; return false ; } return this . api . sendFile ( account . getUserName ( ) , filePath ) ;


signature:
public class WeChatBot { /** * 启动微信监听 */
public void start ( ) { } }

implementation: this . api = new WeChatApiImpl ( this ) ; log . info ( "wechat-bot: {}" , Constant . VERSION ) ; api . login ( config . autoLogin ( ) ) ; Thread msgHandle = new Thread ( new Runnable ( ) { @ Override public void run ( ) { while ( true ) { if ( hasMessage ( ) ) { WeChatMessage weChatMessage = nextMessage ( ) ; callBack ( mapping . get ( MsgType . ALL ) , weChatMessage ) ; callBack ( mapping . get ( weChatMessage . getMsgType ( ) ) , weChatMessage ) ; } else { DateUtils . sleep ( 50 ) ; } } } } ) ; msgHandle . setName ( "message-handle" ) ; msgHandle . setDaemon ( true ) ; msgHandle . start ( ) ; this . other ( ) ;


signature:
public class WeChatBot { /** * 启动后主线程干的事 , 子类可重写 */
protected void other ( ) { } }

implementation: while ( true ) { Scanner scanner = new Scanner ( System . in ) ; if ( scanner . hasNext ( ) ) { String text = scanner . next ( ) ; if ( "quit" . equals ( text ) || "exit" . equals ( text ) ) { api . logout ( ) ; break ; } } DateUtils . sleep ( 100 ) ; }


signature:
public class WeChatBot { /** * 回调微信消息给客户端 、 存储器
 * @ param invokes 执行器
 * @ param message 消息 */
private void callBack ( List < Invoke > invokes , WeChatMessage message ) { } }

implementation: if ( null != invokes && invokes . size ( ) > 0 && null != message ) { for ( Invoke invoke : invokes ) { invoke . call ( this , message ) ; } }


signature:
public class WeChatBot { /** * 更新最后一次正常心跳时间 */
public void updateLastCheck ( ) { } }

implementation: this . lastCheckTs = System . currentTimeMillis ( ) ; if ( this . config ( ) . autoLogin ( ) ) { String file = this . config ( ) . assetsDir ( ) + "/login.json" ; WeChatUtils . writeJson ( file , HotReload . build ( this . session ( ) ) ) ; if ( log . isDebugEnabled ( ) ) { log . debug ( "写入本地登录JSON" ) ; } }


signature:
public class Config { /** * 加载 ClassPath 下的配置文件
 * @ param filePath
 * @ return */
public static Config load ( String filePath ) { } }

implementation: Config config = new Config ( ) ; try ( final InputStream stream = Config . class . getResourceAsStream ( filePath ) ) { config . props . load ( stream ) ; } catch ( Exception e ) { throw new WeChatException ( "加载配置文件出错" , e ) ; } return config ;


signature:
public class Invoke { /** * 回调给客户端
 * @ param bot
 * @ param message
 * @ param < T > */
public < T extends WeChatBot > void call ( T bot , WeChatMessage message ) { } }

implementation:
if ( INVOKED_MSG . contains ( message . getId ( ) ) ) { return ; } try { // 自动同意添加好友
if ( message . getMsgType ( ) == MsgType . ADD_FRIEND && bot . config ( ) . autoAddFriend ( ) ) { bot . api ( ) . verify ( message . getRecommend ( ) ) ; return ; } Account account = bot . api ( ) . getAccountById ( message . getFromUserName ( ) ) ; if ( null == account ) { INVOKED_MSG . add ( message . getId ( ) ) ; method . invoke ( bot , message ) ; return ; } if ( msgType == MsgType . ALL || msgType == message . getMsgType ( ) ) { if ( message . getMsgType ( ) == MsgType . ADD_FRIEND ) { INVOKED_MSG . add ( message . getId ( ) ) ; method . invoke ( bot , message ) ; } else { if ( accountTypes . contains ( account . getAccountType ( ) ) ) { INVOKED_MSG . add ( message . getId ( ) ) ; method . invoke ( bot , message ) ; } } } } catch ( Exception e ) { log . warn ( "回调给客户端出错: {}\r\n" , message , e ) ; }


signature:
public class WeChatUtils { /** * 正则匹配
 * @ param reg
 * @ param text
 * @ return */
public static String match ( String reg , String text ) { } }

implementation: Pattern pattern = Pattern . compile ( reg ) ; Matcher m = pattern . matcher ( text ) ; if ( m . find ( ) ) { return m . group ( 1 ) ; } return null ;


signature:
public class WeChatUtils { /** * 格式化微信消息
 * 处理emoji表情 、 HTML转义符
 * @ param msg
 * @ return */
public static String formatMsg ( String msg ) { } }

implementation: msg = msg . replace ( "<" , "<" ) . replace ( ">" , ">" ) . replace ( "<br/>" , "\n" ) ; return emojiParse ( msg ) ;


signature:
public class WeChatUtils { /** * 获取文件 MimeType
 * @ param fileUrl
 * @ return */
public static String getMimeType ( String fileUrl ) { } }

implementation: FileNameMap fileNameMap = URLConnection . getFileNameMap ( ) ; String type = fileNameMap . getContentTypeFor ( fileUrl ) ; return type ;


signature:
public class DateUtils { /** * 休眠 , 单位 : 毫秒
 * @ param ms */
public static void sleep ( long ms ) { } }

implementation: try { TimeUnit . MILLISECONDS . sleep ( ms ) ; } catch ( InterruptedException e ) { log . error ( "" , e ) ; }


signature:
public class WeChatApiImpl { /** * 自动登录 */
private void autoLogin ( ) { } }

implementation: String file = bot . config ( ) . assetsDir ( ) + "/login.json" ; try { HotReload hotReload = WeChatUtils . fromJson ( new FileReader ( file ) , HotReload . class ) ; hotReload . reLogin ( bot ) ; } catch ( FileNotFoundException e ) { this . login ( false ) ; }


signature:
public class WeChatApiImpl { /** * 获取UUID
 * @ return 返回uuid */
private String getUUID ( ) { } }

implementation:
log . info ( "获取二维码UUID" ) ; // 登录
ApiResponse response = this . client . send ( new StringRequest ( "https://login.weixin.qq.com/jslogin" ) . add ( "appid" , "wx782c26e4c19acffb" ) . add ( "fun" , "new" ) ) ; Matcher matcher = UUID_PATTERN . matcher ( response . getRawBody ( ) ) ; if ( matcher . find ( ) && StateCode . SUCCESS . equals ( matcher . group ( 1 ) ) ) { this . uuid = matcher . group ( 2 ) ; } return this . uuid ;


signature:
public class WeChatApiImpl { /** * 读取二维码图片
 * @ param uuid 二维码uuid
 * @ param terminalShow 是否在终端显示输出 */
private void getQrImage ( String uuid , boolean terminalShow ) { } }

implementation: String uid = null != uuid ? uuid : this . uuid ; String imgDir = bot . config ( ) . assetsDir ( ) ; FileResponse fileResponse = this . client . download ( new FileRequest ( String . format ( "%s/qrcode/%s" , Constant . BASE_URL , uid ) ) ) ; InputStream inputStream = fileResponse . getInputStream ( ) ; File qrCode = WeChatUtils . saveFile ( inputStream , imgDir , "qrcode.png" ) ; DateUtils . sleep ( 200 ) ; try { QRCodeUtils . showQrCode ( qrCode , terminalShow ) ; } catch ( Exception e ) { this . getQrImage ( uid , terminalShow ) ; }


signature:
public class WeChatApiImpl { /** * 检查是否登录
 * @ param uuid 二维码uuid
 * @ return 返回登录状态码 */
private String checkLogin ( String uuid ) { } }

implementation: String uid = null != uuid ? uuid : this . uuid ; String url = String . format ( "%s/cgi-bin/mmwebwx-bin/login" , Constant . BASE_URL ) ; Long time = System . currentTimeMillis ( ) ; ApiResponse response = this . client . send ( new StringRequest ( url ) . add ( "loginicon" , true ) . add ( "uuid" , uid ) . add ( "tip" , "1" ) . add ( "_" , time ) . add ( "r" , ( int ) ( - time / 1000 ) / 1579 ) . timeout ( 30 ) ) ; Matcher matcher = CHECK_LOGIN_PATTERN . matcher ( response . getRawBody ( ) ) ; if ( matcher . find ( ) ) { if ( StateCode . SUCCESS . equals ( matcher . group ( 1 ) ) ) { if ( ! this . processLoginSession ( response . getRawBody ( ) ) ) { return StateCode . FAIL ; } return StateCode . SUCCESS ; } return matcher . group ( 1 ) ; } return StateCode . FAIL ;


signature:
public class WeChatApiImpl { /** * 处理登录session
 * @ param loginContent 登录text
 * @ return 返回是否处理成功 */
private boolean processLoginSession ( String loginContent ) { } }

implementation: LoginSession loginSession = bot . session ( ) ; Matcher matcher = PROCESS_LOGIN_PATTERN . matcher ( loginContent ) ; if ( matcher . find ( ) ) { loginSession . setUrl ( matcher . group ( 1 ) ) ; } ApiResponse response = this . client . send ( new StringRequest ( loginSession . getUrl ( ) ) . noRedirect ( ) ) ; loginSession . setUrl ( loginSession . getUrl ( ) . substring ( 0 , loginSession . getUrl ( ) . lastIndexOf ( "/" ) ) ) ; String body = response . getRawBody ( ) ; List < String > fileUrl = new ArrayList < > ( ) ; List < String > syncUrl = new ArrayList < > ( ) ; for ( int i = 0 ; i < FILE_URL . size ( ) ; i ++ ) { fileUrl . add ( String . format ( "https://%s/cgi-bin/mmwebwx-bin" , FILE_URL . get ( i ) ) ) ; syncUrl . add ( String . format ( "https://%s/cgi-bin/mmwebwx-bin" , WEB_PUSH_URL . get ( i ) ) ) ; } boolean flag = false ; for ( int i = 0 ; i < FILE_URL . size ( ) ; i ++ ) { String indexUrl = INDEX_URL . get ( i ) ; if ( loginSession . getUrl ( ) . contains ( indexUrl ) ) { loginSession . setFileUrl ( fileUrl . get ( i ) ) ; loginSession . setSyncUrl ( syncUrl . get ( i ) ) ; flag = true ; break ; } } if ( ! flag ) { loginSession . setFileUrl ( loginSession . getUrl ( ) ) ; loginSession . setSyncUrl ( loginSession . getUrl ( ) ) ; } loginSession . setDeviceId ( "e" + String . valueOf ( System . currentTimeMillis ( ) ) ) ; BaseRequest baseRequest = new BaseRequest ( ) ; loginSession . setBaseRequest ( baseRequest ) ; loginSession . setSKey ( WeChatUtils . match ( "<skey>(\\S+)</skey>" , body ) ) ; loginSession . setWxSid ( WeChatUtils . match ( "<wxsid>(\\S+)</wxsid>" , body ) ) ; loginSession . setWxUin ( WeChatUtils . match ( "<wxuin>(\\S+)</wxuin>" , body ) ) ; loginSession . setPassTicket ( WeChatUtils . match ( "<pass_ticket>(\\S+)</pass_ticket>" , body ) ) ; baseRequest . setSkey ( loginSession . getSKey ( ) ) ; baseRequest . setSid ( loginSession . getWxSid ( ) ) ; baseRequest . setUin ( loginSession . getWxUin ( ) ) ; baseRequest . setDeviceID ( loginSession . getDeviceId ( ) ) ; return true ;


signature:
public class WeChatApiImpl { /** * 推送登录
 * @ return 返回uuid */
private String pushLogin ( ) { } }

implementation: String uin = this . client . cookie ( "wxUin" ) ; if ( StringUtils . isEmpty ( uin ) ) { return null ; } String url = String . format ( "%s/cgi-bin/mmwebwx-bin/webwxpushloginurl?uin=%s" , Constant . BASE_URL , uin ) ; JsonResponse jsonResponse = this . client . send ( new JsonRequest ( url ) ) ; return jsonResponse . getString ( "uuid" ) ;


signature:
public class WeChatApiImpl { /** * 开启状态通知 */
private void statusNotify ( ) { } }

implementation: log . info ( "开启状态通知" ) ; String url = String . format ( "%s/webwxstatusnotify?lang=zh_CN&pass_ticket=%s" , bot . session ( ) . getUrl ( ) , bot . session ( ) . getPassTicket ( ) ) ; this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) . add ( "Code" , 3 ) . add ( "FromUserName" , bot . session ( ) . getUserName ( ) ) . add ( "ToUserName" , bot . session ( ) . getUserName ( ) ) . add ( "ClientMsgId" , System . currentTimeMillis ( ) / 1000 ) ) ;


signature:
public class WeChatApiImpl { /** * web 初始化 */
private void webInit ( ) { } }

implementation: log . info ( "微信初始化..." ) ; int r = ( int ) ( - System . currentTimeMillis ( ) / 1000 ) / 1579 ; String url = String . format ( "%s/webwxinit?r=%d&pass_ticket=%s" , bot . session ( ) . getUrl ( ) , r , bot . session ( ) . getPassTicket ( ) ) ; JsonResponse response = this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) ) ; WebInitResponse webInitResponse = response . parse ( WebInitResponse . class ) ; List < Account > contactList = webInitResponse . getContactList ( ) ; this . syncRecentContact ( contactList ) ; Account account = webInitResponse . getAccount ( ) ; SyncKey syncKey = webInitResponse . getSyncKey ( ) ; bot . session ( ) . setInviteStartCount ( webInitResponse . getInviteStartCount ( ) ) ; bot . session ( ) . setAccount ( account ) ; bot . session ( ) . setUserName ( account . getUserName ( ) ) ; bot . session ( ) . setNickName ( account . getNickName ( ) ) ; bot . session ( ) . setSyncKey ( syncKey ) ;


signature:
public class WeChatApiImpl { /** * 开启一个县城接收监听 */
private void startRevive ( ) { } }

implementation: bot . setRunning ( true ) ; Thread thread = new Thread ( new ChatLoop ( bot ) ) ; thread . setName ( "wechat-listener" ) ; thread . setDaemon ( true ) ; thread . start ( ) ;


signature:
public class WeChatApiImpl { /** * 心跳检查
 * @ return SyncCheckRet */
@ Override public SyncCheckRet syncCheck ( ) { } }

implementation: String url = String . format ( "%s/synccheck" , bot . session ( ) . getSyncOrUrl ( ) ) ; try { ApiResponse response = this . client . send ( new StringRequest ( url ) . add ( "r" , System . currentTimeMillis ( ) ) . add ( "skey" , bot . session ( ) . getSKey ( ) ) . add ( "sid" , bot . session ( ) . getWxSid ( ) ) . add ( "uin" , bot . session ( ) . getWxUin ( ) ) . add ( "deviceid" , bot . session ( ) . getDeviceId ( ) ) . add ( "synckey" , bot . session ( ) . getSyncKeyStr ( ) ) . add ( "_" , System . currentTimeMillis ( ) ) . timeout ( 30 ) ) ; Matcher matcher = SYNC_CHECK_PATTERN . matcher ( response . getRawBody ( ) ) ; if ( matcher . find ( ) ) { if ( ! "0" . equals ( matcher . group ( 1 ) ) ) { log . debug ( "Unexpected sync check result: {}" , response . getRawBody ( ) ) ; return new SyncCheckRet ( RetCode . parse ( Integer . valueOf ( matcher . group ( 1 ) ) ) , 0 ) ; } return new SyncCheckRet ( RetCode . parse ( Integer . valueOf ( matcher . group ( 1 ) ) ) , Integer . valueOf ( matcher . group ( 2 ) ) ) ; } return new SyncCheckRet ( RetCode . UNKNOWN , 0 ) ; } catch ( Exception e ) { if ( e instanceof SocketTimeoutException ) { log . warn ( "心跳检查超时" ) ; return syncCheck ( ) ; } log . error ( "心跳检查出错" , e ) ; return new SyncCheckRet ( RetCode . UNKNOWN , 0 ) ; }


signature:
public class WeChatApiImpl { /** * 获取最新消息
 * @ return WebSyncResponse */
@ Override public WebSyncResponse webSync ( ) { } }

implementation: String url = String . format ( "%s/webwxsync?sid=%s&sKey=%s&passTicket=%s" , bot . session ( ) . getUrl ( ) , bot . session ( ) . getWxSid ( ) , bot . session ( ) . getSKey ( ) , bot . session ( ) . getPassTicket ( ) ) ; JsonResponse response = this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) . add ( "SyncKey" , bot . session ( ) . getSyncKey ( ) ) . add ( "rr" , ~ ( System . currentTimeMillis ( ) / 1000 ) ) ) ; WebSyncResponse webSyncResponse = response . parse ( WebSyncResponse . class ) ; if ( ! webSyncResponse . success ( ) ) { log . warn ( "获取消息失败" ) ; return webSyncResponse ; } bot . session ( ) . setSyncKey ( webSyncResponse . getSyncKey ( ) ) ; return webSyncResponse ;


signature:
public class WeChatApiImpl { /** * 退出登录 */
@ Override public void logout ( ) { } }

implementation: if ( bot . isRunning ( ) ) { String url = String . format ( "%s/webwxlogout" , bot . session ( ) . getUrl ( ) ) ; this . client . send ( new StringRequest ( url ) . add ( "redirect" , 1 ) . add ( "type" , 1 ) . add ( "sKey" , bot . session ( ) . getSKey ( ) ) ) ; bot . setRunning ( false ) ; } this . logging = false ; this . client . cookies ( ) . clear ( ) ; String file = bot . config ( ) . assetsDir ( ) + "/login.json" ; new File ( file ) . delete ( ) ;


signature:
public class WeChatApiImpl { /** * 加载联系人信息
 * @ param seq 默认为0 , 当一次无法加载完全则大于0 */
@ Override public void loadContact ( int seq ) { } }

implementation:
log . info ( "开始获取联系人信息" ) ; while ( true ) { String url = String . format ( "%s/webwxgetcontact?r=%s&seq=%s&skey=%s" , bot . session ( ) . getUrl ( ) , System . currentTimeMillis ( ) , seq , bot . session ( ) . getSKey ( ) ) ; JsonResponse response = this . client . send ( new JsonRequest ( url ) . jsonBody ( ) ) ; JsonObject jsonObject = response . toJsonObject ( ) ; seq = jsonObject . get ( "Seq" ) . getAsInt ( ) ; this . memberCount += jsonObject . get ( "MemberCount" ) . getAsInt ( ) ; List < Account > memberList = WeChatUtils . fromJson ( WeChatUtils . toJson ( jsonObject . getAsJsonArray ( "MemberList" ) ) , new TypeToken < List < Account > > ( ) { } ) ; for ( Account account : memberList ) { if ( null == account . getUserName ( ) ) { accountMap . put ( account . getUserName ( ) , account ) ; } } // 查看seq是否为0,0表示好友列表已全部获取完毕 , 若大于0 , 则表示好友列表未获取完毕 , 当前的字节数 ( 断点续传 )
if ( seq == 0 ) { break ; } } this . contactList = new ArrayList < > ( this . getAccountByType ( AccountType . TYPE_FRIEND ) ) ; this . publicUsersList = new ArrayList < > ( this . getAccountByType ( AccountType . TYPE_MP ) ) ; this . specialUsersList = new ArrayList < > ( this . getAccountByType ( AccountType . TYPE_SPECIAL ) ) ; Set < Account > groupAccounts = this . getAccountByType ( AccountType . TYPE_GROUP ) ; for ( Account groupAccount : groupAccounts ) { groupUserNames . add ( groupAccount . getUserName ( ) ) ; }


signature:
public class WeChatApiImpl { /** * 加载群信息 */
public void loadGroupList ( ) { } }

implementation:
log . info ( "加载群聊信息" ) ; // 群账号
List < Map < String , String > > list = new ArrayList < > ( groupUserNames . size ( ) ) ; for ( String groupUserName : groupUserNames ) { Map < String , String > map = new HashMap < > ( 2 ) ; map . put ( "UserName" , groupUserName ) ; map . put ( "EncryChatRoomId" , "" ) ; list . add ( map ) ; } String url = String . format ( "%s/webwxbatchgetcontact?type=ex&r=%s&pass_ticket=%s" , bot . session ( ) . getUrl ( ) , System . currentTimeMillis ( ) / 1000 , bot . session ( ) . getPassTicket ( ) ) ; // 加载群信息
JsonResponse jsonResponse = this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) . add ( "Count" , groupUserNames . size ( ) ) . add ( "List" , list ) ) ; this . groupList = WeChatUtils . fromJson ( WeChatUtils . toJson ( jsonResponse . toJsonObject ( ) . getAsJsonArray ( "ContactList" ) ) , new TypeToken < List < Account > > ( ) { } ) ;


signature:
public class WeChatApiImpl { /** * 根据备注或昵称查找账户
 * @ param name
 * @ return */
@ Override public Account getAccountByName ( String name ) { } }

implementation: for ( Account account : accountMap . values ( ) ) { if ( name . equals ( account . getRemarkName ( ) ) ) { return account ; } if ( name . equals ( account . getNickName ( ) ) ) { return account ; } } return null ;


signature:
public class WeChatApiImpl { /** * 根据账号类型筛选
 * @ param accountType 账户类型
 * @ return 返回筛选后的账户列表 */
public Set < Account > getAccountByType ( AccountType accountType ) { } }

implementation: Set < Account > accountSet = new HashSet < > ( ) ; for ( Account account : accountMap . values ( ) ) { if ( account . getAccountType ( ) . equals ( accountType ) ) { accountSet . add ( account ) ; } } return accountSet ;


signature:
public class WeChatApiImpl { /** * 同步最近联系人
 * 避免新建群聊无法同步
 * @ param contactList 联系人列表 */
public void syncRecentContact ( List < Account > contactList ) { } }

implementation: if ( null != contactList && contactList . size ( ) > 0 ) { for ( Account account : contactList ) { accountMap . put ( account . getUserName ( ) , account ) ; } }


signature:
public class WeChatApiImpl { /** * 处理新消息
 * @ param messages 要处理的消息列表 */
@ Override public List < WeChatMessage > handleMsg ( List < Message > messages ) { } }

implementation: if ( null != messages && messages . size ( ) > 0 ) { List < WeChatMessage > weChatMessages = new ArrayList < > ( messages . size ( ) ) ; boolean hashNewMsg = false ; for ( Message message : messages ) { WeChatMessage weChatMessage = this . processMsg ( message ) ; if ( null != weChatMessage ) { weChatMessages . add ( weChatMessage ) ; hashNewMsg = true ; } } if ( hashNewMsg ) { log . info ( "你有新的消息" ) ; } return weChatMessages ; } return null ;


signature:
public class WeChatApiImpl { /** * 下载图片到本地
 * @ param msgId 图片消息id
 * @ return 返回图片本地路径 */
private String downloadImg ( String msgId ) { } }

implementation: return this . downloadFile ( new DownLoad ( ApiURL . IMAGE , bot . session ( ) . getUrl ( ) , msgId , bot . session ( ) . getSKey ( ) ) . msgId ( msgId ) . saveByDay ( ) ) ;


signature:
public class WeChatApiImpl { /** * 下载表情到本地
 * @ param msgId icon消息id
 * @ return 返回Icon本地路径 */
private String downloadIconImg ( String msgId ) { } }

implementation: return this . downloadFile ( new DownLoad ( ApiURL . ICON , bot . session ( ) . getUrl ( ) , msgId , bot . session ( ) . getSKey ( ) ) . msgId ( msgId ) ) ;


signature:
public class WeChatApiImpl { /** * 下载头像到本地
 * @ param userName 用户名
 * @ return 返回头像本地路径 */
private String downloadHeadImg ( String userName ) { } }

implementation: return this . downloadFile ( new DownLoad ( ApiURL . HEAD_IMG , bot . session ( ) . getUrl ( ) , userName , bot . session ( ) . getSKey ( ) ) . msgId ( userName ) ) ;


signature:
public class WeChatApiImpl { /** * 下载视频到本地
 * @ param msgId 视频消息id
 * @ return 返回视频本地路径 */
private String downloadVideo ( String msgId ) { } }

implementation: return this . downloadFile ( new DownLoad ( ApiURL . VIDEO , bot . session ( ) . getUrl ( ) , msgId , bot . session ( ) . getSKey ( ) ) . msgId ( msgId ) . saveByDay ( ) ) ;


signature:
public class WeChatApiImpl { /** * 下载音频到本地
 * @ param msgId 音频消息id
 * @ return 返回音频本地路径 */
private String downloadVoice ( String msgId ) { } }

implementation: return this . downloadFile ( new DownLoad ( ApiURL . VOICE , bot . session ( ) . getUrl ( ) , msgId , bot . session ( ) . getSKey ( ) ) . msgId ( msgId ) . saveByDay ( ) ) ;


signature:
public class WeChatApiImpl { /** * 上传附件
 * @ param toUser 发送给谁
 * @ param filePath 文件路径
 * @ return MediaResponse */
@ Override public MediaResponse uploadMedia ( String toUser , String filePath ) { } }

implementation: File file = new File ( filePath ) ; if ( ! file . exists ( ) ) { throw new WeChatException ( "文件[" + filePath + "]不存在" ) ; } log . info ( "开始上传文件: {}" , filePath ) ; long size = file . length ( ) ; String mimeType = WeChatUtils . getMimeType ( filePath ) ; String mediatype = "doc" ; if ( mediatype . contains ( "image" ) ) { mediatype = "pic" ; } if ( mediatype . contains ( "audio" ) ) { mediatype = "audio" ; } if ( mediatype . contains ( "video" ) ) { mediatype = "video" ; } String url = String . format ( "%s/webwxuploadmedia?f=json" , bot . session ( ) . getFileUrl ( ) ) ; String mediaId = System . currentTimeMillis ( ) / 1000 + StringUtils . random ( 6 ) ; Map < String , Object > uploadMediaRequest = new HashMap < > ( 10 ) ; uploadMediaRequest . put ( "UploadType" , 2 ) ; uploadMediaRequest . put ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) ; uploadMediaRequest . put ( "ClientMediaId" , mediaId ) ; uploadMediaRequest . put ( "TotalLen" , size ) ; uploadMediaRequest . put ( "StartPos" , 0 ) ; uploadMediaRequest . put ( "DataLen" , size ) ; uploadMediaRequest . put ( "MediaType" , 4 ) ; uploadMediaRequest . put ( "FromUserName" , bot . session ( ) . getUserName ( ) ) ; uploadMediaRequest . put ( "ToUserName" , toUser ) ; uploadMediaRequest . put ( "FileMd5" , MD5Checksum . getMD5Checksum ( file . getPath ( ) ) ) ; String dataTicket = this . client . cookie ( "webwx_data_ticket" ) ; if ( StringUtils . isEmpty ( dataTicket ) ) { throw new WeChatException ( "缺少了附件Cookie" ) ; } ApiResponse response = this . client . send ( new StringRequest ( url ) . post ( ) . multipart ( ) . fileName ( file . getName ( ) ) . add ( "id" , "WU_FILE_0" ) . add ( "name" , filePath ) . add ( "type" , mimeType ) . add ( "lastModifieDate" , new SimpleDateFormat ( "yyyy MM dd HH:mm:ss" ) . format ( new Date ( ) ) ) . add ( "size" , String . valueOf ( size ) ) . add ( "mediatype" , mediatype ) . add ( "uploadmediarequest" , WeChatUtils . toJson ( uploadMediaRequest ) ) . add ( "webwx_data_ticket" , dataTicket ) . add ( "pass_ticket" , bot . session ( ) . getPassTicket ( ) ) . add ( "filename" , RequestBody . create ( MediaType . parse ( mimeType ) , file ) ) ) ; MediaResponse mediaResponse = response . parse ( MediaResponse . class ) ; if ( ! mediaResponse . success ( ) ) { log . warn ( "上传附件失败: {}" , mediaResponse . getMsg ( ) ) ; } log . info ( "文件上传成功: {}" , filePath ) ; return mediaResponse ;


signature:
public class WeChatApiImpl { /** * 发送文件
 * @ param toUserName 发送给谁
 * @ param filePath 文件路径 */
@ Override public boolean sendImg ( String toUserName , String filePath ) { } }

implementation: DateUtils . sendSleep ( ) ; String mediaId = this . uploadMedia ( toUserName , filePath ) . getMediaId ( ) ; if ( StringUtils . isEmpty ( mediaId ) ) { log . warn ( "Media为空" ) ; return false ; } String url = String . format ( "%s/webwxsendmsgimg?fun=async&f=json&pass_ticket=%s" , bot . session ( ) . getUrl ( ) , bot . session ( ) . getPassTicket ( ) ) ; String msgId = System . currentTimeMillis ( ) / 1000 + StringUtils . random ( 6 ) ; Map < String , Object > msg = new HashMap < > ( ) ; msg . put ( "Type" , 3 ) ; msg . put ( "MediaId" , mediaId ) ; msg . put ( "FromUserName" , bot . session ( ) . getUserName ( ) ) ; msg . put ( "ToUserName" , toUserName ) ; msg . put ( "LocalID" , msgId ) ; msg . put ( "ClientMsgId" , msgId ) ; JsonResponse response = this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) . add ( "Msg" , msg ) ) ; return null != response && response . success ( ) ;


signature:
public class WeChatApiImpl { /** * 发送文本消息
 * @ param msg 文本消息
 * @ param toUserName 发送给谁 */
@ Override public boolean sendText ( String toUserName , String msg ) { } }

implementation: DateUtils . sendSleep ( ) ; String url = String . format ( "%s/webwxsendmsg?pass_ticket=%s" , bot . session ( ) . getUrl ( ) , bot . session ( ) . getPassTicket ( ) ) ; String msgId = System . currentTimeMillis ( ) / 1000 + StringUtils . random ( 6 ) ; JsonResponse response = this . client . send ( new JsonRequest ( url ) . post ( ) . jsonBody ( ) . add ( "BaseRequest" , bot . session ( ) . getBaseRequest ( ) ) . add ( "Msg" , new SendMessage ( 1 , msg , bot . session ( ) . getUserName ( ) , toUserName , msgId , msgId ) ) ) ; return null != response && response . success ( ) ;


signature:
public class MD5Checksum { /** * a byte array to a HEX string */
public static String getMD5Checksum ( String filename ) { } }

implementation: try { byte [ ] b = createChecksum ( filename ) ; String result = "" ; for ( int i = 0 ; i < b . length ; i ++ ) { result += Integer . toString ( ( b [ i ] & 0xff ) + 0x100 , 16 ) . substring ( 1 ) ; } return result ; } catch ( Exception e ) { return "" ; }


signature:
public class BotClient { /** * 重新恢复Cookie
 * @ param cookieStore */
public static void recoverCookie ( Map < String , List < Cookie > > cookieStore ) { } }

implementation: BotClient . cookieStore . clear ( ) ; BotClient . cookieStore = cookieStore ;


signature:
public class BotClient { /** * 设置超时
 * @ param request
 * @ return */
private OkHttpClient timeout ( ApiRequest request ) { } }

implementation: int timeoutMillis = request . getTimeout ( ) * 1000 ; if ( client . readTimeoutMillis ( ) == 0 || client . readTimeoutMillis ( ) > timeoutMillis ) { return client ; } if ( null != clientWithTimeout && clientWithTimeout . readTimeoutMillis ( ) > timeoutMillis ) { return clientWithTimeout ; } clientWithTimeout = client . newBuilder ( ) . readTimeout ( timeoutMillis + 1000 , TimeUnit . MILLISECONDS ) . build ( ) ; return clientWithTimeout ;


signature:
public class QRCodeUtils { /** * 显示二维码 , Linux会显示在终端
 * @ param qrCode
 * @ param terminal */
public static void showQrCode ( File qrCode , boolean terminal ) throws WriterException { } }

implementation:
if ( ! terminal ) { String os = System . getProperty ( "os.name" ) . toLowerCase ( ) ; try { if ( os . contains ( "mac" ) || os . contains ( "win" ) ) { Desktop . getDesktop ( ) . open ( qrCode ) ; return ; } } catch ( Exception e ) { log . warn ( "在 {} 下打开文件 {} 失败" , os , qrCode . getPath ( ) , e ) ; } } Map < EncodeHintType , Object > hintMap = new EnumMap < EncodeHintType , Object > ( EncodeHintType . class ) ; hintMap . put ( EncodeHintType . CHARACTER_SET , "UTF-8" ) ; // Now with zxing version 3.2.1 you could change border size ( white border size to just 1)
// default = 4
hintMap . put ( EncodeHintType . MARGIN , 1 ) ; hintMap . put ( EncodeHintType . ERROR_CORRECTION , ErrorCorrectionLevel . L ) ; String qrContent = QRCodeUtils . readQRCode ( qrCode , hintMap ) ; QRCodeWriter qrCodeWriter = new QRCodeWriter ( ) ; BitMatrix bitMatrix ; bitMatrix = qrCodeWriter . encode ( qrContent , BarcodeFormat . QR_CODE , 10 , 10 , hintMap ) ; System . out . println ( toAscii ( bitMatrix ) ) ;


signature:
public class QRCodeUtils { /** * 将二维码输出为 ASCII
 * @ param bitMatrix
 * @ return */
private static String toAscii ( BitMatrix bitMatrix ) { } }

implementation:
StringBuilder sb = new StringBuilder ( ) ; for ( int rows = 0 ; rows < bitMatrix . getHeight ( ) ; rows ++ ) { for ( int cols = 0 ; cols < bitMatrix . getWidth ( ) ; cols ++ ) { boolean x = bitMatrix . get ( rows , cols ) ; if ( ! x ) { // white
sb . append ( "\033[47m  \033[0m" ) ; } else { sb . append ( "\033[30m  \033[0;39m" ) ; } } sb . append ( "\n" ) ; } return sb . toString ( ) ;


signature:
public class QRCodeUtils { /** * 读取二维码信息
 * @ param filePath 文件路径
 * @ param hintMap hintMap
 * @ return 二维码内容 */
private static String readQRCode ( File filePath , Map hintMap ) { } }

implementation: try { BinaryBitmap binaryBitmap = new BinaryBitmap ( new HybridBinarizer ( new BufferedImageLuminanceSource ( ImageIO . read ( new FileInputStream ( filePath ) ) ) ) ) ; Result qrCodeResult = new MultiFormatReader ( ) . decode ( binaryBitmap , hintMap ) ; return qrCodeResult . getText ( ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; return null ; }


signature:
public class OkHttpUtils { /** * Setting testMode configuration . If set as testMode , the connection will skip certification check
 * @ param builder
 * @ return */
public static OkHttpClient . Builder configureToIgnoreCertificate ( OkHttpClient . Builder builder ) { } }

implementation:
log . warn ( "Ignore Ssl Certificate" ) ; try { /* Create a trust manager that does not validate certificate chains */
final TrustManager [ ] trustAllCerts = new TrustManager [ ] { new X509TrustManager ( ) { @ Override public void checkClientTrusted ( java . security . cert . X509Certificate [ ] chain , String authType ) { } @ Override public void checkServerTrusted ( java . security . cert . X509Certificate [ ] chain , String authType ) { } @ Override public java . security . cert . X509Certificate [ ] getAcceptedIssuers ( ) { return new java . security . cert . X509Certificate [ ] { } ; } } } ; /* Install the all - trusting trust manager */
final SSLContext sslContext = SSLContext . getInstance ( "SSL" ) ; sslContext . init ( null , trustAllCerts , new java . security . SecureRandom ( ) ) ; /* Create an ssl socket factory with our all - trusting manager */
final SSLSocketFactory sslSocketFactory = sslContext . getSocketFactory ( ) ; builder . sslSocketFactory ( sslSocketFactory , ( X509TrustManager ) trustAllCerts [ 0 ] ) ; builder . hostnameVerifier ( new HostnameVerifier ( ) { @ Override public boolean verify ( String hostname , SSLSession session ) { return true ; } } ) ; } catch ( Exception e ) { log . warn ( "Exception while configuring IgnoreSslCertificate" + e , e ) ; } return builder ;


signature:
public class SourceOrdering { /** * it ' s safe to cast immutable list of < ? extends Element > to a list of < Element > */
@ SuppressWarnings ( "unchecked" ) public static ImmutableList < Element > getEnclosedElements ( Element element ) { } }

implementation: return ( ImmutableList < Element > ) enclosedBy ( element ) . immutableSortedCopy ( element . getEnclosedElements ( ) ) ;


signature:
public class SourceOrdering { /** * While we have { @ link SourceOrdering } , there ' s still a problem : We have inheritance hierarchy
 * and
 * we want to have all defined or inherited accessors returned as members of target type , like
 * { @ link Elements # getAllMembers ( TypeElement ) } , but we need to have them properly and stably
 * sorted .
 * This implementation doesn ' t try to correctly resolve order for accessors inherited from
 * different supertypes ( interfaces ) , just something that stable and reasonable wrt source ordering
 * without handling complex cases .
 * @ param elements the elements utility
 * @ param types the types utility
 * @ param originatingType the type to traverse
 * @ return provider of all accessors in source order and mapping */
public static AccessorProvider getAllAccessorsProvider ( final Elements elements , final Types types , final TypeElement originatingType ) { } }

implementation:
class CollectedOrdering extends Ordering < Element > { class Intratype { final String inType ; final Ordering < String > ordering ; final int rank ; Intratype ( String inType , int rank , List < String > accessors ) { this . inType = inType ; this . rank = rank ; this . ordering = Ordering . explicit ( accessors ) ; } @ Override public String toString ( ) { return "(<=> " + inType + ", " + rank + ", " + ordering + ")" ; } } final Map < String , Intratype > accessorOrderings = new LinkedHashMap < > ( ) ; final Set < TypeElement > linearizedTypes = new LinkedHashSet < > ( ) ; final ArrayListMultimap < String , TypeElement > accessorMapping = ArrayListMultimap . create ( ) ; CollectedOrdering ( ) { traverse ( originatingType ) ; collectAccessors ( ) ; } void traverse ( @ Nullable TypeElement element ) { if ( element == null || isJavaLangObject ( element ) ) { return ; } for ( TypeMirror implementedInterface : element . getInterfaces ( ) ) { traverse ( toElement ( implementedInterface ) ) ; } if ( element . getKind ( ) . isClass ( ) ) { // collectEnclosing ( element ) ;
traverse ( toElement ( element . getSuperclass ( ) ) ) ; } // we add this after so we start with the deepest
linearizedTypes . add ( element ) ; } @ Nullable TypeElement toElement ( TypeMirror type ) { if ( type . getKind ( ) == TypeKind . DECLARED ) { return ( TypeElement ) ( ( DeclaredType ) type ) . asElement ( ) ; } return null ; } void collectAccessors ( ) { int i = 0 ; for ( TypeElement type : linearizedTypes ) { List < String > accessorsInType = FluentIterable . from ( SourceOrdering . getEnclosedElements ( type ) ) . filter ( IsParameterlessNonstaticNonobject . PREDICATE ) . transform ( ToSimpleName . FUNCTION ) . toList ( ) ; String typeTag = type . getSimpleName ( ) . toString ( ) ; Intratype intratype = new Intratype ( typeTag , i ++ , accessorsInType ) ; for ( String name : accessorsInType ) { // we override accessors by the ones redeclared in later types
accessorMapping . put ( name , type ) ; accessorOrderings . put ( name , intratype ) ; } } } @ Override public int compare ( Element left , Element right ) { String leftKey = ToSimpleName . FUNCTION . apply ( left ) ; String rightKey = ToSimpleName . FUNCTION . apply ( right ) ; Intratype leftIntratype = accessorOrderings . get ( leftKey ) ; Intratype rightIntratype = accessorOrderings . get ( rightKey ) ; return leftIntratype == rightIntratype ? leftIntratype . ordering . compare ( leftKey , rightKey ) : Integer . compare ( leftIntratype . rank , rightIntratype . rank ) ; } } final CollectedOrdering ordering = new CollectedOrdering ( ) ; final ImmutableList < ExecutableElement > sortedList = ordering . immutableSortedCopy ( disambiguateMethods ( ElementFilter . methodsIn ( elements . getAllMembers ( originatingType ) ) ) ) ; return new AccessorProvider ( ) { ImmutableListMultimap < String , TypeElement > accessorMapping = ImmutableListMultimap . copyOf ( ordering . accessorMapping ) ; @ Override public ImmutableListMultimap < String , TypeElement > accessorMapping ( ) { return accessorMapping ; } @ Override public ImmutableList < ExecutableElement > get ( ) { return sortedList ; } } ;


signature:
public class ExpectedSubtypesAdapter { /** * Creates adapter from { @ link Gson } and type tokens .
 * @ param < T > the generic type
 * @ param gson Gson instance
 * @ param type supertype token
 * @ param subtypes subtype tokens
 * @ return subtype adapter */
@ SafeVarargs public static < T > ExpectedSubtypesAdapter < T > create ( Gson gson , TypeToken < T > type , TypeToken < ? extends T > ... subtypes ) { } }

implementation: return new ExpectedSubtypesAdapter < > ( gson , type , subtypes ) ;


signature:
public class ExpectedSubtypesAdapter { /** * enforced by constructor parameters . */
@ SuppressWarnings ( "unchecked" ) @ Override public T read ( JsonReader in ) throws IOException { } }

implementation: List < Exception > exceptions = new ArrayList < > ( subtypes . length ) ; ReaderSupplier readerSupplier = readForSupplier ( in ) ; for ( TypeAdapter < ? > typeAdapter : adapters ) { try { return ( T ) typeAdapter . read ( readerSupplier . create ( ) ) ; } catch ( Exception ex ) { exceptions . add ( ex ) ; } } JsonParseException failure = new JsonParseException ( String . format ( "Cannot parse %s with following subtypes: %s" , type , Arrays . toString ( subtypes ) ) ) ; for ( Exception exception : exceptions ) { failure . addSuppressed ( exception ) ; } throw failure ;


signature:
public class Constitution { /** * Value is the canonical outside look of the value type . It should be either
 * { @ link # typeAbstract ( ) } or { @ link # typeImmutable ( ) } .
 * For factory it is a special surrogate .
 * @ return canonical value type name forms */
@ Value . Lazy public NameForms typeValue ( ) { } }

implementation: if ( protoclass ( ) . kind ( ) . isValue ( ) ) { return returnsAbstractValueType ( ) ? typeAbstract ( ) : typeImmutable ( ) ; } if ( isFactory ( ) ) { if ( protoclass ( ) . kind ( ) . isConstructor ( ) ) { TypeElement enclosingType = ( TypeElement ) protoclass ( ) . sourceElement ( ) . getEnclosingElement ( ) ; return ImmutableConstitution . NameForms . builder ( ) . simple ( enclosingType . getSimpleName ( ) . toString ( ) ) . relativeRaw ( enclosingType . getQualifiedName ( ) . toString ( ) ) . genericArgs ( generics ( ) . args ( ) ) . relativeAlreadyQualified ( true ) . packageOf ( NA_ERROR ) . visibility ( protoclass ( ) . visibility ( ) ) . build ( ) ; } ExecutableElement method = ( ExecutableElement ) protoclass ( ) . sourceElement ( ) ; String type = method . getReturnType ( ) . toString ( ) ; return ImmutableConstitution . NameForms . builder ( ) . simple ( NA_ERROR ) . relativeRaw ( type ) . packageOf ( NA_ERROR ) . relativeAlreadyQualified ( true ) . visibility ( protoclass ( ) . visibility ( ) ) . build ( ) ; } return typeEnclosing ( ) ;


signature:
public class Constitution { /** * Actual abstract value type that is definitive model for the value type .
 * @ return abstract value type name forms */
@ Value . Lazy public NameForms typeAbstract ( ) { } }

implementation: if ( protoclass ( ) . kind ( ) . isConstructor ( ) ) { return typeValue ( ) ; } List < String > classSegments = Lists . newArrayListWithExpectedSize ( 2 ) ; Element e = SourceNames . collectClassSegments ( protoclass ( ) . sourceElement ( ) , classSegments ) ; verify ( e instanceof PackageElement ) ; String packageOf = ( ( PackageElement ) e ) . getQualifiedName ( ) . toString ( ) ; String relative = DOT_JOINER . join ( classSegments ) ; boolean relativeAlreadyQualified = false ; if ( ! implementationPackage ( ) . equals ( packageOf ) ) { relative = DOT_JOINER . join ( packageOf , relative ) ; relativeAlreadyQualified = true ; } return ImmutableConstitution . NameForms . builder ( ) . simple ( names ( ) . typeAbstract ) . relativeRaw ( relative ) . packageOf ( packageOf ) . genericArgs ( generics ( ) . args ( ) ) . relativeAlreadyQualified ( relativeAlreadyQualified ) . visibility ( protoclass ( ) . visibility ( ) ) . build ( ) ;


signature:
public class Constitution { /** * Package relative path
 * @ param topLevel
 * @ param nested
 * @ return */
private String inPackage ( String topLevel , String ... nested ) { } }

implementation: return DOT_JOINER . join ( null , topLevel , ( Object [ ] ) nested ) ;


signature:
public class Constitution { /** * Actual immutable value type generated implementation .
 * @ return immutable implementation type name forms */
@ Value . Lazy public NameForms typeImmutable ( ) { } }

implementation: String simple , relative ; if ( protoclass ( ) . kind ( ) . isNested ( ) ) { String enclosingSimpleName = typeImmutableEnclosingSimpleName ( ) ; simple = names ( ) . typeImmutableNested ( ) ; relative = inPackage ( enclosingSimpleName , simple ) ; } else if ( hasImmutableInBuilder ( ) ) { simple = names ( ) . typeImmutable ; relative = inPackage ( typeBuilderSimpleName ( ) , simple ) ; } else { simple = names ( ) . typeImmutable ; relative = inPackage ( simple ) ; } return ImmutableConstitution . NameForms . builder ( ) . simple ( simple ) . relativeRaw ( relative ) . genericArgs ( generics ( ) . args ( ) ) . packageOf ( implementationPackage ( ) ) . visibility ( implementationVisibility ( ) ) . build ( ) ;