signature:
public class ConnectableFlowable { /** * Connects to the upstream { @ code ConnectableFlowable } if the number of subscribed
 * subscriber reaches the specified count and disconnect if all subscribers have unsubscribed .
 * < dl >
 * < dt > < b > Backpressure : < / b > < / dt >
 * < dd > The operator itself doesn ' t interfere with backpressure which is determined by the upstream
 * { @ code ConnectableFlowable } ' s backpressure behavior . < / dd >
 * < dt > < b > Scheduler : < / b > < / dt >
 * < dd > This { @ code refCount } overload does not operate on any particular { @ link Scheduler } . < / dd >
 * < / dl >
 * < p > History : 2.1.14 - experimental
 * @ param subscriberCount the number of subscribers required to connect to the upstream
 * @ return the new Flowable instance
 * @ since 2.2 */
@ CheckReturnValue @ SchedulerSupport ( SchedulerSupport . NONE ) @ BackpressureSupport ( BackpressureKind . PASS_THROUGH ) public final Flowable < T > refCount ( int subscriberCount ) { } }

implementation: return refCount ( subscriberCount , 0 , TimeUnit . NANOSECONDS , Schedulers . trampoline ( ) ) ;


signature:
public class ConnectableFlowable { /** * Connects to the upstream { @ code ConnectableFlowable } if the number of subscribed
 * subscriber reaches 1 and disconnect after the specified
 * timeout if all subscribers have unsubscribed .
 * < dl >
 * < dt > < b > Backpressure : < / b > < / dt >
 * < dd > The operator itself doesn ' t interfere with backpressure which is determined by the upstream
 * { @ code ConnectableFlowable } ' s backpressure behavior . < / dd >
 * < dt > < b > Scheduler : < / b > < / dt >
 * < dd > This { @ code refCount } overload operates on the { @ code computation } { @ link Scheduler } . < / dd >
 * < / dl >
 * < p > History : 2.1.14 - experimental
 * @ param timeout the time to wait before disconnecting after all subscribers unsubscribed
 * @ param unit the time unit of the timeout
 * @ return the new Flowable instance
 * @ see # refCount ( long , TimeUnit , Scheduler )
 * @ since 2.2 */
@ CheckReturnValue @ SchedulerSupport ( SchedulerSupport . COMPUTATION ) @ BackpressureSupport ( BackpressureKind . PASS_THROUGH ) public final Flowable < T > refCount ( long timeout , TimeUnit unit ) { } }

implementation: return refCount ( 1 , timeout , unit , Schedulers . computation ( ) ) ;


signature:
public class ConnectableFlowable { /** * Connects to the upstream { @ code ConnectableFlowable } if the number of subscribed
 * subscriber reaches 1 and disconnect after the specified
 * timeout if all subscribers have unsubscribed .
 * < dl >
 * < dt > < b > Backpressure : < / b > < / dt >
 * < dd > The operator itself doesn ' t interfere with backpressure which is determined by the upstream
 * { @ code ConnectableFlowable } ' s backpressure behavior . < / dd >
 * < dt > < b > Scheduler : < / b > < / dt >
 * < dd > This { @ code refCount } overload operates on the specified { @ link Scheduler } . < / dd >
 * < / dl >
 * < p > History : 2.1.14 - experimental
 * @ param timeout the time to wait before disconnecting after all subscribers unsubscribed
 * @ param unit the time unit of the timeout
 * @ param scheduler the target scheduler to wait on before disconnecting
 * @ return the new Flowable instance
 * @ since 2.2 */
@ CheckReturnValue @ SchedulerSupport ( SchedulerSupport . CUSTOM ) @ BackpressureSupport ( BackpressureKind . PASS_THROUGH ) public final Flowable < T > refCount ( long timeout , TimeUnit unit , Scheduler scheduler ) { } }

implementation: return refCount ( 1 , timeout , unit , scheduler ) ;


signature:
public class ConnectableFlowable { /** * Connects to the upstream { @ code ConnectableFlowable } if the number of subscribed
 * subscriber reaches the specified count and disconnect after the specified
 * timeout if all subscribers have unsubscribed .
 * < dl >
 * < dt > < b > Backpressure : < / b > < / dt >
 * < dd > The operator itself doesn ' t interfere with backpressure which is determined by the upstream
 * { @ code ConnectableFlowable } ' s backpressure behavior . < / dd >
 * < dt > < b > Scheduler : < / b > < / dt >
 * < dd > This { @ code refCount } overload operates on the specified { @ link Scheduler } . < / dd >
 * < / dl >
 * < p > History : 2.1.14 - experimental
 * @ param subscriberCount the number of subscribers required to connect to the upstream
 * @ param timeout the time to wait before disconnecting after all subscribers unsubscribed
 * @ param unit the time unit of the timeout
 * @ param scheduler the target scheduler to wait on before disconnecting
 * @ return the new Flowable instance
 * @ since 2.2 */
@ CheckReturnValue @ SchedulerSupport ( SchedulerSupport . CUSTOM ) @ BackpressureSupport ( BackpressureKind . PASS_THROUGH ) public final Flowable < T > refCount ( int subscriberCount , long timeout , TimeUnit unit , Scheduler scheduler ) { } }

implementation: ObjectHelper . verifyPositive ( subscriberCount , "subscriberCount" ) ; ObjectHelper . requireNonNull ( unit , "unit is null" ) ; ObjectHelper . requireNonNull ( scheduler , "scheduler is null" ) ; return RxJavaPlugins . onAssembly ( new FlowableRefCount < T > ( this , subscriberCount , timeout , unit , scheduler ) ) ;


signature:
public class ConnectableFlowable { /** * Returns a Flowable that automatically connects ( at most once ) to this ConnectableFlowable
 * when the specified number of Subscribers subscribe to it and calls the
 * specified callback with the Subscription associated with the established connection .
 * < img width = " 640 " height = " 392 " src = " https : / / raw . github . com / wiki / ReactiveX / RxJava / images / rx - operators / autoConnect . f . png " alt = " " >
 * The connection happens after the given number of subscriptions and happens at most once
 * during the lifetime of the returned Flowable . If this ConnectableFlowable
 * terminates , the connection is never renewed , no matter how Subscribers come
 * and go . Use { @ link # refCount ( ) } to renew a connection or dispose an active
 * connection when all { @ code Subscriber } s have cancelled their { @ code Subscription } s .
 * @ param numberOfSubscribers the number of subscribers to await before calling connect
 * on the ConnectableFlowable . A non - positive value indicates
 * an immediate connection .
 * @ param connection the callback Consumer that will receive the Subscription representing the
 * established connection
 * @ return a Flowable that automatically connects to this ConnectableFlowable
 * when the specified number of Subscribers subscribe to it and calls the
 * specified callback with the Subscription associated with the established connection */
@ NonNull public Flowable < T > autoConnect ( int numberOfSubscribers , @ NonNull Consumer < ? super Disposable > connection ) { } }

implementation: if ( numberOfSubscribers <= 0 ) { this . connect ( connection ) ; return RxJavaPlugins . onAssembly ( this ) ; } return RxJavaPlugins . onAssembly ( new FlowableAutoConnect < T > ( this , numberOfSubscribers , connection ) ) ;


signature:
public class DefaultSubscriber { /** * Requests from the upstream Subscription .
 * @ param n the request amount , positive */
protected final void request ( long n ) { } }

implementation: Subscription s = this . upstream ; if ( s != null ) { s . request ( n ) ; }


signature:
public class ArrayCompositeDisposable { /** * Sets the resource at the specified index and disposes the old resource .
 * @ param index the index of the resource to set
 * @ param resource the new resource
 * @ return true if the resource has ben set , false if the composite has been disposed */
public boolean setResource ( int index , Disposable resource ) { } }

implementation: for ( ; ; ) { Disposable o = get ( index ) ; if ( o == DisposableHelper . DISPOSED ) { resource . dispose ( ) ; return false ; } if ( compareAndSet ( index , o , resource ) ) { if ( o != null ) { o . dispose ( ) ; } return true ; } }


signature:
public class ArrayCompositeDisposable { /** * Replaces the resource at the specified index and returns the old resource .
 * @ param index the index of the resource to replace
 * @ param resource the new resource
 * @ return the old resource , can be null */
public Disposable replaceResource ( int index , Disposable resource ) { } }

implementation: for ( ; ; ) { Disposable o = get ( index ) ; if ( o == DisposableHelper . DISPOSED ) { resource . dispose ( ) ; return null ; } if ( compareAndSet ( index , o , resource ) ) { return o ; } }


signature:
public class BlockingBaseSubscriber { /** * Block until the first value arrives and return it , otherwise
 * return null for an empty source and rethrow any exception .
 * @ return the first value or null if the source is empty */
public final T blockingGet ( ) { } }

implementation: if ( getCount ( ) != 0 ) { try { BlockingHelper . verifyNonBlocking ( ) ; await ( ) ; } catch ( InterruptedException ex ) { Subscription s = this . upstream ; this . upstream = SubscriptionHelper . CANCELLED ; if ( s != null ) { s . cancel ( ) ; } throw ExceptionHelper . wrapOrThrow ( ex ) ; } } Throwable e = error ; if ( e != null ) { throw ExceptionHelper . wrapOrThrow ( e ) ; } return value ;


signature:
public class PublishSubject { /** * Tries to add the given subscriber to the subscribers array atomically
 * or returns false if the subject has terminated .
 * @ param ps the subscriber to add
 * @ return true if successful , false if the subject has terminated */
boolean add ( PublishDisposable < T > ps ) { } }

implementation: for ( ; ; ) { PublishDisposable < T > [ ] a = subscribers . get ( ) ; if ( a == TERMINATED ) { return false ; } int n = a . length ; @ SuppressWarnings ( "unchecked" ) PublishDisposable < T > [ ] b = new PublishDisposable [ n + 1 ] ; System . arraycopy ( a , 0 , b , 0 , n ) ; b [ n ] = ps ; if ( subscribers . compareAndSet ( a , b ) ) { return true ; } }


signature:
public class PublishSubject { /** * Atomically removes the given subscriber if it is subscribed to the subject .
 * @ param ps the subject to remove */
@ SuppressWarnings ( "unchecked" ) void remove ( PublishDisposable < T > ps ) { } }

implementation: for ( ; ; ) { PublishDisposable < T > [ ] a = subscribers . get ( ) ; if ( a == TERMINATED || a == EMPTY ) { return ; } int n = a . length ; int j = - 1 ; for ( int i = 0 ; i < n ; i ++ ) { if ( a [ i ] == ps ) { j = i ; break ; } } if ( j < 0 ) { return ; } PublishDisposable < T > [ ] b ; if ( n == 1 ) { b = EMPTY ; } else { b = new PublishDisposable [ n - 1 ] ; System . arraycopy ( a , 0 , b , 0 , j ) ; System . arraycopy ( a , j + 1 , b , j , n - j - 1 ) ; } if ( subscribers . compareAndSet ( a , b ) ) { return ; } }


signature:
public class FlowableReplay { /** * Given a connectable observable factory , it multicasts over the generated
 * ConnectableObservable via a selector function .
 * @ param < U > the connectable observable type
 * @ param < R > the result type
 * @ param connectableFactory the factory that returns a ConnectableFlowable for each individual subscriber
 * @ param selector the function that receives a Flowable and should return another Flowable that will be subscribed to
 * @ return the new Observable instance */
public static < U , R > Flowable < R > multicastSelector ( final Callable < ? extends ConnectableFlowable < U > > connectableFactory , final Function < ? super Flowable < U > , ? extends Publisher < R > > selector ) { } }

implementation: return new MulticastFlowable < R , U > ( connectableFactory , selector ) ;


signature:
public class FlowableReplay { /** * Child Subscribers will observe the events of the ConnectableObservable on the
 * specified scheduler .
 * @ param < T > the value type
 * @ param cf the ConnectableFlowable to wrap
 * @ param scheduler the target scheduler
 * @ return the new ConnectableObservable instance */
public static < T > ConnectableFlowable < T > observeOn ( final ConnectableFlowable < T > cf , final Scheduler scheduler ) { } }

implementation: final Flowable < T > flowable = cf . observeOn ( scheduler ) ; return RxJavaPlugins . onAssembly ( new ConnectableFlowableReplay < T > ( cf , flowable ) ) ;


signature:
public class FlowableReplay { /** * Creates a replaying ConnectableObservable with an unbounded buffer .
 * @ param < T > the value type
 * @ param source the source Publisher to use
 * @ return the new ConnectableObservable instance */
@ SuppressWarnings ( "unchecked" ) public static < T > ConnectableFlowable < T > createFrom ( Flowable < ? extends T > source ) { } }

implementation: return create ( source , DEFAULT_UNBOUNDED_FACTORY ) ;


signature:
public class FlowableReplay { /** * Creates a replaying ConnectableObservable with a size bound buffer .
 * @ param < T > the value type
 * @ param source the source Flowable to use
 * @ param bufferSize the maximum number of elements to hold
 * @ return the new ConnectableObservable instance */
public static < T > ConnectableFlowable < T > create ( Flowable < T > source , final int bufferSize ) { } }

implementation: if ( bufferSize == Integer . MAX_VALUE ) { return createFrom ( source ) ; } return create ( source , new ReplayBufferTask < T > ( bufferSize ) ) ;


signature:
public class FlowableReplay { /** * Creates a replaying ConnectableObservable with a time bound buffer .
 * @ param < T > the value type
 * @ param source the source Flowable to use
 * @ param maxAge the maximum age of entries
 * @ param unit the unit of measure of the age amount
 * @ param scheduler the target scheduler providing the current time
 * @ return the new ConnectableObservable instance */
public static < T > ConnectableFlowable < T > create ( Flowable < T > source , long maxAge , TimeUnit unit , Scheduler scheduler ) { } }

implementation: return create ( source , maxAge , unit , scheduler , Integer . MAX_VALUE ) ;


signature:
public class FlowableReplay { /** * Creates a replaying ConnectableObservable with a size and time bound buffer .
 * @ param < T > the value type
 * @ param source the source Flowable to use
 * @ param maxAge the maximum age of entries
 * @ param unit the unit of measure of the age amount
 * @ param scheduler the target scheduler providing the current time
 * @ param bufferSize the maximum number of elements to hold
 * @ return the new ConnectableFlowable instance */
public static < T > ConnectableFlowable < T > create ( Flowable < T > source , final long maxAge , final TimeUnit unit , final Scheduler scheduler , final int bufferSize ) { } }

implementation: return create ( source , new ScheduledReplayBufferTask < T > ( bufferSize , maxAge , unit , scheduler ) ) ;


signature:
public class FlowableReplay { /** * Creates a OperatorReplay instance to replay values of the given source observable .
 * @ param source the source observable
 * @ param bufferFactory the factory to instantiate the appropriate buffer when the observable becomes active
 * @ return the connectable observable */
static < T > ConnectableFlowable < T > create ( Flowable < T > source , final Callable < ? extends ReplayBuffer < T > > bufferFactory ) { } }

implementation:
// the current connection to source needs to be shared between the operator and its onSubscribe call
final AtomicReference < ReplaySubscriber < T > > curr = new AtomicReference < ReplaySubscriber < T > > ( ) ; Publisher < T > onSubscribe = new ReplayPublisher < T > ( curr , bufferFactory ) ; return RxJavaPlugins . onAssembly ( new FlowableReplay < T > ( onSubscribe , source , curr , bufferFactory ) ) ;


signature:
public class MoshiConverterFactory { /** * Create an instance using { @ code moshi } for conversion . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static MoshiConverterFactory create ( Moshi moshi ) { } }

implementation: if ( moshi == null ) throw new NullPointerException ( "moshi == null" ) ; return new MoshiConverterFactory ( moshi , false , false , false ) ;


signature:
public class RxJava2CallAdapterFactory { /** * Returns an instance which creates synchronous observables that
 * { @ linkplain Observable # subscribeOn ( Scheduler ) subscribe on } { @ code scheduler } by default . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static RxJava2CallAdapterFactory createWithScheduler ( Scheduler scheduler ) { } }

implementation: if ( scheduler == null ) throw new NullPointerException ( "scheduler == null" ) ; return new RxJava2CallAdapterFactory ( scheduler , false ) ;


signature:
public class SimpleXmlConverterFactory { /** * Create an instance using { @ code serializer } for non - strict conversion . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static SimpleXmlConverterFactory createNonStrict ( Serializer serializer ) { } }

implementation: if ( serializer == null ) throw new NullPointerException ( "serializer == null" ) ; return new SimpleXmlConverterFactory ( serializer , false ) ;


signature:
public class Utils { /** * Returns the generic supertype for { @ code supertype } . For example , given a class { @ code
 * IntegerSet } , the result for when supertype is { @ code Set . class } is { @ code Set < Integer > } and the
 * result when the supertype is { @ code Collection . class } is { @ code Collection < Integer > } . */
static Type getGenericSupertype ( Type context , Class < ? > rawType , Class < ? > toResolve ) { } }

implementation:
if ( toResolve == rawType ) return context ; // We skip searching through interfaces if unknown is an interface .
if ( toResolve . isInterface ( ) ) { Class < ? > [ ] interfaces = rawType . getInterfaces ( ) ; for ( int i = 0 , length = interfaces . length ; i < length ; i ++ ) { if ( interfaces [ i ] == toResolve ) { return rawType . getGenericInterfaces ( ) [ i ] ; } else if ( toResolve . isAssignableFrom ( interfaces [ i ] ) ) { return getGenericSupertype ( rawType . getGenericInterfaces ( ) [ i ] , interfaces [ i ] , toResolve ) ; } } } // Check our supertypes .
if ( ! rawType . isInterface ( ) ) { while ( rawType != Object . class ) { Class < ? > rawSupertype = rawType . getSuperclass ( ) ; if ( rawSupertype == toResolve ) { return rawType . getGenericSuperclass ( ) ; } else if ( toResolve . isAssignableFrom ( rawSupertype ) ) { return getGenericSupertype ( rawType . getGenericSuperclass ( ) , rawSupertype , toResolve ) ; } rawType = rawSupertype ; } } // We can ' t resolve this further .
return toResolve ;


signature:
public class Calls { /** * Invokes { @ code callable } once for the returned { @ link Call } and once for each instance that is
 * obtained from { @ linkplain Call # clone ( ) cloning } the returned { @ link Call } . */
public static < T > Call < T > defer ( Callable < Call < T > > callable ) { } }

implementation: return new DeferredCall < > ( callable ) ;


signature:
public class Retrofit { /** * Create an implementation of the API endpoints defined by the { @ code service } interface .
 * The relative path for a given method is obtained from an annotation on the method describing
 * the request type . The built - in methods are { @ link retrofit2 . http . GET GET } ,
 * { @ link retrofit2 . http . PUT PUT } , { @ link retrofit2 . http . POST POST } , { @ link retrofit2 . http . PATCH
 * PATCH } , { @ link retrofit2 . http . HEAD HEAD } , { @ link retrofit2 . http . DELETE DELETE } and
 * { @ link retrofit2 . http . OPTIONS OPTIONS } . You can use a custom HTTP method with
 * { @ link HTTP @ HTTP } . For a dynamic URL , omit the path on the annotation and annotate the first
 * parameter with { @ link Url @ Url } .
 * Method parameters can be used to replace parts of the URL by annotating them with
 * { @ link retrofit2 . http . Path @ Path } . Replacement sections are denoted by an identifier
 * surrounded by curly braces ( e . g . , " { foo } " ) . To add items to the query string of a URL use
 * { @ link retrofit2 . http . Query @ Query } .
 * The body of a request is denoted by the { @ link retrofit2 . http . Body @ Body } annotation . The
 * object will be converted to request representation by one of the { @ link Converter . Factory }
 * instances . A { @ link RequestBody } can also be used for a raw representation .
 * Alternative request body formats are supported by method annotations and corresponding
 * parameter annotations :
 * < ul >
 * < li > { @ link retrofit2 . http . FormUrlEncoded @ FormUrlEncoded } - Form - encoded data with key - value
 * pairs specified by the { @ link retrofit2 . http . Field @ Field } parameter annotation .
 * < li > { @ link retrofit2 . http . Multipart @ Multipart } - RFC 2388 - compliant multipart data with
 * parts specified by the { @ link retrofit2 . http . Part @ Part } parameter annotation .
 * < / ul >
 * Additional static headers can be added for an endpoint using the
 * { @ link retrofit2 . http . Headers @ Headers } method annotation . For per - request control over a
 * header annotate a parameter with { @ link Header @ Header } .
 * By default , methods return a { @ link Call } which represents the HTTP request . The generic
 * parameter of the call is the response body type and will be converted by one of the
 * { @ link Converter . Factory } instances . { @ link ResponseBody } can also be used for a raw
 * representation . { @ link Void } can be used if you do not care about the body contents .
 * For example :
 * < pre >
 * public interface CategoryService {
 * & # 64 ; POST ( " category / { cat } / " )
 * Call & lt ; List & lt ; Item & gt ; & gt ; categoryList ( @ Path ( " cat " ) String a , @ Query ( " page " ) int b ) ;
 * < / pre > */
@ SuppressWarnings ( "unchecked" ) // Single - interface proxy creation guarded by parameter safety .
public < T > T create ( final Class < T > service ) { } }

implementation:
Utils . validateServiceInterface ( service ) ; if ( validateEagerly ) { eagerlyValidateMethods ( service ) ; } return ( T ) Proxy . newProxyInstance ( service . getClassLoader ( ) , new Class < ? > [ ] { service } , new InvocationHandler ( ) { private final Platform platform = Platform . get ( ) ; private final Object [ ] emptyArgs = new Object [ 0 ] ; @ Override public @ Nullable Object invoke ( Object proxy , Method method , @ Nullable Object [ ] args ) throws Throwable { // If the method is a method from Object then defer to normal invocation .
if ( method . getDeclaringClass ( ) == Object . class ) { return method . invoke ( this , args ) ; } if ( platform . isDefaultMethod ( method ) ) { return platform . invokeDefaultMethod ( method , service , proxy , args ) ; } return loadServiceMethod ( method ) . invoke ( args != null ? args : emptyArgs ) ; } } ) ;


signature:
public class Retrofit { /** * Returns the { @ link CallAdapter } for { @ code returnType } from the available { @ linkplain
 * # callAdapterFactories ( ) factories } .
 * @ throws IllegalArgumentException if no call adapter available for { @ code type } . */
public CallAdapter < ? , ? > callAdapter ( Type returnType , Annotation [ ] annotations ) { } }

implementation: return nextCallAdapter ( null , returnType , annotations ) ;


signature:
public class Retrofit { /** * Returns the { @ link CallAdapter } for { @ code returnType } from the available { @ linkplain
 * # callAdapterFactories ( ) factories } except { @ code skipPast } .
 * @ throws IllegalArgumentException if no call adapter available for { @ code type } . */
public CallAdapter < ? , ? > nextCallAdapter ( @ Nullable CallAdapter . Factory skipPast , Type returnType , Annotation [ ] annotations ) { } }

implementation: checkNotNull ( returnType , "returnType == null" ) ; checkNotNull ( annotations , "annotations == null" ) ; int start = callAdapterFactories . indexOf ( skipPast ) + 1 ; for ( int i = start , count = callAdapterFactories . size ( ) ; i < count ; i ++ ) { CallAdapter < ? , ? > adapter = callAdapterFactories . get ( i ) . get ( returnType , annotations , this ) ; if ( adapter != null ) { return adapter ; } } StringBuilder builder = new StringBuilder ( "Could not locate call adapter for " ) . append ( returnType ) . append ( ".\n" ) ; if ( skipPast != null ) { builder . append ( "  Skipped:" ) ; for ( int i = 0 ; i < start ; i ++ ) { builder . append ( "\n   * " ) . append ( callAdapterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } builder . append ( '\n' ) ; } builder . append ( "  Tried:" ) ; for ( int i = start , count = callAdapterFactories . size ( ) ; i < count ; i ++ ) { builder . append ( "\n   * " ) . append ( callAdapterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } throw new IllegalArgumentException ( builder . toString ( ) ) ;


signature:
public class Retrofit { /** * Returns a { @ link Converter } for { @ code type } to { @ link RequestBody } from the available
 * { @ linkplain # converterFactories ( ) factories } .
 * @ throws IllegalArgumentException if no converter available for { @ code type } . */
public < T > Converter < T , RequestBody > requestBodyConverter ( Type type , Annotation [ ] parameterAnnotations , Annotation [ ] methodAnnotations ) { } }

implementation: return nextRequestBodyConverter ( null , type , parameterAnnotations , methodAnnotations ) ;


signature:
public class Retrofit { /** * Returns a { @ link Converter } for { @ code type } to { @ link RequestBody } from the available
 * { @ linkplain # converterFactories ( ) factories } except { @ code skipPast } .
 * @ throws IllegalArgumentException if no converter available for { @ code type } . */
public < T > Converter < T , RequestBody > nextRequestBodyConverter ( @ Nullable Converter . Factory skipPast , Type type , Annotation [ ] parameterAnnotations , Annotation [ ] methodAnnotations ) { } }

implementation:
checkNotNull ( type , "type == null" ) ; checkNotNull ( parameterAnnotations , "parameterAnnotations == null" ) ; checkNotNull ( methodAnnotations , "methodAnnotations == null" ) ; int start = converterFactories . indexOf ( skipPast ) + 1 ; for ( int i = start , count = converterFactories . size ( ) ; i < count ; i ++ ) { Converter . Factory factory = converterFactories . get ( i ) ; Converter < ? , RequestBody > converter = factory . requestBodyConverter ( type , parameterAnnotations , methodAnnotations , this ) ; if ( converter != null ) { // noinspection unchecked
return ( Converter < T , RequestBody > ) converter ; } } StringBuilder builder = new StringBuilder ( "Could not locate RequestBody converter for " ) . append ( type ) . append ( ".\n" ) ; if ( skipPast != null ) { builder . append ( "  Skipped:" ) ; for ( int i = 0 ; i < start ; i ++ ) { builder . append ( "\n   * " ) . append ( converterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } builder . append ( '\n' ) ; } builder . append ( "  Tried:" ) ; for ( int i = start , count = converterFactories . size ( ) ; i < count ; i ++ ) { builder . append ( "\n   * " ) . append ( converterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } throw new IllegalArgumentException ( builder . toString ( ) ) ;


signature:
public class Retrofit { /** * Returns a { @ link Converter } for { @ link ResponseBody } to { @ code type } from the available
 * { @ linkplain # converterFactories ( ) factories } .
 * @ throws IllegalArgumentException if no converter available for { @ code type } . */
public < T > Converter < ResponseBody , T > responseBodyConverter ( Type type , Annotation [ ] annotations ) { } }

implementation: return nextResponseBodyConverter ( null , type , annotations ) ;


signature:
public class Retrofit { /** * Returns a { @ link Converter } for { @ link ResponseBody } to { @ code type } from the available
 * { @ linkplain # converterFactories ( ) factories } except { @ code skipPast } .
 * @ throws IllegalArgumentException if no converter available for { @ code type } . */
public < T > Converter < ResponseBody , T > nextResponseBodyConverter ( @ Nullable Converter . Factory skipPast , Type type , Annotation [ ] annotations ) { } }

implementation:
checkNotNull ( type , "type == null" ) ; checkNotNull ( annotations , "annotations == null" ) ; int start = converterFactories . indexOf ( skipPast ) + 1 ; for ( int i = start , count = converterFactories . size ( ) ; i < count ; i ++ ) { Converter < ResponseBody , ? > converter = converterFactories . get ( i ) . responseBodyConverter ( type , annotations , this ) ; if ( converter != null ) { // noinspection unchecked
return ( Converter < ResponseBody , T > ) converter ; } } StringBuilder builder = new StringBuilder ( "Could not locate ResponseBody converter for " ) . append ( type ) . append ( ".\n" ) ; if ( skipPast != null ) { builder . append ( "  Skipped:" ) ; for ( int i = 0 ; i < start ; i ++ ) { builder . append ( "\n   * " ) . append ( converterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } builder . append ( '\n' ) ; } builder . append ( "  Tried:" ) ; for ( int i = start , count = converterFactories . size ( ) ; i < count ; i ++ ) { builder . append ( "\n   * " ) . append ( converterFactories . get ( i ) . getClass ( ) . getName ( ) ) ; } throw new IllegalArgumentException ( builder . toString ( ) ) ;


signature:
public class Retrofit { /** * Returns a { @ link Converter } for { @ code type } to { @ link String } from the available
 * { @ linkplain # converterFactories ( ) factories } . */
public < T > Converter < T , String > stringConverter ( Type type , Annotation [ ] annotations ) { } }

implementation:
checkNotNull ( type , "type == null" ) ; checkNotNull ( annotations , "annotations == null" ) ; for ( int i = 0 , count = converterFactories . size ( ) ; i < count ; i ++ ) { Converter < ? , String > converter = converterFactories . get ( i ) . stringConverter ( type , annotations , this ) ; if ( converter != null ) { // noinspection unchecked
return ( Converter < T , String > ) converter ; } } // Nothing matched . Resort to default converter which just calls toString ( ) .
// noinspection unchecked
return ( Converter < T , String > ) BuiltInConverters . ToStringConverter . INSTANCE ;


signature:
public class JaxbConverterFactory { /** * Create an instance using { @ code context } for conversion . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static JaxbConverterFactory create ( JAXBContext context ) { } }

implementation: if ( context == null ) throw new NullPointerException ( "context == null" ) ; return new JaxbConverterFactory ( context ) ;


signature:
public class GsonConverterFactory { /** * Create an instance using { @ code gson } for conversion . Encoding to JSON and
 * decoding from JSON ( when no charset is specified by a header ) will use UTF - 8. */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static GsonConverterFactory create ( Gson gson ) { } }

implementation: if ( gson == null ) throw new NullPointerException ( "gson == null" ) ; return new GsonConverterFactory ( gson ) ;


signature:
public class RxJavaCallAdapterFactory { /** * Returns an instance which creates synchronous observables that
 * { @ linkplain Observable # subscribeOn ( Scheduler ) subscribe on } { @ code scheduler } by default . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static RxJavaCallAdapterFactory createWithScheduler ( Scheduler scheduler ) { } }

implementation: if ( scheduler == null ) throw new NullPointerException ( "scheduler == null" ) ; return new RxJavaCallAdapterFactory ( scheduler , false ) ;


signature:
public class JacksonConverterFactory { /** * Create an instance using { @ code mapper } for conversion . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static JacksonConverterFactory create ( ObjectMapper mapper ) { } }

implementation: if ( mapper == null ) throw new NullPointerException ( "mapper == null" ) ; return new JacksonConverterFactory ( mapper ) ;


signature:
public class HttpServiceMethod { /** * Inspects the annotations on an interface method to construct a reusable service method that
 * speaks HTTP . This requires potentially - expensive reflection so it is best to build each service
 * method only once and reuse it . */
static < ResponseT , ReturnT > HttpServiceMethod < ResponseT , ReturnT > parseAnnotations ( Retrofit retrofit , Method method , RequestFactory requestFactory ) { } }

implementation:
boolean isKotlinSuspendFunction = requestFactory . isKotlinSuspendFunction ; boolean continuationWantsResponse = false ; boolean continuationBodyNullable = false ; Annotation [ ] annotations = method . getAnnotations ( ) ; Type adapterType ; if ( isKotlinSuspendFunction ) { Type [ ] parameterTypes = method . getGenericParameterTypes ( ) ; Type responseType = Utils . getParameterLowerBound ( 0 , ( ParameterizedType ) parameterTypes [ parameterTypes . length - 1 ] ) ; if ( getRawType ( responseType ) == Response . class && responseType instanceof ParameterizedType ) { // Unwrap the actual body type from Response < T > .
responseType = Utils . getParameterUpperBound ( 0 , ( ParameterizedType ) responseType ) ; continuationWantsResponse = true ; } else { // TODO figure out if type is nullable or not
// Metadata metadata = method . getDeclaringClass ( ) . getAnnotation ( Metadata . class )
// Find the entry for method
// Determine if return type is nullable or not
} adapterType = new Utils . ParameterizedTypeImpl ( null , Call . class , responseType ) ; annotations = SkipCallbackExecutorImpl . ensurePresent ( annotations ) ; } else { adapterType = method . getGenericReturnType ( ) ; } CallAdapter < ResponseT , ReturnT > callAdapter = createCallAdapter ( retrofit , method , adapterType , annotations ) ; Type responseType = callAdapter . responseType ( ) ; if ( responseType == okhttp3 . Response . class ) { throw methodError ( method , "'" + getRawType ( responseType ) . getName ( ) + "' is not a valid response body type. Did you mean ResponseBody?" ) ; } if ( responseType == Response . class ) { throw methodError ( method , "Response must include generic type (e.g., Response<String>)" ) ; } // TODO support Unit for Kotlin ?
if ( requestFactory . httpMethod . equals ( "HEAD" ) && ! Void . class . equals ( responseType ) ) { throw methodError ( method , "HEAD method must use Void as response type." ) ; } Converter < ResponseBody , ResponseT > responseConverter = createResponseConverter ( retrofit , method , responseType ) ; okhttp3 . Call . Factory callFactory = retrofit . callFactory ; if ( ! isKotlinSuspendFunction ) { return new CallAdapted < > ( requestFactory , callFactory , responseConverter , callAdapter ) ; } else if ( continuationWantsResponse ) { // noinspection unchecked Kotlin compiler guarantees ReturnT to be Object .
return ( HttpServiceMethod < ResponseT , ReturnT > ) new SuspendForResponse < > ( requestFactory , callFactory , responseConverter , ( CallAdapter < ResponseT , Call < ResponseT > > ) callAdapter ) ; } else { // noinspection unchecked Kotlin compiler guarantees ReturnT to be Object .
return ( HttpServiceMethod < ResponseT , ReturnT > ) new SuspendForBody < > ( requestFactory , callFactory , responseConverter , ( CallAdapter < ResponseT , Call < ResponseT > > ) callAdapter , continuationBodyNullable ) ; }


signature:
public class NetworkBehavior { /** * Create an instance with default behavior which uses { @ code random } to control variance and
 * failure calculation . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public static NetworkBehavior create ( Random random ) { } }

implementation: if ( random == null ) throw new NullPointerException ( "random == null" ) ; return new NetworkBehavior ( random ) ;


signature:
public class NetworkBehavior { /** * Set the network round trip delay . */
public void setDelay ( long amount , TimeUnit unit ) { } }

implementation: if ( amount < 0 ) { throw new IllegalArgumentException ( "Amount must be positive value." ) ; } this . delayMs = unit . toMillis ( amount ) ;


signature:
public class NetworkBehavior { /** * Set the error response factory to be used when an error is triggered . This factory may only
 * return responses for which { @ link Response # isSuccessful ( ) } returns false . */
@ SuppressWarnings ( "ConstantConditions" ) // Guarding public API nullability .
public void setErrorFactory ( Callable < Response < ? > > errorFactory ) { } }

implementation: if ( errorFactory == null ) { throw new NullPointerException ( "errorFactory == null" ) ; } this . errorFactory = errorFactory ;


signature:
public class NetworkBehavior { /** * The HTTP error to be used when an error is triggered . */
public Response < ? > createErrorResponse ( ) { } }

implementation: Response < ? > call ; try { call = errorFactory . call ( ) ; } catch ( Exception e ) { throw new IllegalStateException ( "Error factory threw an exception." , e ) ; } if ( call == null ) { throw new IllegalStateException ( "Error factory returned null." ) ; } if ( call . isSuccessful ( ) ) { throw new IllegalStateException ( "Error factory returned successful response." ) ; } return call ;


signature:
public class NetworkBehavior { /** * Get the delay that should be used for delaying a response in accordance with configured
 * behavior . */
public long calculateDelay ( TimeUnit unit ) { } }

implementation:
float delta = variancePercent / 100f ; // e . g . , 20 / 100f = = 0.2f
float lowerBound = 1f - delta ; // 0.2f - - > 0.8f
float upperBound = 1f + delta ; // 0.2f - - > 1.2f
float bound = upperBound - lowerBound ; // 1.2f - 0.8f = = 0.4f
float delayPercent = lowerBound + ( random . nextFloat ( ) * bound ) ; // 0.8 + ( rnd * 0.4)
long callDelayMs = ( long ) ( delayMs * delayPercent ) ; return MILLISECONDS . convert ( callDelayMs , unit ) ;


signature:
public class Response { /** * Create a synthetic successful response with { @ code body } as the deserialized body . */
public static < T > Response < T > success ( @ Nullable T body ) { } }

implementation: return success ( body , new okhttp3 . Response . Builder ( ) . code ( 200 ) . message ( "OK" ) . protocol ( Protocol . HTTP_1_1 ) . request ( new Request . Builder ( ) . url ( "http://localhost/" ) . build ( ) ) . build ( ) ) ;


signature:
public class Response { /** * Create a successful response from { @ code rawResponse } with { @ code body } as the deserialized
 * body . */
public static < T > Response < T > success ( @ Nullable T body , okhttp3 . Response rawResponse ) { } }

implementation: checkNotNull ( rawResponse , "rawResponse == null" ) ; if ( ! rawResponse . isSuccessful ( ) ) { throw new IllegalArgumentException ( "rawResponse must be successful response" ) ; } return new Response < > ( rawResponse , body , null ) ;


signature:
public class Response { /** * Create a synthetic error response with an HTTP status code of { @ code code } and { @ code body }
 * as the error body . */
public static < T > Response < T > error ( int code , ResponseBody body ) { } }

implementation: if ( code < 400 ) throw new IllegalArgumentException ( "code < 400: " + code ) ; return error ( body , new okhttp3 . Response . Builder ( ) . code ( code ) . message ( "Response.error()" ) . protocol ( Protocol . HTTP_1_1 ) . request ( new Request . Builder ( ) . url ( "http://localhost/" ) . build ( ) ) . build ( ) ) ;


signature:
public class Response { /** * Create an error response from { @ code rawResponse } with { @ code body } as the error body . */
public static < T > Response < T > error ( ResponseBody body , okhttp3 . Response rawResponse ) { } }

implementation: checkNotNull ( body , "body == null" ) ; checkNotNull ( rawResponse , "rawResponse == null" ) ; if ( rawResponse . isSuccessful ( ) ) { throw new IllegalArgumentException ( "rawResponse should not be successful response" ) ; } return new Response < > ( rawResponse , null , body ) ;


signature:
public class LetterSegmenter { /** * 处理数字字母混合输出
 * 如 : windos2000 | linliangyi2005 @ gmail . com
 * * @ param input
 * @ param context
 * @ return */
private boolean processMixLetter ( AnalyzeContext context ) { } }

implementation:
boolean needLock = false ; if ( this . start == - 1 ) { // 当前的分词器尚未开始处理字符
if ( CharacterUtil . CHAR_ARABIC == context . getCurrentCharType ( ) || CharacterUtil . CHAR_ENGLISH == context . getCurrentCharType ( ) ) { // 记录起始指针的位置 , 标明分词器进入处理状态
this . start = context . getCursor ( ) ; this . end = start ; } } else { // 当前的分词器正在处理字符
if ( CharacterUtil . CHAR_ARABIC == context . getCurrentCharType ( ) || CharacterUtil . CHAR_ENGLISH == context . getCurrentCharType ( ) ) { // 记录下可能的结束位置
this . end = context . getCursor ( ) ; } else if ( CharacterUtil . CHAR_USELESS == context . getCurrentCharType ( ) && this . isLetterConnector ( context . getCurrentChar ( ) ) ) { // 记录下可能的结束位置
this . end = context . getCursor ( ) ; } else { // 遇到非Letter字符 , 输出词元
Lexeme newLexeme = new Lexeme ( context . getBufferOffset ( ) , this . start , this . end - this . start + 1 , Lexeme . TYPE_LETTER ) ; context . addLexeme ( newLexeme ) ; this . start = - 1 ; this . end = - 1 ; } } // 判断缓冲区是否已经读完
if ( context . isBufferConsumed ( ) && ( this . start != - 1 && this . end != - 1 ) ) { // 缓冲以读完 , 输出词元
Lexeme newLexeme = new Lexeme ( context . getBufferOffset ( ) , this . start , this . end - this . start + 1 , Lexeme . TYPE_LETTER ) ; context . addLexeme ( newLexeme ) ; this . start = - 1 ; this . end = - 1 ; } // 判断是否锁定缓冲区
if ( this . start == - 1 && this . end == - 1 ) { // 对缓冲区解锁
needLock = false ; } else { needLock = true ; } return needLock ;


signature:
public class CharacterUtil { /** * 识别字符类型
 * @ param input
 * @ return int CharacterUtil定义的字符类型常量 */
static int identifyCharType ( char input ) { } }

implementation:
if ( input >= '0' && input <= '9' ) { return CHAR_ARABIC ; } else if ( ( input >= 'a' && input <= 'z' ) || ( input >= 'A' && input <= 'Z' ) ) { return CHAR_ENGLISH ; } else { Character . UnicodeBlock ub = Character . UnicodeBlock . of ( input ) ; if ( ub == Character . UnicodeBlock . CJK_UNIFIED_IDEOGRAPHS || ub == Character . UnicodeBlock . CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character . UnicodeBlock . CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ) { // 目前已知的中文字符UTF - 8集合
return CHAR_CHINESE ; } else if ( ub == Character . UnicodeBlock . HALFWIDTH_AND_FULLWIDTH_FORMS // 全角数字字符和日韩字符
// 韩文字符集
|| ub == Character . UnicodeBlock . HANGUL_SYLLABLES || ub == Character . UnicodeBlock . HANGUL_JAMO || ub == Character . UnicodeBlock . HANGUL_COMPATIBILITY_JAMO // 日文字符集
|| ub == Character . UnicodeBlock . HIRAGANA // 平假名
|| ub == Character . UnicodeBlock . KATAKANA // 片假名
|| ub == Character . UnicodeBlock . KATAKANA_PHONETIC_EXTENSIONS ) { return CHAR_OTHER_CJK ; } } // 其他的不做处理的字符
return CHAR_USELESS ;


signature:
public class CharacterUtil { /** * 进行字符规格化 ( 全角转半角 , 大写转小写处理 )
 * @ param input
 * @ return char */
static char regularize ( char input , boolean lowercase ) { } }

implementation: if ( input == 12288 ) { input = ( char ) 32 ; } else if ( input > 65280 && input < 65375 ) { input = ( char ) ( input - 65248 ) ; } else if ( input >= 'A' && input <= 'Z' && lowercase ) { input += 32 ; } return input ;


signature:
public class IKSegmenter { /** * 初始化词典 , 加载子分词器实现
 * @ return List < ISegmenter > */
private List < ISegmenter > loadSegmenters ( ) { } }

implementation:
List < ISegmenter > segmenters = new ArrayList < ISegmenter > ( 4 ) ; // 处理字母的子分词器
segmenters . add ( new LetterSegmenter ( ) ) ; // 处理中文数量词的子分词器
segmenters . add ( new CN_QuantifierSegmenter ( ) ) ; // 处理中文词的子分词器
segmenters . add ( new CJKSegmenter ( ) ) ; return segmenters ;


signature:
public class IKSegmenter { /** * 分词 , 获取下一个词元
 * @ return Lexeme 词元对象
 * @ throws java . io . IOException */
public synchronized Lexeme next ( ) throws IOException { } }

implementation:
Lexeme l = null ; while ( ( l = context . getNextLexeme ( ) ) == null ) { /* * 从reader中读取数据 , 填充buffer
 * 如果reader是分次读入buffer的 , 那么buffer要 进行移位处理
 * 移位处理上次读入的但未处理的数据 */
int available = context . fillBuffer ( this . input ) ; if ( available <= 0 ) { // reader已经读完
context . reset ( ) ; return null ; } else { // 初始化指针
context . initCursor ( ) ; do { // 遍历子分词器
for ( ISegmenter segmenter : segmenters ) { segmenter . analyze ( context ) ; } // 字符缓冲区接近读完 , 需要读入新的字符
if ( context . needRefillBuffer ( ) ) { break ; } // 向前移动指针
} while ( context . moveCursor ( ) ) ; // 重置子分词器 , 为下轮循环进行初始化
for ( ISegmenter segmenter : segmenters ) { segmenter . reset ( ) ; } } // 对分词进行歧义处理
this . arbitrator . process ( context , configuration . isUseSmart ( ) ) ; // 将分词结果输出到结果集 , 并处理未切分的单个CJK字符
context . outputToResult ( ) ; // 记录本次分词的缓冲区位移
context . markBufferOffset ( ) ; } return l ;


signature:
public class IKSegmenter { /** * 重置分词器到初始状态
 * @ param input */
public synchronized void reset ( Reader input ) { } }

implementation: this . input = input ; context . reset ( ) ; for ( ISegmenter segmenter : segmenters ) { segmenter . reset ( ) ; }


signature:
public class IKArbitrator { /** * 分词歧义处理
 * * @ param orgLexemes
 * @ param useSmart */
void process ( AnalyzeContext context , boolean useSmart ) { } }

implementation:
QuickSortSet orgLexemes = context . getOrgLexemes ( ) ; Lexeme orgLexeme = orgLexemes . pollFirst ( ) ; LexemePath crossPath = new LexemePath ( ) ; while ( orgLexeme != null ) { if ( ! crossPath . addCrossLexeme ( orgLexeme ) ) { // 找到与crossPath不相交的下一个crossPath
if ( crossPath . size ( ) == 1 || ! useSmart ) { // crossPath没有歧义 或者 不做歧义处理
// 直接输出当前crossPath
context . addLexemePath ( crossPath ) ; } else { // 对当前的crossPath进行歧义处理
QuickSortSet . Cell headCell = crossPath . getHead ( ) ; LexemePath judgeResult = this . judge ( headCell , crossPath . getPathLength ( ) ) ; // 输出歧义处理结果judgeResult
context . addLexemePath ( judgeResult ) ; } // 把orgLexeme加入新的crossPath中
crossPath = new LexemePath ( ) ; crossPath . addCrossLexeme ( orgLexeme ) ; } orgLexeme = orgLexemes . pollFirst ( ) ; } // 处理最后的path
if ( crossPath . size ( ) == 1 || ! useSmart ) { // crossPath没有歧义 或者 不做歧义处理
// 直接输出当前crossPath
context . addLexemePath ( crossPath ) ; } else { // 对当前的crossPath进行歧义处理
QuickSortSet . Cell headCell = crossPath . getHead ( ) ; LexemePath judgeResult = this . judge ( headCell , crossPath . getPathLength ( ) ) ; // 输出歧义处理结果judgeResult
context . addLexemePath ( judgeResult ) ; }


signature:
public class IKArbitrator { /** * 歧义识别
 * @ param lexemeCell 歧义路径链表头
 * @ param fullTextLength 歧义路径文本长度
 * @ return */
private LexemePath judge ( QuickSortSet . Cell lexemeCell , int fullTextLength ) { } }

implementation:
// 候选路径集合
TreeSet < LexemePath > pathOptions = new TreeSet < LexemePath > ( ) ; // 候选结果路径
LexemePath option = new LexemePath ( ) ; // 对crossPath进行一次遍历 , 同时返回本次遍历中有冲突的Lexeme栈
Stack < QuickSortSet . Cell > lexemeStack = this . forwardPath ( lexemeCell , option ) ; // 当前词元链并非最理想的 , 加入候选路径集合
pathOptions . add ( option . copy ( ) ) ; // 存在歧义词 , 处理
QuickSortSet . Cell c = null ; while ( ! lexemeStack . isEmpty ( ) ) { c = lexemeStack . pop ( ) ; // 回滚词元链
this . backPath ( c . getLexeme ( ) , option ) ; // 从歧义词位置开始 , 递归 , 生成可选方案
this . forwardPath ( c , option ) ; pathOptions . add ( option . copy ( ) ) ; } // 返回集合中的最优方案
return pathOptions . first ( ) ;


signature:
public class IKArbitrator { /** * 向前遍历 , 添加词元 , 构造一个无歧义词元组合
 * * @ param LexemePath path
 * @ return */
private Stack < QuickSortSet . Cell > forwardPath ( QuickSortSet . Cell lexemeCell , LexemePath option ) { } }

implementation:
// 发生冲突的Lexeme栈
Stack < QuickSortSet . Cell > conflictStack = new Stack < QuickSortSet . Cell > ( ) ; QuickSortSet . Cell c = lexemeCell ; // 迭代遍历Lexeme链表
while ( c != null && c . getLexeme ( ) != null ) { if ( ! option . addNotCrossLexeme ( c . getLexeme ( ) ) ) { // 词元交叉 , 添加失败则加入lexemeStack栈
conflictStack . push ( c ) ; } c = c . getNext ( ) ; } return conflictStack ;


signature:
public class IKArbitrator { /** * 回滚词元链 , 直到它能够接受指定的词元
 * * @ param lexeme
 * @ param l */
private void backPath ( Lexeme l , LexemePath option ) { } }

implementation: while ( option . checkCross ( l ) ) { option . removeTail ( ) ; }


signature:
public class IKAnalyzer { /** * 重载Analyzer接口 , 构造分词组件 */
@ Override protected TokenStreamComponents createComponents ( String fieldName ) { } }

implementation: Tokenizer _IKTokenizer = new IKTokenizer ( configuration ) ; return new TokenStreamComponents ( _IKTokenizer ) ;


signature:
public class AnalyzeContext { /** * 根据context的上下文情况 , 填充segmentBuff
 * @ param reader
 * @ return 返回待分析的 ( 有效的 ) 字串长度
 * @ throws java . io . IOException */
int fillBuffer ( Reader reader ) throws IOException { } }

implementation:
int readCount = 0 ; if ( this . buffOffset == 0 ) { // 首次读取reader
readCount = reader . read ( segmentBuff ) ; } else { int offset = this . available - this . cursor ; if ( offset > 0 ) { // 最近一次读取的 > 最近一次处理的 , 将未处理的字串拷贝到segmentBuff头部
System . arraycopy ( this . segmentBuff , this . cursor , this . segmentBuff , 0 , offset ) ; readCount = offset ; } // 继续读取reader , 以onceReadIn - onceAnalyzed为起始位置 , 继续填充segmentBuff剩余的部分
readCount += reader . read ( this . segmentBuff , offset , BUFF_SIZE - offset ) ; } // 记录最后一次从Reader中读入的可用字符长度
this . available = readCount ; // 重置当前指针
this . cursor = 0 ; return readCount ;


signature:
public class AnalyzeContext { /** * 初始化buff指针 , 处理第一个字符 */
void initCursor ( ) { } }

implementation: this . cursor = 0 ; this . segmentBuff [ this . cursor ] = CharacterUtil . regularize ( this . segmentBuff [ this . cursor ] , cfg . isEnableLowercase ( ) ) ; this . charTypes [ this . cursor ] = CharacterUtil . identifyCharType ( this . segmentBuff [ this . cursor ] ) ;


signature:
public class AnalyzeContext { /** * 添加分词结果路径
 * 路径起始位置 - - - > 路径 映射表
 * @ param path */
void addLexemePath ( LexemePath path ) { } }

implementation: if ( path != null ) { this . pathMap . put ( path . getPathBegin ( ) , path ) ; }


signature:
public class AnalyzeContext { /** * 推送分词结果到结果集合
 * 1 . 从buff头部遍历到this . cursor已处理位置
 * 2 . 将map中存在的分词结果推入results
 * 3 . 将map中不存在的CJDK字符以单字方式推入results */
void outputToResult ( ) { } }

implementation:
int index = 0 ; for ( ; index <= this . cursor ; ) { // 跳过非CJK字符
if ( CharacterUtil . CHAR_USELESS == this . charTypes [ index ] ) { index ++ ; continue ; } // 从pathMap找出对应index位置的LexemePath
LexemePath path = this . pathMap . get ( index ) ; if ( path != null ) { // 输出LexemePath中的lexeme到results集合
Lexeme l = path . pollFirst ( ) ; while ( l != null ) { this . results . add ( l ) ; // 字典中无单字 , 但是词元冲突了 , 切分出相交词元的前一个词元中的单字
int innerIndex = index + 1 ; for ( ; innerIndex < index + l . getLength ( ) ; innerIndex ++ ) { Lexeme innerL = path . peekFirst ( ) ; if ( innerL != null && innerIndex == innerL . getBegin ( ) ) { this . outputSingleCJK ( innerIndex - 1 ) ; } } // 将index移至lexeme后
index = l . getBegin ( ) + l . getLength ( ) ; l = path . pollFirst ( ) ; if ( l != null ) { // 输出path内部 , 词元间遗漏的单字
for ( ; index < l . getBegin ( ) ; index ++ ) { this . outputSingleCJK ( index ) ; } } } } else { // pathMap中找不到index对应的LexemePath
// 单字输出
this . outputSingleCJK ( index ) ; index ++ ; } } // 清空当前的Map
this . pathMap . clear ( ) ;


signature:
public class AnalyzeContext { /** * 对CJK字符进行单字输出
 * @ param index */
private void outputSingleCJK ( int index ) { } }

implementation: if ( CharacterUtil . CHAR_CHINESE == this . charTypes [ index ] ) { Lexeme singleCharLexeme = new Lexeme ( this . buffOffset , index , 1 , Lexeme . TYPE_CNCHAR ) ; this . results . add ( singleCharLexeme ) ; } else if ( CharacterUtil . CHAR_OTHER_CJK == this . charTypes [ index ] ) { Lexeme singleCharLexeme = new Lexeme ( this . buffOffset , index , 1 , Lexeme . TYPE_OTHER_CJK ) ; this . results . add ( singleCharLexeme ) ; }


signature:
public class AnalyzeContext { /** * 返回lexeme
 * 同时处理合并
 * @ return */
Lexeme getNextLexeme ( ) { } }

implementation:
// 从结果集取出 , 并移除第一个Lexme
Lexeme result = this . results . pollFirst ( ) ; while ( result != null ) { // 数量词合并
this . compound ( result ) ; if ( Dictionary . getSingleton ( ) . isStopWord ( this . segmentBuff , result . getBegin ( ) , result . getLength ( ) ) ) { // 是停止词继续取列表的下一个
result = this . results . pollFirst ( ) ; } else { // 不是停止词 , 生成lexeme的词元文本 , 输出
result . setLexemeText ( String . valueOf ( segmentBuff , result . getBegin ( ) , result . getLength ( ) ) ) ; break ; } } return result ;


signature:
public class AnalyzeContext { /** * 重置分词上下文状态 */
void reset ( ) { } }

implementation: this . buffLocker . clear ( ) ; this . orgLexemes = new QuickSortSet ( ) ; this . available = 0 ; this . buffOffset = 0 ; this . charTypes = new int [ BUFF_SIZE ] ; this . cursor = 0 ; this . results . clear ( ) ; this . segmentBuff = new char [ BUFF_SIZE ] ; this . pathMap . clear ( ) ;


signature:
public class AnalyzeContext { /** * 组合词元 */
private void compound ( Lexeme result ) { } }

implementation:
if ( ! this . cfg . isUseSmart ( ) ) { return ; } // 数量词合并处理
if ( ! this . results . isEmpty ( ) ) { if ( Lexeme . TYPE_ARABIC == result . getLexemeType ( ) ) { Lexeme nextLexeme = this . results . peekFirst ( ) ; boolean appendOk = false ; if ( Lexeme . TYPE_CNUM == nextLexeme . getLexemeType ( ) ) { // 合并英文数词 + 中文数词
appendOk = result . append ( nextLexeme , Lexeme . TYPE_CNUM ) ; } else if ( Lexeme . TYPE_COUNT == nextLexeme . getLexemeType ( ) ) { // 合并英文数词 + 中文量词
appendOk = result . append ( nextLexeme , Lexeme . TYPE_CQUAN ) ; } if ( appendOk ) { // 弹出
this . results . pollFirst ( ) ; } } // 可能存在第二轮合并
if ( Lexeme . TYPE_CNUM == result . getLexemeType ( ) && ! this . results . isEmpty ( ) ) { Lexeme nextLexeme = this . results . peekFirst ( ) ; boolean appendOk = false ; if ( Lexeme . TYPE_COUNT == nextLexeme . getLexemeType ( ) ) { // 合并中文数词 + 中文量词
appendOk = result . append ( nextLexeme , Lexeme . TYPE_CQUAN ) ; } if ( appendOk ) { // 弹出
this . results . pollFirst ( ) ; } } }


signature:
public class LexemePath { /** * 向LexemePath追加相交的Lexeme
 * @ param lexeme
 * @ return */
boolean addCrossLexeme ( Lexeme lexeme ) { } }

implementation: if ( this . isEmpty ( ) ) { this . addLexeme ( lexeme ) ; this . pathBegin = lexeme . getBegin ( ) ; this . pathEnd = lexeme . getBegin ( ) + lexeme . getLength ( ) ; this . payloadLength += lexeme . getLength ( ) ; return true ; } else if ( this . checkCross ( lexeme ) ) { this . addLexeme ( lexeme ) ; if ( lexeme . getBegin ( ) + lexeme . getLength ( ) > this . pathEnd ) { this . pathEnd = lexeme . getBegin ( ) + lexeme . getLength ( ) ; } this . payloadLength = this . pathEnd - this . pathBegin ; return true ; } else { return false ; }


signature:
public class LexemePath { /** * 向LexemePath追加不相交的Lexeme
 * @ param lexeme
 * @ return */
boolean addNotCrossLexeme ( Lexeme lexeme ) { } }

implementation: if ( this . isEmpty ( ) ) { this . addLexeme ( lexeme ) ; this . pathBegin = lexeme . getBegin ( ) ; this . pathEnd = lexeme . getBegin ( ) + lexeme . getLength ( ) ; this . payloadLength += lexeme . getLength ( ) ; return true ; } else if ( this . checkCross ( lexeme ) ) { return false ; } else { this . addLexeme ( lexeme ) ; this . payloadLength += lexeme . getLength ( ) ; Lexeme head = this . peekFirst ( ) ; this . pathBegin = head . getBegin ( ) ; Lexeme tail = this . peekLast ( ) ; this . pathEnd = tail . getBegin ( ) + tail . getLength ( ) ; return true ; }


signature:
public class LexemePath { /** * 移除尾部的Lexeme
 * @ return */
Lexeme removeTail ( ) { } }

implementation: Lexeme tail = this . pollLast ( ) ; if ( this . isEmpty ( ) ) { this . pathBegin = - 1 ; this . pathEnd = - 1 ; this . payloadLength = 0 ; } else { this . payloadLength -= tail . getLength ( ) ; Lexeme newTail = this . peekLast ( ) ; this . pathEnd = newTail . getBegin ( ) + newTail . getLength ( ) ; } return tail ;


signature:
public class LexemePath { /** * 检测词元位置交叉 ( 有歧义的切分 )
 * @ param lexeme
 * @ return */
boolean checkCross ( Lexeme lexeme ) { } }

implementation: return ( lexeme . getBegin ( ) >= this . pathBegin && lexeme . getBegin ( ) < this . pathEnd ) || ( this . pathBegin >= lexeme . getBegin ( ) && this . pathBegin < lexeme . getBegin ( ) + lexeme . getLength ( ) ) ;


signature:
public class LexemePath { /** * X权重 ( 词元长度积 )
 * @ return */
int getXWeight ( ) { } }

implementation: int product = 1 ; Cell c = this . getHead ( ) ; while ( c != null && c . getLexeme ( ) != null ) { product *= c . getLexeme ( ) . getLength ( ) ; c = c . getNext ( ) ; } return product ;


signature:
public class LexemePath { /** * 词元位置权重
 * @ return */
int getPWeight ( ) { } }

implementation: int pWeight = 0 ; int p = 0 ; Cell c = this . getHead ( ) ; while ( c != null && c . getLexeme ( ) != null ) { p ++ ; pWeight += p * c . getLexeme ( ) . getLength ( ) ; c = c . getNext ( ) ; } return pWeight ;


signature:
public class Dictionary { /** * 词典初始化 由于IK Analyzer的词典采用Dictionary类的静态方法进行词典初始化
 * 只有当Dictionary类被实际调用时 , 才会开始载入词典 , 这将延长首次分词操作的时间 该方法提供了一个在应用加载阶段就初始化字典的手段
 * @ return Dictionary */
public static synchronized void initial ( Configuration cfg ) { } }

implementation:
if ( singleton == null ) { synchronized ( Dictionary . class ) { if ( singleton == null ) { singleton = new Dictionary ( cfg ) ; singleton . loadMainDict ( ) ; singleton . loadSurnameDict ( ) ; singleton . loadQuantifierDict ( ) ; singleton . loadSuffixDict ( ) ; singleton . loadPrepDict ( ) ; singleton . loadStopWordDict ( ) ; if ( cfg . isEnableRemoteDict ( ) ) { // 建立监控线程
for ( String location : singleton . getRemoteExtDictionarys ( ) ) { // 10 秒是初始延迟可以修改的 60是间隔时间 单位秒
pool . scheduleAtFixedRate ( new Monitor ( location ) , 10 , 60 , TimeUnit . SECONDS ) ; } for ( String location : singleton . getRemoteExtStopWordDictionarys ( ) ) { pool . scheduleAtFixedRate ( new Monitor ( location ) , 10 , 60 , TimeUnit . SECONDS ) ; } } } } }


signature:
public class Dictionary { /** * 批量移除 ( 屏蔽 ) 词条 */
public void disableWords ( Collection < String > words ) { } }

implementation:
if ( words != null ) { for ( String word : words ) { if ( word != null ) { // 批量屏蔽词条
singleton . _MainDict . disableSegment ( word . trim ( ) . toCharArray ( ) ) ; } } }


signature:
public class Dictionary { /** * 检索匹配主词典
 * @ return Hit 匹配结果描述 */
public Hit matchInMainDict ( char [ ] charArray , int begin , int length ) { } }

implementation: return singleton . _MainDict . match ( charArray , begin , length ) ;


signature:
public class Dictionary { /** * 检索匹配量词词典
 * @ return Hit 匹配结果描述 */
public Hit matchInQuantifierDict ( char [ ] charArray , int begin , int length ) { } }

implementation: return singleton . _QuantifierDict . match ( charArray , begin , length ) ;


signature:
public class Dictionary { /** * 从已匹配的Hit中直接取出DictSegment , 继续向下匹配
 * @ return Hit */
public Hit matchWithHit ( char [ ] charArray , int currentIndex , Hit matchedHit ) { } }

implementation: DictSegment ds = matchedHit . getMatchedDictSegment ( ) ; return ds . match ( charArray , currentIndex , 1 , matchedHit ) ;


signature:
public class Dictionary { /** * 判断是否是停止词
 * @ return boolean */
public boolean isStopWord ( char [ ] charArray , int begin , int length ) { } }

implementation: return singleton . _StopWords . match ( charArray , begin , length ) . isMatch ( ) ;


signature:
public class Dictionary { /** * 加载主词典及扩展词典 */
private void loadMainDict ( ) { } }

implementation:
// 建立一个主词典实例
_MainDict = new DictSegment ( ( char ) 0 ) ; // 读取主词典文件
Path file = PathUtils . get ( getDictRoot ( ) , Dictionary . PATH_DIC_MAIN ) ; loadDictFile ( _MainDict , file , false , "Main Dict" ) ; // 加载扩展词典
this . loadExtDict ( ) ; // 加载远程自定义词库
this . loadRemoteExtDict ( ) ;


signature:
public class Dictionary { /** * 加载用户配置的扩展词典到主词库表 */
private void loadExtDict ( ) { } }

implementation:
// 加载扩展词典配置
List < String > extDictFiles = getExtDictionarys ( ) ; if ( extDictFiles != null ) { for ( String extDictName : extDictFiles ) { // 读取扩展词典文件
logger . info ( "[Dict Loading] " + extDictName ) ; Path file = PathUtils . get ( extDictName ) ; loadDictFile ( _MainDict , file , false , "Extra Dict" ) ; } }


signature:
public class Dictionary { /** * 加载远程扩展词典到主词库表 */
private void loadRemoteExtDict ( ) { } }

implementation:
List < String > remoteExtDictFiles = getRemoteExtDictionarys ( ) ; for ( String location : remoteExtDictFiles ) { logger . info ( "[Dict Loading] " + location ) ; List < String > lists = getRemoteWords ( location ) ; // 如果找不到扩展的字典 , 则忽略
if ( lists == null ) { logger . error ( "[Dict Loading] " + location + "加载失败" ) ; continue ; } for ( String theWord : lists ) { if ( theWord != null && ! "" . equals ( theWord . trim ( ) ) ) { // 加载扩展词典数据到主内存词典中
logger . info ( theWord ) ; _MainDict . fillSegment ( theWord . trim ( ) . toLowerCase ( ) . toCharArray ( ) ) ; } } }


signature:
public class Dictionary { /** * 从远程服务器上下载自定义词条 */
private static List < String > getRemoteWordsUnprivileged ( String location ) { } }

implementation:
List < String > buffer = new ArrayList < String > ( ) ; RequestConfig rc = RequestConfig . custom ( ) . setConnectionRequestTimeout ( 10 * 1000 ) . setConnectTimeout ( 10 * 1000 ) . setSocketTimeout ( 60 * 1000 ) . build ( ) ; CloseableHttpClient httpclient = HttpClients . createDefault ( ) ; CloseableHttpResponse response ; BufferedReader in ; HttpGet get = new HttpGet ( location ) ; get . setConfig ( rc ) ; try { response = httpclient . execute ( get ) ; if ( response . getStatusLine ( ) . getStatusCode ( ) == 200 ) { String charset = "UTF-8" ; // 获取编码 , 默认为utf - 8
HttpEntity entity = response . getEntity ( ) ; if ( entity != null ) { Header contentType = entity . getContentType ( ) ; if ( contentType != null && contentType . getValue ( ) != null ) { String typeValue = contentType . getValue ( ) ; if ( typeValue != null && typeValue . contains ( "charset=" ) ) { charset = typeValue . substring ( typeValue . lastIndexOf ( "=" ) + 1 ) ; } } if ( entity . getContentLength ( ) > 0 ) { in = new BufferedReader ( new InputStreamReader ( entity . getContent ( ) , charset ) ) ; String line ; while ( ( line = in . readLine ( ) ) != null ) { buffer . add ( line ) ; } in . close ( ) ; response . close ( ) ; return buffer ; } } } response . close ( ) ; } catch ( IllegalStateException | IOException e ) { logger . error ( "getRemoteWords {} error" , e , location ) ; } return buffer ;


signature:
public class Dictionary { /** * 加载用户扩展的停止词词典 */
private void loadStopWordDict ( ) { } }

implementation:
// 建立主词典实例
_StopWords = new DictSegment ( ( char ) 0 ) ; // 读取主词典文件
Path file = PathUtils . get ( getDictRoot ( ) , Dictionary . PATH_DIC_STOP ) ; loadDictFile ( _StopWords , file , false , "Main Stopwords" ) ; // 加载扩展停止词典
List < String > extStopWordDictFiles = getExtStopWordDictionarys ( ) ; if ( extStopWordDictFiles != null ) { for ( String extStopWordDictName : extStopWordDictFiles ) { logger . info ( "[Dict Loading] " + extStopWordDictName ) ; // 读取扩展词典文件
file = PathUtils . get ( extStopWordDictName ) ; loadDictFile ( _StopWords , file , false , "Extra Stopwords" ) ; } } // 加载远程停用词典
List < String > remoteExtStopWordDictFiles = getRemoteExtStopWordDictionarys ( ) ; for ( String location : remoteExtStopWordDictFiles ) { logger . info ( "[Dict Loading] " + location ) ; List < String > lists = getRemoteWords ( location ) ; // 如果找不到扩展的字典 , 则忽略
if ( lists == null ) { logger . error ( "[Dict Loading] " + location + "加载失败" ) ; continue ; } for ( String theWord : lists ) { if ( theWord != null && ! "" . equals ( theWord . trim ( ) ) ) { // 加载远程词典数据到主内存中
logger . info ( theWord ) ; _StopWords . fillSegment ( theWord . trim ( ) . toLowerCase ( ) . toCharArray ( ) ) ; } } }


signature:
public class Dictionary { /** * 加载量词词典 */
private void loadQuantifierDict ( ) { } }

implementation:
// 建立一个量词典实例
_QuantifierDict = new DictSegment ( ( char ) 0 ) ; // 读取量词词典文件
Path file = PathUtils . get ( getDictRoot ( ) , Dictionary . PATH_DIC_QUANTIFIER ) ; loadDictFile ( _QuantifierDict , file , false , "Quantifier" ) ;


signature:
public class Monitor { /** * 监控流程 :
 * 1向词库服务器发送Head请求
 * 2从响应中获取Last - Modify 、 ETags字段值 , 判断是否变化
 * 3如果未变化 , 休眠1min , 返回第1步
 * 4如果有变化 , 重新加载词典
 * 5休眠1min , 返回第1步 */
public void runUnprivileged ( ) { } }

implementation:
// 超时设置
RequestConfig rc = RequestConfig . custom ( ) . setConnectionRequestTimeout ( 10 * 1000 ) . setConnectTimeout ( 10 * 1000 ) . setSocketTimeout ( 15 * 1000 ) . build ( ) ; HttpHead head = new HttpHead ( location ) ; head . setConfig ( rc ) ; // 设置请求头
if ( last_modified != null ) { head . setHeader ( "If-Modified-Since" , last_modified ) ; } if ( eTags != null ) { head . setHeader ( "If-None-Match" , eTags ) ; } CloseableHttpResponse response = null ; try { response = httpclient . execute ( head ) ; // 返回200 才做操作
if ( response . getStatusLine ( ) . getStatusCode ( ) == 200 ) { if ( ( ( response . getLastHeader ( "Last-Modified" ) != null ) && ! response . getLastHeader ( "Last-Modified" ) . getValue ( ) . equalsIgnoreCase ( last_modified ) ) || ( ( response . getLastHeader ( "ETag" ) != null ) && ! response . getLastHeader ( "ETag" ) . getValue ( ) . equalsIgnoreCase ( eTags ) ) ) { // 远程词库有更新 , 需要重新加载词典 , 并修改last _ modified , eTags
Dictionary . getSingleton ( ) . reLoadMainDict ( ) ; last_modified = response . getLastHeader ( "Last-Modified" ) == null ? null : response . getLastHeader ( "Last-Modified" ) . getValue ( ) ; eTags = response . getLastHeader ( "ETag" ) == null ? null : response . getLastHeader ( "ETag" ) . getValue ( ) ; } } else if ( response . getStatusLine ( ) . getStatusCode ( ) == 304 ) { // 没有修改 , 不做操作
// noop
} else { logger . info ( "remote_ext_dict {} return bad code {}" , location , response . getStatusLine ( ) . getStatusCode ( ) ) ; } } catch ( Exception e ) { logger . error ( "remote_ext_dict {} error!" , e , location ) ; } finally { try { if ( response != null ) { response . close ( ) ; } } catch ( IOException e ) { logger . error ( e . getMessage ( ) , e ) ; } }


signature:
public class QuickSortSet { /** * 向链表集合添加词元
 * @ param lexeme */
boolean addLexeme ( Lexeme lexeme ) { } }

implementation:
Cell newCell = new Cell ( lexeme ) ; if ( this . size == 0 ) { this . head = newCell ; this . tail = newCell ; this . size ++ ; return true ; } else { if ( this . tail . compareTo ( newCell ) == 0 ) { // 词元与尾部词元相同 , 不放入集合
return false ; } else if ( this . tail . compareTo ( newCell ) < 0 ) { // 词元接入链表尾部
this . tail . next = newCell ; newCell . prev = this . tail ; this . tail = newCell ; this . size ++ ; return true ; } else if ( this . head . compareTo ( newCell ) > 0 ) { // 词元接入链表头部
this . head . prev = newCell ; newCell . next = this . head ; this . head = newCell ; this . size ++ ; return true ; } else { // 从尾部上逆
Cell index = this . tail ; while ( index != null && index . compareTo ( newCell ) > 0 ) { index = index . prev ; } if ( index . compareTo ( newCell ) == 0 ) { // 词元与集合中的词元重复 , 不放入集合
return false ; } else if ( index . compareTo ( newCell ) < 0 ) { // 词元插入链表中的某个位置
newCell . prev = index ; newCell . next = index . next ; index . next . prev = newCell ; index . next = newCell ; this . size ++ ; return true ; } } } return false ;


signature:
public class QuickSortSet { /** * 取出链表集合的第一个元素
 * @ return Lexeme */
Lexeme pollFirst ( ) { } }

implementation: if ( this . size == 1 ) { Lexeme first = this . head . lexeme ; this . head = null ; this . tail = null ; this . size -- ; return first ; } else if ( this . size > 1 ) { Lexeme first = this . head . lexeme ; this . head = this . head . next ; this . size -- ; return first ; } else { return null ; }


signature:
public class QuickSortSet { /** * 取出链表集合的最后一个元素
 * @ return Lexeme */
Lexeme pollLast ( ) { } }

implementation: if ( this . size == 1 ) { Lexeme last = this . head . lexeme ; this . head = null ; this . tail = null ; this . size -- ; return last ; } else if ( this . size > 1 ) { Lexeme last = this . tail . lexeme ; this . tail = this . tail . prev ; this . size -- ; return last ; } else { return null ; }


signature:
public class CN_QuantifierSegmenter { /** * 分词 */
public void analyze ( AnalyzeContext context ) { } }

implementation:
// 处理中文数词
this . processCNumber ( context ) ; // 处理中文量词
this . processCount ( context ) ; // 判断是否锁定缓冲区
if ( this . nStart == - 1 && this . nEnd == - 1 && countHits . isEmpty ( ) ) { // 对缓冲区解锁
context . unlockBuffer ( SEGMENTER_NAME ) ; } else { context . lockBuffer ( SEGMENTER_NAME ) ; }


signature:
public class CN_QuantifierSegmenter { /** * 判断是否需要扫描量词
 * @ return */
private boolean needCountScan ( AnalyzeContext context ) { } }

implementation:
if ( ( nStart != - 1 && nEnd != - 1 ) || ! countHits . isEmpty ( ) ) { // 正在处理中文数词 , 或者正在处理量词
return true ; } else { // 找到一个相邻的数词
if ( ! context . getOrgLexemes ( ) . isEmpty ( ) ) { Lexeme l = context . getOrgLexemes ( ) . peekLast ( ) ; if ( ( Lexeme . TYPE_CNUM == l . getLexemeType ( ) || Lexeme . TYPE_ARABIC == l . getLexemeType ( ) ) && ( l . getBegin ( ) + l . getLength ( ) == context . getCursor ( ) ) ) { return true ; } } } return false ;


signature:
public class CN_QuantifierSegmenter { /** * 添加数词词元到结果集
 * @ param context */
private void outputNumLexeme ( AnalyzeContext context ) { } }

implementation:
if ( nStart > - 1 && nEnd > - 1 ) { // 输出数词
Lexeme newLexeme = new Lexeme ( context . getBufferOffset ( ) , nStart , nEnd - nStart + 1 , Lexeme . TYPE_CNUM ) ; context . addLexeme ( newLexeme ) ; }


signature:
public class DictSegment { /** * 匹配词段
 * @ param charArray
 * @ param begin
 * @ param length
 * @ return Hit */
Hit match ( char [ ] charArray , int begin , int length ) { } }

implementation: return this . match ( charArray , begin , length , null ) ;


signature:
public class DictSegment { /** * 加载填充词典片段
 * @ param charArray
 * @ param begin
 * @ param length
 * @ param enabled */
private synchronized void fillSegment ( char [ ] charArray , int begin , int length , int enabled ) { } }

implementation:
// 获取字典表中的汉字对象
Character beginChar = Character . valueOf ( charArray [ begin ] ) ; Character keyChar = charMap . get ( beginChar ) ; // 字典中没有该字 , 则将其添加入字典
if ( keyChar == null ) { charMap . put ( beginChar , beginChar ) ; keyChar = beginChar ; } // 搜索当前节点的存储 , 查询对应keyChar的keyChar , 如果没有则创建
DictSegment ds = lookforSegment ( keyChar , enabled ) ; if ( ds != null ) { // 处理keyChar对应的segment
if ( length > 1 ) { // 词元还没有完全加入词典树
ds . fillSegment ( charArray , begin + 1 , length - 1 , enabled ) ; } else if ( length == 1 ) { // 已经是词元的最后一个char , 设置当前节点状态为enabled ,
// enabled = 1表明一个完整的词 , enabled = 0表示从词典中屏蔽当前词
ds . nodeState = enabled ; } }


signature:
public class DictSegment { /** * 查找本节点下对应的keyChar的segment *
 * @ param keyChar
 * @ param create = 1如果没有找到 , 则创建新的segment ; = 0如果没有找到 , 不创建 , 返回null
 * @ return */
private DictSegment lookforSegment ( Character keyChar , int create ) { } }

implementation:
DictSegment ds = null ; if ( this . storeSize <= ARRAY_LENGTH_LIMIT ) { // 获取数组容器 , 如果数组未创建则创建数组
DictSegment [ ] segmentArray = getChildrenArray ( ) ; // 搜寻数组
DictSegment keySegment = new DictSegment ( keyChar ) ; int position = Arrays . binarySearch ( segmentArray , 0 , this . storeSize , keySegment ) ; if ( position >= 0 ) { ds = segmentArray [ position ] ; } // 遍历数组后没有找到对应的segment
if ( ds == null && create == 1 ) { ds = keySegment ; if ( this . storeSize < ARRAY_LENGTH_LIMIT ) { // 数组容量未满 , 使用数组存储
segmentArray [ this . storeSize ] = ds ; // segment数目 + 1
this . storeSize ++ ; Arrays . sort ( segmentArray , 0 , this . storeSize ) ; } else { // 数组容量已满 , 切换Map存储
// 获取Map容器 , 如果Map未创建 , 则创建Map
Map < Character , DictSegment > segmentMap = getChildrenMap ( ) ; // 将数组中的segment迁移到Map中
migrate ( segmentArray , segmentMap ) ; // 存储新的segment
segmentMap . put ( keyChar , ds ) ; // segment数目 + 1 , 必须在释放数组前执行storeSize + + , 确保极端情况下 , 不会取到空的数组
this . storeSize ++ ; // 释放当前的数组引用
this . childrenArray = null ; } } } else { // 获取Map容器 , 如果Map未创建 , 则创建Map
Map < Character , DictSegment > segmentMap = getChildrenMap ( ) ; // 搜索Map
ds = ( DictSegment ) segmentMap . get ( keyChar ) ; if ( ds == null && create == 1 ) { // 构造新的segment
ds = new DictSegment ( keyChar ) ; segmentMap . put ( keyChar , ds ) ; // 当前节点存储segment数目 + 1
this . storeSize ++ ; } } return ds ;


signature:
public class DictSegment { /** * 获取Map容器
 * 线程同步方法 */
private Map < Character , DictSegment > getChildrenMap ( ) { } }

implementation: synchronized ( this ) { if ( this . childrenMap == null ) { this . childrenMap = new ConcurrentHashMap < Character , DictSegment > ( ARRAY_LENGTH_LIMIT * 2 , 0.8f ) ; } } return this . childrenMap ;


signature:
public class DictSegment { /** * 将数组中的segment迁移到Map中
 * @ param segmentArray */
private void migrate ( DictSegment [ ] segmentArray , Map < Character , DictSegment > segmentMap ) { } }

implementation: for ( DictSegment segment : segmentArray ) { if ( segment != null ) { segmentMap . put ( segment . nodeChar , segment ) ; } }


signature:
public class Lexeme { /** * 词元在排序集合中的比较算法
 * @ see java . lang . Comparable # compareTo ( java . lang . Object ) */
public int compareTo ( Lexeme other ) { } }

implementation:
// 起始位置优先
if ( this . begin < other . getBegin ( ) ) { return - 1 ; } else if ( this . begin == other . getBegin ( ) ) { // 词元长度优先
if ( this . length > other . getLength ( ) ) { return - 1 ; } else if ( this . length == other . getLength ( ) ) { return 0 ; } else { // this . length < other . getLength ( )
return 1 ; } } else { // this . begin > other . getBegin ( )
return 1 ; }


signature:
public class Lexeme { /** * 获取词元类型标示字符串
 * @ return String */
public String getLexemeTypeString ( ) { } }

implementation: switch ( lexemeType ) { case TYPE_ENGLISH : return "ENGLISH" ; case TYPE_ARABIC : return "ARABIC" ; case TYPE_LETTER : return "LETTER" ; case TYPE_CNWORD : return "CN_WORD" ; case TYPE_CNCHAR : return "CN_CHAR" ; case TYPE_OTHER_CJK : return "OTHER_CJK" ; case TYPE_COUNT : return "COUNT" ; case TYPE_CNUM : return "TYPE_CNUM" ; case TYPE_CQUAN : return "TYPE_CQUAN" ; default : return "UNKONW" ; }


signature:
public class Lexeme { /** * 合并两个相邻的词元
 * @ param l
 * @ param lexemeType
 * @ return boolean 词元是否成功合并 */
public boolean append ( Lexeme l , int lexemeType ) { } }

implementation: if ( l != null && this . getEndPosition ( ) == l . getBeginPosition ( ) ) { this . length += l . getLength ( ) ; this . lexemeType = lexemeType ; return true ; } else { return false ; }


signature:
public class OAuth2ErrorHttpMessageConverter { /** * Sets the { @ link Converter } used for converting the OAuth 2.0 Error parameters
 * to an { @ link OAuth2Error } .
 * @ param errorConverter the { @ link Converter } used for converting to an { @ link OAuth2Error } */
public final void setErrorConverter ( Converter < Map < String , String > , OAuth2Error > errorConverter ) { } }

implementation: Assert . notNull ( errorConverter , "errorConverter cannot be null" ) ; this . errorConverter = errorConverter ;


signature:
public class OAuth2ErrorHttpMessageConverter { /** * Sets the { @ link Converter } used for converting the { @ link OAuth2Error }
 * to a { @ code Map } representation of the OAuth 2.0 Error parameters .
 * @ param errorParametersConverter the { @ link Converter } used for converting to a { @ code Map } representation of the Error parameters */
public final void setErrorParametersConverter ( Converter < OAuth2Error , Map < String , String > > errorParametersConverter ) { } }

implementation: Assert . notNull ( errorParametersConverter , "errorParametersConverter cannot be null" ) ; this . errorParametersConverter = errorParametersConverter ;


signature:
public class CsrfLogoutHandler { /** * Clears the { @ link CsrfToken }
 * @ see org . springframework . security . web . authentication . logout . LogoutHandler # logout ( javax . servlet . http . HttpServletRequest ,
 * javax . servlet . http . HttpServletResponse ,
 * org . springframework . security . core . Authentication ) */
public void logout ( HttpServletRequest request , HttpServletResponse response , Authentication authentication ) { } }

implementation: this . csrfTokenRepository . saveToken ( null , request , response ) ;


signature:
public class OidcIdTokenValidator { /** * Sets the maximum acceptable clock skew . The default is 60 seconds .
 * The clock skew is used when validating the { @ link JwtClaimNames # EXP exp }
 * and { @ link JwtClaimNames # IAT iat } claims .
 * @ since 5.2
 * @ param clockSkew the maximum acceptable clock skew */
public final void setClockSkew ( Duration clockSkew ) { } }

implementation: Assert . notNull ( clockSkew , "clockSkew cannot be null" ) ; Assert . isTrue ( clockSkew . getSeconds ( ) >= 0 , "clockSkew must be >= 0" ) ; this . clockSkew = clockSkew ;


signature:
public class JwtAuthenticationConverter { /** * Sets the { @ link Converter Converter & lt ; Jwt , Collection & lt ; GrantedAuthority & gt ; & gt ; } to use .
 * Defaults to { @ link JwtGrantedAuthoritiesConverter } .
 * @ param jwtGrantedAuthoritiesConverter The converter
 * @ since 5.2
 * @ see JwtGrantedAuthoritiesConverter */
public void setJwtGrantedAuthoritiesConverter ( Converter < Jwt , Collection < GrantedAuthority > > jwtGrantedAuthoritiesConverter ) { } }

implementation: Assert . notNull ( jwtGrantedAuthoritiesConverter , "jwtGrantedAuthoritiesConverter cannot be null" ) ; this . jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter ;


signature:
public class PortMapperImpl { /** * Set to override the default HTTP port to HTTPS port mappings of 80:443 , and
 * 8080:8443 . In a Spring XML ApplicationContext , a definition would look something
 * like this :
 * < pre >
 * & lt ; property name = " portMappings " & gt ;
 * & lt ; map & gt ;
 * & lt ; entry key = " 80 " & gt ; & lt ; value & gt ; 443 & lt ; / value & gt ; & lt ; / entry & gt ;
 * & lt ; entry key = " 8080 " & gt ; & lt ; value & gt ; 8443 & lt ; / value & gt ; & lt ; / entry & gt ;
 * & lt ; / map & gt ;
 * & lt ; / property & gt ;
 * < / pre >
 * @ param newMappings A Map consisting of String keys and String values , where for
 * each entry the key is the string representation of an integer HTTP port number , and
 * the value is the string representation of the corresponding integer HTTPS port
 * number .
 * @ throws IllegalArgumentException if input map does not consist of String keys and
 * values , each representing an integer port number in the range 1-65535 for that
 * mapping . */
public void setPortMappings ( Map < String , String > newMappings ) { } }

implementation: Assert . notNull ( newMappings , "A valid list of HTTPS port mappings must be provided" ) ; this . httpsPortMappings . clear ( ) ; for ( Map . Entry < String , String > entry : newMappings . entrySet ( ) ) { Integer httpPort = Integer . valueOf ( entry . getKey ( ) ) ; Integer httpsPort = Integer . valueOf ( entry . getValue ( ) ) ; if ( ( httpPort . intValue ( ) < 1 ) || ( httpPort . intValue ( ) > 65535 ) || ( httpsPort . intValue ( ) < 1 ) || ( httpsPort . intValue ( ) > 65535 ) ) { throw new IllegalArgumentException ( "one or both ports out of legal range: " + httpPort + ", " + httpsPort ) ; } this . httpsPortMappings . put ( httpPort , httpsPort ) ; } if ( this . httpsPortMappings . size ( ) < 1 ) { throw new IllegalArgumentException ( "must map at least one port" ) ; }


signature:
public class DataSourcePopulator { /** * Creates a directory for the user , and a series of sub - directories . The root
 * directory is the parent for the user directory . The sub - directories are
 * " confidential " and " shared " . The ROLE _ USER will be given read and write access to
 * " shared " . */
private void createSampleData ( String username , String password ) { } }

implementation:
Assert . notNull ( documentDao , "DocumentDao required" ) ; Assert . hasText ( username , "Username required" ) ; Authentication auth = new UsernamePasswordAuthenticationToken ( username , password ) ; try { // Set the SecurityContextHolder ThreadLocal so any subclasses
// automatically know which user is operating
SecurityContextHolder . getContext ( ) . setAuthentication ( auth ) ; // Create the home directory first
Directory home = new Directory ( username , Directory . ROOT_DIRECTORY ) ; documentDao . create ( home ) ; addPermission ( documentDao , home , username , LEVEL_GRANT_ADMIN ) ; addPermission ( documentDao , home , "ROLE_USER" , LEVEL_GRANT_READ ) ; createFiles ( documentDao , home ) ; // Now create the confidential directory
Directory confid = new Directory ( "confidential" , home ) ; documentDao . create ( confid ) ; addPermission ( documentDao , confid , "ROLE_USER" , LEVEL_NEGATE_READ ) ; createFiles ( documentDao , confid ) ; // Now create the shared directory
Directory shared = new Directory ( "shared" , home ) ; documentDao . create ( shared ) ; addPermission ( documentDao , shared , "ROLE_USER" , LEVEL_GRANT_READ ) ; addPermission ( documentDao , shared , "ROLE_USER" , LEVEL_GRANT_WRITE ) ; createFiles ( documentDao , shared ) ; } finally { // Clear the SecurityContextHolder ThreadLocal so future calls are
// guaranteed to be clean
SecurityContextHolder . clearContext ( ) ; }


signature:
public class Pbkdf2PasswordEncoder { /** * Sets the algorithm to use . See
 * < a href = " https : / / docs . oracle . com / javase / 8 / docs / technotes / guides / security / StandardNames . html # SecretKeyFactory " > SecretKeyFactory Algorithms < / a >
 * @ param secretKeyFactoryAlgorithm the algorithm to use ( i . e .
 * { @ code SecretKeyFactoryAlgorithm . PBKDF2WithHmacSHA1 } ,
 * { @ code SecretKeyFactoryAlgorithm . PBKDF2WithHmacSHA256 } ,
 * { @ code SecretKeyFactoryAlgorithm . PBKDF2WithHmacSHA512 } )
 * @ since 5.0 */
public void setAlgorithm ( SecretKeyFactoryAlgorithm secretKeyFactoryAlgorithm ) { } }

implementation: if ( secretKeyFactoryAlgorithm == null ) { throw new IllegalArgumentException ( "secretKeyFactoryAlgorithm cannot be null" ) ; } String algorithmName = secretKeyFactoryAlgorithm . name ( ) ; try { SecretKeyFactory . getInstance ( algorithmName ) ; } catch ( NoSuchAlgorithmException e ) { throw new IllegalArgumentException ( "Invalid algorithm '" + algorithmName + "'." , e ) ; } this . algorithm = algorithmName ;


signature:
public class JaasPasswordCallbackHandler { /** * If the callback passed to the ' handle ' method is an instance of PasswordCallback ,
 * the JaasPasswordCallbackHandler will call ,
 * callback . setPassword ( authentication . getCredentials ( ) . toString ( ) ) .
 * @ param callback
 * @ param auth
 * @ throws IOException
 * @ throws UnsupportedCallbackException */
public void handle ( Callback callback , Authentication auth ) throws IOException , UnsupportedCallbackException { } }

implementation: if ( callback instanceof PasswordCallback ) { PasswordCallback pc = ( PasswordCallback ) callback ; pc . setPassword ( auth . getCredentials ( ) . toString ( ) . toCharArray ( ) ) ; }


signature:
public class RegexRequestMatcher { /** * Provides a save way of obtaining the HttpMethod from a String . If the method is
 * invalid , returns null .
 * @ param method the HTTP method to use .
 * @ return the HttpMethod or null if method is invalid . */
private static HttpMethod valueOf ( String method ) { } }

implementation: try { return HttpMethod . valueOf ( method ) ; } catch ( IllegalArgumentException e ) { } return null ;


signature: public class LogoutFilter { public void doFilter ( ServletRequest req , ServletResponse res , FilterChain chain ) throws IOException , ServletException { } }

implementation: HttpServletRequest request = ( HttpServletRequest ) req ; HttpServletResponse response = ( HttpServletResponse ) res ; if ( requiresLogout ( request , response ) ) { Authentication auth = SecurityContextHolder . getContext ( ) . getAuthentication ( ) ; if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Logging out user '" + auth + "' and transferring to logout destination" ) ; } this . handler . logout ( request , response , auth ) ; logoutSuccessHandler . onLogoutSuccess ( request , response , auth ) ; return ; } chain . doFilter ( request , response ) ;


signature:
public class FilterBasedLdapUserSearch { /** * Return the LdapUserDetails containing the user ' s information
 * @ param username the username to search for .
 * @ return An LdapUserDetails object containing the details of the located user ' s
 * directory entry
 * @ throws UsernameNotFoundException if no matching entry is found . */
@ Override public DirContextOperations searchForUser ( String username ) { } }

implementation:
if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Searching for user '" + username + "', with user search " + this ) ; } SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate ( contextSource ) ; template . setSearchControls ( searchControls ) ; try { return template . searchForSingleEntry ( searchBase , searchFilter , new String [ ] { username } ) ; } catch ( IncorrectResultSizeDataAccessException notFound ) { if ( notFound . getActualSize ( ) == 0 ) { throw new UsernameNotFoundException ( "User " + username + " not found in directory." ) ; } // Search should never return multiple results if properly configured , so just
// rethrow
throw notFound ; }


signature: public class OpenID4JavaConsumer { public String beginConsumption ( HttpServletRequest req , String identityUrl , String returnToUrl , String realm ) throws OpenIDConsumerException { } }

implementation: List < DiscoveryInformation > discoveries ; try { discoveries = consumerManager . discover ( identityUrl ) ; } catch ( DiscoveryException e ) { throw new OpenIDConsumerException ( "Error during discovery" , e ) ; } DiscoveryInformation information = consumerManager . associate ( discoveries ) ; req . getSession ( ) . setAttribute ( DISCOVERY_INFO_KEY , information ) ; AuthRequest authReq ; try { authReq = consumerManager . authenticate ( information , returnToUrl , realm ) ; logger . debug ( "Looking up attribute fetch list for identifier: " + identityUrl ) ; List < OpenIDAttribute > attributesToFetch = attributesToFetchFactory . createAttributeList ( identityUrl ) ; if ( ! attributesToFetch . isEmpty ( ) ) { req . getSession ( ) . setAttribute ( ATTRIBUTE_LIST_KEY , attributesToFetch ) ; FetchRequest fetchRequest = FetchRequest . createFetchRequest ( ) ; for ( OpenIDAttribute attr : attributesToFetch ) { if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Adding attribute " + attr . getType ( ) + " to fetch request" ) ; } fetchRequest . addAttribute ( attr . getName ( ) , attr . getType ( ) , attr . isRequired ( ) , attr . getCount ( ) ) ; } authReq . addExtension ( fetchRequest ) ; } } catch ( MessageException e ) { throw new OpenIDConsumerException ( "Error processing ConsumerManager authentication" , e ) ; } catch ( ConsumerException e ) { throw new OpenIDConsumerException ( "Error processing ConsumerManager authentication" , e ) ; } return authReq . getDestinationUrl ( true ) ;


signature:
public class MessageDigestPasswordEncoder { /** * Encodes the rawPass using a MessageDigest . If a salt is specified it will be merged
 * with the password before encoding .
 * @ param rawPassword The plain text password
 * @ return Hex string of password digest ( or base64 encoded string if
 * encodeHashAsBase64 is enabled . */
public String encode ( CharSequence rawPassword ) { } }

implementation: String salt = PREFIX + this . saltGenerator . generateKey ( ) + SUFFIX ; return digest ( salt , rawPassword ) ;


signature:
public class MessageDigestPasswordEncoder { /** * Takes a previously encoded password and compares it with a rawpassword after mixing
 * in the salt and encoding that value
 * @ param rawPassword plain text password
 * @ param encodedPassword previously encoded password
 * @ return true or false */
public boolean matches ( CharSequence rawPassword , String encodedPassword ) { } }

implementation: String salt = extractSalt ( encodedPassword ) ; String rawPasswordEncoded = digest ( salt , rawPassword ) ; return PasswordEncoderUtils . equals ( encodedPassword . toString ( ) , rawPasswordEncoded ) ;


signature:
public class SpringSecurityCoreVersion { /** * Perform version checks with specific min Spring Version
 * @ param minSpringVersion */
private static void performVersionChecks ( String minSpringVersion ) { } }

implementation:
if ( minSpringVersion == null ) { return ; } // Check Spring Compatibility
String springVersion = SpringVersion . getVersion ( ) ; String version = getVersion ( ) ; if ( disableChecks ( springVersion , version ) ) { return ; } logger . info ( "You are running with Spring Security Core " + version ) ; if ( new ComparableVersion ( springVersion ) . compareTo ( new ComparableVersion ( minSpringVersion ) ) < 0 ) { logger . warn ( "**** You are advised to use Spring " + minSpringVersion + " or later with this version. You are running: " + springVersion ) ; }


signature:
public class SpringSecurityCoreVersion { /** * Disable if springVersion and springSecurityVersion are the same to allow working
 * with Uber Jars .
 * @ param springVersion
 * @ param springSecurityVersion
 * @ return */
private static boolean disableChecks ( String springVersion , String springSecurityVersion ) { } }

implementation: if ( springVersion == null || springVersion . equals ( springSecurityVersion ) ) { return true ; } return Boolean . getBoolean ( DISABLE_CHECKS ) ;


signature:
public class SpringSecurityCoreVersion { /** * Loads the spring version or null if it cannot be found .
 * @ return */
private static String getSpringVersion ( ) { } }

implementation: Properties properties = new Properties ( ) ; try { properties . load ( SpringSecurityCoreVersion . class . getClassLoader ( ) . getResourceAsStream ( "META-INF/spring-security.versions" ) ) ; } catch ( IOException | NullPointerException e ) { return null ; } return properties . getProperty ( "org.springframework:spring-core" ) ;


signature:
public class OAuth2AuthorizedClientResolver { /** * Attempts to load the client registration id from the current { @ link Authentication }
 * @ return */
private Mono < String > clientRegistrationId ( Mono < Authentication > authentication ) { } }

implementation: return authentication . filter ( t -> this . defaultOAuth2AuthorizedClient && t instanceof OAuth2AuthenticationToken ) . cast ( OAuth2AuthenticationToken . class ) . map ( OAuth2AuthenticationToken :: getAuthorizedClientRegistrationId ) ;


signature:
public class AfterInvocationProviderManager { /** * Iterates through all < code > AfterInvocationProvider < / code > s and ensures each can
 * support the presented class .
 * If one or more providers cannot support the presented class , < code > false < / code > is
 * returned .
 * @ param clazz the secure object class being queries
 * @ return if the < code > AfterInvocationProviderManager < / code > can support the secure
 * object class , which requires every one of its < code > AfterInvocationProvider < / code > s
 * to support the secure object class */
public boolean supports ( Class < ? > clazz ) { } }

implementation: for ( AfterInvocationProvider provider : providers ) { if ( ! provider . supports ( clazz ) ) { return false ; } } return true ;


signature:
public class X509Configurer { /** * Shortcut for invoking
 * { @ link # authenticationUserDetailsService ( AuthenticationUserDetailsService ) } with a
 * { @ link UserDetailsByNameServiceWrapper } .
 * @ param userDetailsService the { @ link UserDetailsService } to use
 * @ return the { @ link X509Configurer } for further customizations */
public X509Configurer < H > userDetailsService ( UserDetailsService userDetailsService ) { } }

implementation: UserDetailsByNameServiceWrapper < PreAuthenticatedAuthenticationToken > authenticationUserDetailsService = new UserDetailsByNameServiceWrapper < > ( ) ; authenticationUserDetailsService . setUserDetailsService ( userDetailsService ) ; return authenticationUserDetailsService ( authenticationUserDetailsService ) ;


signature:
public class X509Configurer { /** * Specifies the regex to extract the principal from the certificate . If not
 * specified , the default expression from { @ link SubjectDnX509PrincipalExtractor } is
 * used .
 * @ param subjectPrincipalRegex the regex to extract the user principal from the
 * certificate ( i . e . " CN = ( . * ? ) ( ? : , | $ ) " ) .
 * @ return the { @ link X509Configurer } for further customizations */
public X509Configurer < H > subjectPrincipalRegex ( String subjectPrincipalRegex ) { } }

implementation: SubjectDnX509PrincipalExtractor principalExtractor = new SubjectDnX509PrincipalExtractor ( ) ; principalExtractor . setSubjectDnRegex ( subjectPrincipalRegex ) ; this . x509PrincipalExtractor = principalExtractor ; return this ;


signature:
public class AbstractSecurityBuilder { /** * ( non - Javadoc )
 * @ see org . springframework . security . config . annotation . SecurityBuilder # build ( ) */
public final O build ( ) throws Exception { } }

implementation: if ( this . building . compareAndSet ( false , true ) ) { this . object = doBuild ( ) ; return this . object ; } throw new AlreadyBuiltException ( "This object has already been built" ) ;


signature: public class AbstractMethodSecurityMetadataSource { public final Collection < ConfigAttribute > getAttributes ( Object object ) { } }

implementation: if ( object instanceof MethodInvocation ) { MethodInvocation mi = ( MethodInvocation ) object ; Object target = mi . getThis ( ) ; Class < ? > targetClass = null ; if ( target != null ) { targetClass = target instanceof Class < ? > ? ( Class < ? > ) target : AopProxyUtils . ultimateTargetClass ( target ) ; } Collection < ConfigAttribute > attrs = getAttributes ( mi . getMethod ( ) , targetClass ) ; if ( attrs != null && ! attrs . isEmpty ( ) ) { return attrs ; } if ( target != null && ! ( target instanceof Class < ? > ) ) { attrs = getAttributes ( mi . getMethod ( ) , target . getClass ( ) ) ; } return attrs ; } throw new IllegalArgumentException ( "Object must be a non-null MethodInvocation" ) ;


signature:
public class HttpSessionOAuth2AuthorizationRequestRepository { /** * Gets a non - null and mutable map of { @ link OAuth2AuthorizationRequest # getState ( ) } to an { @ link OAuth2AuthorizationRequest }
 * @ param request
 * @ return a non - null and mutable map of { @ link OAuth2AuthorizationRequest # getState ( ) } to an { @ link OAuth2AuthorizationRequest } . */
private Map < String , OAuth2AuthorizationRequest > getAuthorizationRequests ( HttpServletRequest request ) { } }

implementation: HttpSession session = request . getSession ( false ) ; Map < String , OAuth2AuthorizationRequest > authorizationRequests = session == null ? null : ( Map < String , OAuth2AuthorizationRequest > ) session . getAttribute ( this . sessionAttributeName ) ; if ( authorizationRequests == null ) { return new HashMap < > ( ) ; } return authorizationRequests ;


signature: public class ConsoleAuditLogger { public void logIfNeeded ( boolean granted , AccessControlEntry ace ) { } }

implementation: Assert . notNull ( ace , "AccessControlEntry required" ) ; if ( ace instanceof AuditableAccessControlEntry ) { AuditableAccessControlEntry auditableAce = ( AuditableAccessControlEntry ) ace ; if ( granted && auditableAce . isAuditSuccess ( ) ) { System . out . println ( "GRANTED due to ACE: " + ace ) ; } else if ( ! granted && auditableAce . isAuditFailure ( ) ) { System . out . println ( "DENIED due to ACE: " + ace ) ; } }


signature:
public class OpenIDLoginConfigurer { /** * Sets up OpenID attribute exchange for OpenID ' s matching the specified pattern .
 * @ param identifierPattern the regular expression for matching on OpenID ' s ( i . e .
 * " https : / / www . google . com / . * " , " . * yahoo . com . * " , etc )
 * @ return a { @ link AttributeExchangeConfigurer } for further customizations of the
 * attribute exchange */
public AttributeExchangeConfigurer attributeExchange ( String identifierPattern ) { } }

implementation: AttributeExchangeConfigurer attributeExchangeConfigurer = new AttributeExchangeConfigurer ( identifierPattern ) ; this . attributeExchangeConfigurers . add ( attributeExchangeConfigurer ) ; return attributeExchangeConfigurer ;


signature:
public class OpenIDLoginConfigurer { /** * Gets the { @ link OpenIDConsumer } that was configured or defaults to an
 * { @ link OpenID4JavaConsumer } .
 * @ return the { @ link OpenIDConsumer } to use
 * @ throws ConsumerException */
private OpenIDConsumer getConsumer ( ) throws ConsumerException { } }

implementation: if ( this . openIDConsumer == null ) { this . openIDConsumer = new OpenID4JavaConsumer ( getConsumerManager ( ) , attributesToFetchFactory ( ) ) ; } return this . openIDConsumer ;


signature:
public class OpenIDLoginConfigurer { /** * Creates an { @ link RegexBasedAxFetchListFactory } using the attributes populated by
 * { @ link AttributeExchangeConfigurer }
 * @ return the { @ link AxFetchListFactory } to use */
private AxFetchListFactory attributesToFetchFactory ( ) { } }

implementation: Map < String , List < OpenIDAttribute > > identityToAttrs = new HashMap < String , List < OpenIDAttribute > > ( ) ; for ( AttributeExchangeConfigurer conf : this . attributeExchangeConfigurers ) { identityToAttrs . put ( conf . identifier , conf . getAttributes ( ) ) ; } return new RegexBasedAxFetchListFactory ( identityToAttrs ) ;


signature:
public class OpenIDLoginConfigurer { /** * Gets the { @ link AuthenticationUserDetailsService } that was configured or defaults
 * to { @ link UserDetailsByNameServiceWrapper } that uses a { @ link UserDetailsService }
 * looked up using { @ link HttpSecurity # getSharedObject ( Class ) }
 * @ param http the current { @ link HttpSecurity }
 * @ return the { @ link AuthenticationUserDetailsService } . */
private AuthenticationUserDetailsService < OpenIDAuthenticationToken > getAuthenticationUserDetailsService ( H http ) { } }

implementation: if ( this . authenticationUserDetailsService != null ) { return this . authenticationUserDetailsService ; } return new UserDetailsByNameServiceWrapper < > ( http . getSharedObject ( UserDetailsService . class ) ) ;


signature:
public class OpenIDLoginConfigurer { /** * If available , initializes the { @ link DefaultLoginPageGeneratingFilter } shared
 * object .
 * @ param http the { @ link HttpSecurityBuilder } to use */
private void initDefaultLoginFilter ( H http ) { } }

implementation: DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http . getSharedObject ( DefaultLoginPageGeneratingFilter . class ) ; if ( loginPageGeneratingFilter != null && ! isCustomLoginPage ( ) ) { loginPageGeneratingFilter . setOpenIdEnabled ( true ) ; loginPageGeneratingFilter . setOpenIDauthenticationUrl ( getLoginProcessingUrl ( ) ) ; String loginPageUrl = loginPageGeneratingFilter . getLoginPageUrl ( ) ; if ( loginPageUrl == null ) { loginPageGeneratingFilter . setLoginPageUrl ( getLoginPage ( ) ) ; loginPageGeneratingFilter . setFailureUrl ( getFailureUrl ( ) ) ; } loginPageGeneratingFilter . setOpenIDusernameParameter ( OpenIDAuthenticationFilter . DEFAULT_CLAIMED_IDENTITY_FIELD ) ; }