Mittwoch, 9. September 2015

NEW Android-Plugin version + Archetype Update

Today I am very glad to announce the update of BARACUS maven archetype. Now it uses the simpligility android-maven-plugin, which is the successor of the deprecated jayway plugin.

The new archetype is compliant to the required structure of the new plugin version.

To create a new BARACUS based project, mvn archetype:generate your app and simply follow the steps-to-perform-section here

IntelliJ users please keep in mind to modifiy the project structure after creating the project or after migrating to the new plugin version:




HOW TO MIGRATE AN EXISTING PROJECT


  1. in pom.xml, set android.plugin.version to 4.3.0
  2. in pom.xml, change (both plugin-management and plugins) android plugin group IDs to com.simpligility.maven.plugins
  3. move res folder to src/main/res
  4. move AndroidManifest.xml to /src/main/AndroidManifest.xml
  5. if you have assets, do the same
  6. eventually move your native libs too (I don't have any ones, so I can't tell you)
Finally, if you use IntelliJ IDEA, alter the project structure as shown above.

Have Fun,
MNT

Sonntag, 21. Juni 2015

BARACUS 0.9.1 has been released!

Today I am very glad to announce the release of BARACUS 0.9.1.

It contains some bugfixes, and now enables the user to have ManagedActivities stable after a device rotate; the device caused android 4 to have an internal construction call which had to be tangled with the bean container. Now the ManagedActivity will be able to survive a device rotation by reinjecting all beans.

Also, I added a macro call to simplify yes-no-requester handling a little bit.

Finally, I added the capability to deregister a delete callback safely.



To use the current apklib (in your Android application module), simply use the dependency


        <dependency>
            <groupId>org.baracus</groupId>
            <artifactId>baracus-framework</artifactId>
            <version>0.9.1</version>
            <type>apklib</type>
        </dependency>

... as usual.

The sourcecode has been branched here - the javadocs can be found here



Regards,
MNT

Samstag, 21. März 2015

BARACUS has been successfully tested under ANDROID 5.1

I am glad to announce that the BARACUS reference application, another BARACUS based customer application and one of my own applications using the full BARACUS feature set have been successfully deployed and tested on an Android 5.1 device. There should be no known issues with the latest Android version. Please report any discoveries to the BARACUS forum on G+. Have fun! MNT

Freitag, 13. März 2015

BARACUS Release 0.9 -The namespace flip

Today I am glad to announce the release of BARACUS version 0.9.
You can obtain the libary by adding these maven coordinates to the project

<dependency>
<groupid>org.baracus</groupid>
<artifactid>baracus-framework</artifactid>
<version>0.9</version>
<type>apklib</type>
</dependency>


VERSION 0.9

This release is dominated by the change of the BARACUS namespace from net.mantucon.baracus to org.baracus. The change can be easily performed by replacing all references plus altering the framework version - with IntelliJ IDEA it took me 10 minutes to migrate the entire project to the new namespace.

Simply replace all occurences of

import net.mantucon.baracus

by

import org.baracus

and all static imports

import static net.mantucon.baracus.

by

import static org.baracus.

In case that you are using ConstrainedText-Elements, you also must alter all layout XMLs.

The maven archetype already is using the new packages so you can create BARACUS based applications easily using  mvn generate:archetype (see this article for details)

Within the next weeks I will upgrade all tutorials and sample applications to use the new BARACUS namespaces.

Regards,
MNT





Dienstag, 10. März 2015

BARACUS now backed by Crowdcode

I am very pleased to announce, that the Crowdcode company will now back the BARACUS project. My company MANTUCON has dissolved in Crowdcode GmbH & Co. KG (I only will continue to perform trainings under the MANTUCON label).

We are more people with a larger range of contacts and better capabilities to keep this framework alive and maintained.

Also, I announce hereby to modify the package domains of the framework. I mischose them to run onder net.mantucon.baracus - despite this is an open source framework hosted and published under baracus.org.

This will be subject of change within the next minor release or the when we will ascend to the 1.0 milestone :)

So be prepared to refactor your applications (net.mantucon.baracus -> org.baracus - that's all) in near future!

Cheers,
MNT


Sonntag, 12. Oktober 2014

BARACUS from Scratch - Part 9 - Using interface and implementations & context bootstrap


Table of Contents

In this tutorial I am going to explain You how to use the BARACUS framework to work with alternative Implementations of an Interface plus hot-restarting the context to make use of them. Also, I will demonstrate the afterContextInitialized hook which enables You to perform post-container-startup operations.

Previous Tutorial : Lifecycle support with migr8

You can download the sources of this tutorial here

0 - Basics


Since Version 0.8, Baracus offers the capability to register an implementation to an interface. This can be very useful in combination with the bootstrap feature (reinitialize context), because it allows You to switch between several application varieties using different implementations of the interface. The registration is simply an alternative call on BaracusApplicationContext.registerBeanClass.

For this example, we will define a BankAccountLoadService, which we are going to wire twice to the BankAccountDao, logging each call on it.

1 - Defining the interface


Simply define the interface in the service package :


 
public interface BankAccountLoadService {

    List<BankAccount> loadAllAccountsByCustomerId(Long id);

}



2 - Implement the interface 


Next, we implement the interface :

 
public class BankAccountLoadServiceImpl1 implements BankAccountLoadService {



    @Bean
    BankAccountDao bankAccountDao;

    final Logger logger = new Logger(this.getClass());

    @Override
    public List<BankAccount> loadAllAccountsByCustomerId(Long id) {
        // In this demo, this is the primary implementation
        logger.info("Primary implementation called!");
        return bankAccountDao.getByCustomerId(id);

    }

}


3 - Implement the alternative (dummy here)


Then we implement an alternative; this could be a test class, a webservice or whatever. Interface implementations also can be used to improve testability.

 
/**
 * Created by marcus on 30.07.14.
 */
public class BankAccountLoadServiceImpl2 implements BankAccountLoadService {

    @Bean
    BankAccountDao bankAccountDao;

    final Logger logger = new Logger(this.getClass());

    @Override
    public List<BankAccount> loadAllAccountsByCustomerId(Long id) {
        // In this demo, this is the alternative implementation
        logger.info("Alternative implementation called!");
        return bankAccountDao.getByCustomerId(id);
    }
}


4 - Register interface


The interface now is used to register the implementation

 
public class ApplicationContext extends BaracusApplicationContext {

    static {
        ....

        registerBeanClass(BankAccountLoadService.class, BankAccountLoadServiceImpl1.class);

    }
}


This enables the Baracus DI container to inject the implementation wherever the interface is used.


5 - Use interface for injection


Then we will pimp the RowMapper to use the implementation :

public class CustomerDao extends BaseDao<Customer> {



    @Bean

    BankAccountLoadService bankAccountLoadService;

 

...



    private final RowMapper<Customer> rowMapper = new RowMapper<Customer>() {

        @Override

        public Customer from(Cursor c) {



  ....

  

         result.setAccounts(new LazyCollection<BankAccount>(new LazyCollection.LazyLoader<BankAccount>() {

                @Override

                public List<BankAccount> loadReference() {

                    return bankAccountLoadService.loadAllAccountsByCustomerId(id);

                }

            }));



That's all. Now we are able to use the Interface for DI. But that's not all, right? We want to make use of the ability to switch the implementation. Therefore, we will implement a ApplicationContextInitializer setting the Implementation "by random" - just for demonstration purpose. Since the decision, which implementation shall be used only happens on the boot of the app, we use a small semaphore to avoid permanent reinit. Imagine a basic context, you define and then, by configuration data (e.g. thru built-in configurationDao) you decide wether to build a thin client or a fat client - that is the one of the purposes of this class.

public class AfterContextInitialized implements ApplicationContextInitializer {

    static boolean reinit = true;

    @Override
    public void afterContextIsBuilt() {
        if ((new Date().getTime() % 2 ) == 0) {
            ApplicationContext.registerBeanClass(BankAccountLoadService.class, BankAccountLoadServiceImpl1.class);
        } else {
            ApplicationContext.registerBeanClass(BankAccountLoadService.class, BankAccountLoadServiceImpl2.class);
        }
        if (reinit) {
            reinit = false;
            ApplicationContext.reinitializeContext();;
        }
    }
}


This initializer also is registered in the application config :

public class ApplicationContext extends BaracusApplicationContext {

        static { 
          ....
          setApplicationContextInitializer(new AfterContextInitialized());
        }
}


That's it, now You can check by restarting the app several time, which implementation is used by checking the logs when expanding the customer details:

07-30 14:56:51.531    5316-5316/org.baracustutorial I/TUTORIAL_APP﹕ -BankAccountLoadServiceImpl1 Primary implementation called!

other try :

07-30 15:00:55.639    8815-8815/org.baracustutorial I/TUTORIAL_APP﹕ BankAccountLoadServiceImpl2 Alternative implementation called!


Conclusion :


As You can see, the implementation of alternatives can be used - in combination with configuration information - as a very powerful utility to create varying types of implementations / behaviour within the same codebase. The classic can be a client to be run locally using the local dao as a data service or a thin client pipelining all requests thru json requests on a remote system.

Also, it can be very useful to make the software more testable.

Next Tutorial :Writing custom validators




Montag, 6. Oktober 2014

BARACUS from Scratch - Part 10 - Writing custom validators

Table of Contents

Previous Tutorial :Using interfaces & implementations

You can download the sourcecode for this demo here

In this tutorial I will explain you how create custom validation objects to be used within your application. This enables you to have your application shipped with customized validators to fit your personal needs. This tutorial is basing on the FormValidation-Tutorial I published earlier.

Step 1 - Define validator


We want to add a constraint for defining names to our software. A name must start with a capital one letter and continue with zero or more small caps letters. This can be achieved by matching this java regex pattern [A-Z]+[a-z]*. So at first, we will define the constraint message plus the class:

strings.xml:

    <string name="nameViolation">Bad string format. Must be lowercase with starting capital letter</string>


public class NameValidator extends AbstractValidator<String>{



    static final String pattern = "[A-Z]+[a-z]*"; // Will allow John but neither JOHN nor john



    @Override

    public boolean validate(ConstrainedView<String> view) {

        return view.getCurrentValue().matches(pattern);

    }



    @Override

    public int getMessageId() {

        return R.string.nameViolation;

    }

}



Step 2 - Register validator


You must register the validator by-name in order to be able to use it. The ValidationRegistry internally used in the BARACUS framework is a managed bean which registers the validators in a postConstruct method. But since this validator is a more or less invariant item, we will add it to the context after the context has been built. This is necessary since the ValidationFactory has not been setup in the Context-initialization phase.

In a prior tutorial we have created an after-context-init trigger (AfterContextInitialized). This is the correct place to add the validator to the registry because in the ApplicationContext's init phase the internal ValidationFactory (which is also a bean) still is null.

So we add the validator to the context :

public class AfterContextInitialized implements ApplicationContextInitializer {

    ...

    @Override

    public void afterContextIsBuilt() {

        if (reinit) {

            ...

            ApplicationContext.registerValidator(new NameValidator());



        }

    }

}



Step 3 - Wire the validator


We are almost done. You simply have to wire the validator by-name inside the desired layout xml file. In our case, we want to have this validator added to the existing validator in the customer_editor.xml :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              xmlns:app="http://schemas.android.com/apk/res-auto"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

    ...

    <net.mantucon.baracus.ui.ConstrainedEditText android:id="@+id/txtCustomerFirstName"

                                                 android:layout_width="fill_parent"

                                                 android:layout_height="wrap_content"

                                                 app:validatedBy="stringNotEmpty,nameValidator"

            />

    ...

    <net.mantucon.baracus.ui.ConstrainedEditText android:id="@+id/txtCustomerLastName"

                                                 android:layout_width="fill_parent"

                                                 android:layout_height="wrap_content"

                                                 app:validatedBy="stringNotEmpty,nameValidator"

            />

    ...

</LinearLayout>


The validators are applied in the direction you add them to the list.

Conclusion


Writing custom validators is easy. They make the app design more easy and efficient and allow you to have very specific rules beeing applied to user's form data. But that's not all. You even can have more sophisticated constraints; since you can access any bean through your ApplicationContest statically you even can have database driven checks.

Next Tutorial : Advanced Logging (coming up)