Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, May 11, 2016

How to define build strategies in your android app over BuildConfig

Hi there!

Today i'm gonna show you, how your could define your build strategies in android studio in an elegant, enhanceable way using the strategy design pattern.

Most of the times, Google defines its product making usage of best practises and good, enhanceable design pattern. I saw recently, in a big project we got, that they were not taking advantage of this and instead of that, they were using enumerations, resulting in a bunch of switch cases and later on another bunch of if-else cases and a lot of repeated code that breaks the DRY-principle and even more important the open-close-principle.

What does it mean to be programming respecting the open-close-principle? It means that every time a new component is created, that i don't have to change running code. i.e. I don't have to create another enum type, another switch-case to identify this type and later on another if-else case to know, depending on the comparation result, what kind of environment i want to set.

That's the code we got. This code has a lot of problems. It is fragile. Every new environment forces you to change a chain of steps in the code. Further it forces you to hold 4 variables in a static way to be able to share it over the application instead of hold only one object responsible for that. We define new enum types and define a new if statement running the risk of breaking existing logic. All of this can be avoided using the strategy pattern.

Let's take a look at the actual code, before enhancing it to visualize the problems:

    // somewhere in code this method was called passing the enum defined in BuildConfig
    setEnvironmentKeys(BuildConfig.ENVIRONMENT);
    // later in the class who defined this method over if-statements we identify the environment
    public static void setEnvironmentKeys(ENV env){
        try{
         if (MainApplication.isProduction()) {
                CONTENT_SERVER_URL = "https://content.mycompany.com/";
                PROFILE_SERVER_URL = "https://profile.mycompany.com/";
                IMAGE_SERVER_URL = "https://image.mycompany.com/log";
                Utils.GOOGLE_DEVELOPER_KEY = Utils.getStringRes(R.string.key_production);
            } else if (env == MainApplication.ENV.STAGING) {
                CONTENT_SERVER_URL = "http://content-staging.mycompany.com/";
                PROFILE_SERVER_URL = "http://profile-staging.mycompany.com/";
                IMAGE_SERVER_URL = "http://image.staging.maycompany.com/";
                Utils.GOOGLE_DEVELOPER_KEY = Utils.getStringRes(R.string.key_staging);
            }  else if (env == MainApplication.ENV.STAGING_TWO) {
                Utils.GOOGLE_DEVELOPER_KEY = Utils.getStringRes(R.string.key_staging);
                CONTENT_SERVER_URL = "http://content-staging2.mycompany.com/";
                PROFILE_SERVER_URL = "http://profile-staging2.mycompany.com/";
                IMAGE_SERVER_URL = "http://image.staging2.mycompany.com/";
            }else if (MainApplication.isDev()) {
                Utils.GOOGLE_DEVELOPER_KEY = Utils.getStringRes(R.string.key_development);
                CONTENT_SERVER_URL = "https://content.dev.mycompany.com/";
                PROFILE_SERVER_URL = "https://profile.dev.mycompany.com/";
                IMAGE_SERVER_URL = "https://image.dev.mycompany.com/";
            }
        }catch(Exception e){
            Log.wtf(TAG, "Couldn't set ENV variables. Setting to Production as default.");
        }
    }
    
    // and somewhere was defined the enum with the build types
    public enum ENV {
        DEVELOPMENT("DEVELOPMENT"),
        STAGING("STAGING"),
        STAGING_TWO("STAGING_TWO"),
        OPS_PREVIEW("OPS_PREVIEW"),
        PRODUCTION("PRODUCTION"), ;

        private final String name;

        private ENV(String s) {
            name = s;
        }

        public boolean equalsName(String otherName){
            return (otherName == null)? false:name.equals(otherName);
        }

        public String toString(){
            return name;
        }

    }

The code above is functional but when it comes to enhancement, maintainability and so on, then we can see some problems on that. We will discuss this later on. Let's now see how we could do it better by using the strategy pattern. First have a look at the uml diagram of it.



And now the little code of if:

   
  // this method is called somewhere in code
  setEnvironment(BuildConfig.ENVIRONMENT);
  
  // then we set the environment and use it without any change in code
  private Environment environment;
  public void setEnvironment(final Environment env){
   environment = env;
  }
  /**
   * In your android studio look for the tab: "Build Variants" (bottom left side)
   * and select "Build Variant > debug" while developing the application.
   * This will automatically instantiate this class and assign this value to BuildConfig.ENVIRONMENT
   * @author Ricardo Ferreira
   */
  public class DeveloperEnvironment extends Environment{
   private final static String CONTENT_SERVER_URL = "https://content.dev.mycompany.com/";
   private final static String PROFILE_SERVER_URL = "https://profile.dev.mycompany.com/";
   private final static String S3_AMAZON_SERVER_URL = "https://s3.amazon.dev.mycompany.com";
   private final static String GOOGLE_DEVELOPER_KEY = "123456";
   public DeveloperEnvironment() {
    super(CONTENT_SERVER_URL, PROFILE_SERVER_URL, S3_AMAZON_SERVER_URL, GOOGLE_DEVELOPER_KEY);
   }
  }
  /**
   * Build environment strategy - Every environment phase should extend from this strategy.
   * This way, you can access your app's environment configuration over the system class 
   * BuildConfig.ENVIRONMENT everywhere without the necessity of enumerations, switch cases 
   * or a bunch of if-else statements. If you create new environments, no change in your code
   * will be needed. 
   * @author Ricardo Ferreira
   */
  public abstract class Environment{
   private final String CONTENT_SERVER_URL;
   private final String PROFILE_SERVER_URL;
   private final String S3_AMAZON_SERVER_URL;
   private final String GOOGLE_DEVELOPER_KEY;
   // ... other environment variables ...
 public Environment(
   final String contentServerUrl, 
   final String profileServerUrl,
   final String s3amazonServerUrl, 
   final String googleDeveloperKey) {
  super();
  this.CONTENT_SERVER_URL = contentServerUrl;
  this.PROFILE_SERVER_URL = profileServerUrl;
  this.S3_AMAZON_SERVER_URL = s3amazonServerUrl;
  this.GOOGLE_DEVELOPER_KEY = googleDeveloperKey;
 }
 public String getContentServerUrl() {
  return CONTENT_SERVER_URL;
 }
 public String getProfileServerUrl() {
  return PROFILE_SERVER_URL;
 }
 public String getS3AmazonServerUrl() {
  return S3_AMAZON_SERVER_URL;
 }
 public String getGoogleDeveloperKey() {
  return GOOGLE_DEVELOPER_KEY;
 }
  }

Coming back to our initial discussion. Imagine now you need to add a new enviromnet. lets say staging. with the approach above you just have to say to someone: create a class who extends from environment, analogical DeveloperEnvironment, define it in your build.gradle, like you would do for the other approach also and done! It would work just fine without touching already written, functional code.The other way around you would have to change the enum, change the if-else statements.

Here is how you could define the strategies in your build.gradle. This will automatically assign the right value to the variable ENVIRONMENT depending on which environment you choose over Android Studio by selecting the tab Build Variants on the bottom left side of your IDE:

buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            debuggable true
            setApplicationIdSuffix("dev")
            versionNameSuffix " Dev"
            buildConfigField "com.treslines.learn.environment.Environment", "ENVIRONMENT", "new com.treslines.learn.environment.DeveloperEnvironment()"
            buildConfigField "boolean", "DEBUGLOG", "true"
            manifestPlaceholders = [
                    appName         : "MyApp Debug"
            ]
        }
        Staging {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
            debuggable true
            setApplicationIdSuffix("staging")
            versionNameSuffix " Staging"
            buildConfigField "com.treslines.learn.environment.Environment", "ENVIRONMENT", "new com.treslines.learn.environment.StagingEnrivornment()"
            buildConfigField "boolean", "DEBUGLOG", "true"
            manifestPlaceholders = [
                    appName         : "MyApp Stg"
            ]
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            zipAlignEnabled true

            buildConfigField "com.treslines.learn.environment.Environment", "ENVIRONMENT", "new com.treslines.learn.environment.ProductionEnrivornment()"
            buildConfigField "boolean", "DEBUGLOG", "false"
        }
    } 

That's all! hope you like it! :)

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Tuesday, March 15, 2016

Fast CPF formatter to be used in Android's EditText View combined with a TextWatcher

Hi there! Today i'm gonna show to you, how i solved a common problem, while dealing with brazilian cpf in edittext view in android studio.

Problem/Chalange: Mask a CPF editText field such a way, that as soon as the user starts typing digits in it, the text field inserts or updates its needed signs for the user automatically.

The first solution was very elegant and well thought and well done with a mask like ###.###.###-## but as soon as the user starts typing very fast in the text field, the mask algorithm was very slow and swallowed some digits in some cases.

For this reason, i took the chalange to myself and decided to create my own, fast cpf formatter. Bellow the solution that solved the problem and that you may use in your apps as you may need.

Solution:


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new CpfWatcher((EditText) findViewById(R.id.inputCpf));

    }

    public class CpfWatcher implements TextWatcher {

        private EditText inputField;
        private int flag = 0;
        private int signsBeforeChange = 0;
        private int dots = 0;
        private int dash = 0;
        private String txtBeforeChange;

        public CpfWatcher(final EditText inputField) {
            this.inputField = inputField;
            this.inputField.setInputType(InputType.TYPE_CLASS_NUMBER);
            this.inputField.setHint("###.###.###-##");
            this.inputField.addTextChangedListener(this);
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            final String input = s.toString();
            inputField.removeTextChangedListener(this);
            final String formattedCpf = formatCpf(input);
            inputField.setText(formattedCpf);
            inputField.addTextChangedListener(this);
            placeCursorDependingOnUserAction(start, formattedCpf, findOutIfUserWasTypingOrDeleting(input));
        }

        private void placeCursorDependingOnUserAction(int start, String formattedCpf, Action action) {
            switch (action){
                case TYPING:{
                    dots = formattedCpf.length() - formattedCpf.replace(".", "").length();
                    dash = formattedCpf.length() - formattedCpf.replace("-", "").length();
                    signsBeforeChange = dots+dash;
                    inputField.setSelection(formattedCpf.length());
                    break;
                }
                case DELETING:{

                    if(start-1 < 0){
                        inputField.setSelection(0);
                    }else if(txtBeforeChange.equalsIgnoreCase(formattedCpf)){
                        inputField.setSelection( start );
                        flag++;
                    }
                    else{
                        dots = formattedCpf.length() - formattedCpf.replace(".", "").length();
                        dash = formattedCpf.length() - formattedCpf.replace("-", "").length();
                        int sigsAfterChange = dots+dash;
                        if(signsBeforeChange > sigsAfterChange){
                            inputField.setSelection( start-1 );
                            signsBeforeChange = sigsAfterChange;
                        }else{
                            inputField.setSelection( start );
                        }
                    }
                    break;
                }
            }
        }

        private Action findOutIfUserWasTypingOrDeleting(String input) {
            Action action = Action.TYPING;
            if(flag <=input.length()){
                flag = input.length();
                action = Action.TYPING;
            }else{
                flag = input.length();
                action = Action.DELETING;
            }
            return action;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            txtBeforeChange = s.toString();
        }

        @Override
        public void afterTextChanged(Editable s) { /* NOP*/ }

        public  Editable getCpf(){
           return inputField.getText();
        }

    }

    public enum Action {
        TYPING, DELETING
    }

    private String formatCpf(String cpf) {
        String[] sign = new String[]{".", ".", "-"};
        String[] signRegEx = new String[]{"\\.", "\\.", "-"};
        int[] signPos = new int[]{4, 8, 12};
        return formatCpfDependingOnLentgh(sign, signPos, removeAllSigns(cpf, signRegEx));
    }

    private String removeAllSigns(String cpf, String[] signRegEx) {
        String empty = "";
        String tmp = cpf;
        for (String sign : signRegEx) {
            tmp = tmp.replaceAll(sign, empty);
        }
        return tmp;
    }

    private String formatCpfDependingOnLentgh(String[] sign, int[] signPos, String cpfWithoutAnySign) {
        String tmp = cpfWithoutAnySign;
        int aLentgh = tmp.length();
        if (aLentgh <= signPos[0] - 1) {
            // nothing to format
        }else if(aLentgh == signPos[0]-1) {
            tmp = create1Punctuation(tmp, sign);
        }
        else if (aLentgh > signPos[0] - 1 && aLentgh < signPos[1] - 1) {
            tmp = create2Punctuations(tmp, sign);
        }
        else if (aLentgh == signPos[1] - 1) {
            tmp = create3Punctuations(tmp, sign);
        }
        else if (aLentgh > signPos[1] - 1 && aLentgh < signPos[2] - 2) {
            tmp = create3Punctuations(tmp, sign);
        }
        else if (aLentgh == signPos[2] - 2) {
            tmp = create4Punctuations(tmp, sign);
        }
        else if (aLentgh > signPos[2] - 2 && aLentgh < signPos[2]) {
            tmp = create4Punctuations(tmp, sign);
        } else {
            tmp = trunk4Punctuations(tmp, sign);
        }
        return tmp;
    }

    private String create1Punctuation(String tmp, String[] punc) {
        return tmp + punc[0];
    }

    private String create2Punctuations(String tmp, String[] punc) {
        String s1 = tmp.substring(0, 3);
        String s2 = tmp.substring(3, tmp.length());
        return s1 + punc[0] + s2;
    }

    private String create3Punctuations(String tmp, String[] punc) {
        String s1 = tmp.substring(0, 3);
        String s2 = tmp.substring(3, 6);
        String s3 = tmp.substring(6, tmp.length());
        return s1 + punc[0] + s2 + punc[1] + s3;
    }

    private String create4Punctuations(String tmp, String[] punc) {
        String s1 = tmp.substring(0, 3);
        String s2 = tmp.substring(3, 6);
        String s3 = tmp.substring(6, 9);
        String s4 = tmp.substring(9, tmp.length());
        return s1 + punc[0] + s2 + punc[1] + s3 + punc[2] + s4;
    }

    private String trunk4Punctuations(String tmp, String[] punc) {
        String s1 = tmp.substring(0, 3);
        String s2 = tmp.substring(3, 6);
        String s3 = tmp.substring(6, 9);
        String s4 = tmp.substring(9, 11);
        return s1 + punc[0] + s2 + punc[1] + s3 + punc[2] + s4;
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Tuesday, January 19, 2016

How to create REST web services in pure java as easy as with node.js - This is so beautiful!!!

Hi there!

Today i'm gonna show you how to create REST web services as fast and as simple as with node.js, but with PURE java!!! Yes!!!! it is possible and so beautiful and clean :) I love it and i am sure you'll love it too, if you love java like i do. ;)

Now a days everybody is using and speaking from node.js, javascript, angular, ruby, etc. There are so many "frameworks" to do "more or less" the same thing, that i was wondering me, if there was nothing to help the java-community with. And yessssss...... there is! :)

Putting things together and inspired by the post of "creating REST api quickly using java" i decided to give them a try and create a more detailed post of it. It works so fine and nice that i must share it with you!

Technologies involved


  • We will be using SparkJava which is a tiny, compact framework, designed to develop web applications with minimal effort.
  • To create DAO's out of the box and manipulate database as easy as like stealing candy from a babies... :) we will use ormlite jdbc for java. Another great tool i love.
  • As a database we will use MySQL. 


Don't worry, we will see how to add those tools to your project in a few minutes step by step. There is no mystery using it.

Creating a maven project

With your IDE, i use eclipse Enide 2015, Version: Mars Release (4.5.0), Build id: Nodeclipse-20150706-0921 in this example, create a simple maven project like that:





Open the pom.xml and insert the following code to get the jars from spark, ormlite and mysql-connector:

<!-- library dependencies -->
<dependencies>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-jdbc</artifactId>
<version>4.48</version>
</dependency>


<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>

Defining an Entity User

Well, now we are fine to start with our service. Let's define first an user class. Use the code snippet bellow:

package com.companyname.modulename.server.model;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
 
@DatabaseTable(tableName = "users")
public class User {
    
    @DatabaseField(generatedId = true)
    private int id;
    
    @DatabaseField
    private String username;
    
    @DatabaseField
    private String email;
    
    public User() {
        // ORMLite needs a no-arg constructor 
    }
    
    public int getId() {
        return this.id;
    }
    
    public String getUsername() {    
        return this.username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
}

Defining the Server with the services inside

Now to the cool things. :) Let's define a GET and POST method to insert and retrieve data from the database.

package com.companyname.modulename.server;

import static spark.Spark.get;
import static spark.Spark.post;

import java.sql.SQLException;

import com.companyname.modulename.server.model.User;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

import spark.Request;
import spark.Response;
import spark.Route;

public class Server {

 private static Dao userDao;
 // other DAO's my be defined here...

 // TUTORIAL EXECUTION DATE: 18/01/2016
 // IMPORTANT: Before runnning this class: make sure your mysql server is running
 //
 // Run as > Java Application... Than you should see a message similar to
 // that bellow:
 //
 // [Thread-0] INFO spark.webserver.SparkServer - == Spark has ignited ...
 // [Thread-0] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:4567
 // [Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.0.2.v20130417
 // [Thread-0] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@6255aad1{HTTP/1.1}{0.0.0.0:4567}
 // [qtp1296900317-19] INFO spark.webserver.MatcherFilter - The requested route [/favicon.ico] has not been mapped in Spark
 
 
 // In your Browser type in: http://localhost:4567/users/1
 // than you should see: User: username=test, [email protected]
 public static void main(String[] args) throws SQLException {
  initMySQL();

  // define the http action methods here...
  // get sample: http://localhost:4567/users/1
  get("/users/:id", new Route() {
   public Object handle(Request req, Response res) throws Exception {
    final User user = userDao.queryForId(req.params(":id"));
    if (user != null) {
     return "Username: " + user.getUsername(); // or JSON? :-)
    } else {
     final int httpNotFound = 404;
     final String msg = "User not found";
     res.status(httpNotFound); 
     return msg;
    }
   }
  });

  // post sample: (using postman)
  // http://localhost:4567/users?username=ricardo&[email protected]
  post("/users", new Route() {
   public Object handle(Request request, Response response) throws SQLException {
    final String username = request.queryParams("username");
    final String email = request.queryParams("email");

    final User user = new User();
    user.setUsername(username);
    user.setEmail(email);

    final int createdUserId = userDao.create(user);
    final int httpCreated = 201;
    response.status(httpCreated);
    return createdUserId;
   }
  });
 }

 // make sure your mysql server is running, than:
 // connect and start to previously created MySQL database called spark
 // with username: root and password: 123456
 private static void initMySQL() throws SQLException {
  final String databaseUrl = "jdbc:mysql://localhost/spark";
  final ConnectionSource connectionSource = new JdbcConnectionSource(databaseUrl);
  ((JdbcConnectionSource) connectionSource).setUsername("root");
  ((JdbcConnectionSource) connectionSource).setPassword("123456");
  // creates tables and DAO's to be used in GET/POST or whatever 
  // you may define in main method
  createTablesIfNotExitsAlready(connectionSource);
  initDAOs(connectionSource);
 }

 private static void createTablesIfNotExitsAlready(final ConnectionSource connectionSource) throws SQLException {
  TableUtils.createTableIfNotExists(connectionSource, User.class);
  // other tables may be defined here...
 }

 private static void initDAOs(final ConnectionSource connectionSource) throws SQLException {
  userDao = DaoManager.createDao(connectionSource, User.class);
  // other DAO's may be defined here...
 }

}


Creating the database

Just one more thing! :) Before you can run this, make sure you have created the database called spark with user root and password 123456. To do so, under linux, first install the mysql server by typing this line in your terminal: (to open a terminal press Ctrl+Alt+T)

  • sudo apt-get install mysql-server


When the installer prompts the window to define the password for the root user, type 123456 and complete the installation.

Creating the Table User with MySQL Workbench

That is a nice exercise. I was not used to it, and that's way i'm showing it here also. Download it and double click it to install from here https://dev.mysql.com/downloads/workbench/ Once you are done with, start it and create a new db called spark like that:

Once you've opened it, there should be a connection available. This is the connection you've previously installed. Double click it and connect with your credentials. root and 123456


Than this window will open. Here create a new schema called spark and inside of it, create a table called User with id, username and email like shown bellow(the record there will not appear yet, be patient :)


Lets play with now!

Ok, now we are fine. Note that we have not written much code. Most of the work was infrastructure. Real code there is almost nothing. Ormlite abstracts table creation, manipulation and so on. Spark defines urls and http actions. Ok, if everything went well, you should be able to run the Server.class as Java Application. You should see the following statement in the console(which means your server is running well and the service is listening to it on port 4567):

[main] INFO com.j256.ormlite.table.TableUtils - creating table 'users'
[main] INFO com.j256.ormlite.table.TableUtils - executed create table statement changed 0 rows: CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER AUTO_INCREMENT , `username` VARCHAR(255) , `email` VARCHAR(255) , PRIMARY KEY (`id`) ) ENGINE=InnoDB 
[Thread-0] INFO spark.webserver.SparkServer - == Spark has ignited ...
[Thread-0] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:4567
[Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.0.2.v20130417
[Thread-0] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@2695c365{HTTP/1.1}{0.0.0.0:4567}

Testing the service

Well, now we should be able to test our services. Lets POST something using postman.



After that, try to execute a GET to retrieve the previous inserted data.


You could also check the data in the database by running this command line:
SELECT * FROM spark.users; You should see the record now:


That's all! hope you like it! :)


😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†


Thursday, August 20, 2015

How to run/install pagseguro on android without thirdpart apps

Hi there!

Today i'm gonna show to you, how to run PagSeguro on Android Apps without any third part app from PagSeguro.

Everybody knows how important it is to offer payment methods in our apps. PagSeguro is a very common payment method in Brazil, but very tricky to get it run correctly on android apps. In fact almost every payment method is very annoying to implement! :)

For this reason I decided to implement my own PagSeguro solution and share a complete sample with the world.

First Step - Get a PagSeguro Account

To do so, register yourself on pagseguro, log in and go to: Vender > Ferramentas para desenvolvedores > Sandbox



There you'll find a automatic created test buyer (comprador de teste) and a test seller (vendedor de teste) like in the images bellow. kepp it open, then you'll need those values in the app we will see here.




Second Step - Fork or just download the sample from Github

The sample was developed using android studio and tested on my pagseguro sandbox account. It is available from here: https://github.com/treslines/pagseguro_android. The image bellow shows some transactions i made using my sandbox account:


What you'll get?

The pictures bellow show how the app looks like. It addresses already navigations issues e user notifications.
















Go download it!

Go now to github: https://github.com/treslines/pagseguro_android. download it and test it. Any feedback or contribution to make it better is welcome!

That's all! Hope you like it!

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Thursday, August 13, 2015

Android AlertDialog utilities, redirect to google play store, check if third part app is istalled

Hi there!

Today i'm gonna share some utility methods i use very often while developing. Creating a popup dialog, a confirm dialog, ok-cancel-dialog, check if a third part app is installed, redirect to google play store if some app is missing and so on are common tasks in our daily business.

/**
 * Use this class to create alert dialogs on the fly, redirect to google play store and so on...< br / >
 * < br / >Author: Ricardo Ferreira, 8/13/15
 */
public final class AppUtil {

    /**
     * Shows a confirm dialog with a custom message and custom quit button text.
     * If you pass null to btnTxt, "ok" will be shown per default.
     *
     * @param context the apps context This value can't be null.
     * @param msg     the message to be shown. his value can't be null or empty.
     * @param btnTxt  the text to be shown in the quit button. For example "close"
     */
    public static void showConfirmDialog(@NonNull final Context context, @NonNull final String msg, final String btnTxt) {
        if (msg.isEmpty()) {
            throw new IllegalArgumentException("This value can't be empty!");
        }
        final AlertDialog dialog = new AlertDialog.Builder(context).setMessage(msg)
                .setPositiveButton((btnTxt == null ? "Ok" : btnTxt), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).create();
        dialog.show();
    }

    /**
     * Shows a confirm dialog with a custom message, custom buttons and custom actions.
     *
     * @param ctx                the apps context. This value can't be null.
     * @param msg                the message to be shown This value can't be null or empty.
     * @param okBtn              the text to be shown in the ok button. If you pass null, ok will be shown per default
     * @param cancelBtn          the text to be shown in the cancel button. If you pass null, cancel will be shown per default
     * @param okAction           the action to be performed as soon as the user presses the ok button. if you pass null, nothing happens.
     * @param cancelAction       the action to be performed as soon as the user presses the cancel button. if you pass null, nothing happens.
     * @param backPressendAction the action to be performed as soon as the user presses the system back button. if you pass null, nothing happens.
     */
    public static void showOkCancelDialog(@NonNull final Context ctx, @NonNull final String msg, final String okBtn, final String cancelBtn, final AlertAction okAction, final AlertAction cancelAction, final AlertAction backPressendAction) {
        if (msg.isEmpty()) {
            throw new IllegalArgumentException("This value can't be empty!");
        }
        final AlertDialog dialog = new AlertDialog.Builder(ctx).setMessage(msg)
                .setPositiveButton((okBtn == null ? "Ok" : okBtn), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        if (okAction != null) {
                            okAction.perform();
                        }
                    }
                }).setNegativeButton((cancelBtn == null ? "Cancel" : cancelBtn), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        if (cancelAction != null) {
                            cancelAction.perform();
                        }
                    }
                }).setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        dialog.dismiss();
                        if (backPressendAction != null) {
                            backPressendAction.perform();
                        }
                    }
                }).create();
        dialog.show();
    }

    public interface AlertAction {
        void perform();
    }

    /**
     * Use this method to check if a third part app is istalled or not
     * @param ctx the app's context
     * @param packageName the third part app's package name. something like: com.example.package
     * @return true if the app is installed.
     */
    public static boolean isAppInstalled(final Context ctx, final String packageName) {
        PackageManager pm = ctx.getPackageManager();
        boolean installed = false;
        try {
            pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            installed = true;
        } catch (PackageManager.NameNotFoundException e) {
            installed = false;
        }
        return installed;
    }

    /**
     *  Use this method to open the google play store
     * @param activity the app which wants to redirect to the google play store
     * @param googlePlayStoreId the third part app's package name. something like: com.example.package
     * @param requestCode the request code to be used in the method onActivityForResult in the app which called this method.
     */
    public static void navigateToGooglePlayStore(final Activity activity, final String googlePlayStoreId, final int requestCode) {
        try {
            activity.startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + googlePlayStoreId)), requestCode);
        } catch (android.content.ActivityNotFoundException anfe) {
            // last chance: try again a second time with a different approach
            activity.startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + googlePlayStoreId)), requestCode);
        }
    }
}

Usage Example:

//... 
// check if app is istalled
return AppUtil.isAppInstalled(context,packageName);
//... 
// redirect to google play store
AppUtil.navigateToGooglePlayStore(activity ,googlePlayStoreId, requestCode);
//... 
// create a Ok-Cancel-Dialog
final String msg = "The app will no work without PagSeguro.";
        AppUtil.showOkCancelDialog(context, msg, "Install", "Cancel",
        new AppUtil.AlertAction() {
            @Override
            public void perform() {
                navigateToGooglePlayStore(PAG_SEGURO_PACKAGE_NAME);
            }
        }, new AppUtil.AlertAction() {
            @Override
            public void perform() {
                finish();
            }
        }, new AppUtil.AlertAction() {
            @Override
            public void perform() {
                finish();
            }
        });
//... code omitted

That's all! hope you like it! :)

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Tuesday, August 11, 2015

Router Design Pattern - Route messages, Objects or whatever you want!

Hi there!

Today i'm gonna show you the router pattern i wrote myself in action. The Router design pattern is a very useful programming design pattern whenever you need to be able to send objects or messages between instances over the application.

The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it. If you use it anywhere, please come back and give me a feedback. It would be nice to have more real use cases.

First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.

The UML Diagram of the Router Pattern


Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.





The example

In our example we will see, how we could create clients that listen to server responses. The servers are lazy instantiated and are created on demand.

Response and Request Interfaces

Those interfaces defines a contract to be used to design which type the client will use to send requests and receive responses. Let's take a closer look to it:
public interface Response < T >  {
  T getResponse();
  void setResponse(T value);
}

public interface Request < T >  {
  T getRequest();
  void setRequest(T value);
}

Client and Server Interfaces

Those interfaces defines a contract to be used while implementing concrete clients and servers. It uses either the Response or the Request depending on the what you are implementing:
public interface Client {
   < T extends Response < ? >  >  void onServerResponse(T response);
}

public interface Server {
  < T extends Request < ? > > void onClientRequest(T request, Client client);
}

Routable interface and Router class

The routable defines the contract for the router. The router itself is designed as a singleton and can be accessed and used everywhere in the application sending and receiving messages or objects. In this implementation the servers are lazy implemented and created on demand. For sure you may adapt it to your needs. Feel free to do it and give me feedback of the usage of it in your applications.
public interface Routable {
  public  < T extends Client >  void registerClient(T clientImpl);
  public void registerServer(Class < ? extends Server >  serverImpl);
  public  < T extends Request < ? >  >  void routeClientToServer(Class < ? extends Client >  clientImpl, Class < ? extends Server >  serverImpl, T request);
  public void removeClient(Class < ? >  serverClass);
  public void removeAllClients();
  public void removeServer(Class < ? >  clientClass);
  public void removeAllServers();
  public boolean isRegistered(Class < ? >  clazz);
}


public class Router implements Routable {

  private Map < String, Client >  clients = new HashMap < String, Client > ();
  // using sets to avoid duplicates
  public Set < Class < ? extends Client >  >  clientSet = new HashSet < Class < ? extends Client >  > ();
  public Set < Class < ? extends Server >  >  serverSet = new HashSet < Class < ? extends Server >  > ();
  private static final Router ROUTER = new Router();

  private Router() {
    // singleton - can be accessed anywhere in the application
  }

  public static Router turnOn() {
    return ROUTER;
  }

  public  < T extends Request < ? >  >  void routeClientToServer(Class < ? extends Client >  clientImpl, Class < ? extends Server >  serverImpl, T request) {
    doNotAllowNullValue(clientImpl);
    doNotAllowNullValue(serverImpl);
    doNotAllowNullValue(request);
    doNotAllowUnregisteredNullValue(isRegistered(clientImpl));
    // just to ensure that the server implementation exits already
    doNotAllowUnregisteredNullValue(isRegistered(serverImpl));
    // as we now know that the server implementation exists,
    // we just create a lazy instance over reflection on demand
    try {
      serverImpl.newInstance().onClientRequest(request, clients.get(clientImpl.getName()));
    } catch (InstantiationException e) {
      // we shall never run into this situation, except if the user does NOT define
      // a default constructor in any of the concrete implementation of Server as per
      // convention.
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
  }

  public void removeServer(Class < ? >  serverClass) {
    serverSet.remove(serverClass);
  }

  public void removeAllServers() {
    serverSet.clear();
  }

  public void removeClient(Class < ? >  clientclass) {
    clients.remove(clientclass.getName());
    clientSet.remove(clientclass);
  }

  public void removeAllClients() {
    clients.clear();
  }

  public boolean isRegistered(Class < ? >  clazz) {
    boolean result = false;
    boolean searchBreak = false;
    Iterator < Class < ? extends Client >  >  iterator = clientSet.iterator();
    while (iterator.hasNext()) {
      Class < ? extends Client >  next = iterator.next();
      // note: we can't use equalsIgnoreCase here
      if (next.getName().equals(clazz.getName())) {
        result = true;
        searchBreak = true;
        break;
      }
    }
    if (!searchBreak) {
      Iterator < Class < ? extends Server >  >  it = serverSet.iterator();
      while (it.hasNext()) {
        Class < ? extends Server >  next = it.next();
        // note: we can't use equalsIgnoreCase here
        if (next.getName().equals(clazz.getName())) {
          result = true;
          searchBreak = true;
          break;
        }
      }
    }
    return result;
  }

  public  < T extends Client >  void registerClient(T clientImpl) {
    doNotAllowNullValue(clientImpl);
    clientSet.add((Class < ? extends Client > ) clientImpl.getClass());
    clients.put(clientImpl.getClass().getName(), clientImpl);
  }

  public void registerServer(Class < ? extends Server >  serverImpl) {
    doNotAllowNullValue(serverImpl);
    serverSet.add(serverImpl);
  }

  private void doNotAllowNullValue(Object toCheck) {
    if (toCheck == null) {
      final String msg = "You can't pass null to this method!";
      throw new NullPointerException(msg);
    }
  }

  private void doNotAllowUnregisteredNullValue(boolean isRegistered) {
    if (!isRegistered) {
      final String msg = "Either the client or the server was not registered in this router. Register it first!";
      throw new IllegalArgumentException(msg);
    }
  }
}

Sample Implementation and Test

Now let's see how a real implementation could looks like and how it works in practise. First of all we are gonna define some responses and requests. Then we will create the clients and servers. Finally we will test it, by running a junit test to show it in action.
//SAMPLE CLIENT RESPONSE
public class ClientResponse implements Response < String >  {
  private String response;
  public String getResponse() {return response;}
  public void setResponse(String value) {response = value;}
}

//SAMPLE SERVER REQUEST
public class ServerRequest implements Request < String >  {
  String request;
  public String getRequest() {return request;}
  public void setRequest(String value) {request = value;}
}

// SAMPLE CLIENT IMPL
public class ClientImpl implements Client {
  public  < T extends Response < ? > > void onServerResponse(T response) {
    System.out.println(response.getResponse());
  }
}

//SAMPLE SERVER IMPL
public class ServerImpl implements Server {
  public < T extends Request < ? > >  void onClientRequest(T request, Client client) {
    // handle request and depending on it create response
    ClientResponse clientResponse = new ClientResponse();
    clientResponse.setResponse("Server is sending a response to client...");
    // route response back to client immediately or whenever you want
    client.onServerResponse(clientResponse);
  }
}

public class RouterTest {
  @Test
  public void testRouter() {
    Router.turnOn().registerClient(new ClientImpl());
    // servers would be only referenced and lazy instantiated later
    Router.turnOn().registerServer(ServerImpl.class);
    System.out.println("Client is sending a request to server...");
    ServerRequest request = new ServerRequest();
    request.setRequest("Client is sending a request to server...");
    Router.turnOn().routeClientToServer(ClientImpl.class, ServerImpl.class, request);
  }
}


That's all! hope you like it! :)


😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†



Wednesday, August 27, 2014

How to make intellij works like eclipse incl. appearance and shortcuts in 1 min.

Hi there!

Since a few days I'm thinking about to move to AndroidStudio's IntelliJ IDEA. One of biggest problem and resistance i had, was the fact that IntelliJ IDEA has totally different shortcuts than eclipse. We don't want to learn or invent the wheel again for the same thing, right? For this reason, i'll show to you, how to use eclipse's shortcuts in IntelliJ.

Another thing i don't like very much, is the color schema. I've been programming with eclipse since years and although I like the black look and feel, I still prefer the traditional white appearance. So i will also show, how we can override the color schema of IntelliJ with a few clicks


Changing the shortcut list

Once you´ve downloaded and installed your AndroidStudio, start it and follow the sequences bellow:





Changing the color Schema

Now let's change also the color schema. To do so, copy this eclipse.xml file and save it in your desktop with the extension .xml

 
< ?xml version="1.0" encoding="UTF-8"? >
< scheme name="eclipse" version="1" parent_scheme="Default" >
  < option name="LINE_SPACING" value="1.2" /  >
  < option name="EDITOR_FONT_SIZE" value="12" /  >
  < option name="EDITOR_FONT_NAME" value="Courier New" /  >
  < colors >
    < option name="CARET_ROW_COLOR" value="e8f2fe" /  >
  < / colors >
  < attributes >
    < option name="ANNOTATION_NAME_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="646464" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.FUNCTION" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.IDENT" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.PROPERTY_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.PROPERTY_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.URL" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD1_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD2_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="660e7a" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD3_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="6666" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD4_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="660000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_LINE_COMMENT_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_STRING_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.BOUNDS" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.BRACKETS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.IDENT" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.NUMBER" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.PARENTHS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL_BACKGROUND" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="edffed" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ATTRIBUTE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ATTRIBUTE_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ENTITY_REFERENCE" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="INSTANCE_FIELD_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_BLOCK_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f7f5f" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_DOC_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f5fbf" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_DOC_MARKUP" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="1" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_INVALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_KEYWORD" >
      < value >
        < option name="FOREGROUND" value="7f0055" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_LINE_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f7f5f" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_NUMBER" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_STRING" >
      < value >
        < option name="FOREGROUND" value="2a00ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BADCHARACTER" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BLOCK_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BRACES" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BRACKETS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.COMMA" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_MARKUP" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="e2ffe2" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_TAG" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="1" /  >
        < option name="EFFECT_COLOR" value="808080" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOT" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.INVALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.LINE_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.NUMBER" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.OPERATION_SIGN" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.PARENTHS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.REGEXP" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="-1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.SEMICOLON" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JSP_DIRECTIVE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.KEY" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Problems" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Production" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Tests" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="STATIC_FIELD_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="TEXT" >
      < value >
        < option name="FOREGROUND" value="323232" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="WARNING_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" value="f4c82d" /  >
        < option name="EFFECT_TYPE" value="2" /  >
        < option name="ERROR_STRIPE_COLOR" value="f4c82d" /  >
      < / value >
    < / option >
    < option name="XML_ATTRIBUTE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_ATTRIBUTE_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_ENTITY_REFERENCE" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_TAG_DATA" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
  < / attributes >
< / scheme >

Setting the color Schema

Now cut this saved file from your desktop using Ctrl+X and put it in your user's directory by pressing Ctrl+V like that: (Note, your user's color config directory may not be equal to my presented here in this example)


Now you should see this file by looking at:



Done! That's all! Hope you like it.

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†