Input: If the list changed we want the recreate the targetType representation [CODESPLIT] private void initListEvents ( ) { this . listChangeListener = new ListChangeListener < SourceType > ( ) { @ Override public void onChanged ( Change < ? extends SourceType > listEvent ) { // We have to stage delete events, because if we process them // separately, there will be unwanted ChangeEvents on the // targetList List < TargetType > deleteStaging = new ArrayList <> ( ) ; while ( listEvent . next ( ) ) { if ( listEvent . wasUpdated ( ) ) { processUpdateEvent ( listEvent ) ; } else if ( listEvent . wasReplaced ( ) ) { processReplaceEvent ( listEvent , deleteStaging ) ; } else if ( listEvent . wasAdded ( ) ) { processAddEvent ( listEvent ) ; } else if ( listEvent . wasRemoved ( ) ) { processRemoveEvent ( listEvent , deleteStaging ) ; } } // Process the staged elements processStagingLists ( deleteStaging ) ; } } ; modelListProperty ( ) . addListener ( new WeakListChangeListener <> ( listChangeListener ) ) ; }


Input: Maps an add event of the model list to new elements of the { @link #viewModelList } . [CODESPLIT] private void processAddEvent ( ListChangeListener . Change < ? extends SourceType > listEvent ) { final List < TargetType > toAdd = new ArrayList <> ( ) ; for ( int index = listEvent . getFrom ( ) ; index < listEvent . getTo ( ) ; index ++ ) { final SourceType item = listEvent . getList ( ) . get ( index ) ; toAdd . add ( function . apply ( item ) ) ; } viewModelList . addAll ( listEvent . getFrom ( ) , toAdd ) ; }


Input: Maps an remove event of the model list to new elements of the { @link #viewModelList } . [CODESPLIT] private void processRemoveEvent ( ListChangeListener . Change < ? extends SourceType > listEvent , List < TargetType > deleteStaging ) { for ( int i = 0 ; i < listEvent . getRemovedSize ( ) ; i ++ ) { deleteStaging . add ( viewModelList . get ( listEvent . getFrom ( ) + i ) ) ; } }


Input: Maps an update event of the model list to new elements of the { @link #viewModelList } . [CODESPLIT] private void processUpdateEvent ( ListChangeListener . Change < ? extends SourceType > listEvent ) { for ( int i = listEvent . getFrom ( ) ; i < listEvent . getTo ( ) ; i ++ ) { SourceType item = listEvent . getList ( ) . get ( i ) ; viewModelList . set ( i , ListTransformation . this . function . apply ( item ) ) ; } }


Input: Maps an replace event of the model list to new elements of the { @link #viewModelList } . [CODESPLIT] private void processReplaceEvent ( ListChangeListener . Change < ? extends SourceType > listEvent , List < TargetType > deletedStaging ) { processRemoveEvent ( listEvent , deletedStaging ) ; processStagingLists ( deletedStaging ) ; processAddEvent ( listEvent ) ; }


Input: Gets a Person . s [CODESPLIT] public Person getPersonById ( final int id ) { for ( Person person : persons ) { if ( id == person . getId ( ) ) { return person ; } } return null ; }


Input: Create a new BuilderFactory instance that contains all custom factories of this instance combined with the list of factories passed as argument to this method . <br / > This instance of the builderFactory is not changed by this method . [CODESPLIT] public BuilderFactory mergeWith ( List < BuilderFactory > factories ) { GlobalBuilderFactory factory = new GlobalBuilderFactory ( ) ; factory . factories . addAll ( factories ) ; return factory ; }


Input: Puts a new ( key value ) into the map . <p > [CODESPLIT] @ Override public Object put ( Object key , Object value ) { // If the map already contains an equivalent key, the new key // of a (key, value) pair is NOT stored in the map but the new // value only. But as the key is strongly referenced by the // map, it can not be removed from the garbage collector, even // if the key becomes weakly reachable due to the old // value. So, it isn't necessary to remove all garbage // collected values with their keys from the map before the // new entry is made. We only clean up here to distribute // clean up calls on different operations. processQueue ( ) ; WeakValue oldValue = ( WeakValue ) super . put ( key , WeakValue . create ( key , value , queue ) ) ; return getReferenceObject ( oldValue ) ; }


Input: Removes all garbage collected values with their keys from the map . Since we don t know how much the ReferenceQueue . poll () operation costs we should not call it every map operation . [CODESPLIT] private void processQueue ( ) { WeakValue wv = null ; while ( ( wv = ( WeakValue ) this . queue . poll ( ) ) != null ) { // "super" is not really necessary but use it // to be on the safe side super . remove ( wv . key ) ; } }


Input: Returns a <code > Set< / code > view of the mappings in this map . <p > [CODESPLIT] @ Override public Set entrySet ( ) { if ( entrySet == null ) { hashEntrySet = super . entrySet ( ) ; entrySet = new EntrySet ( ) ; } return entrySet ; }


Input: Returns a <code > Collection< / code > view of the values contained in this map . <p > [CODESPLIT] @ Override public Collection values ( ) { // delegates to entrySet, because super method returns // WeakValues instead of value objects if ( values == null ) { values = new AbstractCollection ( ) { @ Override public Iterator iterator ( ) { return new Iterator ( ) { private final Iterator i = entrySet ( ) . iterator ( ) ; @ Override public boolean hasNext ( ) { return i . hasNext ( ) ; } @ Override public Object next ( ) { return ( ( Entry ) i . next ( ) ) . getValue ( ) ; } @ Override public void remove ( ) { i . remove ( ) ; } } ; } @ Override public int size ( ) { return WeakValueHashMap . this . size ( ) ; } @ Override public boolean contains ( Object v ) { return WeakValueHashMap . this . containsValue ( v ) ; } } ; } return values ; }


Input: Add a list of validation messages for the specified validator . [CODESPLIT] void addMessage ( Validator validator , List < ? extends ValidationMessage > messages ) { if ( messages . isEmpty ( ) ) { return ; } final int validatorHash = System . identityHashCode ( validator ) ; if ( ! validatorToMessagesMap . containsKey ( validatorHash ) ) { validatorToMessagesMap . put ( validatorHash , new ArrayList <> ( ) ) ; } final List < Integer > messageHashesOfThisValidator = validatorToMessagesMap . get ( validatorHash ) ; // add the hashCodes of the messages to the internal map messages . stream ( ) . map ( System :: identityHashCode ) . forEach ( messageHashesOfThisValidator :: add ) ; // add the actual messages to the message list so that they are accessible by the user. getMessagesInternal ( ) . addAll ( messages ) ; }


Input: / * Remove all given messages for the given validator . [CODESPLIT] void removeMessage ( final Validator validator , final List < ? extends ValidationMessage > messages ) { if ( messages . isEmpty ( ) ) { return ; } final int validatorHash = System . identityHashCode ( validator ) ; // if the validator is unknown by the map we haven't stored any messages for it yet that could be removed if ( validatorToMessagesMap . containsKey ( validatorHash ) ) { final List < Integer > messageHashesOfThisValidator = validatorToMessagesMap . get ( validatorHash ) ; final List < Integer > hashesOfMessagesToRemove = messages . stream ( ) . filter ( m -> { // only those messages that are stored for this validator int hash = System . identityHashCode ( m ) ; return messageHashesOfThisValidator . contains ( hash ) ; } ) . map ( System :: identityHashCode ) // we only need the hashCode here . collect ( Collectors . toList ( ) ) ; // only remove those messages that we have the hashCode stored getMessagesInternal ( ) . removeIf ( message -> { int hash = System . identityHashCode ( message ) ; return hashesOfMessagesToRemove . contains ( hash ) ; } ) ; // we need to cleanup our internal map messageHashesOfThisValidator . removeAll ( hashesOfMessagesToRemove ) ; if ( messageHashesOfThisValidator . isEmpty ( ) ) { validatorToMessagesMap . remove ( validatorHash ) ; } } }


Input: / * Remove all messages for this particular validator . [CODESPLIT] void removeMessage ( final Validator validator ) { final int validatorHash = System . identityHashCode ( validator ) ; if ( validatorToMessagesMap . containsKey ( validatorHash ) ) { final List < Integer > messageHashesOfThisValidator = validatorToMessagesMap . get ( validatorHash ) ; getMessagesInternal ( ) . removeIf ( message -> { int hash = System . identityHashCode ( message ) ; return messageHashesOfThisValidator . contains ( hash ) ; } ) ; validatorToMessagesMap . remove ( validatorHash ) ; } }


Input: Set Person id for the screen [CODESPLIT] public void setPersonId ( int personId ) { person = repository . getPersonById ( personId ) ; StringBinding salutationBinding = Bindings . when ( person . genderProperty ( ) . isEqualTo ( Gender . NOT_SPECIFIED ) ) . then ( "Herr/Frau/* " ) . otherwise ( Bindings . when ( person . genderProperty ( ) . isEqualTo ( Gender . MALE ) ) . then ( "Herr " ) . otherwise ( "Frau " ) ) ; welcomeString . unbind ( ) ; welcomeString . bind ( Bindings . concat ( "Willkommen " , salutationBinding , person . firstNameProperty ( ) , " " , person . lastNameProperty ( ) ) ) ; }


Input:
Loads the java written view of the given type and injects the ViewModel for this view .
 If the given view type implements the { @link javafx . fxml . Initializable } interface the initialize method of this interface will be invoked . When this is not the case an implicit initialization will be done that is working similar to the way the { @link javafx . fxml . FXMLLoader } is working .
 When there is a  public no - args method named initialize is available this method will be called . When there is a  public field of type { @link java . util . ResourceBundle } named resources is available this field will get the provided ResourceBundle injected .
 The initialize method ( whether from the { @link javafx . fxml . Initializable } interface or implicit ) will be invoked  after the viewModel was injected . This way the user can create bindings to the viewModel in the initialize method . [CODESPLIT] public < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewTuple < ViewType , ViewModelType > loadJavaViewTuple ( Class < ? extends ViewType > viewType , ResourceBundle resourceBundle , final ViewModelType existingViewModel , ViewType codeBehind , Context parentContext , Collection < Scope > providedScopes ) { // FIXME Woanders hin?! ContextImpl context = ViewLoaderScopeUtils . prepareContext ( parentContext , providedScopes ) ; //////////////////////////// DependencyInjector injectionFacade = DependencyInjector . getInstance ( ) ; final ViewType view = codeBehind == null ? injectionFacade . getInstanceOf ( viewType ) : codeBehind ; if ( ! ( view instanceof Parent ) ) { throw new IllegalArgumentException ( "Can not load java view! The view class has to extend from " + Parent . class . getName ( ) + " or one of it's subclasses" ) ; } ViewModelType viewModel = null ; // when no viewmodel was provided by the user... if ( existingViewModel == null ) { // ... we create a new one (if possible) viewModel = ViewLoaderReflectionUtils . createViewModel ( view ) ; } else { viewModel = existingViewModel ; } ResourceBundleInjector . injectResourceBundle ( view , resourceBundle ) ; // if no ViewModel is available... if ( viewModel == null ) { // we need to check if the user is trying to inject a viewModel. final List < Field > viewModelFields = ViewLoaderReflectionUtils . getViewModelFields ( viewType ) ; if ( ! viewModelFields . isEmpty ( ) ) { throw new RuntimeException ( "The given view of type <" + view . getClass ( ) + "> has no generic viewModel type declared but tries to inject a viewModel." ) ; } } else { ResourceBundleInjector . injectResourceBundle ( viewModel , resourceBundle ) ; // if the user has provided an existing ViewModel, we will not // (re-)initialize this existing instance ViewLoaderReflectionUtils . createAndInjectScopes ( viewModel , context ) ; if ( existingViewModel == null ) { ViewLoaderReflectionUtils . initializeViewModel ( viewModel ) ; } ViewLoaderReflectionUtils . injectViewModel ( view , viewModel ) ; } if ( view instanceof Initializable ) { Initializable initializable = ( Initializable ) view ; initializable . initialize ( null , resourceBundle ) ; } else { injectResourceBundle ( view , resourceBundle ) ; callInitialize ( view ) ; } return new ViewTuple <> ( view , ( Parent ) view , viewModel ) ; }


Input: This method is trying to invoke the initialize method of the given view by reflection . This is done to meet the conventions of the { @link javafx . fxml . FXMLLoader } . The conventions say that when there is a <strong > public< / strong > no - args method with the simple name initialize and the class does not implement the { @link javafx . fxml . Initializable } interface the initialize method will be invoked . <br > This method is package scoped for better testability . [CODESPLIT] < ViewModelType extends ViewModel > void callInitialize ( View < ? extends ViewModelType > view ) { try { final Method initializeMethod = view . getClass ( ) . getMethod ( NAMING_CONVENTION_INITIALIZE_IDENTIFIER ) ; AccessController . doPrivileged ( ( PrivilegedAction ) ( ) -> { try { return initializeMethod . invoke ( view ) ; } catch ( InvocationTargetException e ) { LOG . warn ( "The '{}' method of the view {} has thrown an exception!" , NAMING_CONVENTION_INITIALIZE_IDENTIFIER , view ) ; Throwable cause = e . getCause ( ) ; if ( cause instanceof RuntimeException ) { throw ( RuntimeException ) cause ; } else { throw new RuntimeException ( cause ) ; } } catch ( IllegalAccessException e ) { LOG . warn ( "Can't invoke the '{}' method of the view {} because it is not accessible" , NAMING_CONVENTION_INITIALIZE_IDENTIFIER , view ) ; } return null ; } ) ; } catch ( NoSuchMethodException e ) { // This exception means that there is no initialize method declared. // While it's possible that the user has no such method by design, // normally and in most cases you need an initialize method in your // view (either with Initialize interface // or implicit). // So it's likely that the user has misspelled the method name or // uses a wrong naming convention. // For this reason we give the user the log message. LOG . debug ( "There is no '{}' method declared at the view {}" , NAMING_CONVENTION_INITIALIZE_IDENTIFIER , view ) ; } }


Input: Injects the given ResourceBundle into the given view using reflection . This is done to meet the conventions of the { @link javafx . fxml . FXMLLoader } . The resourceBundle is only injected when there is a <strong > public< / strong > field of the type { @link java . util . ResourceBundle } named resources . <br > This method is package scoped for better testability . [CODESPLIT] < ViewModelType extends ViewModel > void injectResourceBundle ( View < ? extends ViewModelType > view , ResourceBundle resourceBundle ) { try { Field resourcesField = view . getClass ( ) . getField ( NAMING_CONVENTION_RESOURCES_IDENTIFIER ) ; if ( resourcesField . getType ( ) . isAssignableFrom ( ResourceBundle . class ) ) { resourcesField . set ( view , resourceBundle ) ; } } catch ( NoSuchFieldException e ) { // This exception means that there is no field for the // ResourceBundle. // This is no exceptional case but is normal when you don't need a // resourceBundle in a specific view. // Therefore it's save to silently catch the exception. } catch ( IllegalAccessException e ) { LOG . warn ( "Can't inject the ResourceBundle into the view {} because the field isn't accessible" , view ) ; } }


Input: When the given source binding has a value of <code > null< / code > an empty string is used for the returned binding . Otherwise the value of the source binding is used . [CODESPLIT] private StringBinding emptyStringOnNull ( ObservableValue < String > source ) { return Bindings . createStringBinding ( ( ) -> { if ( source . getValue ( ) == null ) { return "" ; } else { return source . getValue ( ) ; } } , source ) ; }


Input: Returns the { @link java . lang . reflect . Field } of the viewModel for a given view type and viewModel type . If there is no annotated field for the viewModel in the view the returned Optional will be empty . [CODESPLIT] public static Optional < Field > getViewModelField ( Class < ? extends View > viewType , Class < ? > viewModelType ) { List < Field > allViewModelFields = getViewModelFields ( viewType ) ; if ( allViewModelFields . isEmpty ( ) ) { return Optional . empty ( ) ; } if ( allViewModelFields . size ( ) > 1 ) { throw new RuntimeException ( "The View <" + viewType + "> may only define one viewModel but there were <" + allViewModelFields . size ( ) + "> viewModel fields with the @InjectViewModel annotation!" ) ; } Field field = allViewModelFields . get ( 0 ) ; if ( ! ViewModel . class . isAssignableFrom ( field . getType ( ) ) ) { throw new RuntimeException ( "The View <" + viewType + "> has a field annotated with @InjectViewModel but the type of the field doesn't implement the 'ViewModel' interface!" ) ; } if ( ! field . getType ( ) . isAssignableFrom ( viewModelType ) ) { throw new RuntimeException ( "The View <" + viewType + "> has a field annotated with @InjectViewModel but the type of the field doesn't match the generic ViewModel type of the View class. " + "The declared generic type is <" + viewModelType + "> but the actual type of the field is <" + field . getType ( ) + ">." ) ; } return Optional . of ( field ) ; }


Input: This method is used to get the ViewModel instance of a given view / codeBehind . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewModelType getExistingViewModel ( ViewType view ) { final Class < ? > viewModelType = TypeResolver . resolveRawArgument ( View . class , view . getClass ( ) ) ; Optional < Field > fieldOptional = getViewModelField ( view . getClass ( ) , viewModelType ) ; if ( fieldOptional . isPresent ( ) ) { Field field = fieldOptional . get ( ) ; return ReflectionUtils . accessMember ( field , ( ) -> ( ViewModelType ) field . get ( view ) , "Can't get the viewModel of type <" + viewModelType + ">" ) ; } else { return null ; } }


Input: Injects the given viewModel instance into the given view . The injection will only happen when the class of the given view has a viewModel field that fulfills all requirements for the viewModel injection ( matching types no viewModel already existing ... ) . [CODESPLIT] public static void injectViewModel ( final View view , ViewModel viewModel ) { if ( viewModel == null ) { return ; } final Optional < Field > fieldOptional = getViewModelField ( view . getClass ( ) , viewModel . getClass ( ) ) ; if ( fieldOptional . isPresent ( ) ) { Field field = fieldOptional . get ( ) ; ReflectionUtils . accessMember ( field , ( ) -> { Object existingViewModel = field . get ( view ) ; if ( existingViewModel == null ) { field . set ( view , viewModel ) ; } } , "Can't inject ViewModel of type <" + viewModel . getClass ( ) + "> into the view <" + view + ">" ) ; } }


Input: This method is used to create and inject the ViewModel for a given View instance . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static < V extends View < ? extends VM > , VM extends ViewModel > void createAndInjectViewModel ( final V view , Consumer < ViewModel > newVmConsumer ) { final Class < ? > viewModelType = TypeResolver . resolveRawArgument ( View . class , view . getClass ( ) ) ; if ( viewModelType == ViewModel . class ) { // if no viewModel can be created, we have to check if the user has // tried to inject a ViewModel final List < Field > viewModelFields = ViewLoaderReflectionUtils . getViewModelFields ( view . getClass ( ) ) ; if ( ! viewModelFields . isEmpty ( ) ) { throw new RuntimeException ( "The given view of type <" + view . getClass ( ) + "> has no generic viewModel type declared but tries to inject a viewModel." ) ; } return ; } if ( viewModelType == TypeResolver . Unknown . class ) { return ; } final Optional < Field > fieldOptional = getViewModelField ( view . getClass ( ) , viewModelType ) ; if ( fieldOptional . isPresent ( ) ) { Field field = fieldOptional . get ( ) ; ReflectionUtils . accessMember ( field , ( ) -> { Object existingViewModel = field . get ( view ) ; if ( existingViewModel == null ) { final Object newViewModel = DependencyInjector . getInstance ( ) . getInstanceOf ( viewModelType ) ; field . set ( view , newViewModel ) ; newVmConsumer . accept ( ( ViewModel ) newViewModel ) ; } } , "Can't inject ViewModel of type <" + viewModelType + "> into the view <" + view + ">" ) ; } }


Input: Creates a viewModel instance for a View type . The type of the view is determined by the given view instance . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) public static < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewModelType createViewModel ( ViewType view ) { final Class < ? > viewModelType = TypeResolver . resolveRawArgument ( View . class , view . getClass ( ) ) ; if ( viewModelType == ViewModel . class ) { return null ; } if ( TypeResolver . Unknown . class == viewModelType ) { return null ; } return ( ViewModelType ) DependencyInjector . getInstance ( ) . getInstanceOf ( viewModelType ) ; }


Input: If a ViewModel has a method annotated with { @link Initialize } or method with the signature <code > public void initialize () < / code > it will be invoked . If no such method is available nothing happens . [CODESPLIT] public static < ViewModelType extends ViewModel > void initializeViewModel ( ViewModelType viewModel ) { if ( viewModel == null ) { return ; } final Collection < Method > initializeMethods = getInitializeMethods ( viewModel . getClass ( ) ) ; initializeMethods . forEach ( initMethod -> { // if there is a @PostConstruct annotation, throw an exception to prevent double injection final boolean postConstructPresent = Arrays . stream ( initMethod . getAnnotations ( ) ) . map ( Annotation :: annotationType ) . map ( Class :: getName ) . anyMatch ( "javax.annotation.PostConstruct" :: equals ) ; if ( postConstructPresent ) { throw new IllegalStateException ( String . format ( "initialize method of ViewModel [%s] is annotated with @PostConstruct. " + "This will lead to unexpected behaviour and duplicate initialization. " + "Please rename the method or remove the @PostConstruct annotation. " + "See mvvmFX wiki for more details: " + "https://github.com/sialcasa/mvvmFX/wiki/Dependency-Injection#lifecycle-postconstruct" , viewModel ) ) ; } ReflectionUtils . accessMember ( initMethod , ( ) -> initMethod . invoke ( viewModel ) , "mvvmFX wasn't able to call the initialize method of ViewModel [" + viewModel + "]." ) ; } ) ; }


Input: Returns a collection of { [CODESPLIT] private static Collection < Method > getInitializeMethods ( Class < ? > classType ) { final List < Method > initializeMethods = new ArrayList <> ( ) ; Arrays . stream ( classType . getMethods ( ) ) . filter ( method -> "initialize" . equals ( method . getName ( ) ) ) . filter ( method -> void . class . equals ( method . getReturnType ( ) ) ) . filter ( method -> method . getParameterCount ( ) == 0 ) . forEach ( initializeMethods :: add ) ; Arrays . stream ( classType . getDeclaredMethods ( ) ) . filter ( method -> method . isAnnotationPresent ( Initialize . class ) ) . forEach ( initializeMethods :: add ) ; return initializeMethods ; }


Input: This method adds listeners for the { [CODESPLIT] static void addSceneLifecycleHooks ( ViewModel viewModel , ObservableBooleanValue viewInSceneProperty ) { if ( viewModel != null ) { if ( viewModel instanceof SceneLifecycle ) { SceneLifecycle lifecycleViewModel = ( SceneLifecycle ) viewModel ; PreventGarbageCollectionStore . getInstance ( ) . put ( viewInSceneProperty ) ; viewInSceneProperty . addListener ( ( observable , oldValue , newValue ) -> { if ( newValue ) { lifecycleViewModel . onViewAdded ( ) ; } else { lifecycleViewModel . onViewRemoved ( ) ; PreventGarbageCollectionStore . getInstance ( ) . remove ( viewInSceneProperty ) ; } } ) ; } } }


Input: This method is used to check if the given View instance has one or more fields that try to inject a scope with the { [CODESPLIT] static void checkScopesInView ( View codeBehind ) { List < Field > scopeFields = ReflectionUtils . getFieldsWithAnnotation ( codeBehind , InjectScope . class ) ; if ( ! scopeFields . isEmpty ( ) ) { throw new IllegalStateException ( "The view class [" + codeBehind . getClass ( ) . getSimpleName ( ) + "] tries to inject a Scope with " + "@InjectScope. This would be a violation of the mvvm pattern. Scopes are only supported in ViewModels." ) ; } }


Input: Set the currently selected country . This will lead to an update of the { @link #subdivisions () } observable list and the { @link #subdivisionLabel () } . [CODESPLIT] @ Override public void setCountry ( Country country ) { if ( country == null ) { subdivisionLabel . set ( null ) ; subdivisions . clear ( ) ; return ; } subdivisionLabel . set ( countryCodeSubdivisionNameMap . get ( country ) ) ; subdivisions . clear ( ) ; if ( countryCodeSubdivisionMap . containsKey ( country ) ) { subdivisions . addAll ( countryCodeSubdivisionMap . get ( country ) ) ; } }


Input: Load all countries from the XML file source with DataFX . [CODESPLIT] void loadCountries ( ) { InputStream iso3166Resource = this . getClass ( ) . getResourceAsStream ( ISO_3166_LOCATION ) ; if ( iso3166Resource == null ) { throw new IllegalStateException ( "Can't find the list of countries! Expected location was:" + ISO_3166_LOCATION ) ; } XmlConverter < Country > countryConverter = new XmlConverter <> ( "iso_3166_entry" , Country . class ) ; try { DataReader < Country > dataSource = new InputStreamSource <> ( iso3166Resource , countryConverter ) ; ListDataProvider < Country > listDataProvider = new ListDataProvider <> ( dataSource ) ; listDataProvider . setResultObservableList ( countries ) ; Worker < ObservableList < Country > > worker = listDataProvider . retrieve ( ) ; // when the countries are loaded we start the loading of the subdivisions. worker . stateProperty ( ) . addListener ( obs -> { if ( worker . getState ( ) == Worker . State . SUCCEEDED ) { loadSubdivisions ( ) ; } } ) ; } catch ( IOException e ) { LOG . error ( "A problem was detected while loading the XML file with the available countries." , e ) ; } }


Input: Load all subdivisions from the XML file source with DataFX . [CODESPLIT] void loadSubdivisions ( ) { InputStream iso3166_2Resource = this . getClass ( ) . getResourceAsStream ( ISO_3166_2_LOCATION ) ; if ( iso3166_2Resource == null ) { throw new IllegalStateException ( "Can't find the list of subdivisions! Expected location was:" + ISO_3166_2_LOCATION ) ; } XmlConverter < ISO3166_2_CountryEntity > converter = new XmlConverter <> ( "iso_3166_country" , ISO3166_2_CountryEntity . class ) ; ObservableList < ISO3166_2_CountryEntity > subdivisionsEntities = FXCollections . observableArrayList ( ) ; try { DataReader < ISO3166_2_CountryEntity > dataSource = new InputStreamSource <> ( iso3166_2Resource , converter ) ; ListDataProvider < ISO3166_2_CountryEntity > listDataProvider = new ListDataProvider <> ( dataSource ) ; listDataProvider . setResultObservableList ( subdivisionsEntities ) ; Worker < ObservableList < ISO3166_2_CountryEntity > > worker = listDataProvider . retrieve ( ) ; worker . stateProperty ( ) . addListener ( obs -> { if ( worker . getState ( ) == Worker . State . SUCCEEDED ) { subdivisionsEntities . forEach ( entity -> { if ( entity . subsets != null && ! entity . subsets . isEmpty ( ) ) { Country country = findCountryByCode ( entity . code ) ; if ( ! countryCodeSubdivisionMap . containsKey ( country ) ) { countryCodeSubdivisionMap . put ( country , new ArrayList <> ( ) ) ; } List < Subdivision > subdivisionList = countryCodeSubdivisionMap . get ( country ) ; entity . subsets . forEach ( subset -> { subset . entryList . forEach ( entry -> { subdivisionList . add ( new Subdivision ( entry . name , entry . code , country ) ) ; } ) ; } ) ; String subdivisionName = entity . subsets . stream ( ) . map ( subset -> subset . subdivisionType ) . collect ( Collectors . joining ( "/" ) ) ; countryCodeSubdivisionNameMap . put ( country , subdivisionName ) ; } } ) ; inProgress . set ( false ) ; } } ) ; } catch ( IOException e ) { LOG . error ( "A problem was detected while loading the XML file with the available subdivisions." , e ) ; } }


Input: This notification will be send to the UI - Thread ( if the UI - toolkit was bootstrapped ) . If no UI - Toolkit is available the notification will be directly published . This is typically the case in unit tests . [CODESPLIT] @ Override public void publish ( Object channel , String messageName , Object [ ] payload ) { if ( channelObserverMap . containsKey ( channel ) ) { final ObserverMap observerMap = channelObserverMap . get ( channel ) ; if ( shouldPublishInThisThread ( ) ) { publish ( messageName , payload , observerMap ) ; } else { try { Platform . runLater ( ( ) -> publish ( messageName , payload , observerMap ) ) ; } catch ( IllegalStateException e ) { // If the toolkit isn't initialized yet we will publish the notification directly. // In most cases this means that we are in a unit test and not JavaFX application is running. if ( e . getMessage ( ) . equals ( "Toolkit not initialized" ) ) { publish ( messageName , payload , observerMap ) ; } else { throw e ; } } } } }


Input: / * Helper [CODESPLIT] private static void publish ( String messageName , Object [ ] payload , ObserverMap observerMap ) { Collection < NotificationObserver > notificationReceivers = observerMap . get ( messageName ) ; if ( notificationReceivers != null ) { // make a copy to prevent ConcurrentModificationException if inside of an observer a new observer is subscribed. for ( NotificationObserver observer : notificationReceivers ) { observer . receivedNotification ( messageName , payload ) ; } } }


Input: This method is invoked when the javafx application is initialized . See { @link javafx . application . Application#init () } for more details . <p > Unlike the original init method in { @link javafx . application . Application } this method contains logic to initialize the Spring - Boot container . For this reason this method is now final to prevent unintended overriding . Please use { @link #initMvvmfx () } for you own initialization logic . [CODESPLIT] @ Override public final void init ( ) throws Exception { ctx = SpringApplication . run ( this . getClass ( ) ) ; MvvmFX . setCustomDependencyInjector ( ctx :: getBean ) ; ctx . getBeanFactory ( ) . autowireBean ( this ) ; initMvvmfx ( ) ; }


Input: Resets all defined fields to their default values . <p > Default values can be defined as last argument of the overloaded field methods ( see { @link #field ( StringGetter StringSetter String ) } ) or by using the { @link #useCurrentValuesAsDefaults () } method . [CODESPLIT] public void reset ( ) { fields . forEach ( PropertyField :: resetToDefault ) ; immutableFields . forEach ( PropertyField :: resetToDefault ) ; calculateDifferenceFlag ( ) ; }


Input: Use all values that are currently present in the wrapped model object as new default values for respective fields . This overrides / updates the values that were set during the initialization of the field mappings . <p > Subsequent calls to { @link #reset () } will reset the values to this new default values . <p > Usage example : <pre > ModelWrapper { @code<Person > } wrapper = new ModelWrapper { @code< > } () ; [CODESPLIT] public void useCurrentValuesAsDefaults ( ) { M wrappedModelInstance = model . get ( ) ; if ( wrappedModelInstance != null ) { for ( final PropertyField < ? , M , ? > field : fields ) { field . updateDefault ( wrappedModelInstance ) ; } for ( final ImmutablePropertyField < ? , M , ? > field : immutableFields ) { field . updateDefault ( wrappedModelInstance ) ; } } }


Input: Take the current value of each property field and write it into the wrapped model element . <p > If no model element is defined then nothing will happen . <p > <b > Note : < / b > This method has no effects on the values of the defined property fields but will only change the state of the wrapped model element . [CODESPLIT] public void commit ( ) { if ( model . get ( ) != null ) { inCommitPhase = true ; fields . forEach ( field -> field . commit ( model . get ( ) ) ) ; if ( ! immutableFields . isEmpty ( ) ) { M tmp = model . get ( ) ; for ( ImmutablePropertyField < ? , M , ? > immutableField : immutableFields ) { tmp = immutableField . commitImmutable ( tmp ) ; } model . set ( tmp ) ; } inCommitPhase = false ; dirtyFlag . set ( false ) ; calculateDifferenceFlag ( ) ; } }


Input: Take the current values from the wrapped model element and put them in the corresponding property fields . <p > If no model element is defined then nothing will happen . <p > <b > Note : < / b > This method has no effects on the wrapped model element but will only change the values of the defined property fields . [CODESPLIT] public void reload ( ) { M wrappedModelInstance = model . get ( ) ; if ( wrappedModelInstance != null ) { fields . forEach ( field -> field . reload ( wrappedModelInstance ) ) ; immutableFields . forEach ( field -> field . reload ( wrappedModelInstance ) ) ; dirtyFlag . set ( false ) ; calculateDifferenceFlag ( ) ; } }


Input: This method can be used to copy all values of this { @link ModelWrapper } instance to the model instance provided as argument . Existing values in the provided model instance will be overwritten . <p > This method doesn t change the state of this modelWrapper or the wrapped model instance . [CODESPLIT] public void copyValuesTo ( M model ) { Objects . requireNonNull ( model ) ; fields . forEach ( field -> field . commit ( model ) ) ; }


Input: Add a new field of type String to this instance of the wrapper . This method is used for model elements that are following the normal Java - Beans - standard i . e . the model fields are only available via getter and setter methods and not as JavaFX Properties . [CODESPLIT] public StringProperty field ( StringGetter < M > getter , StringSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter , setter , SimpleStringProperty :: new ) ) ; }


Input: Add a new immutable field of type String to this instance of the wrapper . This method is used for immutable model elements that have getters to get values for it s fields but not setters . Instead immutables have methods that take a new value for a field and return a new cloned instance of the model element with only this field updated to the new value . The old model instance isn t changed . [CODESPLIT] public StringProperty immutableField ( StringGetter < M > getter , StringImmutableSetter < M > immutableSetter ) { return addImmutable ( new ImmutableBeanPropertyField <> ( this :: propertyWasChanged , getter , immutableSetter , SimpleStringProperty :: new ) ) ; }


Input: Add a new field of type { @link String } to this instance of the wrapper . This method is used for model elements that are following the enhanced JavaFX - Beans - standard i . e . the model fields are available as JavaFX Properties . <p > [CODESPLIT] public StringProperty field ( StringPropertyAccessor < M > accessor ) { return add ( new FxPropertyField <> ( this :: propertyWasChanged , accessor , SimpleStringProperty :: new ) ) ; }


Input: Add a new field of type String to this instance of the wrapper . See { @link #field ( StringGetter StringSetter ) } . This method additionally takes a string identifier as first parameter . <p / > This identifier is used to return the same property instance even when the method is invoked multiple times . [CODESPLIT] public StringProperty field ( String identifier , StringGetter < M > getter , StringSetter < M > setter ) { return addIdentified ( identifier , new BeanPropertyField <> ( this :: propertyWasChanged , getter , setter , ( ) -> new SimpleStringProperty ( null , identifier ) ) ) ; }


Input: Add a new immutable field of type String to this instance of the wrapper . See { @link #immutableField ( StringGetter StringImmutableSetter } ) . This method additionally takes a string identifier as first parameter . <p / > This identifier is used to return the same property instance even when the method is invoked multiple times . [CODESPLIT] public StringProperty immutableField ( String identifier , StringGetter < M > getter , StringImmutableSetter < M > immutableSetter ) { return addIdentifiedImmutable ( identifier , new ImmutableBeanPropertyField <> ( this :: propertyWasChanged , getter , immutableSetter , ( ) -> new SimpleStringProperty ( null , identifier ) ) ) ; }


Input: Add a new field of type String to this instance of the wrapper . See { @link #field ( StringPropertyAccessor ) } . This method additionally takes a string identifier as first parameter . [CODESPLIT] public StringProperty field ( String identifier , StringPropertyAccessor < M > accessor ) { return addIdentified ( identifier , new FxPropertyField <> ( this :: propertyWasChanged , accessor , ( ) -> new SimpleStringProperty ( null , identifier ) ) ) ; }


Input: / * Field type Boolean [CODESPLIT] public BooleanProperty field ( BooleanGetter < M > getter , BooleanSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter , setter , SimpleBooleanProperty :: new ) ) ; }


Input: / * Field type Double [CODESPLIT] public DoubleProperty field ( DoubleGetter < M > getter , DoubleSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter :: apply , ( m , number ) -> setter . accept ( m , number . doubleValue ( ) ) , SimpleDoubleProperty :: new ) ) ; }


Input: / * Field type Float [CODESPLIT] public FloatProperty field ( FloatGetter < M > getter , FloatSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter :: apply , ( m , number ) -> setter . accept ( m , number . floatValue ( ) ) , SimpleFloatProperty :: new ) ) ; }


Input: / * Field type Integer [CODESPLIT] public IntegerProperty field ( IntGetter < M > getter , IntSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter :: apply , ( m , number ) -> setter . accept ( m , number . intValue ( ) ) , SimpleIntegerProperty :: new ) ) ; }


Input: / * Field type Long [CODESPLIT] public LongProperty field ( LongGetter < M > getter , LongSetter < M > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter :: apply , ( m , number ) -> setter . accept ( m , number . longValue ( ) ) , SimpleLongProperty :: new ) ) ; }


Input: / * Field type generic [CODESPLIT] public < T > ObjectProperty < T > field ( ObjectGetter < M , T > getter , ObjectSetter < M , T > setter ) { return add ( new BeanPropertyField <> ( this :: propertyWasChanged , getter , setter , SimpleObjectProperty :: new ) ) ; }


Input: / * Field type list [CODESPLIT] public < E > ListProperty < E > field ( ListGetter < M , E > getter , ListSetter < M , E > setter ) { return add ( new BeanListPropertyField <> ( this :: propertyWasChanged , getter , ( m , list ) -> setter . accept ( m , FXCollections . observableArrayList ( list ) ) , SimpleListProperty :: new ) ) ; }


Input: This helper method is needed because there is no equivalent of { [CODESPLIT] private static < T > ObservableSet < T > observableHashSet ( Set < T > source ) { return FXCollections . observableSet ( new HashSet <> ( source ) ) ; }


Input: / * Field type map [CODESPLIT] public < K , V > MapProperty < K , V > field ( MapGetter < M , K , V > getter , MapSetter < M , K , V > setter ) { return add ( new BeanMapPropertyField <> ( this :: propertyWasChanged , getter , ( m , map ) -> setter . accept ( m , FXCollections . observableMap ( map ) ) , SimpleMapProperty :: new ) ) ; }


Input: Add a rule for this validator . <p > The rule defines a condition that has to be fulfilled . <p > A rule is defined by an observable boolean value . If the rule has a value of <code > true< / code > the rule is fulfilled . If the rule has a value of <code > false< / code > the rule is violated . In this case the given message object will be added to the status of this validator . <p > There are some predefined rules for common use cases in the { @link ObservableRules } class that can be used . [CODESPLIT] public void addRule ( ObservableValue < Boolean > rule , ValidationMessage message ) { booleanRules . add ( rule ) ; rule . addListener ( ( observable , oldValue , newValue ) -> { validateBooleanRule ( newValue , message ) ; } ) ; validateBooleanRule ( rule . getValue ( ) , message ) ; }


Input: Add a complex rule for this validator . <p > The rule is defined by an { @link ObservableValue } . If this observable contains a { @link ValidationMessage } object the rule is considered to be violated and the { @link ValidationStatus } of this validator will contain the validation message object contained in the observable value . If the observable doesn t contain a value ( in other words it contains <code > null< / code > ) the rule is considered to be fulfilled and the validation status of this validator will be valid ( given that no other rule is violated ) . <p > [CODESPLIT] public void addRule ( ObservableValue < ValidationMessage > rule ) { complexRules . add ( rule ) ; rule . addListener ( ( observable , oldValue , newValue ) -> { if ( oldValue != null ) { validationStatus . removeMessage ( oldValue ) ; } if ( newValue != null ) { validationStatus . addMessage ( newValue ) ; } } ) ; if ( rule . getValue ( ) != null ) { validationStatus . addMessage ( rule . getValue ( ) ) ; } }


Input: Creates an observable list that always has { [CODESPLIT] static ObservableList < String > createListWithNothingSelectedMarker ( ObservableList < String > source ) { final ObservableList < String > result = FXCollections . observableArrayList ( ) ; result . add ( NOTHING_SELECTED_MARKER ) ; result . addAll ( source ) ; // for sure there are better solutions for this but it's sufficient for our demo source . addListener ( ( ListChangeListener < String > ) c -> { result . clear ( ) ; result . add ( NOTHING_SELECTED_MARKER ) ; result . addAll ( source ) ; } ) ; return result ; }


Input: This method is the entry point of the Fluent API to load a java based view . [CODESPLIT] public static < ViewType extends JavaView < ? extends ViewModelType > , ViewModelType extends ViewModel > JavaViewStep < ViewType , ViewModelType > javaView ( Class < ? extends ViewType > viewType ) { return new JavaViewStep <> ( viewType ) ; }


Input: This method is the entry point of the Fluent API to load a fxml based View . [CODESPLIT] public static < ViewType extends FxmlView < ? extends ViewModelType > , ViewModelType extends ViewModel > FxmlViewStep < ViewType , ViewModelType > fxmlView ( Class < ? extends ViewType > viewType ) { return new FxmlViewStep <> ( viewType ) ; }


Input: Register the given { @link ChangeListener } to the { @link ObservableValue } . The listener is added to the observable and will be added for management so it can be cleaned up with the { @link #clean () } method . [CODESPLIT] public < T > void register ( ObservableValue < T > observable , ChangeListener < ? super T > listener ) { if ( ! simpleChangeListeners . containsKey ( observable ) ) { this . simpleChangeListeners . put ( observable , Collections . newSetFromMap ( new WeakHashMap <> ( ) ) ) ; } Set < ChangeListener > observers = this . simpleChangeListeners . get ( observable ) ; observers . add ( listener ) ; observable . addListener ( listener ) ; }


Input: Register the given { @link ListChangeListener } to the { @link ObservableList } . The listener is added to the observable and will be added for management so it can be cleaned up with the { @link #clean () } method . [CODESPLIT] public < T > void register ( ObservableList < T > observable , ListChangeListener < ? super T > listener ) { if ( ! listChangeListeners . containsKey ( observable ) ) { this . listChangeListeners . put ( observable , Collections . newSetFromMap ( new WeakHashMap <> ( ) ) ) ; } Set < ListChangeListener > observers = this . listChangeListeners . get ( observable ) ; observers . add ( listener ) ; observable . addListener ( listener ) ; }


Input: Register the given { @link InvalidationListener } to the { @link Observable } . The listener is added to the observable and will be added for management so it can be cleaned up with the { @link #clean () } method . [CODESPLIT] public void register ( Observable observable , InvalidationListener listener ) { if ( ! invalidationListeners . containsKey ( observable ) ) { this . invalidationListeners . put ( observable , Collections . newSetFromMap ( new WeakHashMap <> ( ) ) ) ; } Set < InvalidationListener > observers = this . invalidationListeners . get ( observable ) ; observers . add ( listener ) ; observable . addListener ( listener ) ; }


Input: This method is used to clear the given map . To do this you need to implement a BiConsumer that calls the specific method to remove a listener from an observable . [CODESPLIT] private < T , U > void clearMap ( Map < T , Set < U > > map , BiConsumer < T , U > consumer ) { for ( T observable : map . keySet ( ) ) { for ( U listener : map . get ( observable ) ) { consumer . accept ( observable , listener ) ; } } map . clear ( ) ; }


Input: This method is overridden to initialize the mvvmFX framework . Override the { [CODESPLIT] @ Override public final void start ( Stage primaryStage ) throws Exception { producer . setPrimaryStage ( primaryStage ) ; startMvvmfx ( primaryStage ) ; }


Input: This method is called when the javafx application is initialized . See { @link javafx . application . Application#init () } for more details . [CODESPLIT] @ SuppressWarnings ( "unchecked" ) @ Override public final void init ( ) throws Exception { ctx = beanManager . createCreationalContext ( null ) ; injectionTarget = beanManager . createInjectionTarget ( beanManager . createAnnotatedType ( ( Class < MvvmfxCdiApplication > ) this . getClass ( ) ) ) ; injectionTarget . inject ( this , ctx ) ; injectionTarget . postConstruct ( this ) ; producer . setApplicationParameters ( getParameters ( ) ) ; initMvvmfx ( ) ; }


Input: This method is called when the application should stop . See { @link javafx . application . Application#stop () } for more details . [CODESPLIT] @ Override public final void stop ( ) throws Exception { stopMvvmfx ( ) ; injectionTarget . preDestroy ( this ) ; injectionTarget . dispose ( this ) ; ctx . release ( ) ; container . close ( ) ; }


Input: When the selected item changed we want to set the index property too [CODESPLIT] private void createIndexEvents ( ) { selectionModel . selectedIndexProperty ( ) . addListener ( ( bean , oldVal , newVal ) -> { int index = newVal . intValue ( ) ; ListType item = index == - 1 ? null : modelListProperty ( ) . get ( index ) ; selectedItem . set ( item ) ; } ) ; selectedItem . addListener ( ( observable , oldVal , newVal ) -> { // Item null if ( newVal == null ) { selectionModel . select ( - 1 ) ; selectedItem . set ( null ) ; } else { int index = modelListProperty ( ) . get ( ) . indexOf ( newVal ) ; // Item not found if ( index != - 1 ) { selectionModel . select ( index ) ; } else { // If item not found - Rollback selectedItem . set ( oldVal ) ; } } } ) ; }


Input: Returns all fields with the given annotation . Only fields that are declared in the actual class of the instance are considered ( i . e . no fields from super classes ) . This includes private fields . [CODESPLIT] public static List < Field > getFieldsWithAnnotation ( Object target , Class < ? extends Annotation > annotationType ) { return ReflectionUtils . getFieldsFromClassHierarchy ( target . getClass ( ) ) . stream ( ) . filter ( field -> field . isAnnotationPresent ( annotationType ) ) . collect ( Collectors . toList ( ) ) ; }


Input:
Returns all fields of the given type and all parent types ( except Object ) .
 The difference to { @link Class#getFields () } is that getFields only returns public fields while this method will return all fields whatever the access modifier is .
 [CODESPLIT] public static List < Field > getFieldsFromClassHierarchy ( Class < ? > type ) { final List < Field > classFields = new ArrayList <> ( ) ; classFields . addAll ( Arrays . asList ( type . getDeclaredFields ( ) ) ) ; final Class < ? > parentClass = type . getSuperclass ( ) ; if ( parentClass != null && ! ( parentClass . equals ( Object . class ) ) ) { List < Field > parentClassFields = getFieldsFromClassHierarchy ( parentClass ) ; classFields . addAll ( parentClassFields ) ; } return classFields ; }


Input: Helper method to execute a callback on a given member . This method encapsulates the error handling logic and the handling of accessibility of the member . [CODESPLIT] public static < T > T accessMember ( final AccessibleObject member , final Callable < T > callable , String errorMessage ) { if ( callable == null ) { return null ; } return AccessController . doPrivileged ( ( PrivilegedAction < T > ) ( ) -> { boolean wasAccessible = member . isAccessible ( ) ; try { member . setAccessible ( true ) ; return callable . call ( ) ; } catch ( Exception exception ) { throw new IllegalStateException ( errorMessage , exception ) ; } finally { member . setAccessible ( wasAccessible ) ; } } ) ; }


Input: This method can be used to set ( private / public ) fields to a given value by reflection . Handling of accessibility and errors is encapsulated . [CODESPLIT] public static void setField ( final Field field , Object target , Object value ) { accessMember ( field , ( ) -> field . set ( target , value ) , "Cannot set the field [" + field . getName ( ) + "] of instance [" + target + "] to value [" + value + "]" ) ; }


Input: Helper method to execute a callback on a given member . This method encapsulates the error handling logic and the handling of accessibility of the member . The difference to { @link ReflectionUtils#accessMember ( AccessibleObject Callable String ) } is that this method takes a callback that doesn t return anything but only creates a sideeffect . [CODESPLIT] public static void accessMember ( final AccessibleObject member , final SideEffectWithException sideEffect , String errorMessage ) { if ( sideEffect == null ) { return ; } AccessController . doPrivileged ( ( PrivilegedAction < ? > ) ( ) -> { boolean wasAccessible = member . isAccessible ( ) ; try { member . setAccessible ( true ) ; sideEffect . call ( ) ; } catch ( Exception exception ) { throw new IllegalStateException ( errorMessage , exception ) ; } finally { member . setAccessible ( wasAccessible ) ; } return null ; } ) ; }


Input: Load the viewTuple by it s ViewType . [CODESPLIT] public < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewTuple < ViewType , ViewModelType > loadFxmlViewTuple ( Class < ? extends ViewType > viewType , ResourceBundle resourceBundle , ViewType codeBehind , Object root , ViewModelType viewModel , Context context , Collection < Scope > providedScopes , List < BuilderFactory > builderFactories ) { final String pathToFXML = createFxmlPath ( viewType ) ; return loadFxmlViewTuple ( viewType , pathToFXML , resourceBundle , codeBehind , root , viewModel , context , providedScopes , builderFactories ) ; }


Input: This method is used to create a String with the path to the FXML file for a given View class . [CODESPLIT] private String createFxmlPath ( Class < ? > viewType ) { final StringBuilder pathBuilder = new StringBuilder ( ) ; final FxmlPath pathAnnotation = viewType . getDeclaredAnnotation ( FxmlPath . class ) ; //Get annotation from view final String fxmlPath = Optional . ofNullable ( pathAnnotation ) . map ( FxmlPath :: value ) . map ( String :: trim ) . orElse ( "" ) ; if ( fxmlPath . isEmpty ( ) ) { pathBuilder . append ( "/" ) ; if ( viewType . getPackage ( ) != null ) { pathBuilder . append ( viewType . getPackage ( ) . getName ( ) . replaceAll ( "\\." , "/" ) ) ; pathBuilder . append ( "/" ) ; } pathBuilder . append ( viewType . getSimpleName ( ) ) ; pathBuilder . append ( ".fxml" ) ; } else { pathBuilder . append ( fxmlPath ) ; } return pathBuilder . toString ( ) ; }


Input: Load the viewTuple by the path of the fxml file . [CODESPLIT] public < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewTuple < ViewType , ViewModelType > loadFxmlViewTuple ( final String resource , ResourceBundle resourceBundle , final ViewType codeBehind , final Object root , ViewModelType viewModel , Context parentContext , Collection < Scope > providedScopes , List < BuilderFactory > builderFactories ) { return loadFxmlViewTuple ( null , resource , resourceBundle , codeBehind , root , viewModel , parentContext , providedScopes , builderFactories ) ; }


Input: Load the viewTuple by the path of the fxml file . [CODESPLIT] private < ViewType extends View < ? extends ViewModelType > , ViewModelType extends ViewModel > ViewTuple < ViewType , ViewModelType > loadFxmlViewTuple ( final Class < ? > resourceLoader , final String resource , ResourceBundle resourceBundle , final ViewType codeBehind , final Object root , ViewModelType viewModel , Context parentContext , Collection < Scope > providedScopes , List < BuilderFactory > builderFactories ) { try { // FIXME Woanders hin? ContextImpl context = ViewLoaderScopeUtils . prepareContext ( parentContext , providedScopes ) ; ////////////////////////////////////////////////////////////////////// // for the SceneLifecycle we need to know when the view is put into the scene BooleanProperty viewInSceneProperty = new SimpleBooleanProperty ( ) ; final FXMLLoader loader = createFxmlLoader ( resourceLoader , resource , resourceBundle , codeBehind , root , viewModel , context , viewInSceneProperty , builderFactories ) ; loader . load ( ) ; final ViewType loadedController = loader . getController ( ) ; final Parent loadedRoot = loader . getRoot ( ) ; viewInSceneProperty . bind ( loadedRoot . sceneProperty ( ) . isNotNull ( ) ) ; if ( loadedController == null ) { throw new IOException ( "Could not load the controller for the View " + resource + " maybe your missed the fx:controller in your fxml?" ) ; } // the actually used ViewModel instance. We need this so we can // return it in the ViewTuple ViewModelType actualViewModel ; // FIXME CONTEXT // if no existing viewModel was provided... if ( viewModel == null ) { // ... we try to find the created ViewModel from the codeBehind. // this is only possible when the codeBehind has a field for the // VM and the VM was injected actualViewModel = ViewLoaderReflectionUtils . getExistingViewModel ( loadedController ) ; // otherwise we create a new ViewModel. This is needed because // the ViewTuple has to contain a VM even if // the codeBehind doesn't need one if ( actualViewModel == null ) { actualViewModel = ViewLoaderReflectionUtils . createViewModel ( loadedController ) ; // it is possible that no viewModel could be created (f.e. // when no generic VM type was specified) // otherwise we need to initialize the created ViewModel // instance. if ( actualViewModel != null ) { ViewLoaderReflectionUtils . initializeViewModel ( actualViewModel ) ; } } } else { actualViewModel = viewModel ; } if ( actualViewModel != null ) { // TODO: Create Testcase for this corner case: // If this view is the root view (the one that is loaded with // the FluentViewLoader) // but in the view there is no injection of the ViewModel // only in this case the scope has to be injected here, // If the viewModel was already injected in the View, it has // it's scopes already injected // ViewLoaderReflectionUtils.createAndInjectScopes(actualViewModel, // context); } return new ViewTuple <> ( loadedController , loadedRoot , actualViewModel ) ; } catch ( final IOException ex ) { throw new RuntimeException ( ex ) ; } }


Input: Query for the style row from a style mapping row [CODESPLIT] public StyleRow queryForRow ( StyleMappingRow styleMappingRow ) { StyleRow styleRow = null ; AttributesRow attributesRow = queryForIdRow ( styleMappingRow . getRelatedId ( ) ) ; if ( attributesRow != null ) { styleRow = getRow ( attributesRow ) ; } return styleRow ; }


Input:
{ [CODESPLIT] @ Override public void setValue ( int index , Object value ) { if ( index == getGeometryColumnIndex ( ) && value instanceof byte [ ] ) { byte [ ] bytes = ( byte [ ] ) value ; value = new GeoPackageGeometryData ( bytes ) ; } super . setValue ( index , value ) ; } /**
     * Get the geometry
     *
     * @return geometry data
     */ public GeoPackageGeometryData getGeometry ( ) { GeoPackageGeometryData geometryData = null ; Object value = getValue ( getGeometryColumnIndex ( ) ) ; if ( value != null ) { geometryData = ( GeoPackageGeometryData ) value ; } return geometryData ; } /**
     * Set the geometry data
     *
     * @param geometryData geometry data
     */ public void setGeometry ( GeoPackageGeometryData geometryData ) { setValue ( getGeometryColumnIndex ( ) , geometryData ) ; } /**
     * Get the simple features geometry value
     *
     * @return geometry
     * @since 3.1.0
     */ public Geometry getGeometryValue ( ) { GeoPackageGeometryData data = getGeometry ( ) ; Geometry geometry = null ; if ( data != null ) { geometry = data . getGeometry ( ) ; } return geometry ; } /**
     * Get the simple features geometry type
     *
     * @return geometry type
     * @since 3.2.0
     */ public GeometryType getGeometryType ( ) { Geometry geometry = getGeometryValue ( ) ; GeometryType geometryType = null ; if ( geometry != null ) { geometryType = geometry . getGeometryType ( ) ; } return geometryType ; } /**
     * Get the geometry envelope
     *
     * @return geometry envelope
     * @since 3.1.0
     */ public GeometryEnvelope getGeometryEnvelope ( ) { GeoPackageGeometryData data = getGeometry ( ) ; GeometryEnvelope envelope = null ; if ( data != null ) { envelope = data . getOrBuildEnvelope ( ) ; } return envelope ; } /**
     * Copy the row
     *
     * @return row copy
     * @since 3.0.1
     */ public FeatureRow copy ( ) { return new FeatureRow ( this ) ; } /**
     * {@inheritDoc}
     * Handles geometry columns
     */ @ Override protected Object copyValue ( FeatureColumn column , Object value ) { Object copyValue = null ; if ( column . isGeometry ( ) && value instanceof GeoPackageGeometryData ) { GeoPackageGeometryData geometryData = ( GeoPackageGeometryData ) value ; try { byte [ ] bytes = geometryData . toBytes ( ) ; byte [ ] copyBytes = Arrays . copyOf ( bytes , bytes . length ) ; copyValue = new GeoPackageGeometryData ( copyBytes ) ; } catch ( IOException e ) { throw new GeoPackageException ( "Failed to copy Geometry Data bytes. column: " + column . getName ( ) , e ) ; } } else { copyValue = super . copyValue ( column , value ) ; } return copyValue ; }


Input: { [CODESPLIT] @ Override protected void columnToContentValue ( ContentValues contentValues , FeatureColumn column , Object value ) { if ( column . isGeometry ( ) ) { String columnName = column . getName ( ) ; if ( value instanceof GeoPackageGeometryData ) { GeoPackageGeometryData geometryData = ( GeoPackageGeometryData ) value ; try { contentValues . put ( columnName , geometryData . toBytes ( ) ) ; } catch ( IOException e ) { throw new GeoPackageException ( "Failed to write Geometry Data bytes. column: " + columnName , e ) ; } } else if ( value instanceof byte [ ] ) { contentValues . put ( columnName , ( byte [ ] ) value ) ; } else { throw new GeoPackageException ( "Unsupported update geometry column value type. column: " + columnName + ", value type: " + value . getClass ( ) . getName ( ) ) ; } }


Input: { [CODESPLIT] @ Override public double getValue ( GriddedTile griddedTile , TileRow tileRow , int x , int y ) { byte [ ] imageBytes = tileRow . getTileData ( ) ; double value = getValue ( griddedTile , imageBytes , x , y ) ; return value ; }


Input: { [CODESPLIT] @ Override public Double getValue ( GriddedTile griddedTile , CoverageDataPngImage image , int x , int y ) { Double value = null ; if ( image . getReader ( ) != null ) { int pixelValue = image . getPixel ( x , y ) ; value = getValue ( griddedTile , pixelValue ) ; } else { value = getValue ( griddedTile , image . getImageBytes ( ) , x , y ) ; } return value ; }


Input: Get the pixel value as a 16 bit unsigned integer value [CODESPLIT] public int getPixelValue ( byte [ ] imageBytes , int x , int y ) { PngReaderInt reader = new PngReaderInt ( new ByteArrayInputStream ( imageBytes ) ) ; validateImageType ( reader ) ; ImageLineInt row = ( ImageLineInt ) reader . readRow ( y ) ; int pixelValue = row . getScanline ( ) [ x ] ; reader . close ( ) ; return pixelValue ; }


Input: Get the pixel values of the image as 16 bit unsigned integer values [CODESPLIT] public int [ ] getPixelValues ( byte [ ] imageBytes ) { PngReaderInt reader = new PngReaderInt ( new ByteArrayInputStream ( imageBytes ) ) ; validateImageType ( reader ) ; int [ ] pixels = new int [ reader . imgInfo . cols * reader . imgInfo . rows ] ; int rowNumber = 0 ; while ( reader . hasMoreRows ( ) ) { ImageLineInt row = reader . readRowInt ( ) ; int [ ] rowValues = row . getScanline ( ) ; System . arraycopy ( rowValues , 0 , pixels , rowNumber * reader . imgInfo . cols , rowValues . length ) ; rowNumber ++ ; } reader . close ( ) ; return pixels ; }


Input: Validate that the image type is single channel 16 bit [CODESPLIT] public static void validateImageType ( PngReader reader ) { if ( reader == null ) { throw new GeoPackageException ( "The image is null" ) ; } if ( reader . imgInfo . channels != 1 || reader . imgInfo . bitDepth != 16 ) { throw new GeoPackageException ( "The coverage data tile is expected to be a single channel 16 bit unsigned short, channels: " + reader . imgInfo . channels + ", bits: " + reader . imgInfo . bitDepth ) ; } }


Input: Draw a coverage data tile from the double array of unsigned short pixel values formatted as short [ row ] [ width ] [CODESPLIT] public CoverageDataPngImage drawTile ( short [ ] [ ] pixelValues ) { int tileWidth = pixelValues [ 0 ] . length ; int tileHeight = pixelValues . length ; CoverageDataPngImage image = createImage ( tileWidth , tileHeight ) ; PngWriter writer = image . getWriter ( ) ; for ( int y = 0 ; y < tileHeight ; y ++ ) { ImageLineInt row = new ImageLineInt ( writer . imgInfo , new int [ tileWidth ] ) ; int [ ] rowLine = row . getScanline ( ) ; for ( int x = 0 ; x < tileWidth ; x ++ ) { short pixelValue = pixelValues [ y ] [ x ] ; setPixelValue ( rowLine , x , pixelValue ) ; } writer . writeRow ( row ) ; } writer . end ( ) ; image . flushStream ( ) ; return image ; }


Input: Draw a coverage data tile and format as PNG bytes from the double array of unsigned short pixel values formatted as short [ row ] [ width ] [CODESPLIT] public byte [ ] drawTileData ( short [ ] [ ] pixelValues ) { CoverageDataPngImage image = drawTile ( pixelValues ) ; byte [ ] bytes = image . getImageBytes ( ) ; return bytes ; }


Input: Draw a coverage data image tile and format as PNG bytes from the double array of unsigned 16 bit integer pixel values formatted as int [ row ] [ width ] [CODESPLIT] public byte [ ] drawTileData ( int [ ] [ ] unsignedPixelValues ) { CoverageDataPngImage image = drawTile ( unsignedPixelValues ) ; byte [ ] bytes = image . getImageBytes ( ) ; return bytes ; }


Input: Draw a coverage data image tile from the double array of unsigned coverage data values formatted as Double [ row ] [ width ] [CODESPLIT] public CoverageDataPngImage drawTile ( GriddedTile griddedTile , Double [ ] [ ] values ) { int tileWidth = values [ 0 ] . length ; int tileHeight = values . length ; CoverageDataPngImage image = createImage ( tileWidth , tileHeight ) ; PngWriter writer = image . getWriter ( ) ; for ( int y = 0 ; y < tileHeight ; y ++ ) { ImageLineInt row = new ImageLineInt ( writer . imgInfo , new int [ tileWidth ] ) ; int [ ] rowLine = row . getScanline ( ) ; for ( int x = 0 ; x < tileWidth ; x ++ ) { Double value = values [ y ] [ x ] ; short pixelValue = getPixelValue ( griddedTile , value ) ; setPixelValue ( rowLine , x , pixelValue ) ; } writer . writeRow ( row ) ; } writer . end ( ) ; image . flushStream ( ) ; return image ; }


Input: Create a new 16 bit single channel image [CODESPLIT] public CoverageDataPngImage createImage ( int tileWidth , int tileHeight ) { ImageInfo imageInfo = new ImageInfo ( tileWidth , tileHeight , 16 , false , true , false ) ; CoverageDataPngImage image = new CoverageDataPngImage ( imageInfo ) ; return image ; }


Input: Set the pixel value [CODESPLIT] public void setPixelValue ( ImageLineInt row , int x , short pixelValue ) { setPixelValue ( row . getScanline ( ) , x , pixelValue ) ; }


Input: Set the pixel value [CODESPLIT] public void setPixelValue ( ImageLineInt row , int x , int unsignedPixelValue ) { short pixelValue = getPixelValue ( unsignedPixelValue ) ; setPixelValue ( row , x , pixelValue ) ; }


Input: Create the coverage data tile table with metadata and extension [CODESPLIT] public static CoverageDataPng createTileTableWithMetadata ( GeoPackage geoPackage , String tableName , BoundingBox contentsBoundingBox , long contentsSrsId , BoundingBox tileMatrixSetBoundingBox , long tileMatrixSetSrsId ) { CoverageDataPng coverageData = ( CoverageDataPng ) CoverageData . createTileTableWithMetadata ( geoPackage , tableName , contentsBoundingBox , contentsSrsId , tileMatrixSetBoundingBox , tileMatrixSetSrsId , GriddedCoverageDataType . INTEGER ) ; return coverageData ; }


Input: Set the tile data from a bitmap [CODESPLIT] public void setTileData ( Bitmap bitmap , CompressFormat format , int quality ) throws IOException { byte [ ] tileData = BitmapConverter . toBytes ( bitmap , format , quality ) ; setTileData ( tileData ) ; }


Input: { [CODESPLIT] @ Override public int delete ( String table , String whereClause , String [ ] whereArgs ) { return db . delete ( table , whereClause , whereArgs ) ; }


Input: { [CODESPLIT] @ Override public int count ( String table , String where , String [ ] args ) { StringBuilder countQuery = new StringBuilder ( ) ; countQuery . append ( "select count(*) from " ) . append ( CoreSQLUtils . quoteWrap ( table ) ) ; if ( where != null ) { countQuery . append ( " where " ) . append ( where ) ; } String sql = countQuery . toString ( ) ; int count = querySingleInteger ( sql , args , true ) ; return count ; }


Input: { [CODESPLIT] @ Override public boolean columnExists ( String tableName , String columnName ) { boolean exists = false ; Cursor cursor = rawQuery ( "PRAGMA table_info(" + CoreSQLUtils . quoteWrap ( tableName ) + ")" , null ) ; try { int nameIndex = cursor . getColumnIndex ( NAME_COLUMN ) ; while ( cursor . moveToNext ( ) ) { String name = cursor . getString ( nameIndex ) ; if ( columnName . equals ( name ) ) { exists = true ; break ; } } } finally { cursor . close ( ) ; } return exists ; }


Input: { [CODESPLIT] @ Override public Object querySingleResult ( String sql , String [ ] args , int column , GeoPackageDataType dataType ) { CursorResult result = wrapQuery ( sql , args ) ; Object value = ResultUtils . buildSingleResult ( result , column , dataType ) ; return value ; }


Input: { [CODESPLIT] @ Override public List < Object > querySingleColumnResults ( String sql , String [ ] args , int column , GeoPackageDataType dataType , Integer limit ) { CursorResult result = wrapQuery ( sql , args ) ; List < Object > results = ResultUtils . buildSingleColumnResults ( result , column , dataType , limit ) ; return results ; }


Input: { [CODESPLIT] @ Override public List < List < Object > > queryResults ( String sql , String [ ] args , GeoPackageDataType [ ] dataTypes , Integer limit ) { CursorResult result = wrapQuery ( sql , args ) ; List < List < Object > > results = ResultUtils . buildResults ( result , dataTypes , limit ) ; return results ; }


Input: Perform a raw database query [CODESPLIT] public Cursor rawQuery ( String sql , String [ ] args ) { return db . rawQuery ( sql , args ) ; }


Input: Perform the query and wrap as a result [CODESPLIT] public CursorResult wrapQuery ( String sql , String [ ] selectionArgs ) { return new CursorResult ( rawQuery ( sql , selectionArgs ) ) ; }


Input: { [CODESPLIT] @ Override public TResult rawQuery ( String sql , String [ ] selectionArgs ) { UserQuery query = new UserQuery ( sql , selectionArgs ) ; TResult result = query ( query ) ; return result ; }


Input: { [CODESPLIT] @ Override public TResult query ( String table , String [ ] columns , String selection , String [ ] selectionArgs , String groupBy , String having , String orderBy ) { UserQuery query = new UserQuery ( table , columns , selection , selectionArgs , groupBy , having , orderBy ) ; TResult result = query ( query ) ; return result ; }


Input: Query using the query from a previous query result [CODESPLIT] public TResult query ( TResult previousResult ) { UserQuery query = previousResult . getQuery ( ) ; TResult result = query ( query ) ; return result ; }


Input: Query using the user query arguments [CODESPLIT] public TResult query ( UserQuery query ) { Cursor cursor = null ; String [ ] selectionArgs = query . getSelectionArgs ( ) ; String sql = query . getSql ( ) ; if ( sql != null ) { cursor = database . rawQuery ( sql , selectionArgs ) ; } else { String table = query . getTable ( ) ; String [ ] columns = query . getColumns ( ) ; String selection = query . getSelection ( ) ; String groupBy = query . getGroupBy ( ) ; String having = query . getHaving ( ) ; String orderBy = query . getOrderBy ( ) ; String [ ] columnsAs = query . getColumnsAs ( ) ; String limit = query . getLimit ( ) ; if ( columnsAs != null && limit != null ) { cursor = database . query ( table , columns , columnsAs , selection , selectionArgs , groupBy , having , orderBy , limit ) ; } else if ( columnsAs != null ) { cursor = database . query ( table , columns , columnsAs , selection , selectionArgs , groupBy , having , orderBy ) ; } else if ( limit != null ) { cursor = database . query ( table , columns , selection , selectionArgs , groupBy , having , orderBy , limit ) ; } else { cursor = database . query ( table , columns , selection , selectionArgs , groupBy , having , orderBy ) ; } } TResult result = handleCursor ( cursor , query ) ; return result ; }


Input: Convert the cursor to the result type cursor [CODESPLIT] private TResult handleCursor ( Cursor cursor , UserQuery query ) { TResult result = convertCursor ( cursor ) ; result . setQuery ( query ) ; if ( table != null ) { result . setTable ( table ) ; } return result ; }


Input: Index the feature row . This method assumes that indexing has been completed and maintained as the last indexed time is updated . [CODESPLIT] public boolean index ( FeatureRow row ) { TableIndex tableIndex = getTableIndex ( ) ; if ( tableIndex == null ) { throw new GeoPackageException ( "GeoPackage table is not indexed. GeoPackage: " + getGeoPackage ( ) . getName ( ) + ", Table: " + getTableName ( ) ) ; } boolean indexed = index ( tableIndex , row . getId ( ) , row . getGeometry ( ) ) ; // Update the last indexed time updateLastIndexed ( ) ; return indexed ; }


Input: Index the feature rows in the cursor [CODESPLIT] private int indexRows ( TableIndex tableIndex , FeatureCursor cursor ) { int count = - 1 ; try { while ( ( progress == null || progress . isActive ( ) ) && cursor . moveToNext ( ) ) { if ( count < 0 ) { count ++ ; } try { FeatureRow row = cursor . getRow ( ) ; if ( row . isValid ( ) ) { boolean indexed = index ( tableIndex , row . getId ( ) , row . getGeometry ( ) ) ; if ( indexed ) { count ++ ; } if ( progress != null ) { progress . addProgress ( 1 ) ; } } } catch ( Exception e ) { Log . e ( FeatureTableIndex . class . getSimpleName ( ) , "Failed to index feature. Table: " + tableIndex . getTableName ( ) + ", Position: " + cursor . getPosition ( ) , e ) ; } } } finally { cursor . close ( ) ; } return count ; }


Input: Get the feature row for the Geometry Index [CODESPLIT] public FeatureRow getFeatureRow ( GeometryIndex geometryIndex ) { long geomId = geometryIndex . getGeomId ( ) ; // Get the row or lock for reading FeatureRow row = featureRowSync . getRowOrLock ( geomId ) ; if ( row == null ) { // Query for the row and set in the sync try { row = featureDao . queryForIdRow ( geomId ) ; } finally { featureRowSync . setRow ( geomId , row ) ; } } return row ; }


Input:
{ [CODESPLIT] @ Override public Iterator < FeatureRow > iterator ( ) { return new Iterator < FeatureRow > ( ) { /**
             * {@inheritDoc}
             */ @ Override public boolean hasNext ( ) { return cursor . moveToNext ( ) ; } /**
             * {@inheritDoc}
             */ @ Override public FeatureRow next ( ) { return dao . getFeatureRow ( cursor ) ; } } ; }


Input:
{ [CODESPLIT] @ Override public Iterable < Long > ids ( ) { return new Iterable < Long > ( ) { /**
             * {@inheritDoc}
             */ @ Override public Iterator < Long > iterator ( ) { return new Iterator < Long > ( ) { /**
                     * {@inheritDoc}
                     */ @ Override public boolean hasNext ( ) { return cursor . moveToNext ( ) ; } /**
                     * {@inheritDoc}
                     */ @ Override public Long next ( ) { return dao . getRow ( cursor ) . getId ( ) ; } } ; } } ; }


Input: Register a cursor wrapper for the provided table name . Database queries will wrap the returned cursor [CODESPLIT] public void registerTable ( String tableName , GeoPackageCursorWrapper cursorWrapper ) { // Remove an existing cursor wrapper tableCursors . remove ( tableName ) ; // Add the wrapper tableCursors . put ( tableName , cursorWrapper ) ; String quotedTableName = CoreSQLUtils . quoteWrap ( tableName ) ; tableCursors . put ( quotedTableName , cursorWrapper ) ; // The Android android.database.sqlite.SQLiteDatabase findEditTable method // finds the new cursor edit table name based upon the first space or comma. // Fix (hopefully temporary) to wrap with the expected cursor type int spacePosition = tableName . indexOf ( ' ' ) ; if ( spacePosition > 0 ) { tableCursors . put ( tableName . substring ( 0 , spacePosition ) , cursorWrapper ) ; tableCursors . put ( quotedTableName . substring ( 0 , quotedTableName . indexOf ( ' ' ) ) , cursorWrapper ) ; } }


Input: { [CODESPLIT] @ Override public Cursor newCursor ( SQLiteDatabase db , SQLiteCursorDriver driver , String editTable , SQLiteQuery query ) { // Create a standard cursor Cursor cursor = new SQLiteCursor ( driver , editTable , query ) ; // Check if there is an edit table if ( editTable != null ) { // Check if the table has a cursor wrapper GeoPackageCursorWrapper cursorWrapper = tableCursors . get ( editTable ) ; if ( cursorWrapper != null ) { cursor = cursorWrapper . wrapCursor ( cursor ) ; } } return cursor ; }


Input: { [CODESPLIT] @ Override public boolean hasTile ( int x , int y , int zoom ) { return retrieveTileRow ( x , y , zoom ) != null ; }


Input: { [CODESPLIT] @ Override public GeoPackageTile getTile ( int x , int y , int zoom ) { GeoPackageTile tile = null ; TileRow tileRow = retrieveTileRow ( x , y , zoom ) ; if ( tileRow != null ) { TileMatrix tileMatrix = tileDao . getTileMatrix ( zoom ) ; int tileWidth = ( int ) tileMatrix . getTileWidth ( ) ; int tileHeight = ( int ) tileMatrix . getTileHeight ( ) ; tile = new GeoPackageTile ( tileWidth , tileHeight , tileRow . getTileData ( ) ) ; } return tile ; }


Input: Retrieve the tile row [CODESPLIT] private TileRow retrieveTileRow ( int x , int y , int zoom ) { return tileDao . queryForTile ( x , y , zoom ) ; }


Input: Get a Tiled Gridded Coverage Data [CODESPLIT] public static CoverageData < ? > getCoverageData ( GeoPackage geoPackage , TileDao tileDao , Integer width , Integer height , Projection requestProjection ) { TileMatrixSet tileMatrixSet = tileDao . getTileMatrixSet ( ) ; GriddedCoverageDao griddedCoverageDao = geoPackage . getGriddedCoverageDao ( ) ; GriddedCoverage griddedCoverage = null ; try { if ( griddedCoverageDao . isTableExists ( ) ) { griddedCoverage = griddedCoverageDao . query ( tileMatrixSet ) ; } } catch ( SQLException e ) { throw new GeoPackageException ( "Failed to get Gridded Coverage for table name: " + tileMatrixSet . getTableName ( ) , e ) ; } CoverageData < ? > coverageData = null ; GriddedCoverageDataType dataType = griddedCoverage . getDataType ( ) ; switch ( dataType ) { case INTEGER : coverageData = new CoverageDataPng ( geoPackage , tileDao , width , height , requestProjection ) ; break ; case FLOAT : coverageData = new CoverageDataTiff ( geoPackage , tileDao , width , height , requestProjection ) ; break ; default : throw new GeoPackageException ( "Unsupported Gridded Coverage Data Type: " + dataType ) ; } return coverageData ; }


Input: Get a Tiled Gridded Coverage Data use the coverage data pixel tile size as the request size width and height [CODESPLIT] public static CoverageData < ? > getCoverageData ( GeoPackage geoPackage , TileDao tileDao ) { return getCoverageData ( geoPackage , tileDao , null , null , tileDao . getProjection ( ) ) ; }


Input: Get a Tiled Gridded Coverage Data use the coverage data pixel tile size as the request size width and height request as the specified projection [CODESPLIT] public static CoverageData < ? > getCoverageData ( GeoPackage geoPackage , TileDao tileDao , Projection requestProjection ) { return getCoverageData ( geoPackage , tileDao , null , null , requestProjection ) ; }


Input: Create the coverage data tile table with metadata and extension [CODESPLIT] public static CoverageData < ? > createTileTableWithMetadata ( GeoPackage geoPackage , String tableName , BoundingBox contentsBoundingBox , long contentsSrsId , BoundingBox tileMatrixSetBoundingBox , long tileMatrixSetSrsId , GriddedCoverageDataType dataType ) { TileMatrixSet tileMatrixSet = CoverageDataCore . createTileTableWithMetadata ( geoPackage , tableName , contentsBoundingBox , contentsSrsId , tileMatrixSetBoundingBox , tileMatrixSetSrsId ) ; TileDao tileDao = geoPackage . getTileDao ( tileMatrixSet ) ; CoverageData < ? > coverageData = null ; switch ( dataType ) { case INTEGER : coverageData = new CoverageDataPng ( geoPackage , tileDao ) ; break ; case FLOAT : coverageData = new CoverageDataTiff ( geoPackage , tileDao ) ; break ; default : throw new GeoPackageException ( "Unsupported Gridded Coverage Data Type: " + dataType ) ; } coverageData . getOrCreate ( ) ; return coverageData ; }


Input: { [CODESPLIT] @ Override public CoverageDataResults getValues ( CoverageDataRequest request , Integer width , Integer height ) { CoverageDataResults coverageDataResults = null ; // Transform to the projection of the coverage data tiles ProjectionTransform transformRequestToCoverage = null ; BoundingBox requestProjectedBoundingBox = request . getBoundingBox ( ) ; if ( ! sameProjection ) { transformRequestToCoverage = requestProjection . getTransformation ( coverageProjection ) ; requestProjectedBoundingBox = requestProjectedBoundingBox . transform ( transformRequestToCoverage ) ; } request . setProjectedBoundingBox ( requestProjectedBoundingBox ) ; // Determine how many overlapping pixels to store based upon the // algorithm int overlappingPixels ; switch ( algorithm ) { case BICUBIC : overlappingPixels = 3 ; break ; default : overlappingPixels = 1 ; } // Find the tile matrix and results CoverageDataTileMatrixResults results = getResults ( request , requestProjectedBoundingBox , overlappingPixels ) ; if ( results != null ) { TileMatrix tileMatrix = results . getTileMatrix ( ) ; TileCursor tileResults = results . getTileResults ( ) ; try { // Determine the requested coverage data dimensions, or use the // dimensions of a single tile matrix coverage data tile int requestedCoverageDataWidth = width != null ? width : ( int ) tileMatrix . getTileWidth ( ) ; int requestedCoverageDataHeight = height != null ? height : ( int ) tileMatrix . getTileHeight ( ) ; // Determine the size of the non projected coverage data results int tileWidth = requestedCoverageDataWidth ; int tileHeight = requestedCoverageDataHeight ; if ( ! sameProjection ) { int projectedWidth = ( int ) Math . round ( ( requestProjectedBoundingBox . getMaxLongitude ( ) - requestProjectedBoundingBox . getMinLongitude ( ) ) / tileMatrix . getPixelXSize ( ) ) ; if ( projectedWidth > 0 ) { tileWidth = projectedWidth ; } int projectedHeight = ( int ) Math . round ( ( requestProjectedBoundingBox . getMaxLatitude ( ) - requestProjectedBoundingBox . getMinLatitude ( ) ) / tileMatrix . getPixelYSize ( ) ) ; if ( projectedHeight > 0 ) { tileHeight = projectedHeight ; } } // Retrieve the coverage data from the results Double [ ] [ ] values = getValues ( tileMatrix , tileResults , request , tileWidth , tileHeight , overlappingPixels ) ; // Project the coverage data if needed if ( values != null && ! sameProjection && ! request . isPoint ( ) ) { values = reprojectCoverageData ( values , requestedCoverageDataWidth , requestedCoverageDataHeight , request . getBoundingBox ( ) , transformRequestToCoverage , requestProjectedBoundingBox ) ; } // Create the results if ( values != null ) { coverageDataResults = new CoverageDataResults ( values , tileMatrix ) ; } } finally { tileResults . close ( ) ; } } return coverageDataResults ; }


Input: { [CODESPLIT] @ Override public CoverageDataResults getValuesUnbounded ( CoverageDataRequest request ) { CoverageDataResults coverageDataResults = null ; // Transform to the projection of the coverage data tiles ProjectionTransform transformRequestToCoverage = null ; BoundingBox requestProjectedBoundingBox = request . getBoundingBox ( ) ; if ( ! sameProjection ) { transformRequestToCoverage = requestProjection . getTransformation ( coverageProjection ) ; requestProjectedBoundingBox = requestProjectedBoundingBox . transform ( transformRequestToCoverage ) ; } request . setProjectedBoundingBox ( requestProjectedBoundingBox ) ; // Find the tile matrix and results CoverageDataTileMatrixResults results = getResults ( request , requestProjectedBoundingBox ) ; if ( results != null ) { TileMatrix tileMatrix = results . getTileMatrix ( ) ; TileCursor tileResults = results . getTileResults ( ) ; try { // Retrieve the coverage data values from the results Double [ ] [ ] values = getValuesUnbounded ( tileMatrix , tileResults , request ) ; // Project the coverage data if needed if ( values != null && ! sameProjection && ! request . isPoint ( ) ) { values = reprojectCoverageData ( values , values [ 0 ] . length , values . length , request . getBoundingBox ( ) , transformRequestToCoverage , requestProjectedBoundingBox ) ; } // Create the results if ( values != null ) { coverageDataResults = new CoverageDataResults ( values , tileMatrix ) ; } } finally { tileResults . close ( ) ; } } return coverageDataResults ; }


Input: Get the coverage data tile results by finding the tile matrix with values [CODESPLIT] private CoverageDataTileMatrixResults getResults ( CoverageDataRequest request , BoundingBox requestProjectedBoundingBox , int overlappingPixels ) { // Try to get the coverage data from the current zoom level TileMatrix tileMatrix = getTileMatrix ( request ) ; CoverageDataTileMatrixResults results = null ; if ( tileMatrix != null ) { results = getResults ( requestProjectedBoundingBox , tileMatrix , overlappingPixels ) ; // Try to zoom in or out to find a matching coverage data if ( results == null ) { results = getResultsZoom ( requestProjectedBoundingBox , tileMatrix , overlappingPixels ) ; } } return results ; }


Input: Get the coverage data tile results by zooming in or out as needed from the provided tile matrix to find values [CODESPLIT] private CoverageDataTileMatrixResults getResultsZoom ( BoundingBox requestProjectedBoundingBox , TileMatrix tileMatrix , int overlappingPixels ) { CoverageDataTileMatrixResults results = null ; if ( zoomIn && zoomInBeforeOut ) { results = getResultsZoomIn ( requestProjectedBoundingBox , tileMatrix , overlappingPixels ) ; } if ( results == null && zoomOut ) { results = getResultsZoomOut ( requestProjectedBoundingBox , tileMatrix , overlappingPixels ) ; } if ( results == null && zoomIn && ! zoomInBeforeOut ) { results = getResultsZoomIn ( requestProjectedBoundingBox , tileMatrix , overlappingPixels ) ; } return results ; }


Input: Get the coverage data tile results by zooming in from the provided tile matrix [CODESPLIT] private CoverageDataTileMatrixResults getResultsZoomIn ( BoundingBox requestProjectedBoundingBox , TileMatrix tileMatrix , int overlappingPixels ) { CoverageDataTileMatrixResults results = null ; for ( long zoomLevel = tileMatrix . getZoomLevel ( ) + 1 ; zoomLevel <= tileDao . getMaxZoom ( ) ; zoomLevel ++ ) { TileMatrix zoomTileMatrix = tileDao . getTileMatrix ( zoomLevel ) ; if ( zoomTileMatrix != null ) { results = getResults ( requestProjectedBoundingBox , zoomTileMatrix , overlappingPixels ) ; if ( results != null ) { break ; } } } return results ; }


Input: Get the coverage data tile results by zooming out from the provided tile matrix [CODESPLIT] private CoverageDataTileMatrixResults getResultsZoomOut ( BoundingBox requestProjectedBoundingBox , TileMatrix tileMatrix , int overlappingPixels ) { CoverageDataTileMatrixResults results = null ; for ( long zoomLevel = tileMatrix . getZoomLevel ( ) - 1 ; zoomLevel >= tileDao . getMinZoom ( ) ; zoomLevel -- ) { TileMatrix zoomTileMatrix = tileDao . getTileMatrix ( zoomLevel ) ; if ( zoomTileMatrix != null ) { results = getResults ( requestProjectedBoundingBox , zoomTileMatrix , overlappingPixels ) ; if ( results != null ) { break ; } } } return results ; }


Input: Get the tile matrix for the zoom level as defined by the area of the request [CODESPLIT] private TileMatrix getTileMatrix ( CoverageDataRequest request ) { TileMatrix tileMatrix = null ; // Check if the request overlaps coverage data bounding box if ( request . overlap ( coverageBoundingBox ) != null ) { // Get the tile distance BoundingBox projectedBoundingBox = request . getProjectedBoundingBox ( ) ; double distanceWidth = projectedBoundingBox . getMaxLongitude ( ) - projectedBoundingBox . getMinLongitude ( ) ; double distanceHeight = projectedBoundingBox . getMaxLatitude ( ) - projectedBoundingBox . getMinLatitude ( ) ; // Get the zoom level to request based upon the tile size Long zoomLevel = tileDao . getClosestZoomLevel ( distanceWidth , distanceHeight ) ; // If there is a matching zoom level if ( zoomLevel != null ) { tileMatrix = tileDao . getTileMatrix ( zoomLevel ) ; } } return tileMatrix ; }


Input: Get the coverage data value of the pixel in the tile row image [CODESPLIT] public double getValue ( TileRow tileRow , int x , int y ) { GriddedTile griddedTile = getGriddedTile ( tileRow . getId ( ) ) ; double value = getValue ( griddedTile , tileRow , x , y ) ; return value ; }


Input: Set the icon for the geometry type [CODESPLIT] public void setIcon ( IconRow iconRow , GeometryType geometryType ) { if ( geometryType != null ) { if ( iconRow != null ) { icons . put ( geometryType , iconRow ) ; } else { icons . remove ( geometryType ) ; } } else { defaultIcon = iconRow ; } }


Input: Get the icon for the geometry type [CODESPLIT] public IconRow getIcon ( GeometryType geometryType ) { IconRow iconRow = null ; if ( geometryType != null && ! icons . isEmpty ( ) ) { List < GeometryType > geometryTypes = GeometryUtils . parentHierarchy ( geometryType ) ; geometryTypes . add ( 0 , geometryType ) ; for ( GeometryType type : geometryTypes ) { iconRow = icons . get ( type ) ; if ( iconRow != null ) { break ; } } } if ( iconRow == null ) { iconRow = defaultIcon ; } if ( iconRow == null && geometryType == null && icons . size ( ) == 1 ) { iconRow = icons . values ( ) . iterator ( ) . next ( ) ; } return iconRow ; }


Input: { [CODESPLIT] @ Override public UserCustomRow getRow ( int [ ] columnTypes , Object [ ] values ) { return new UserCustomRow ( getTable ( ) , columnTypes , values ) ; }


Input: { [CODESPLIT] @ Override protected UserInvalidCursor < UserCustomColumn , UserCustomTable , UserCustomRow , ? extends UserCursor < UserCustomColumn , UserCustomTable , UserCustomRow > , ? extends UserDao < UserCustomColumn , UserCustomTable , UserCustomRow , ? extends UserCursor < UserCustomColumn , UserCustomTable , UserCustomRow > > > createInvalidCursor ( UserDao dao , UserCursor cursor , List < Integer > invalidPositions , List < UserCustomColumn > blobColumns ) { return new UserCustomInvalidCursor ( ( UserCustomDao ) dao , ( UserCustomCursor ) cursor , invalidPositions , blobColumns ) ; }


Input: Open or get a connection using the SQLite Android Bindings connection [CODESPLIT] public org . sqlite . database . sqlite . SQLiteDatabase openOrGetBindingsDb ( ) { if ( bindingsDb == null ) { synchronized ( db ) { if ( bindingsDb == null ) { System . loadLibrary ( "sqliteX" ) ; bindingsDb = org . sqlite . database . sqlite . SQLiteDatabase . openDatabase ( db . getPath ( ) , null , org . sqlite . database . sqlite . SQLiteDatabase . OPEN_READWRITE ) ; } } } return bindingsDb ; }


Input: Decode the bytes to a bitmap with options [CODESPLIT] public static Bitmap toBitmap ( byte [ ] bytes , Options options ) { Bitmap bitmap = BitmapFactory . decodeByteArray ( bytes , 0 , bytes . length , options ) ; return bitmap ; }


Input: Compress the bitmap to a byte array [CODESPLIT] public static byte [ ] toBytes ( Bitmap bitmap , CompressFormat format , int quality ) throws IOException { byte [ ] bytes = null ; ByteArrayOutputStream byteStream = new ByteArrayOutputStream ( ) ; try { bitmap . compress ( format , quality , byteStream ) ; bytes = byteStream . toByteArray ( ) ; } finally { byteStream . close ( ) ; } return bytes ; }


Input: Create a new table metadata [CODESPLIT] public void create ( TableMetadata metadata ) { ContentValues values = new ContentValues ( ) ; values . put ( TableMetadata . COLUMN_GEOPACKAGE_ID , metadata . getGeoPackageId ( ) ) ; values . put ( TableMetadata . COLUMN_TABLE_NAME , metadata . getTableName ( ) ) ; values . put ( TableMetadata . COLUMN_LAST_INDEXED , metadata . getLastIndexed ( ) ) ; long insertId = db . insert ( TableMetadata . TABLE_NAME , null , values ) ; if ( insertId == - 1 ) { throw new GeoPackageException ( "Failed to insert table metadata. GeoPackage Id: " + metadata . getGeoPackageId ( ) + ", Table Name: " + metadata . getTableName ( ) + ", Last Indexed: " + metadata . getLastIndexed ( ) ) ; } }


Input: Delete the database table name [CODESPLIT] public boolean delete ( long geoPackageId , String tableName ) { GeometryMetadataDataSource geomDs = new GeometryMetadataDataSource ( db ) ; geomDs . delete ( geoPackageId , tableName ) ; String whereClause = TableMetadata . COLUMN_GEOPACKAGE_ID + " = ? AND " + TableMetadata . COLUMN_TABLE_NAME + " = ?" ; String [ ] whereArgs = new String [ ] { String . valueOf ( geoPackageId ) , tableName } ; int deleteCount = db . delete ( TableMetadata . TABLE_NAME , whereClause , whereArgs ) ; return deleteCount > 0 ; }


Input: Update the last indexed time [CODESPLIT] public boolean updateLastIndexed ( TableMetadata metadata , long lastIndexed ) { boolean updated = updateLastIndexed ( metadata . getGeoPackageId ( ) , metadata . getTableName ( ) , lastIndexed ) ; if ( updated ) { metadata . setLastIndexed ( lastIndexed ) ; } return updated ; }


Input: Update the last indexed time [CODESPLIT] public boolean updateLastIndexed ( String geoPackage , String tableName , long lastIndexed ) { return updateLastIndexed ( getGeoPackageId ( geoPackage ) , tableName , lastIndexed ) ; }


Input: Update the last indexed time [CODESPLIT] public boolean updateLastIndexed ( long geoPackageId , String tableName , long lastIndexed ) { String whereClause = TableMetadata . COLUMN_GEOPACKAGE_ID + " = ? AND " + TableMetadata . COLUMN_TABLE_NAME + " = ?" ; String [ ] whereArgs = new String [ ] { String . valueOf ( geoPackageId ) , tableName } ; ContentValues values = new ContentValues ( ) ; values . put ( TableMetadata . COLUMN_LAST_INDEXED , lastIndexed ) ; int updateCount = db . update ( TableMetadata . TABLE_NAME , values , whereClause , whereArgs ) ; return updateCount > 0 ; }


Input: Get a table metadata [CODESPLIT] public TableMetadata get ( String geoPackage , String tableName ) { return get ( getGeoPackageId ( geoPackage ) , tableName ) ; }


Input: Get a table metadata [CODESPLIT] public TableMetadata get ( long geoPackageId , String tableName ) { String selection = TableMetadata . COLUMN_GEOPACKAGE_ID + " = ? AND " + TableMetadata . COLUMN_TABLE_NAME + " = ?" ; String [ ] selectionArgs = new String [ ] { String . valueOf ( geoPackageId ) , tableName } ; Cursor cursor = db . query ( TableMetadata . TABLE_NAME , TableMetadata . COLUMNS , selection , selectionArgs , null , null , null ) ; TableMetadata metadata = null ; try { if ( cursor . moveToNext ( ) ) { metadata = createTableMetadata ( cursor ) ; } } finally { cursor . close ( ) ; } return metadata ; }


Input: Get a table metadata or create if it does not exist [CODESPLIT] public TableMetadata getOrCreate ( String geoPackage , String tableName ) { GeoPackageMetadataDataSource ds = new GeoPackageMetadataDataSource ( db ) ; GeoPackageMetadata geoPackageMetadata = ds . getOrCreate ( geoPackage ) ; TableMetadata metadata = get ( geoPackageMetadata . getId ( ) , tableName ) ; if ( metadata == null ) { metadata = new TableMetadata ( ) ; metadata . setGeoPackageId ( geoPackageMetadata . getId ( ) ) ; metadata . setTableName ( tableName ) ; create ( metadata ) ; } return metadata ; }


Input: Get a GeoPackage id from the name [CODESPLIT] public long getGeoPackageId ( String geoPackage ) { long id = - 1 ; GeoPackageMetadataDataSource ds = new GeoPackageMetadataDataSource ( db ) ; GeoPackageMetadata metadata = ds . get ( geoPackage ) ; if ( metadata != null ) { id = metadata . getId ( ) ; } return id ; }


Input: Create a table metadata from the current cursor location [CODESPLIT] private TableMetadata createTableMetadata ( Cursor cursor ) { TableMetadata metadata = new TableMetadata ( ) ; metadata . setGeoPackageId ( cursor . getLong ( 0 ) ) ; metadata . setTableName ( cursor . getString ( 1 ) ) ; if ( ! cursor . isNull ( 2 ) ) { metadata . setLastIndexed ( cursor . getLong ( 2 ) ) ; } return metadata ; }


Input: Create the RTree extension for the feature table [CODESPLIT] public Extensions create ( ) { Extensions extension = null ; if ( ! has ( ) ) { extension = rTree . create ( featureDao . getTable ( ) ) ; if ( progress != null ) { progress . addProgress ( count ( ) ) ; } } return extension ; }


Input: Get the feature row from the RTree Index Table row [CODESPLIT] public FeatureRow getFeatureRow ( UserCustomCursor cursor ) { RTreeIndexTableRow row = getRow ( cursor ) ; return getFeatureRow ( row ) ; }


Input: Perform a raw query [CODESPLIT] public UserCustomCursor rawQuery ( String sql , String [ ] selectionArgs ) { validateRTree ( ) ; Cursor cursor = database . rawQuery ( sql , selectionArgs ) ; UserCustomCursor customCursor = new UserCustomCursor ( getTable ( ) , cursor ) ; return customCursor ; }


Input: { [CODESPLIT] @ Override public UserCustomCursor query ( String where , String [ ] whereArgs ) { StringBuilder query = new StringBuilder ( ) ; query . append ( "select * from " ) . append ( CoreSQLUtils . quoteWrap ( getTableName ( ) ) ) ; if ( where != null ) { query . append ( " where " ) . append ( where ) ; } String sql = query . toString ( ) ; UserCustomCursor customCursor = rawQuery ( sql , whereArgs ) ; return customCursor ; }


Input: { [CODESPLIT] @ Override public int count ( String where , String [ ] args ) { int count = 0 ; StringBuilder countQuery = new StringBuilder ( ) ; countQuery . append ( "select count(*) from " ) . append ( CoreSQLUtils . quoteWrap ( getTableName ( ) ) ) ; if ( where != null ) { countQuery . append ( " where " ) . append ( where ) ; } String sql = countQuery . toString ( ) ; UserCustomCursor customCursor = rawQuery ( sql , args ) ; Object value = ResultUtils . buildSingleResult ( customCursor , 0 , GeoPackageDataType . MEDIUMINT ) ; if ( value != null ) { count = ( ( Number ) value ) . intValue ( ) ; } return count ; }


Input: { [CODESPLIT] @ Override public BoundingBox getBoundingBox ( ) { BoundingBox boundingBox = null ; String sql = "SELECT MIN(" + RTreeIndexExtension . COLUMN_MIN_X + "), MIN(" + RTreeIndexExtension . COLUMN_MIN_Y + "), MAX(" + RTreeIndexExtension . COLUMN_MAX_X + "), MAX(" + RTreeIndexExtension . COLUMN_MAX_Y + ") FROM " + CoreSQLUtils . quoteWrap ( getTableName ( ) ) ; UserCustomCursor customCursor = rawQuery ( sql , null ) ; List < List < Object > > results = ResultUtils . buildResults ( customCursor , new GeoPackageDataType [ ] { GeoPackageDataType . DOUBLE , GeoPackageDataType . DOUBLE , GeoPackageDataType . DOUBLE , GeoPackageDataType . DOUBLE } , 1 ) ; if ( ! results . isEmpty ( ) ) { List < Object > resultRow = results . get ( 0 ) ; boundingBox = new BoundingBox ( ( Double ) resultRow . get ( 0 ) , ( Double ) resultRow . get ( 1 ) , ( Double ) resultRow . get ( 2 ) , ( Double ) resultRow . get ( 3 ) ) ; } return boundingBox ; }


Input: Query for rows within the bounding box in the provided projection [CODESPLIT] public UserCustomCursor query ( BoundingBox boundingBox , Projection projection ) { BoundingBox featureBoundingBox = projectBoundingBox ( boundingBox , projection ) ; return query ( featureBoundingBox ) ; }


Input: Query for rows within the geometry envelope [CODESPLIT] public UserCustomCursor query ( GeometryEnvelope envelope ) { return query ( envelope . getMinX ( ) , envelope . getMinY ( ) , envelope . getMaxX ( ) , envelope . getMaxY ( ) ) ; }


Input: Count the rows within the geometry envelope [CODESPLIT] public long count ( GeometryEnvelope envelope ) { return count ( envelope . getMinX ( ) , envelope . getMinY ( ) , envelope . getMaxX ( ) , envelope . getMaxY ( ) ) ; }


Input: Query for rows within the bounds [CODESPLIT] public UserCustomCursor query ( double minX , double minY , double maxX , double maxY ) { String where = buildWhere ( minX , minY , maxX , maxY ) ; String [ ] whereArgs = buildWhereArgs ( minX , minY , maxX , maxY ) ; return query ( where , whereArgs ) ; }


Input: Build a where clause from the bounds for overlapping ranges [CODESPLIT] private String buildWhere ( double minX , double minY , double maxX , double maxY ) { StringBuilder where = new StringBuilder ( ) ; where . append ( buildWhere ( RTreeIndexExtension . COLUMN_MIN_X , maxX , "<=" ) ) ; where . append ( " AND " ) ; where . append ( buildWhere ( RTreeIndexExtension . COLUMN_MIN_Y , maxY , "<=" ) ) ; where . append ( " AND " ) ; where . append ( buildWhere ( RTreeIndexExtension . COLUMN_MAX_X , minX , ">=" ) ) ; where . append ( " AND " ) ; where . append ( buildWhere ( RTreeIndexExtension . COLUMN_MAX_Y , minY , ">=" ) ) ; return where . toString ( ) ; }


Input: Build where arguments from the bounds to match the order in { @link #buildWhereArgs ( double double double double ) } [CODESPLIT] private String [ ] buildWhereArgs ( double minX , double minY , double maxX , double maxY ) { minX -= tolerance ; maxX += tolerance ; minY -= tolerance ; maxY += tolerance ; return buildWhereArgs ( new Object [ ] { maxX , maxY , minX , minY } ) ; }


Input: Manually query for rows within the bounding box in the provided projection [CODESPLIT] public ManualFeatureQueryResults query ( BoundingBox boundingBox , Projection projection ) { BoundingBox featureBoundingBox = featureDao . projectBoundingBox ( boundingBox , projection ) ; return query ( featureBoundingBox ) ; }