signature:
public class PullToRefreshBase { /** * Actions a Pull Event
 * @ return true if the Event has been handled , false if there has been no
 * change */
private void pullEvent ( ) { } }

implementation: final int newScrollValue ; final int itemDimension ; final float initialMotionValue , lastMotionValue ; switch ( getPullToRefreshScrollDirection ( ) ) { case HORIZONTAL : initialMotionValue = mInitialMotionX ; lastMotionValue = mLastMotionX ; break ; case VERTICAL : default : initialMotionValue = mInitialMotionY ; lastMotionValue = mLastMotionY ; break ; } switch ( mCurrentMode ) { case PULL_FROM_END : newScrollValue = Math . round ( Math . max ( initialMotionValue - lastMotionValue , 0 ) / FRICTION ) ; itemDimension = getFooterSize ( ) ; break ; case PULL_FROM_START : default : newScrollValue = Math . round ( Math . min ( initialMotionValue - lastMotionValue , 0 ) / FRICTION ) ; itemDimension = getHeaderSize ( ) ; break ; } setHeaderScroll ( newScrollValue ) ; if ( newScrollValue != 0 && ! isRefreshing ( ) ) { float scale = Math . abs ( newScrollValue ) / ( float ) itemDimension ; switch ( mCurrentMode ) { case PULL_FROM_END : mFooterLayout . onPull ( scale ) ; break ; case PULL_FROM_START : default : mHeaderLayout . onPull ( scale ) ; break ; } if ( mState != State . PULL_TO_REFRESH && itemDimension >= Math . abs ( newScrollValue ) ) { setState ( State . PULL_TO_REFRESH ) ; } else if ( mState == State . PULL_TO_REFRESH && itemDimension < Math . abs ( newScrollValue ) ) { setState ( State . RELEASE_TO_REFRESH ) ; } }


signature:
public class PullToRefreshHorizontalScrollViewActivity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation: super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_horizontalscrollview ) ; mPullRefreshScrollView = ( PullToRefreshHorizontalScrollView ) findViewById ( R . id . pull_refresh_horizontalscrollview ) ; mPullRefreshScrollView . setOnRefreshListener ( new OnRefreshListener < HorizontalScrollView > ( ) { @ Override public void onRefresh ( PullToRefreshBase < HorizontalScrollView > refreshView ) { new GetDataTask ( ) . execute ( ) ; } } ) ; mScrollView = mPullRefreshScrollView . getRefreshableView ( ) ;


signature:
public class PullToRefreshListFragmentActivity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation:
super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_list_fragment ) ; mPullRefreshListFragment = ( PullToRefreshListFragment ) getSupportFragmentManager ( ) . findFragmentById ( R . id . frag_ptr_list ) ; // Get PullToRefreshListView from Fragment
mPullRefreshListView = mPullRefreshListFragment . getPullToRefreshListView ( ) ; // Set a listener to be invoked when the list should be refreshed .
mPullRefreshListView . setOnRefreshListener ( this ) ; // You can also just use mPullRefreshListFragment . getListView ( )
ListView actualListView = mPullRefreshListView . getRefreshableView ( ) ; mListItems = new LinkedList < String > ( ) ; mListItems . addAll ( Arrays . asList ( mStrings ) ) ; mAdapter = new ArrayAdapter < String > ( this , android . R . layout . simple_list_item_1 , mListItems ) ; // You can also just use setListAdapter ( mAdapter ) or
// mPullRefreshListView . setAdapter ( mAdapter )
actualListView . setAdapter ( mAdapter ) ; mPullRefreshListFragment . setListShown ( true ) ;


signature:
public class PullToRefreshWebView2Activity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation:
super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_webview2 ) ; PullToRefreshWebView2 pullRefreshWebView = ( PullToRefreshWebView2 ) findViewById ( R . id . pull_refresh_webview2 ) ; pullRefreshWebView . setOnRefreshListener ( this ) ; WebView webView = pullRefreshWebView . getRefreshableView ( ) ; webView . getSettings ( ) . setJavaScriptEnabled ( true ) ; webView . setWebViewClient ( new SampleWebViewClient ( ) ) ; // We just load a prepared HTML page from the assets folder for this
// sample , see that file for the Javascript implementation
webView . loadUrl ( "file:///android_asset/ptr_webview2_sample.html" ) ;


signature:
public class PullToRefreshWebViewActivity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation: super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_webview ) ; mPullRefreshWebView = ( PullToRefreshWebView ) findViewById ( R . id . pull_refresh_webview ) ; mWebView = mPullRefreshWebView . getRefreshableView ( ) ; mWebView . getSettings ( ) . setJavaScriptEnabled ( true ) ; mWebView . setWebViewClient ( new SampleWebViewClient ( ) ) ; mWebView . loadUrl ( "http://www.google.com" ) ;


signature:
public class PullToRefreshScrollViewActivity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation: super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_scrollview ) ; mPullRefreshScrollView = ( PullToRefreshScrollView ) findViewById ( R . id . pull_refresh_scrollview ) ; mPullRefreshScrollView . setOnRefreshListener ( new OnRefreshListener < ScrollView > ( ) { @ Override public void onRefresh ( PullToRefreshBase < ScrollView > refreshView ) { new GetDataTask ( ) . execute ( ) ; } } ) ; mScrollView = mPullRefreshScrollView . getRefreshableView ( ) ;


signature:
public class OverscrollHelper { /** * Helper method for Overscrolling that encapsulates all of the necessary
 * function .
 * This should only be used on AdapterView ' s such as ListView as it just
 * calls through to overScrollBy ( ) with the scrollRange = 0 . AdapterView ' s
 * do not have a scroll range ( i . e . getScrollY ( ) doesn ' t work ) .
 * @ param view - PullToRefreshView that is calling this .
 * @ param deltaX - Change in X in pixels , passed through from from
 * overScrollBy call
 * @ param scrollX - Current X scroll value in pixels before applying deltaY ,
 * passed through from from overScrollBy call
 * @ param deltaY - Change in Y in pixels , passed through from from
 * overScrollBy call
 * @ param scrollY - Current Y scroll value in pixels before applying deltaY ,
 * passed through from from overScrollBy call
 * @ param isTouchEvent - true if this scroll operation is the result of a
 * touch event , passed through from from overScrollBy call */
public static void overScrollBy ( final PullToRefreshBase < ? > view , final int deltaX , final int scrollX , final int deltaY , final int scrollY , final boolean isTouchEvent ) { } }

implementation: overScrollBy ( view , deltaX , scrollX , deltaY , scrollY , 0 , isTouchEvent ) ;


signature:
public class OverscrollHelper { /** * Helper method for Overscrolling that encapsulates all of the necessary
 * function . This is the advanced version of the call .
 * @ param view - PullToRefreshView that is calling this .
 * @ param deltaX - Change in X in pixels , passed through from from
 * overScrollBy call
 * @ param scrollX - Current X scroll value in pixels before applying deltaY ,
 * passed through from from overScrollBy call
 * @ param deltaY - Change in Y in pixels , passed through from from
 * overScrollBy call
 * @ param scrollY - Current Y scroll value in pixels before applying deltaY ,
 * passed through from from overScrollBy call
 * @ param scrollRange - Scroll Range of the View , specifically needed for
 * ScrollView
 * @ param fuzzyThreshold - Threshold for which the values how fuzzy we
 * should treat the other values . Needed for WebView as it
 * doesn ' t always scroll back to it ' s edge . 0 = no fuzziness .
 * @ param scaleFactor - Scale Factor for overscroll amount
 * @ param isTouchEvent - true if this scroll operation is the result of a
 * touch event , passed through from from overScrollBy call */
public static void overScrollBy ( final PullToRefreshBase < ? > view , final int deltaX , final int scrollX , final int deltaY , final int scrollY , final int scrollRange , final int fuzzyThreshold , final float scaleFactor , final boolean isTouchEvent ) { } }

implementation:
final int deltaValue , currentScrollValue , scrollValue ; switch ( view . getPullToRefreshScrollDirection ( ) ) { case HORIZONTAL : deltaValue = deltaX ; scrollValue = scrollX ; currentScrollValue = view . getScrollX ( ) ; break ; case VERTICAL : default : deltaValue = deltaY ; scrollValue = scrollY ; currentScrollValue = view . getScrollY ( ) ; break ; } // Check that OverScroll is enabled and that we ' re not currently
// refreshing .
if ( view . isPullToRefreshOverScrollEnabled ( ) && ! view . isRefreshing ( ) ) { final Mode mode = view . getMode ( ) ; // Check that Pull - to - Refresh is enabled , and the event isn ' t from
// touch
if ( mode . permitsPullToRefresh ( ) && ! isTouchEvent && deltaValue != 0 ) { final int newScrollValue = ( deltaValue + scrollValue ) ; if ( PullToRefreshBase . DEBUG ) { Log . d ( LOG_TAG , "OverScroll. DeltaX: " + deltaX + ", ScrollX: " + scrollX + ", DeltaY: " + deltaY + ", ScrollY: " + scrollY + ", NewY: " + newScrollValue + ", ScrollRange: " + scrollRange + ", CurrentScroll: " + currentScrollValue ) ; } if ( newScrollValue < ( 0 - fuzzyThreshold ) ) { // Check the mode supports the overscroll direction , and
// then move scroll
if ( mode . showHeaderLoadingLayout ( ) ) { // If we ' re currently at zero , we ' re about to start
// overscrolling , so change the state
if ( currentScrollValue == 0 ) { view . setState ( State . OVERSCROLLING ) ; } view . setHeaderScroll ( ( int ) ( scaleFactor * ( currentScrollValue + newScrollValue ) ) ) ; } } else if ( newScrollValue > ( scrollRange + fuzzyThreshold ) ) { // Check the mode supports the overscroll direction , and
// then move scroll
if ( mode . showFooterLoadingLayout ( ) ) { // If we ' re currently at zero , we ' re about to start
// overscrolling , so change the state
if ( currentScrollValue == 0 ) { view . setState ( State . OVERSCROLLING ) ; } view . setHeaderScroll ( ( int ) ( scaleFactor * ( currentScrollValue + newScrollValue - scrollRange ) ) ) ; } } else if ( Math . abs ( newScrollValue ) <= fuzzyThreshold || Math . abs ( newScrollValue - scrollRange ) <= fuzzyThreshold ) { // Means we ' ve stopped overscrolling , so scroll back to 0
view . setState ( State . RESET ) ; } } else if ( isTouchEvent && State . OVERSCROLLING == view . getState ( ) ) { // This condition means that we were overscrolling from a fling ,
// but the user has touched the View and is now overscrolling
// from touch instead . We need to just reset .
view . setState ( State . RESET ) ; } }


signature:
public class PullToRefreshGridActivity { /** * Called when the activity is first created . */
@ Override public void onCreate ( Bundle savedInstanceState ) { } }

implementation:
super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_ptr_grid ) ; mPullRefreshGridView = ( PullToRefreshGridView ) findViewById ( R . id . pull_refresh_grid ) ; mGridView = mPullRefreshGridView . getRefreshableView ( ) ; // Set a listener to be invoked when the list should be refreshed .
mPullRefreshGridView . setOnRefreshListener ( new OnRefreshListener2 < GridView > ( ) { @ Override public void onPullDownToRefresh ( PullToRefreshBase < GridView > refreshView ) { Toast . makeText ( PullToRefreshGridActivity . this , "Pull Down!" , Toast . LENGTH_SHORT ) . show ( ) ; new GetDataTask ( ) . execute ( ) ; } @ Override public void onPullUpToRefresh ( PullToRefreshBase < GridView > refreshView ) { Toast . makeText ( PullToRefreshGridActivity . this , "Pull Up!" , Toast . LENGTH_SHORT ) . show ( ) ; new GetDataTask ( ) . execute ( ) ; } } ) ; mListItems = new LinkedList < String > ( ) ; TextView tv = new TextView ( this ) ; tv . setGravity ( Gravity . CENTER ) ; tv . setText ( "Empty View, Pull Down/Up to Add Items" ) ; mPullRefreshGridView . setEmptyView ( tv ) ; mAdapter = new ArrayAdapter < String > ( this , android . R . layout . simple_list_item_1 , mListItems ) ; mGridView . setAdapter ( mAdapter ) ;


signature:
public class PullToRefreshAdapterViewBase { /** * Sets the Empty View to be used by the Adapter View .
 * We need it handle it ourselves so that we can Pull - to - Refresh when the
 * Empty View is shown .
 * Please note , you do < strong > not < / strong > usually need to call this method
 * yourself . Calling setEmptyView on the AdapterView will automatically call
 * this method and set everything up . This includes when the Android
 * Framework automatically sets the Empty View based on it ' s ID .
 * @ param newEmptyView - Empty View to be used */
public final void setEmptyView ( View newEmptyView ) { } }

implementation:
FrameLayout refreshableViewWrapper = getRefreshableViewWrapper ( ) ; if ( null != newEmptyView ) { // New view needs to be clickable so that Android recognizes it as a
// target for Touch Events
newEmptyView . setClickable ( true ) ; ViewParent newEmptyViewParent = newEmptyView . getParent ( ) ; if ( null != newEmptyViewParent && newEmptyViewParent instanceof ViewGroup ) { ( ( ViewGroup ) newEmptyViewParent ) . removeView ( newEmptyView ) ; } // We need to convert any LayoutParams so that it works in our
// FrameLayout
FrameLayout . LayoutParams lp = convertEmptyViewLayoutParams ( newEmptyView . getLayoutParams ( ) ) ; if ( null != lp ) { refreshableViewWrapper . addView ( newEmptyView , lp ) ; } else { refreshableViewWrapper . addView ( newEmptyView ) ; } } if ( mRefreshableView instanceof EmptyViewMethodAccessor ) { ( ( EmptyViewMethodAccessor ) mRefreshableView ) . setEmptyViewInternal ( newEmptyView ) ; } else { mRefreshableView . setEmptyView ( newEmptyView ) ; } mEmptyView = newEmptyView ;


signature:
public class RuleBookRuleWithFactTypeBuilder { /** * Specifies the condition for the Rule .
 * @ param condition the condition for the Rule
 * @ return a builder for building Rules with a specified condition */
public WhenRuleBuilder < T , U > when ( Predicate < NameValueReferableTypeConvertibleMap < T > > condition ) { } }

implementation: return new WhenRuleBuilder < > ( _rule , condition ) ;


signature:
public class RuleHandler { /** * Invokes the current Rule ' s action and then moves down the chain to the successor
 * if the RuleState of the current Rule is next or the action ( s ) was not executed .
 * @ param obj facts to be applied to the request ( rule invocation ) */
@ Override @ SuppressWarnings ( "unchecked" ) public void handleRequest ( Object obj ) { } }

implementation: boolean actionResult = _rule . invoke ( ( NameValueReferableMap ) obj ) ; if ( ! actionResult || _rule . getRuleState ( ) == RuleState . NEXT ) { getSuccessor ( ) . ifPresent ( handler -> { _rule . getResult ( ) . ifPresent ( result -> handler . getDelegate ( ) . setResult ( ( Result ) result ) ) ; handler . handleRequest ( obj ) ; } ) ; }


signature:
public class FactMap { /** * The method getOne ( ) gets the value of the single Fact in the FactMap .
 * @ return the value of a fact stored if only one fact is stored , otherwise null */
@ Override public T getOne ( ) { } }

implementation: if ( _facts . size ( ) == 1 ) { return _facts . values ( ) . iterator ( ) . next ( ) . getValue ( ) ; } return null ;


signature:
public class FactMap { /** * The method getValue ( ) returns the value of the Fact associated with the name passed in .
 * @ param name the name of the Fact
 * @ return the value of the Fact */
@ Override public T getValue ( String name ) { } }

implementation: return Optional . ofNullable ( _facts . get ( name ) ) . map ( NameValueReferable :: getValue ) . orElse ( null ) ;


signature:
public class FactMap { /** * Method getStrVal ( ) gets the String value of a Fact in the FactMap .
 * @ param name the name of the Fact in the FactMap
 * @ return the String value of the Fact specified */
@ Deprecated public String getStrVal ( String name ) { } }

implementation: if ( getValue ( name ) instanceof String ) { return ( String ) getValue ( name ) ; } return String . valueOf ( getValue ( name ) ) ;


signature:
public class FactMap { /** * Method getIntVal ( ) gets the Integer value of a Fact in the FactMap .
 * @ param name the name of the Fact in the FactMap
 * @ return the Integer value of the Fact specified */
@ Deprecated public Integer getIntVal ( String name ) { } }

implementation: Object value = getValue ( name ) ; if ( value != null ) { if ( Integer . class == value . getClass ( ) ) { return ( Integer ) value ; } if ( value . getClass ( ) == String . class ) { return Integer . valueOf ( ( String ) value ) ; } } return null ;


signature:
public class FactMap { /** * Method getDblVal ( ) gets the Double value of a Fact in the FactMap .
 * @ param name the name of the Fact in the FactMap
 * @ return the Double value of the Fact specified */
@ Deprecated public Double getDblVal ( String name ) { } }

implementation: Object value = getValue ( name ) ; if ( value != null ) { if ( Float . class == value . getClass ( ) ) { return Double . valueOf ( ( Float ) value ) ; } if ( Double . class == value . getClass ( ) ) { return ( Double ) value ; } if ( Integer . class == value . getClass ( ) ) { return Double . valueOf ( ( Integer ) value ) ; } if ( Long . class == value . getClass ( ) ) { return Double . valueOf ( ( Long ) value ) ; } if ( String . class == value . getClass ( ) ) { return Double . parseDouble ( ( String ) value ) ; } } return null ;


signature:
public class FactMap { /** * The method setValue sets the value of the Fact by its name . < br / >
 * If no Fact exists with the associated name , a new fact is created with the specified name and value . < br / >
 * @ param name the name of the Fact
 * @ param value the value object of the Fact */
public void setValue ( String name , T value ) { } }

implementation: NameValueReferable < T > fact = _facts . get ( name ) ; if ( fact == null ) { fact = new Fact < > ( name , value ) ; _facts . put ( name , fact ) ; return ; } fact . setValue ( value ) ;


signature:
public class FactMap { /** * This put ( ) method is a convenience method for adding a Fact to a FactMap . < br / >
 * It uses the name of the Fact as the key and the Fact as the value .
 * @ param fact the Fact to be added to the FactMap
 * @ return the Fact that was just added */
@ Override public Fact < T > put ( NameValueReferable < T > fact ) { } }

implementation: return put ( fact . getName ( ) , fact ) ;


signature:
public class GivenRuleBuilder { /** * Adds a fact to the Rule .
 * @ param name the name of the fact
 * @ param value the value of the fact
 * @ return a GivenRuleBuilder */
GivenRuleBuilder < T , U > given ( String name , T value ) { } }

implementation: return given ( new Fact < T > ( name , value ) ) ;


signature:
public class GivenRuleBuilder { /** * Adds one or more facts into the Rule .
 * @ param facts one or more facts
 * @ return the current builder object */
@ SafeVarargs public final GivenRuleBuilder < T , U > given ( NameValueReferable ... facts ) { } }

implementation: _rule . addFacts ( facts ) ; return this ;


signature:
public class GivenRuleBuilder { /** * Adds a using constraint in the Rule that restricts the facts supplied to the subsequent ' then ' action .
 * @ param factNames the fact names to be supplied to the subsequent ' then ' action
 * @ return a builder the allows for the Rule to be built following the ' using ' statement */
public UsingRuleBuilder < T , U > using ( String ... factNames ) { } }

implementation: return new UsingRuleBuilder < T , U > ( _rule , factNames ) ;


signature:
public class RuleBuilder { /** * Returns a new RuleBuilder for the specified Rule class .
 * @ param ruleClass the class of Rule to build
 * @ param actionType if STOP _ ON _ FAILURE , stops the rule chain if RuleState is BREAK only if the rule fails
 * ( for supported rule classes ) ; if ERROR _ ON _ FAILURE , allows exceptions to be thrown from rule ;
 * default is CONTINUE _ ON _ FAILURE
 * @ return a new RuleBuilder */
public static RuleBuilder < Object , Object > create ( Class < ? extends Rule > ruleClass , RuleChainActionType actionType ) { } }

implementation: return new RuleBuilder < > ( ruleClass , actionType ) ;


signature:
public class RuleBuilder { /** * Returns a new RuleBuilder for the default Rule type .
 * @ return a new RuleBuilder */
public static RuleBuilder < Object , Object > create ( ) { } }

implementation: RuleBuilder < Object , Object > rule = new RuleBuilder < > ( GoldenRule . class ) ; rule . _factType = Object . class ; return rule ;


signature:
public class RuleBuilder { /** * Specifies the fact type for the Rule being built .
 * @ param factType the type of facts to be used in the Rule
 * @ param < S > the type of facts
 * @ return a builder using the new fact type for building a Rule */
public < S > RuleBuilder < S , U > withFactType ( Class < S > factType ) { } }

implementation: RuleBuilder < S , U > builder = new RuleBuilder < > ( _ruleClass ) ; builder . _factType = factType ; builder . _resultType = _resultType ; builder . _actionType = _actionType ; return builder ;


signature:
public class RuleBuilder { /** * Specifies the Result type for the Rule being built .
 * @ param resultType the type of the Result to be used in the Rule
 * @ param < S > the type of Result
 * @ return a builder using a new result type for building a Rule */
public < S > RuleBuilder < T , S > withResultType ( Class < S > resultType ) { } }

implementation: RuleBuilder < T , S > builder = new RuleBuilder < > ( _ruleClass ) ; builder . _factType = _factType ; builder . _resultType = resultType ; builder . _actionType = _actionType ; builder . _name = _name ; return builder ;


signature:
public class RuleBuilder { /** * Adds a fact to the Rule using a name value pair to specify a new fact .
 * @ param name the name of the fact
 * @ param value the value of the fact
 * @ return a builder for building rules after a ' given ' statement */
@ SuppressWarnings ( "unchecked" ) public GivenRuleBuilder < T , U > given ( String name , T value ) { } }

implementation: Rule < T , U > rule = _name . map ( ruleName -> ( Rule < T , U > ) new AuditableRule < T , U > ( newRule ( ) , ruleName ) ) . orElse ( newRule ( ) ) ; if ( rule == null ) { throw new IllegalStateException ( "No Rule is instantiated; An invalid Rule class may have been provided" ) ; } return new GivenRuleBuilder < T , U > ( rule , new Fact < T > ( name , value ) ) ;


signature:
public class RuleBuilder { /** * Adds one or more facts to the Rule .
 * @ param facts the facts to be added to the Rule
 * @ return a builder for building rules after a ' given ' statement */
@ SuppressWarnings ( "unchecked" ) @ SafeVarargs public final GivenRuleBuilder < T , U > given ( NameValueReferable ... facts ) { } }

implementation: Rule < T , U > rule = _name . map ( name -> ( Rule < T , U > ) new AuditableRule < T , U > ( newRule ( ) , name ) ) . orElse ( newRule ( ) ) ; if ( rule == null ) { throw new IllegalStateException ( "No Rule is instantiated; An invalid Rule class may have been provided" ) ; } return new GivenRuleBuilder < T , U > ( rule , facts ) ;


signature:
public class RuleBuilder { /** * Specifies the condition for the Rule .
 * @ param condition the condition for the Rule
 * @ return a builder for building rules after a ' when ' statement */
@ SuppressWarnings ( "unchecked" ) public WhenRuleBuilder < T , U > when ( Predicate < NameValueReferableTypeConvertibleMap < T > > condition ) { } }

implementation: Rule < T , U > rule = _name . map ( name -> ( Rule < T , U > ) new AuditableRule < T , U > ( newRule ( ) , name ) ) . orElse ( newRule ( ) ) ; if ( rule == null ) { throw new IllegalStateException ( "No Rule is instantiated; An invalid Rule class may have been provided" ) ; } return new WhenRuleBuilder < T , U > ( rule , condition ) ;


signature:
public class RuleBuilder { /** * Adds a using constraint in the Rule that restricts the facts supplied to the subsequent ' then ' action .
 * @ param factNames the fact names to be supplied to the subsequent ' then ' action
 * @ return a builder the allows for the Rule to be built following the ' using ' statement */
@ SuppressWarnings ( "unchecked" ) public UsingRuleBuilder < T , U > using ( String ... factNames ) { } }

implementation: Rule < T , U > rule = _name . map ( name -> ( Rule < T , U > ) new AuditableRule < T , U > ( newRule ( ) , name ) ) . orElse ( newRule ( ) ) ; if ( rule == null ) { throw new IllegalStateException ( "No Rule is instantiated; An invalid Rule class may have been provided" ) ; } return new UsingRuleBuilder < T , U > ( rule , factNames ) ;


signature:
public class RuleBuilder { /** * Adds an action as a Consumer to the Rule .
 * @ param action a Consumer action to be added to the Rule that accepts the facts specified for the Rule
 * @ return a builder for building rules after a ' then ' action is specified */
@ SuppressWarnings ( "unchecked" ) public ThenRuleBuilder < T , U > then ( Consumer < NameValueReferableTypeConvertibleMap < T > > action ) { } }

implementation: Rule < T , U > rule = _name . map ( name -> ( Rule < T , U > ) new AuditableRule < T , U > ( newRule ( ) , name ) ) . orElse ( newRule ( ) ) ; if ( rule == null ) { throw new IllegalStateException ( "No Rule is instantiated; An invalid Rule class may have been provided" ) ; } return new ThenRuleBuilder < T , U > ( rule , action ) ;


signature:
public class RuleAdapter { /** * Convert the Facts to properties with the @ Given annotation in the class .
 * If any matched properties are non - Facts , then the value of the associated Facts are mapped to those
 * properties . If any matched properties are Facts , then the Fact object are mapped to those properties . */
@ SuppressWarnings ( "unchecked" ) private void mapFactsToProperties ( NameValueReferableMap facts ) { } }

implementation:
for ( Field field : getAnnotatedFields ( Given . class , _pojoRule . getClass ( ) ) ) { Given given = field . getAnnotation ( Given . class ) ; try { field . setAccessible ( true ) ; if ( NameValueReferable . class . isAssignableFrom ( field . getType ( ) ) ) { field . set ( _pojoRule , facts . get ( given . value ( ) ) ) ; } else { Object value = facts . getValue ( given . value ( ) ) ; if ( value != null ) { // set the field to the Fact that has the name of the @ Given value
field . set ( _pojoRule , value ) ; } else if ( NameValueReferableMap . class . isAssignableFrom ( field . getType ( ) ) ) { // if the field is a FactMap then give it the FactMap
field . set ( _pojoRule , facts ) ; } else if ( Collection . class . isAssignableFrom ( field . getType ( ) ) ) { // set a Collection of Fact object values
Stream stream = facts . values ( ) . stream ( ) . filter ( fact -> { // filter on only facts that contain objects matching the generic type
ParameterizedType paramType = ( ParameterizedType ) field . getGenericType ( ) ; Class < ? > genericType = ( Class < ? > ) paramType . getActualTypeArguments ( ) [ 0 ] ; return genericType . equals ( ( ( NameValueReferable ) fact ) . getValue ( ) . getClass ( ) ) ; } ) . map ( fact -> { ParameterizedType paramType = ( ParameterizedType ) field . getGenericType ( ) ; Class < ? > genericType = ( Class < ? > ) paramType . getActualTypeArguments ( ) [ 0 ] ; return genericType . cast ( ( ( NameValueReferable ) fact ) . getValue ( ) ) ; } ) ; if ( List . class == field . getType ( ) ) { // map List of Fact values to field
field . set ( _pojoRule , stream . collect ( Collectors . toList ( ) ) ) ; } else if ( Set . class == field . getType ( ) ) { // map Set of Fact values to field
field . set ( _pojoRule , stream . collect ( Collectors . toSet ( ) ) ) ; } } else if ( Map . class == field . getType ( ) ) { // map Map of Fact values to field
Map map = ( Map ) facts . keySet ( ) . stream ( ) . filter ( key -> { ParameterizedType paramType = ( ParameterizedType ) field . getGenericType ( ) ; Class < ? > genericType = ( Class < ? > ) paramType . getActualTypeArguments ( ) [ 1 ] ; return genericType . equals ( facts . getValue ( ( String ) key ) . getClass ( ) ) ; } ) . collect ( Collectors . toMap ( key -> key , key -> facts . getValue ( ( String ) key ) ) ) ; field . set ( _pojoRule , map ) ; } } } catch ( Exception ex ) { LOGGER . error ( "Unable to update field '" + field . getName ( ) + "' in rule object '" + _pojoRule . getClass ( ) + "'" , ex ) ; } }


signature:
public class AbstractRuleBookRunner { /** * Returns a rule instance
 * < p > For container aware contexts ( like Spring , Guice , Weld , etc . ) override this method and instantiate the rule
 * via the container .
 * @ param rule The rule class
 * @ return The rule instance */
protected Object getRuleInstance ( Class < ? > rule ) { } }

implementation: try { return rule . newInstance ( ) ; } catch ( InstantiationException | IllegalAccessException ex ) { LOGGER . warn ( "Unable to create instance of rule using '" + rule + "'" , ex ) ; } return null ;


signature:
public class RuleBook { /** * The run ( ) method adds the rules [ via defineRules ( ) ] and runs the rules as long as at least one rule was
 * added . */
public final void run ( ) { } }

implementation: if ( _headRule . isPresent ( ) == false ) { defineRules ( ) ; } _headRule . ifPresent ( rule -> rule . given ( _facts ) ) ; _headRule . ifPresent ( Rule :: run ) ;


signature:
public class RuleBook { /** * The given ( ) method accepts the Facts for this RuleBook .
 * The facts passed in will also be applied to all rules added to this RuleBook .
 * @ param facts Facts to be added to the RuleBook and applied to all the Rules in the RuleBook
 * @ return the current RuleBook object */
@ SafeVarargs public final RuleBook < T > given ( Fact < T > ... facts ) { } }

implementation: Arrays . stream ( facts ) . forEach ( _facts :: add ) ; return this ;


signature:
public class RuleBook { /** * The given ( ) method accepts a key / value pair as a Fact for this RuleBook .
 * @ param name the name of the Fact
 * @ param value the value of the Fact
 * @ return the current RuleBook object */
public RuleBook < T > given ( String name , T value ) { } }

implementation: _facts . add ( new Fact < T > ( name , value ) ) ; return this ;


signature:
public class RuleBook { /** * The addRule ( ) method adds a rule to the end of the Rules chain .
 * @ param rule the Rule to be added */
public void addRule ( Rule < T > rule ) { } }

implementation:
if ( rule == null ) { return ; } if ( ! _headRule . isPresent ( ) ) { _headRule = Optional . of ( rule ) ; // this rule is the head if there was no head
_tailRule = rule ; } else { _tailRule . setNextRule ( rule ) ; _tailRule = rule ; }


signature:
public class AnnotationUtils { /** * Method getAnnotatedFields gets the fields annotated of a specific type from the class and its parent classes . < br / >
 * The List is in order of closest parent = > current obj fields , parent obj fields , etc .
 * @ param annotation the annotation type
 * @ param clazz the class that is expected to be annotated
 * @ return a { @ link Set } of { @ link Field } objects annotated with the annotatedClass */
@ SuppressWarnings ( "unchecked" ) public static List < Field > getAnnotatedFields ( Class annotation , Class clazz ) { } }

implementation: if ( clazz == Object . class ) { return new ArrayList < > ( ) ; } List < Field > fields = ( List < Field > ) Arrays . stream ( clazz . getDeclaredFields ( ) ) . filter ( field -> field . getAnnotation ( annotation ) != null ) . collect ( Collectors . toList ( ) ) ; if ( clazz . getSuperclass ( ) != null ) { fields . addAll ( getAnnotatedFields ( annotation , clazz . getSuperclass ( ) ) ) ; } return fields ;


signature:
public class AnnotationUtils { /** * Method getAnnotatedField gets the first annotated field of the type of annotation specified .
 * @ param annotation the type of the annotation
 * @ param clazz the annotated class
 * @ return the first annotated field found in clazz of the type annotation */
public static Optional < Field > getAnnotatedField ( Class annotation , Class clazz ) { } }

implementation: List < Field > fields = getAnnotatedFields ( annotation , clazz ) ; return Optional . ofNullable ( fields . size ( ) > 0 ? fields . get ( 0 ) : null ) ;


signature:
public class AnnotationUtils { /** * Method getAnnotatedMethods gets the methods annotated of a specific type from the class and its parent
 * classes . < br / > The List is in order of closest parent = > current obj methods , parent obj methods , etc .
 * @ param annotation the type of the annotation
 * @ param clazz the annotated class
 * @ return a List of Methods that have been annotated using annotation in the class clazz */
@ SuppressWarnings ( "unchecked" ) public static List < Method > getAnnotatedMethods ( Class annotation , Class clazz ) { } }

implementation: List < Method > methods = new ArrayList < > ( ) ; if ( clazz == Object . class ) { return methods ; } methods . addAll ( ( List < Method > ) Arrays . stream ( clazz . getDeclaredMethods ( ) ) . filter ( field -> field . getAnnotation ( annotation ) != null ) . collect ( Collectors . toList ( ) ) ) ; methods . addAll ( getAnnotatedMethods ( annotation , clazz . getSuperclass ( ) ) ) ; return methods ;


signature:
public class AnnotationUtils { /** * Method getAnnotatedMethod the first annotated method of the type of annotation specified .
 * @ param annotation the type of the annotation
 * @ param clazz the annotated class
 * @ return the first annotated field found in clazz of the type annotation */
public static Optional < Method > getAnnotatedMethod ( Class annotation , Class clazz ) { } }

implementation: List < Method > methods = getAnnotatedMethods ( annotation , clazz ) ; return Optional . ofNullable ( methods . size ( ) > 0 ? methods . get ( 0 ) : null ) ;


signature:
public class AnnotationUtils { /** * Method getAnnotation returns the annotation on a class or its parent annotation .
 * @ param clazz the annotated class
 * @ param annotation the annotation to find
 * @ param < A > the type of the annotation
 * @ return the actual annotation used or null if it doesn ' t exist */
@ SuppressWarnings ( "unchecked" ) public static < A extends Annotation > A getAnnotation ( Class < A > annotation , Class < ? > clazz ) { } }

implementation: return Optional . ofNullable ( clazz . getAnnotation ( annotation ) ) . orElse ( ( A ) Arrays . stream ( clazz . getDeclaredAnnotations ( ) ) . flatMap ( anno -> Arrays . stream ( anno . getClass ( ) . getInterfaces ( ) ) . flatMap ( iface -> Arrays . stream ( iface . getDeclaredAnnotations ( ) ) ) ) . filter ( annotation :: isInstance ) . findFirst ( ) . orElse ( null ) ) ;


signature:
public class StandardDecision { /** * This create ( ) method is a convenience method to avoid using new and generic syntax .
 * @ param factType the type of object stored in facts for this Decision
 * @ param resultType the type of object stored in the Result
 * @ param < T > the class type of the objects in the Facts used
 * @ param < U > the class type of object stored in the Result
 * @ return a new instance of StandardDecision */
public static < T , U > StandardDecision < T , U > create ( Class < T > factType , Class < U > resultType ) { } }

implementation: return new StandardDecision < T , U > ( factType , resultType ) ;


signature:
public class StandardDecision { /** * The given ( ) method accepts a name / value pair to be used as a Fact .
 * @ param name name of the Fact
 * @ param value object provided as the Fact with the given name
 * @ return the current object */
@ Override public Decision < T , U > given ( String name , T value ) { } }

implementation: _rule . given ( name , value ) ; return this ;


signature:
public class StandardDecision { /** * The given ( ) method accepts Facts for the StandardDecision .
 * @ param facts Facts to be used by the Rule
 * @ return the current object for chaining other methods */
@ Override public Decision < T , U > given ( Fact < T > ... facts ) { } }

implementation: _rule . given ( facts ) ; return this ;


signature:
public class StandardDecision { /** * The given ( ) method accepts Facts for the StandardDecision .
 * @ param facts a { @ link FactMap }
 * @ return the current object */
@ Override public Decision < T , U > given ( FactMap < T > facts ) { } }


signature:
public class StandardDecision { /** * The when ( ) method accepts a { @ link Predicate } that returns true or false based on Facts .
 * @ param test the condition ( s ) to be evaluated against the Facts
 * @ return true , if the then ( ) statement ( s ) should be evaluated , otherwise false */
@ Override public Decision < T , U > when ( Predicate < FactMap < T > > test ) { } }

implementation: _rule . when ( test ) ; return this ;


signature:
public class StandardDecision { /** * The then ( ) method accepts a { @ link BiConsumer } that performs an action based on Facts . < br / >
 * The arguments of the BiConsumer are a { @ link FactMap } and a { @ link Result } , respectively .
 * @ param action the action to be performed
 * @ return the current object */
@ Override public Decision < T , U > then ( BiConsumer < FactMap < T > , Result < U > > action ) { } }

implementation: _rule . getThen ( ) . add ( action ) ; return this ;


signature:
public class StandardDecision { /** * The then ( ) method accepts a { @ link Consumer } that performs an action based on Facts .
 * @ param action the action to be performed
 * @ return the current object */
@ Override public Decision < T , U > then ( Consumer < FactMap < T > > action ) { } }

implementation: _rule . then ( action ) ; return this ;


signature:
public class StandardDecision { /** * The using ( ) method reduces the facts to those specifically named here .
 * The using ( ) method only applies to the then ( ) method immediately following it .
 * @ param factNames the names of the facts to be used
 * @ return the current object */
@ Override @ SuppressWarnings ( "unchecked" ) public Decision < T , U > using ( String ... factNames ) { } }

implementation: _rule . using ( factNames ) ; return this ;


signature:
public class Auditor { /** * Registers a rule to be audited .
 * @ param rule and { @ link Auditable } rule */
public void registerRule ( Auditable rule ) { } }

implementation: _lock . writeLock ( ) . lock ( ) ; try { _auditMap . put ( rule . getName ( ) , new HashMap < > ( ) ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; }


signature:
public class Auditor { /** * Updates the status of the rule & stores the status with the Auditor .
 * @ param rule the rule in question
 * @ param status the status of the rule */
public void updateRuleStatus ( Auditable rule , RuleStatus status ) { } }

implementation: _lock . readLock ( ) . lock ( ) ; try { if ( _auditMap . containsKey ( rule . getName ( ) ) ) { _lock . readLock ( ) . unlock ( ) ; _lock . writeLock ( ) . lock ( ) ; try { _auditMap . get ( rule . getName ( ) ) . put ( Thread . currentThread ( ) . getId ( ) , status ) ; _lock . readLock ( ) . lock ( ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; } } } finally { _lock . readLock ( ) . unlock ( ) ; }


signature:
public class Auditor { /** * Gets a map of each rule name with its associated status .
 * @ return a map of rule names and their associated status */
public Map < String , RuleStatus > getRuleStatusMap ( ) { } }

implementation: _lock . readLock ( ) . lock ( ) ; try { return _auditMap . keySet ( ) . stream ( ) . collect ( Collectors . toMap ( key -> key , key -> _auditMap . get ( key ) . getOrDefault ( Thread . currentThread ( ) . getId ( ) , RuleStatus . PENDING ) ) ) ; } finally { _lock . readLock ( ) . unlock ( ) ; }


signature:
public class RuleBookBuilder { /** * Specifies the Result type for the RuleBook .
 * @ param resultType result class
 * @ param < U > type of the result class
 * @ return a builder with the new Result type */
public < U > RuleBookWithResultTypeBuilder < U > withResultType ( Class < U > resultType ) { } }

implementation: _resultType = resultType ; return new RuleBookWithResultTypeBuilder < U > ( ( new RuleBookBuilder < U > ( this ) ) . newRuleBook ( ) ) ;


signature:
public class RuleBookBuilder { /** * Adds a rule to the RuleBook .
 * @ param consumer functional interface that supplies a RuleBookRuleBuilder for building a Rule
 * @ return a builder with the added Rule */
public RuleBookAddRuleBuilder < T > addRule ( Consumer < RuleBookRuleBuilder < T > > consumer ) { } }

implementation: return new RuleBookAddRuleBuilder < > ( newRuleBook ( ) , consumer ) ;


signature:
public class RuleBookBuilder { /** * Adds a rule to the RuleBook .
 * @ param rule Rule to be added into the RuleBook
 * @ param < U > the fact type of the Rule
 * @ return RuleBookBuilder with the added Rule */
public < U > RuleBookAddRuleBuilder < T > addRule ( Rule < U , T > rule ) { } }

implementation: return new RuleBookAddRuleBuilder < > ( newRuleBook ( ) , rule ) ;


signature:
public class StandardRule { /** * The run ( Object [ ] ) method runs the { @ link Predicate } supplied by the when ( ) method . < br / >
 * If it evaluates to true then the action ( s ) supplied by the then ( ) method ( s ) are executed . < br / >
 * If the stop ( ) method was invoked then no further rules are evaluated . < br / >
 * Otherwise , the next rule in the chain is evaluated . */
@ Override @ SuppressWarnings ( "unchecked" ) public void run ( Object ... otherArgs ) { } }

implementation:
try { // only use facts of the specified type
FactMap < T > typeFilteredFacts = new FactMap < T > ( ( Map < String , NameValueReferable < T > > ) _facts . values ( ) . stream ( ) . filter ( ( Object fact ) -> _factType . isAssignableFrom ( ( ( Fact ) fact ) . getValue ( ) . getClass ( ) ) ) . collect ( Collectors . toMap ( fact -> ( ( Fact ) fact ) . getName ( ) , fact -> ( Fact < T > ) fact ) ) ) ; // invoke then ( ) action ( s ) if when ( ) is true or if when ( ) was never specified
if ( getWhen ( ) == null || getWhen ( ) . test ( typeFilteredFacts ) ) { // iterate through the then ( ) actions specified
List < Object > actionList = getThen ( ) ; for ( int i = 0 ; i < ( getThen ( ) ) . size ( ) ; i ++ ) { Object action = actionList . get ( i ) ; List < String > factNames = _factNameMap . get ( i ) ; // if using ( ) fact names were specified for the specific then ( ) , use only those facts specified
FactMap < T > usingFacts ; if ( factNames != null ) { usingFacts = new FactMap < T > ( factNames . stream ( ) . filter ( typeFilteredFacts :: containsKey ) . collect ( Collectors . toMap ( name -> name , name -> _facts . get ( name ) ) ) ) ; } else { usingFacts = typeFilteredFacts ; } // invoke the action
Stream . of ( action . getClass ( ) . getMethods ( ) ) . filter ( method -> method . getName ( ) . equals ( "accept" ) ) . findFirst ( ) . ifPresent ( method -> { try { method . setAccessible ( true ) ; method . invoke ( action , ArrayUtils . combine ( new Object [ ] { usingFacts } , otherArgs , method . getParameterCount ( ) ) ) ; } catch ( IllegalAccessException | InvocationTargetException err ) { LOGGER . error ( "Error invoking action on " + action . getClass ( ) , err ) ; } } ) ; } // if stop ( ) was invoked , stop the rule chain after then is finished executing
if ( _ruleState == BREAK ) { return ; } } } catch ( Exception ex ) { // catch errors in case something like one rule was chained expecting a Fact that doesn ' t exist
// eventually , we ' ll have to resolve that kind of issue ahead of time
LOGGER . error ( "Error occurred when trying to evaluate rule!" , ex ) ; } // continue down the rule chain
_nextRule . ifPresent ( rule -> rule . given ( _facts ) ) ; _nextRule . ifPresent ( Rule :: run ) ;


signature:
public class StandardRule { /** * The given ( ) method accepts a name / value pair to be used as a Fact .
 * @ param name name of the Fact
 * @ param value object provided as the Fact with the given name
 * @ return the current object */
@ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > given ( String name , T value ) { } }

implementation: _facts . put ( name , new Fact < T > ( name , value ) ) ; return this ;


signature:
public class StandardRule { /** * The given ( ) method accepts Facts to be evaluated in the Rule .
 * @ param facts Facts to be used by the Rule
 * @ return the current object */
@ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > given ( Fact < T > ... facts ) { } }

implementation: for ( Fact f : facts ) { _facts . put ( f . getName ( ) , f ) ; } return this ;


signature:
public class StandardRule { /** * The when ( ) method accepts a { @ link Predicate } that returns true or false based on Facts .
 * @ param test the condition ( s ) to be evaluated against the Facts
 * @ return the current object */
@ Override public Rule < T > when ( Predicate < FactMap < T > > test ) { } }

implementation: _test = test ; return this ;


signature:
public class StandardRule { /** * The then ( ) method accepts a { @ link Consumer } that performs an action based on Facts .
 * @ param action the action to be performed
 * @ return the current object */
@ Override @ SuppressWarnings ( "unchecked" ) public Rule < T > then ( Consumer < FactMap < T > > action ) { } }

implementation: _actionChain . add ( action ) ; return this ;


signature:
public class StandardRule { /** * The using ( ) method reduces the facts to those specifically named here .
 * The using ( ) method only applies to the then ( ) method immediately following it .
 * @ param factNames the names of the facts to be used
 * @ return the current object */
@ Override @ SuppressWarnings ( "unchecked" ) public StandardRule < T > using ( String ... factNames ) { } }

implementation: List < String > factNameList = Stream . of ( factNames ) . filter ( name -> _factType . isInstance ( _facts . getValue ( name ) ) ) . collect ( Collectors . toList ( ) ) ; if ( _factNameMap . containsKey ( ( getThen ( ) ) . size ( ) ) ) { List < String > existingFactNames = _factNameMap . get ( ( getThen ( ) ) . size ( ) ) ; existingFactNames . addAll ( factNameList ) ; return this ; } _factNameMap . put ( ( getThen ( ) ) . size ( ) , factNameList ) ; return this ;


signature:
public class DecisionBook { /** * The addRule ( ) method allows a rule to be added to the DecisionBook in the abstract defineRules
 * method .
 * @ param rule the Decision rule to be added to the DecisionBook */
public void addRule ( Decision < T , U > rule ) { } }

implementation: if ( rule == null ) { return ; } super . addRule ( rule ) ; rule . setResult ( _result ) ;


signature:
public class ThenRuleBuilder { /** * Adds a then action into the Rule .
 * @ param action an action that the rule will execute based on the condition
 * @ return a builder that allows for the Rule to be built following the ' then ' statement */
public ThenRuleBuilder < T , U > then ( Consumer < NameValueReferableTypeConvertibleMap < T > > action ) { } }

implementation: _rule . addAction ( action ) ; return this ;


signature:
public class ThenRuleBuilder { /** * Addds a then action into the Rule .
 * @ param action an action that the rule will execute based on the condition ; accepts facts and the result
 * @ return a builder that allows for the Rule to be built following the ' then ' statement */
public ThenRuleBuilder < T , U > then ( BiConsumer < NameValueReferableTypeConvertibleMap < T > , Result < U > > action ) { } }


signature:
public class RuleBookWithResultTypeBuilder { /** * Specifies the default Result value .
 * Note : RuleBooks that return a single Result must have a default Result value set .
 * @ param result the default value of the Result
 * @ return a builder with the default Result value */
public RuleBookDefaultResultBuilder < T > withDefaultResult ( T result ) { } }

implementation: _ruleBook . setDefaultResult ( result ) ; return new RuleBookDefaultResultBuilder < > ( _ruleBook ) ;


signature:
public class Result { /** * Resets the value of the Result to its default value . */
public void reset ( ) { } }

implementation: _lock . readLock ( ) . lock ( ) ; try { if ( _defaultValue == null ) { return ; } } finally { _lock . readLock ( ) . unlock ( ) ; } setValue ( _defaultValue ) ;


signature:
public class Result { /** * The method getValue ( ) returns the object contained in the Result object .
 * @ return the object stored in the Result object */
@ Override public T getValue ( ) { } }

implementation: _lock . readLock ( ) . lock ( ) ; try { long key = Thread . currentThread ( ) . getId ( ) ; if ( _valueMap . containsKey ( key ) ) { return _valueMap . get ( Thread . currentThread ( ) . getId ( ) ) ; } return _defaultValue ; } finally { _lock . readLock ( ) . unlock ( ) ; }


signature:
public class Result { /** * The method setValue ( ) sets the object to be contained in the Result object .
 * @ param value the object to be stored in the Result object */
@ Override public void setValue ( T value ) { } }

implementation: _lock . writeLock ( ) . lock ( ) ; try { _valueMap . put ( Thread . currentThread ( ) . getId ( ) , value ) ; } finally { _lock . writeLock ( ) . unlock ( ) ; }


signature:
public class RuleBookDefaultResultBuilder { /** * Adds a rule to the RuleBook .
 * @ param consumer functional interface that supplies a RuleBookRuleBuilder for building a Rule
 * @ return a builder with the added Rule */
public RuleBookAddRuleBuilder < T > addRule ( Consumer < RuleBookRuleBuilder < T > > consumer ) { } }

implementation: return new RuleBookAddRuleBuilder < > ( _ruleBook , consumer ) ;


signature:
public class RuleBookDefaultResultBuilder { /** * Adds a rule to the RuleBook .
 * @ param rule Rule to be added into the RuleBook
 * @ param < U > the fact type of the Rule
 * @ return RuleBookBuilder with the added Rule */
public < U > RuleBookAddRuleBuilder < T > addRule ( Rule < U , T > rule ) { } }

implementation: return new RuleBookAddRuleBuilder < > ( _ruleBook , rule ) ;


signature:
public class RuleBookRuleBuilder { /** * Specifies the fact type
 * @ param factType the type of object that facts are restricted to in the Rule .
 * @ param < T > the generic fact type
 * @ return RuleBookRuleWithFactTypeBuilder for building RuleBook Rules with a specific fact type */
@ SuppressWarnings ( "unchecked" ) public < T > RuleBookRuleWithFactTypeBuilder < T , U > withFactType ( Class < T > factType ) { } }

implementation: Rule < T , U > rule = ( Rule < T , U > ) RuleBuilder . create ( _ruleClass ) . withFactType ( factType ) . build ( ) ; _ruleBook . addRule ( rule ) ; return new RuleBookRuleWithFactTypeBuilder < > ( rule ) ;


signature:
public class RuleBookRunner { /** * Gets the POJO Rules to be used by the RuleBook via reflection of the specified package .
 * @ return a List of POJO Rules */
protected List < Class < ? > > getPojoRules ( ) { } }

implementation:
Reflections reflections = new Reflections ( _package ) ; List < Class < ? > > rules = reflections . getTypesAnnotatedWith ( com . deliveredtechnologies . rulebook . annotation . Rule . class ) . stream ( ) . filter ( rule -> rule . getAnnotatedSuperclass ( ) != null ) // Include classes only , exclude interfaces , etc .
. filter ( rule -> _subPkgMatch . test ( rule . getPackage ( ) . getName ( ) ) ) . collect ( Collectors . toList ( ) ) ; rules . sort ( comparingInt ( aClass -> getAnnotation ( com . deliveredtechnologies . rulebook . annotation . Rule . class , aClass ) . order ( ) ) ) ; return rules ;


signature:
public class ArrayUtils { /** * The combine ( ) static method combines the contents of two arrays into a single array of the same type .
 * @ param array1 the array to be concatenated on the left
 * @ param array2 the array to be concatenated on the right
 * @ param < T > the type of array
 * @ return a concatenation of array1 and array2 */
@ SuppressWarnings ( "unchecked" ) public static < T > T [ ] combine ( T [ ] array1 , T [ ] array2 ) { } }

implementation: return combine ( array1 , array2 , array1 . length + array2 . length ) ;


signature:
public class ArrayUtils { /** * The combine ( ) static method combines the contents of two arrays into a single array of the same type that contains
 * no more than the maxElements number of elements .
 * @ param array1 the array to be concatenated on the left
 * @ param array2 the array to be concatenated on the right
 * @ param maxElements the maximum number of elements in the resulting array
 * @ param < T > the type of array
 * @ return a concatenation of array1 and array2 */
@ SuppressWarnings ( "unchecked" ) public static < T > T [ ] combine ( T [ ] array1 , T [ ] array2 , int maxElements ) { } }

implementation: if ( array1 . length == maxElements ) { return array1 ; } else if ( array1 . length > maxElements ) { T [ ] combinedArray = ( T [ ] ) Array . newInstance ( array1 . getClass ( ) . getComponentType ( ) , maxElements ) ; System . arraycopy ( array1 , 0 , combinedArray , 0 , maxElements ) ; return combinedArray ; } maxElements = array1 . length + array2 . length >= maxElements ? maxElements : array1 . length + array2 . length ; T [ ] combinedArray = ( T [ ] ) Array . newInstance ( array1 . getClass ( ) . getComponentType ( ) , maxElements ) ; System . arraycopy ( array1 , 0 , combinedArray , 0 , array1 . length ) ; System . arraycopy ( array2 , 0 , combinedArray , array1 . length , maxElements - array1 . length ) ; return combinedArray ;


signature:
public class AsciiDocParser { /** * Reads empty line or throw an exception if a none empty line was found . */
private String readEmptyLineOrEndTable ( final BufferedReader tableContent ) throws IOException { } }

implementation: final String column = tableContent . readLine ( ) ; if ( column != null && column . startsWith ( END_TABLE ) ) { return END_TABLE ; } if ( column == null || ! column . isEmpty ( ) ) { throw new IllegalArgumentException ( String . format ( "Trying to read an empty line for end of row, but content %s was found or EOF" , column ) ) ; } return "" ;


signature:
public class AsciiDocParser { /** * Moves buffer until it finds the first content column ( skipping headers ) .
 * @ param tableContent */
private void skipUntilColumns ( final BufferedReader tableContent ) throws IOException { } }

implementation: String line ; while ( ( line = tableContent . readLine ( ) ) != null ) { if ( line . trim ( ) . isEmpty ( ) ) { break ; } }


signature: public class DeploymentConfigHandler { private ObjectMeta createDeploymentConfigMetaData ( ResourceConfig config ) { } }

implementation: return new ObjectMetaBuilder ( ) . withName ( KubernetesHelper . validateKubernetesId ( config . getControllerName ( ) , "controller name" ) ) . build ( ) ;


signature: public class DefaultServiceEnricher { private void addServices ( KubernetesListBuilder builder ) { } }

implementation: ResourceConfig resources = new ResourceConfig ( ) ; if ( resources != null && resources . getServices ( ) != null ) { List < ServiceConfig > serviceConfig = resources . getServices ( ) ; ServiceHandler serviceHandler = new ServiceHandler ( ) ; builder . addToServiceItems ( toArray ( serviceHandler . getServices ( serviceConfig ) ) ) ; }


signature:
public class DefaultServiceEnricher { /** * convert list to array , never returns null . */
private Service [ ] toArray ( List < Service > services ) { } }

implementation: if ( services == null ) { return new Service [ 0 ] ; } if ( services instanceof ArrayList ) { return ( ( ArrayList < Service > ) services ) . toArray ( new Service [ services . size ( ) ] ) ; } else { Service [ ] ret = new Service [ services . size ( ) ] ; for ( int i = 0 ; i < services . size ( ) ; i ++ ) { ret [ i ] = services . get ( i ) ; } return ret ; }


signature: public class DefaultServiceEnricher { private Map < String , String > extractLabels ( ) { } }

implementation: Map < String , String > labels = new HashMap < > ( ) ; if ( Configs . asBoolean ( getConfig ( Config . expose ) ) ) { labels . put ( "expose" , "true" ) ; } return labels ;


signature:
public class DefaultServiceEnricher { /** * Port handling */
private List < ServicePort > extractPorts ( List < ImageConfiguration > images ) { } }

implementation:
List < ServicePort > ret = new ArrayList < > ( ) ; boolean isMultiPort = Boolean . parseBoolean ( getConfig ( Config . multiPort ) ) ; List < ServicePort > configuredPorts = extractPortsFromConfig ( ) ; for ( ImageConfiguration image : images ) { Map < String , String > labels = extractLabelsFromConfig ( image ) ; List < String > podPorts = getPortsFromBuildConfiguration ( image ) ; List < String > portsFromImageLabels = getLabelWithService ( labels ) ; if ( podPorts . isEmpty ( ) ) { continue ; } // Extract first port and remove first element
if ( portsFromImageLabels == null || portsFromImageLabels . isEmpty ( ) ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , podPorts . remove ( 0 ) , shiftOrNull ( configuredPorts ) , null ) ) ; } else { for ( String imageLabelPort : portsFromImageLabels ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , podPorts . remove ( 0 ) , shiftOrNull ( configuredPorts ) , imageLabelPort ) ) ; } } // Remaining port specs if multi - port is selected
if ( isMultiPort ) { for ( String port : podPorts ) { addPortIfNotNull ( ret , extractPortsFromImageSpec ( image . getName ( ) , port , shiftOrNull ( configuredPorts ) , null ) ) ; } } } // If there are still ports configured add them directly
if ( isMultiPort ) { ret . addAll ( mirrorMissingTargetPorts ( configuredPorts ) ) ; } else if ( ret . isEmpty ( ) && ! configuredPorts . isEmpty ( ) ) { ret . addAll ( mirrorMissingTargetPorts ( Collections . singletonList ( configuredPorts . get ( 0 ) ) ) ) ; } return ret ;


signature:
public class DefaultServiceEnricher { /** * Examine images for build configuration and extract all ports */
private List < String > getPortsFromBuildConfiguration ( ImageConfiguration image ) { } }

implementation:
// No build , no default service ( doesn ' t make much sense to have no build config , though )
BuildImageConfiguration buildConfig = image . getBuildConfiguration ( ) ; if ( buildConfig == null ) { return Collections . emptyList ( ) ; } return buildConfig . getPorts ( ) ;


signature:
public class DefaultServiceEnricher { /** * Config can override ports */
private List < ServicePort > extractPortsFromConfig ( ) { } }

implementation: List < ServicePort > ret = new LinkedList < > ( ) ; String ports = getConfig ( Config . port ) ; if ( ports != null ) { for ( String port : StringUtils . split ( ports , "," ) ) { ret . add ( parsePortMapping ( port ) ) ; } } return ret ;


signature:
public class DefaultServiceEnricher { /** * parse config specified ports */
private ServicePort parsePortMapping ( String port ) { } }

implementation:
Matcher matcher = PORT_MAPPING_PATTERN . matcher ( port ) ; if ( ! matcher . matches ( ) ) { log . error ( "Invalid 'port' configuration '%s'. Must match <port>(:<targetPort>)?,<port2>?,..." , port ) ; throw new IllegalArgumentException ( "Invalid port mapping specification " + port ) ; } int servicePort = Integer . parseInt ( matcher . group ( "port" ) ) ; String optionalTargetPort = matcher . group ( "targetPort" ) ; String protocol = getProtocol ( matcher . group ( "protocol" ) ) ; ServicePortBuilder builder = new ServicePortBuilder ( ) . withPort ( servicePort ) . withProtocol ( protocol ) . withName ( getDefaultPortName ( servicePort , protocol ) ) ; // leave empty if not set . will be filled up with the port from the image config
if ( optionalTargetPort != null ) { builder . withNewTargetPort ( Integer . parseInt ( optionalTargetPort ) ) ; } return builder . build ( ) ;


signature:
public class DefaultServiceEnricher { /** * null ports can happen for ignored mappings */
private void addPortIfNotNull ( List < ServicePort > ret , ServicePort port ) { } }

implementation: if ( port != null ) { ret . add ( port ) ; }


signature:
public class DefaultServiceEnricher { /** * remove first element of list or null if list is empty */
private ServicePort shiftOrNull ( List < ServicePort > ports ) { } }

implementation: if ( ! ports . isEmpty ( ) ) { return ports . remove ( 0 ) ; } return null ;


signature: public class DefaultServiceEnricher { private String getDefaultServiceName ( Service defaultService ) { } }

implementation: String defaultServiceName = KubernetesHelper . getName ( defaultService ) ; if ( StringUtils . isBlank ( defaultServiceName ) ) { defaultServiceName = getContext ( ) . getGav ( ) . getSanitizedArtifactId ( ) ; } return defaultServiceName ;


signature:
public class DefaultServiceEnricher { /** * Merge services of same name with the default service */
private void addMissingServiceParts ( ServiceBuilder service , Service defaultService ) { } }

implementation:
// If service has no spec - > take over the complete spec from default service
if ( ! service . hasSpec ( ) ) { service . withNewSpecLike ( defaultService . getSpec ( ) ) . endSpec ( ) ; return ; } // If service has no ports - > take over ports from default service
List < ServicePort > ports = service . buildSpec ( ) . getPorts ( ) ; if ( ports == null || ports . isEmpty ( ) ) { service . editSpec ( ) . withPorts ( defaultService . getSpec ( ) . getPorts ( ) ) . endSpec ( ) ; return ; } // Complete missing parts :
service . editSpec ( ) . withPorts ( addMissingDefaultPorts ( ports , defaultService ) ) . endSpec ( ) ;


signature:
public class ImageStreamService { /** * Save the images stream to a file
 * @ param imageName name of the image for which the stream should be extracted
 * @ param target file to store the image stream */
public void appendImageStreamResource ( ImageName imageName , File target ) throws MojoExecutionException { } }

implementation: String tag = StringUtils . isBlank ( imageName . getTag ( ) ) ? "latest" : imageName . getTag ( ) ; try { ImageStream is = new ImageStreamBuilder ( ) . withNewMetadata ( ) . withName ( imageName . getSimpleName ( ) ) . endMetadata ( ) . withNewSpec ( ) . addNewTag ( ) . withName ( tag ) . withNewFrom ( ) . withKind ( "ImageStreamImage" ) . endFrom ( ) . endTag ( ) . endSpec ( ) . build ( ) ; createOrUpdateImageStreamTag ( client , imageName , is ) ; appendImageStreamToFile ( is , target ) ; log . info ( "ImageStream %s written to %s" , imageName . getSimpleName ( ) , target ) ; } catch ( KubernetesClientException e ) { KubernetesResourceUtil . handleKubernetesClientException ( e , this . log ) ; } catch ( IOException e ) { throw new MojoExecutionException ( String . format ( "Cannot write ImageStream descriptor for %s to %s : %s" , imageName . getFullName ( ) , target . getAbsoluteFile ( ) , e . getMessage ( ) ) , e ) ; }


signature:
public class ServiceUrlUtil { /** * Returns the URL to access the service ; using the environment variables , routes
 * or service clusterIP address
 * @ throws IllegalArgumentException if the URL cannot be found for the serviceName and namespace */
public static String getServiceURL ( KubernetesClient client , String serviceName , String serviceNamespace , String serviceProtocol , boolean serviceExternal ) { } }

implementation:
Service srv = null ; String serviceHost = serviceToHostOrBlank ( serviceName ) ; String servicePort = serviceToPortOrBlank ( serviceName ) ; String serviceProto = serviceProtocol != null ? serviceProtocol : serviceToProtocol ( serviceName , servicePort ) ; // Use specified or fallback namespace .
String actualNamespace = StringUtils . isNotBlank ( serviceNamespace ) ? serviceNamespace : client . getNamespace ( ) ; // 1 . Inside Kubernetes : Services as ENV vars
if ( ! serviceExternal && StringUtils . isNotBlank ( serviceHost ) && StringUtils . isNotBlank ( servicePort ) && StringUtils . isNotBlank ( serviceProtocol ) ) { return serviceProtocol + "://" + serviceHost + ":" + servicePort ; // 2 . Anywhere : When namespace is passed System / Env var . Mostly needed for integration tests .
} else if ( StringUtils . isNotBlank ( actualNamespace ) ) { srv = client . services ( ) . inNamespace ( actualNamespace ) . withName ( serviceName ) . get ( ) ; } if ( srv == null ) { // lets try use environment variables
String hostAndPort = getServiceHostAndPort ( serviceName , "" , "" ) ; if ( ! hostAndPort . startsWith ( ":" ) ) { return serviceProto + "://" + hostAndPort ; } } if ( srv == null ) { throw new IllegalArgumentException ( "No kubernetes service could be found for name: " + serviceName + " in namespace: " + actualNamespace ) ; } String answer = KubernetesHelper . getOrCreateAnnotations ( srv ) . get ( Fabric8Annotations . SERVICE_EXPOSE_URL . toString ( ) ) ; if ( StringUtils . isNotBlank ( answer ) ) { return answer ; } if ( OpenshiftHelper . isOpenShift ( client ) ) { OpenShiftClient openShiftClient = client . adapt ( OpenShiftClient . class ) ; Route route = openShiftClient . routes ( ) . inNamespace ( actualNamespace ) . withName ( serviceName ) . get ( ) ; if ( route != null ) { return ( serviceProto + "://" + route . getSpec ( ) . getHost ( ) ) . toLowerCase ( ) ; } } ServicePort port = findServicePortByName ( srv , null ) ; if ( port == null ) { throw new RuntimeException ( "Couldn't find port: " + null + " for service:" + serviceName ) ; } String clusterIP = srv . getSpec ( ) . getClusterIP ( ) ; if ( "None" . equals ( clusterIP ) ) { throw new IllegalStateException ( "Service: " + serviceName + " in namespace:" + serviceNamespace + "is head-less. Search for endpoints instead." ) ; } Integer portNumber = port . getPort ( ) ; if ( StringUtils . isBlank ( clusterIP ) ) { IngressList ingresses = client . extensions ( ) . ingresses ( ) . inNamespace ( serviceNamespace ) . list ( ) ; if ( ingresses != null ) { List < Ingress > items = ingresses . getItems ( ) ; if ( items != null ) { for ( Ingress item : items ) { String ns = KubernetesHelper . getNamespace ( item ) ; if ( Objects . equal ( serviceNamespace , ns ) ) { IngressSpec spec = item . getSpec ( ) ; if ( spec != null ) { List < IngressRule > rules = spec . getRules ( ) ; List < IngressTLS > tls = spec . getTls ( ) ; if ( rules != null ) { for ( IngressRule rule : rules ) { HTTPIngressRuleValue http = rule . getHttp ( ) ; if ( http != null ) { List < HTTPIngressPath > paths = http . getPaths ( ) ; if ( paths != null ) { for ( HTTPIngressPath path : paths ) { IngressBackend backend = path . getBackend ( ) ; if ( backend != null ) { String backendServiceName = backend . getServiceName ( ) ; if ( serviceName . equals ( backendServiceName ) && portsMatch ( port , backend . getServicePort ( ) ) ) { String pathPostfix = path . getPath ( ) ; if ( tls != null ) { for ( IngressTLS tlsHost : tls ) { List < String > hosts = tlsHost . getHosts ( ) ; if ( hosts != null ) { for ( String host : hosts ) { if ( StringUtils . isNotBlank ( host ) ) { return String . format ( "https://%s/%s" , host , preparePath ( pathPostfix ) ) ; } } } } } answer = rule . getHost ( ) ; if ( StringUtils . isNotBlank ( answer ) ) { return String . format ( "http://%s/%s" , answer , preparePath ( pathPostfix ) ) ; } } } } } } } } } } } } } // lets try use the status on GKE
ServiceStatus status = srv . getStatus ( ) ; if ( status != null ) { LoadBalancerStatus loadBalancerStatus = status . getLoadBalancer ( ) ; if ( loadBalancerStatus != null ) { List < LoadBalancerIngress > loadBalancerIngresses = loadBalancerStatus . getIngress ( ) ; if ( loadBalancerIngresses != null ) { for ( LoadBalancerIngress loadBalancerIngress : loadBalancerIngresses ) { String ip = loadBalancerIngress . getIp ( ) ; if ( StringUtils . isNotBlank ( ip ) ) { clusterIP = ip ; break ; } } } } } } if ( StringUtils . isBlank ( clusterIP ) ) { // on vanilla kubernetes we can use nodePort to access things externally
boolean found = false ; Integer nodePort = port . getNodePort ( ) ; if ( nodePort != null ) { NodeList nodeList = client . nodes ( ) . list ( ) ; if ( nodeList != null ) { List < Node > items = nodeList . getItems ( ) ; if ( items != null ) { for ( Node item : items ) { NodeStatus status = item . getStatus ( ) ; if ( ! found && status != null ) { List < NodeAddress > addresses = status . getAddresses ( ) ; if ( addresses != null ) { for ( NodeAddress address : addresses ) { String ip = address . getAddress ( ) ; if ( StringUtils . isNotBlank ( ip ) ) { clusterIP = ip ; portNumber = nodePort ; found = true ; break ; } } } } if ( ! found ) { NodeSpec spec = item . getSpec ( ) ; if ( spec != null ) { clusterIP = spec . getExternalID ( ) ; if ( StringUtils . isNotBlank ( clusterIP ) ) { portNumber = nodePort ; break ; } } } } } } } } return ( serviceProto + "://" + clusterIP + ":" + portNumber ) . toLowerCase ( ) ;


signature:
public class ServiceUrlUtil { /** * Returns true if the given servicePort matches the intOrString value */
private static boolean portsMatch ( ServicePort servicePort , IntOrString intOrString ) { } }

implementation:
if ( intOrString != null ) { Integer port = servicePort . getPort ( ) ; Integer intVal = intOrString . getIntVal ( ) ; String strVal = intOrString . getStrVal ( ) ; if ( intVal != null ) { if ( port != null ) { return port . intValue ( ) == intVal . intValue ( ) ; } else { // / should we find the port by name now ?
} } else if ( strVal != null ) { return Objects . equal ( strVal , servicePort . getName ( ) ) ; } } return false ;


signature:
public class ServiceUrlUtil { /** * Returns the named port for the given service name or blank */
private static String serviceToPortOrBlank ( String serviceName ) { } }

implementation: String envVarName = toServicePortEnvironmentVariable ( serviceName ) ; return getEnvVarOrSystemProperty ( envVarName , "" ) ;


signature:
public class ServiceUrlUtil { /** * Returns the service host and port for the given environment variable name .
 * @ param serviceName the name of the service which is used as a prefix to access the < code > $ { serviceName } _ SERVICE _ HOST < / code > and < code > $ { serviceName } _ SERVICE _ PORT < / code > environment variables to find the hos and port
 * @ param defaultHost the default host to use if not injected via an environment variable ( e . g . localhost )
 * @ parma defaultPort the default port to use to connect to the service if there is not an environment variable defined */
private static String getServiceHostAndPort ( String serviceName , String defaultHost , String defaultPort ) { } }

implementation: String serviceEnvVarPrefix = getServiceEnvVarPrefix ( serviceName ) ; String hostEnvVar = serviceEnvVarPrefix + "_HOST" ; String portEnvVar = serviceEnvVarPrefix + "_PORT" ; String host = getEnvVarOrSystemProperty ( hostEnvVar , hostEnvVar , defaultHost ) ; String port = getEnvVarOrSystemProperty ( portEnvVar , portEnvVar , defaultPort ) ; String answer = host + ":" + port ; return answer ;


signature:
public class MapUtil { /** * Adds the given key and value pair into the map if the map does not already contain a value for that key */
public static void putIfAbsent ( Map < String , String > map , String name , String value ) { } }

implementation: if ( ! map . containsKey ( name ) ) { map . put ( name , value ) ; }


signature:
public class MapUtil { /** * Add all values of a map to another map , but onlfy if not already existing .
 * @ param map target map
 * @ param toMerge the values to ad */
public static void mergeIfAbsent ( Map < String , String > map , Map < String , String > toMerge ) { } }

implementation: for ( Map . Entry < String , String > entry : toMerge . entrySet ( ) ) { putIfAbsent ( map , entry . getKey ( ) , entry . getValue ( ) ) ; ; }


signature:
public class MapUtil { /** * Returns a new map with all the entries of map1 and any from map2 which don ' t override map1.
 * Can handle either maps being null . Always returns a new mutable map */
public static < K , V > Map < K , V > mergeMaps ( Map < K , V > map1 , Map < K , V > map2 ) { } }

implementation: Map < K , V > answer = new HashMap < > ( ) ; if ( map2 != null ) { answer . putAll ( map2 ) ; } if ( map1 != null ) { answer . putAll ( map1 ) ; } return answer ;


signature:
public class MapUtil { /** * Copies all of the elements i . e . , the mappings , from toPut map into ret , if toPut isn ' t null .
 * @ param ret
 * @ param toPut */
public static void putAllIfNotNull ( Map < String , String > ret , Map < String , String > toPut ) { } }

implementation: if ( toPut != null ) { ret . putAll ( toPut ) ; }


signature: public class ImageEnricher { private void ensureTemplateSpecs ( KubernetesListBuilder builder ) { } }

implementation: ensureTemplateSpecsInReplicationControllers ( builder ) ; ensureTemplateSpecsInRelicaSet ( builder ) ; ensureTemplateSpecsInDeployments ( builder ) ; ensureTemplateSpecsInDaemonSet ( builder ) ; ensureTemplateSpecsInStatefulSet ( builder ) ; ensureTemplateSpecsInDeploymentConfig ( builder ) ;


signature: public class ImageEnricher { private void updateContainers ( KubernetesListBuilder builder ) { } }

implementation: builder . accept ( new TypedVisitor < PodTemplateSpecBuilder > ( ) { @ Override public void visit ( PodTemplateSpecBuilder templateBuilder ) { PodTemplateSpecFluent . SpecNested < PodTemplateSpecBuilder > podSpec = templateBuilder . getSpec ( ) == null ? templateBuilder . withNewSpec ( ) : templateBuilder . editSpec ( ) ; List < Container > containers = podSpec . getContainers ( ) ; if ( containers == null ) { containers = new ArrayList < Container > ( ) ; } mergeImageConfigurationWithContainerSpec ( containers ) ; podSpec . withContainers ( containers ) . endSpec ( ) ; } } ) ;


signature:
public class ImageEnricher { /** * configured */
private void mergeImageConfigurationWithContainerSpec ( List < Container > containers ) { } }

implementation: getImages ( ) . ifPresent ( images -> { int idx = 0 ; for ( ImageConfiguration image : images ) { Container container = getContainer ( idx , containers ) ; mergeImagePullPolicy ( image , container ) ; mergeImage ( image , container ) ; mergeContainerName ( image , container ) ; mergeEnvVariables ( container ) ; idx ++ ; } } ) ;


signature:
public class OpenshiftBuildService { /** * A Simple utility function to watch over pod until it gets ready
 * @ param podName Name of the pod
 * @ param nAwaitTimeout Time in seconds upto which pod must be watched
 * @ param log Logger object
 * @ throws InterruptedException */
private void waitUntilPodIsReady ( String podName , int nAwaitTimeout , final Logger log ) throws InterruptedException { } }

implementation:
final CountDownLatch readyLatch = new CountDownLatch ( 1 ) ; try ( Watch watch = client . pods ( ) . withName ( podName ) . watch ( new Watcher < Pod > ( ) { @ Override public void eventReceived ( Action action , Pod aPod ) { if ( KubernetesHelper . isPodReady ( aPod ) ) { readyLatch . countDown ( ) ; } } @ Override public void onClose ( KubernetesClientException e ) { // Ignore
} } ) ) { readyLatch . await ( nAwaitTimeout , TimeUnit . SECONDS ) ; } catch ( KubernetesClientException | InterruptedException e ) { log . error ( "Could not watch pod" , e ) ; }


signature:
public class OpenshiftBuildService { /** * = = Utility methods = = = = = */
private String getS2IBuildName ( BuildServiceConfig config , ImageName imageName ) { } }

implementation: return imageName . getSimpleName ( ) + config . getS2iBuildNameSuffix ( ) ;


signature: public class PatchService { private static EntityPatcher < BuildConfig > bcPatcher ( ) { } }

implementation: return ( KubernetesClient client , String namespace , BuildConfig newObj , BuildConfig oldObj ) -> { if ( UserConfigurationCompare . configEqual ( newObj , oldObj ) ) { return oldObj ; } OpenShiftClient openShiftClient = OpenshiftHelper . asOpenShiftClient ( client ) ; if ( openShiftClient == null ) { throw new IllegalArgumentException ( "BuildConfig can only be patched when connected to an OpenShift cluster" ) ; } DoneableBuildConfig entity = openShiftClient . buildConfigs ( ) . inNamespace ( namespace ) . withName ( oldObj . getMetadata ( ) . getName ( ) ) . edit ( ) ; if ( ! UserConfigurationCompare . configEqual ( newObj . getMetadata ( ) , oldObj . getMetadata ( ) ) ) { entity . withMetadata ( newObj . getMetadata ( ) ) ; } if ( ! UserConfigurationCompare . configEqual ( newObj . getSpec ( ) , oldObj . getSpec ( ) ) ) { entity . withSpec ( newObj . getSpec ( ) ) ; } return entity . done ( ) ; } ;


signature:
public class KubernetesHelper { /** * Validates that the given value is valid according to the kubernetes ID parsing rules , throwing an exception if not . */
public static String validateKubernetesId ( String currentValue , String description ) throws IllegalArgumentException { } }

implementation: if ( StringUtils . isBlank ( currentValue ) ) { throw new IllegalArgumentException ( "No " + description + " is specified!" ) ; } int size = currentValue . length ( ) ; for ( int i = 0 ; i < size ; i ++ ) { char ch = currentValue . charAt ( i ) ; if ( Character . isUpperCase ( ch ) ) { throw new IllegalArgumentException ( "Invalid upper case letter '" + ch + "' at index " + i + " for " + description + " value: " + currentValue ) ; } } return currentValue ;


signature:
public class KubernetesHelper { /** * Loads the Kubernetes JSON and converts it to a list of entities */
@ SuppressWarnings ( "unchecked" ) public static List < HasMetadata > toItemList ( Object entity ) throws IOException { } }

implementation: if ( entity instanceof List ) { return ( List < HasMetadata > ) entity ; } else if ( entity instanceof HasMetadata [ ] ) { HasMetadata [ ] array = ( HasMetadata [ ] ) entity ; return Arrays . asList ( array ) ; } else if ( entity instanceof KubernetesList ) { KubernetesList config = ( KubernetesList ) entity ; return config . getItems ( ) ; } else if ( entity instanceof Template ) { Template objects = ( Template ) entity ; return objects . getObjects ( ) ; } else { List < HasMetadata > answer = new ArrayList < > ( ) ; if ( entity instanceof HasMetadata ) { answer . add ( ( HasMetadata ) entity ) ; } return answer ; }


signature:
public class KubernetesHelper { /** * Returns the resource version for the entity or null if it does not have one */
public static String getResourceVersion ( HasMetadata entity ) { } }

implementation: if ( entity != null ) { ObjectMeta metadata = entity . getMetadata ( ) ; if ( metadata != null ) { String resourceVersion = metadata . getResourceVersion ( ) ; if ( StringUtils . isNotBlank ( resourceVersion ) ) { return resourceVersion ; } } } return null ;


signature:
public class KubernetesHelper { /** * Creates an IntOrString from the given string which could be a number or a name */
public static IntOrString createIntOrString ( int intVal ) { } }

implementation: IntOrString answer = new IntOrString ( ) ; answer . setIntVal ( intVal ) ; answer . setKind ( 0 ) ; return answer ;


signature:
public class KubernetesHelper { /** * Creates an IntOrString from the given string which could be a number or a name */
public static IntOrString createIntOrString ( String nameOrNumber ) { } }

implementation:
if ( StringUtils . isBlank ( nameOrNumber ) ) { return null ; } else { IntOrString answer = new IntOrString ( ) ; Integer intVal = null ; try { intVal = Integer . parseInt ( nameOrNumber ) ; } catch ( Exception e ) { // ignore invalid number
} if ( intVal != null ) { answer . setIntVal ( intVal ) ; answer . setKind ( 0 ) ; } else { answer . setStrVal ( nameOrNumber ) ; answer . setKind ( 1 ) ; } return answer ; }


signature:
public class KubernetesHelper { /** * Returns true if the pod is running and ready */
public static boolean isPodReady ( Pod pod ) { } }

implementation:
if ( ! isPodRunning ( pod ) ) { return false ; } PodStatus podStatus = pod . getStatus ( ) ; if ( podStatus == null ) { return true ; } List < PodCondition > conditions = podStatus . getConditions ( ) ; if ( conditions == null || conditions . isEmpty ( ) ) { return true ; } // Check " ready " condition
for ( PodCondition condition : conditions ) { if ( "ready" . equalsIgnoreCase ( condition . getType ( ) ) ) { return Boolean . parseBoolean ( condition . getStatus ( ) ) ; } } return true ;


signature:
public class KubernetesHelper { /** * Returns the current context in the given config */
private static Context getCurrentContext ( Config config ) { } }

implementation: String contextName = config . getCurrentContext ( ) ; if ( contextName != null ) { List < NamedContext > contexts = config . getContexts ( ) ; if ( contexts != null ) { for ( NamedContext context : contexts ) { if ( Objects . equals ( contextName , context . getName ( ) ) ) { return context . getContext ( ) ; } } } } return null ;


signature:
public class RouteEnricher { /** * Returns true if we already have a route created for the given name */
private boolean hasRoute ( final KubernetesListBuilder listBuilder , final String name ) { } }

implementation: final AtomicBoolean answer = new AtomicBoolean ( false ) ; listBuilder . accept ( new TypedVisitor < RouteBuilder > ( ) { @ Override public void visit ( RouteBuilder builder ) { ObjectMeta metadata = builder . getMetadata ( ) ; if ( metadata != null && name . equals ( metadata . getName ( ) ) ) { answer . set ( true ) ; } } } ) ; return answer . get ( ) ;


signature:
public class DocLinkEnricher { /** * Replaces all text of the form < code > $ { foo } < / code > with the value in the properties object */
protected static String replaceProperties ( String text , Properties properties ) { } }

implementation: Set < Map . Entry < Object , Object > > entries = properties . entrySet ( ) ; for ( Map . Entry < Object , Object > entry : entries ) { Object key = entry . getKey ( ) ; Object value = entry . getValue ( ) ; if ( key != null && value != null ) { String pattern = "${" + key + "}" ; text = StringUtils . replace ( text , pattern , value . toString ( ) ) ; } } return text ;


signature: public class ProcessUtil { private static void addShutdownHook ( final Logger log , final Process process , final File command ) { } }

implementation:
Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( command . getName ( ) ) { @ Override public void run ( ) { if ( process != null ) { // Trying to determine if the process is alive
boolean alive = false ; try { process . exitValue ( ) ; } catch ( IllegalThreadStateException e ) { alive = true ; } if ( alive ) { log . info ( "Terminating process %s" , command ) ; try { process . destroy ( ) ; } catch ( Exception e ) { log . error ( "Failed to terminate process %s" , command ) ; } /* Only available in Java 8 : So disabled for now until we switch to Java 8
 try {
 if ( process ! = null & & process . isAlive ( ) ) {
 process . destroyForcibly ( ) ;
 } catch ( Exception e ) {
 log . error ( " Failed to forcibly terminate process % s " , command ) ; */
} } } } ) ;


signature:
public class PortForwardService { /** * Forwards a port to the newest pod matching the given selector .
 * If another pod is created , it forwards connections to the new pod once it ' s ready . */
public Closeable forwardPortAsync ( final Logger externalProcessLogger , final LabelSelector podSelector , final int remotePort , final int localPort ) throws Fabric8ServiceException { } }

implementation:
final Lock monitor = new ReentrantLock ( true ) ; final Condition podChanged = monitor . newCondition ( ) ; final Pod [ ] nextForwardedPod = new Pod [ 1 ] ; final Thread forwarderThread = new Thread ( ) { @ Override public void run ( ) { Pod currentPod = null ; Closeable currentPortForward = null ; try { monitor . lock ( ) ; while ( true ) { if ( podEquals ( currentPod , nextForwardedPod [ 0 ] ) ) { podChanged . await ( ) ; } else { Pod nextPod = nextForwardedPod [ 0 ] ; // may be null
try { monitor . unlock ( ) ; // out of critical section
if ( currentPortForward != null ) { log . info ( "Closing port-forward from pod %s" , KubernetesHelper . getName ( currentPod ) ) ; currentPortForward . close ( ) ; currentPortForward = null ; } if ( nextPod != null ) { log . info ( "Starting port-forward to pod %s" , KubernetesHelper . getName ( nextPod ) ) ; currentPortForward = forwardPortAsync ( externalProcessLogger , KubernetesHelper . getName ( nextPod ) , remotePort , localPort ) ; } else { log . info ( "Waiting for a pod to become ready before starting port-forward" ) ; } currentPod = nextPod ; } finally { monitor . lock ( ) ; } } } } catch ( InterruptedException e ) { log . debug ( "Port-forwarding thread interrupted" , e ) ; Thread . currentThread ( ) . interrupt ( ) ; } catch ( Exception e ) { log . warn ( "Error while port-forwarding to pod" , e ) ; } finally { monitor . unlock ( ) ; if ( currentPortForward != null ) { try { currentPortForward . close ( ) ; } catch ( Exception e ) { } } } } } ; // Switching forward to the current pod if present
Pod newPod = getNewestPod ( podSelector ) ; nextForwardedPod [ 0 ] = newPod ; final Watch watch = KubernetesClientUtil . withSelector ( kubernetes . pods ( ) , podSelector , log ) . watch ( new Watcher < Pod > ( ) { @ Override public void eventReceived ( Action action , Pod pod ) { monitor . lock ( ) ; try { List < Pod > candidatePods ; if ( nextForwardedPod [ 0 ] != null ) { candidatePods = new LinkedList < > ( ) ; candidatePods . add ( nextForwardedPod [ 0 ] ) ; candidatePods . add ( pod ) ; } else { candidatePods = Collections . singletonList ( pod ) ; } Pod newPod = getNewestPod ( candidatePods ) ; // may be null
if ( ! podEquals ( nextForwardedPod [ 0 ] , newPod ) ) { nextForwardedPod [ 0 ] = newPod ; podChanged . signal ( ) ; } } finally { monitor . unlock ( ) ; } } @ Override public void onClose ( KubernetesClientException e ) { // don ' t care
} } ) ; forwarderThread . start ( ) ; final Closeable handle = ( ) -> { try { watch . close ( ) ; } catch ( Exception e ) { } try { forwarderThread . interrupt ( ) ; forwarderThread . join ( 15000 ) ; } catch ( Exception e ) { } } ; Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( ) { @ Override public void run ( ) { try { handle . close ( ) ; } catch ( Exception e ) { // suppress
} } } ) ; return handle ;


signature: public class MavenUtil { private static URLClassLoader createClassLoader ( List < String > classpathElements , String ... paths ) { } }

implementation: List < URL > urls = new ArrayList < > ( ) ; for ( String path : paths ) { URL url = pathToUrl ( path ) ; urls . add ( url ) ; } for ( Object object : classpathElements ) { if ( object != null ) { String path = object . toString ( ) ; URL url = pathToUrl ( path ) ; urls . add ( url ) ; } } return createURLClassLoader ( urls ) ;


signature:
public class MavenUtil { /** * Returns true if the maven project has a dependency with the given groupId and artifactId ( if not null ) */
public static boolean hasDependency ( MavenProject project , String groupId , String artifactId ) { } }

implementation: return getDependencyVersion ( project , groupId , artifactId ) != null ;


signature:
public class MavenUtil { /** * Returns the version associated to the dependency dependency with the given groupId and artifactId ( if present ) */
public static String getDependencyVersion ( MavenProject project , String groupId , String artifactId ) { } }

implementation: Set < Artifact > artifacts = project . getArtifacts ( ) ; if ( artifacts != null ) { for ( Artifact artifact : artifacts ) { String scope = artifact . getScope ( ) ; if ( Objects . equal ( "test" , scope ) ) { continue ; } if ( artifactId != null && ! Objects . equal ( artifactId , artifact . getArtifactId ( ) ) ) { continue ; } if ( Objects . equal ( groupId , artifact . getGroupId ( ) ) ) { return artifact . getVersion ( ) ; } } } return null ;


signature:
public class MavenUtil { /** * Returns the plugin with the given groupId ( if present ) and artifactId . */
public static Plugin getPlugin ( MavenProject project , String groupId , String artifactId ) { } }

implementation: if ( artifactId == null ) { throw new IllegalArgumentException ( "artifactId cannot be null" ) ; } List < Plugin > plugins = project . getBuildPlugins ( ) ; if ( plugins != null ) { for ( Plugin plugin : plugins ) { boolean matchesArtifactId = artifactId . equals ( plugin . getArtifactId ( ) ) ; boolean matchesGroupId = groupId == null || groupId . equals ( plugin . getGroupId ( ) ) ; if ( matchesGroupId && matchesArtifactId ) { return plugin ; } } } return null ;


signature:
public class MavenUtil { /** * Returns true if any of the given resources could be found on the given class loader */
public static boolean hasResource ( MavenProject project , String ... paths ) { } }

implementation:
URLClassLoader compileClassLoader = getCompileClassLoader ( project ) ; for ( String path : paths ) { try { if ( compileClassLoader . getResource ( path ) != null ) { return true ; } } catch ( Throwable e ) { // ignore
} } return false ;


signature:
public class MavenUtil { /** * Returns the version from the list of pre - configured versions of common groupId / artifact pairs */
public static String getVersion ( String groupId , String artifactId ) throws IOException { } }

implementation: String path = "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties" ; InputStream in = MavenUtil . class . getClassLoader ( ) . getResourceAsStream ( path ) ; if ( in == null ) { throw new IOException ( "Could not find " + path + " on classath!" ) ; } Properties properties = new Properties ( ) ; try { properties . load ( in ) ; } catch ( IOException e ) { throw new IOException ( "Failed to load " + path + ". " + e , e ) ; } String version = properties . getProperty ( "version" ) ; if ( StringUtils . isBlank ( version ) ) { throw new IOException ( "No version property in " + path ) ; } return version ;


signature:
public class ClusterAccess { /** * Returns true if this cluster is a traditional OpenShift cluster with the < code > / oapi < / code > REST API
 * or supports the new < code > / apis / image . openshift . io < / code > API Group */
public boolean isOpenShiftImageStream ( Logger log ) { } }

implementation: if ( isOpenShift ( log ) ) { OpenShiftClient openShiftClient = null ; if ( this . client == null ) { openShiftClient = createOpenShiftClient ( ) ; } else if ( this . client instanceof OpenShiftClient ) { openShiftClient = ( OpenShiftClient ) this . client ; } else if ( this . client . isAdaptable ( OpenShiftClient . class ) ) { openShiftClient = client . adapt ( OpenShiftClient . class ) ; } else { return false ; } return openShiftClient . supportsOpenShiftAPIGroup ( OpenShiftAPIGroups . IMAGE ) ; } return false ;


signature:
public class KubernetesResourceUtil { /** * Read all Kubernetes resource fragments from a directory and create a { @ link KubernetesListBuilder } which
 * can be adapted later .
 * @ param apiVersions the api versions to use
 * @ param defaultName the default name to use when none is given
 * @ param resourceFiles files to add .
 * @ return the list builder
 * @ throws IOException */
public static KubernetesListBuilder readResourceFragmentsFrom ( PlatformMode platformMode , ResourceVersioning apiVersions , String defaultName , File [ ] resourceFiles ) throws IOException { } }

implementation: KubernetesListBuilder builder = new KubernetesListBuilder ( ) ; if ( resourceFiles != null ) { for ( File file : resourceFiles ) { HasMetadata resource = getResource ( platformMode , apiVersions , file , defaultName ) ; builder . addToItems ( resource ) ; } } return builder ;


signature:
public class KubernetesResourceUtil { /** * Read a Kubernetes resource fragment and add meta information extracted from the filename
 * to the resource descriptor . I . e . the following elements are added if not provided in the fragment :
 * < ul >
 * < li > name - Name of the resource added to metadata < / li >
 * < li > kind - Resource ' s kind < / li >
 * < li > apiVersion - API version ( given as parameter to this method ) < / li >
 * < / ul >
 * @ param apiVersions the API versions to add if not given .
 * @ param file file to read , whose name must match { @ link # FILENAME _ PATTERN } . @ return map holding the fragment
 * @ param appName resource name specifying resources belonging to this application */
public static HasMetadata getResource ( PlatformMode platformMode , ResourceVersioning apiVersions , File file , String appName ) throws IOException { } }

implementation: Map < String , Object > fragment = readAndEnrichFragment ( platformMode , apiVersions , file , appName ) ; ObjectMapper mapper = new ObjectMapper ( ) ; try { return mapper . convertValue ( fragment , HasMetadata . class ) ; } catch ( ClassCastException exp ) { throw new IllegalArgumentException ( String . format ( "Resource fragment %s has an invalid syntax (%s)" , file . getPath ( ) , exp . getMessage ( ) ) ) ; }


signature:
public class KubernetesResourceUtil { /** * Read fragment and add default values */
private static Map < String , Object > readAndEnrichFragment ( PlatformMode platformMode , ResourceVersioning apiVersions , File file , String appName ) throws IOException { } }

implementation:
Pattern pattern = Pattern . compile ( FILENAME_PATTERN , Pattern . CASE_INSENSITIVE ) ; Matcher matcher = pattern . matcher ( file . getName ( ) ) ; if ( ! matcher . matches ( ) ) { throw new IllegalArgumentException ( String . format ( "Resource file name '%s' does not match pattern <name>-<type>.(yaml|yml|json)" , file . getName ( ) ) ) ; } String name = matcher . group ( "name" ) ; String type = matcher . group ( "type" ) ; String ext = matcher . group ( "ext" ) . toLowerCase ( ) ; String kind ; Map < String , Object > fragment = readFragment ( file , ext ) ; if ( type != null ) { kind = getAndValidateKindFromType ( file , type ) ; } else { // Try name as type
kind = FILENAME_TO_KIND_MAPPER . get ( name . toLowerCase ( ) ) ; if ( kind != null ) { // Name is in fact the type , so lets erase the name .
name = null ; } } addKind ( fragment , kind , file . getName ( ) ) ; String apiVersion = apiVersions . getCoreVersion ( ) ; if ( Objects . equals ( kind , "Ingress" ) ) { apiVersion = apiVersions . getExtensionsVersion ( ) ; } else if ( Objects . equals ( kind , "StatefulSet" ) || Objects . equals ( kind , "Deployment" ) ) { apiVersion = apiVersions . getAppsVersion ( ) ; } else if ( Objects . equals ( kind , "Job" ) ) { apiVersion = apiVersions . getJobVersion ( ) ; } else if ( Objects . equals ( kind , "DeploymentConfig" ) && platformMode == PlatformMode . openshift ) { apiVersion = apiVersions . getOpenshiftV1version ( ) ; } addIfNotExistent ( fragment , "apiVersion" , apiVersion ) ; Map < String , Object > metaMap = getMetadata ( fragment ) ; // No name means : generated app name should be taken as resource name
addIfNotExistent ( metaMap , "name" , StringUtils . isNotBlank ( name ) ? name : appName ) ; return fragment ;


signature: public class KubernetesResourceUtil { private static Map < String , Object > getMetadata ( Map < String , Object > fragment ) { } }

implementation: Object mo = fragment . get ( "metadata" ) ; Map < String , Object > meta ; if ( mo == null ) { meta = new HashMap < > ( ) ; fragment . put ( "metadata" , meta ) ; return meta ; } else if ( mo instanceof Map ) { return ( Map < String , Object > ) mo ; } else { throw new IllegalArgumentException ( "Metadata is expected to be a Map, not a " + mo . getClass ( ) ) ; }


signature:
public class KubernetesResourceUtil { /** * Convert a map of env vars to a list of K8s EnvVar objects .
 * @ param envVars the name - value map containing env vars which must not be null
 * @ return list of converted env vars */
public static List < EnvVar > convertToEnvVarList ( Map < String , String > envVars ) { } }

implementation: List < EnvVar > envList = new LinkedList < > ( ) ; for ( Map . Entry < String , String > entry : envVars . entrySet ( ) ) { String name = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( name != null ) { EnvVar env = new EnvVarBuilder ( ) . withName ( name ) . withValue ( value ) . build ( ) ; envList . add ( env ) ; } } return envList ;


signature:
public class KubernetesResourceUtil { /** * Uses reflection to copy over default values from the defaultValues object to the targetValues
 * object similar to the following :
 * < code >
 * \ * if ( values . get $ { FIELD } ( ) = = null ) {
 * values . ( with | set ) { FIELD } ( defaultValues . get $ { FIELD } ) ;
 * < / code >
 * Only fields that which use primitives , boxed primitives , or String object are copied .
 * @ param targetValues
 * @ param defaultValues */
public static void mergeSimpleFields ( Object targetValues , Object defaultValues ) { } }

implementation: Class < ? > tc = targetValues . getClass ( ) ; Class < ? > sc = defaultValues . getClass ( ) ; for ( Method targetGetMethod : tc . getMethods ( ) ) { if ( ! targetGetMethod . getName ( ) . startsWith ( "get" ) ) { continue ; } Class < ? > fieldType = targetGetMethod . getReturnType ( ) ; if ( ! SIMPLE_FIELD_TYPES . contains ( fieldType ) ) { continue ; } String fieldName = targetGetMethod . getName ( ) . substring ( 3 ) ; Method withMethod = null ; try { withMethod = tc . getMethod ( "with" + fieldName , fieldType ) ; } catch ( NoSuchMethodException e ) { try { withMethod = tc . getMethod ( "set" + fieldName , fieldType ) ; } catch ( NoSuchMethodException e2 ) { continue ; } } Method sourceGetMethod = null ; try { sourceGetMethod = sc . getMethod ( "get" + fieldName ) ; } catch ( NoSuchMethodException e ) { continue ; } try { if ( targetGetMethod . invoke ( targetValues ) == null ) { withMethod . invoke ( targetValues , sourceGetMethod . invoke ( defaultValues ) ) ; } } catch ( IllegalAccessException e ) { throw new RuntimeException ( e ) ; } catch ( InvocationTargetException e ) { throw new RuntimeException ( e . getCause ( ) ) ; } }


signature:
public class KubernetesResourceUtil { /** * Merges the given resources together into a single resource .
 * If switchOnLocalCustomisation is false then the overrides from item2 are merged into item1
 * @ return the newly merged resources */
public static HasMetadata mergeResources ( HasMetadata item1 , HasMetadata item2 , Logger log , boolean switchOnLocalCustomisation ) { } }

implementation: if ( item1 instanceof Deployment && item2 instanceof Deployment ) { return mergeDeployments ( ( Deployment ) item1 , ( Deployment ) item2 , log , switchOnLocalCustomisation ) ; } if ( item1 instanceof ConfigMap && item2 instanceof ConfigMap ) { ConfigMap cm1 = ( ConfigMap ) item1 ; ConfigMap cm2 = ( ConfigMap ) item2 ; return mergeConfigMaps ( cm1 , cm2 , log , switchOnLocalCustomisation ) ; } mergeMetadata ( item1 , item2 ) ; return item1 ;


signature:
public class KubernetesResourceUtil { /** * Returns a merge of the given maps and then removes any resulting empty string values ( which is the way to remove , say , a label or annotation
 * when overriding */
private static Map < String , String > mergeMapsAndRemoveEmptyStrings ( Map < String , String > overrideMap , Map < String , String > originalMap ) { } }

implementation: Map < String , String > answer = MapUtil . mergeMaps ( overrideMap , originalMap ) ; Set < Map . Entry < String , String > > entries = overrideMap . entrySet ( ) ; for ( Map . Entry < String , String > entry : entries ) { String value = entry . getValue ( ) ; if ( value == null || value . isEmpty ( ) ) { String key = entry . getKey ( ) ; answer . remove ( key ) ; } } return answer ;