Monthly Archives: November 2016

Java Enums

Enum Example

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

Enums in if Statements

Level level = ...  //assign some Level constant to it

if( level == Level.HIGH) {

} else if( level == Level.MEDIUM) {

} else if( level == Level.LOW) {

}

Enum Iteration

for (Level level : Level.values()) {
    System.out.println(level);
}

Enum Fields

public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow


    private final int levelCode;

    private Level(int levelCode) {
        this.levelCode = levelCode;
    }
}

Enum Methods

public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow


    private final int levelCode;

    Level(int levelCode) {
        this.levelCode = levelCode;
    }
    
    public int getLevelCode() {
        return this.levelCode;
    }
    
}

References
http://tutorials.jenkov.com/java/enums.html
https://www.mkyong.com/java/java-enum-example/

Spring Data MongoDB – Indexes, Annotations and Converters

Indexed
This annotation marks the field as indexed in MongoDB

@QueryEntity
@Document
public class User {
    @Indexed
    private String name;
     
    ... 
}

Compound Indexes
MongoDB supports compound indexes, where a single index structure holds references to multiple fields.

@QueryEntity
@Document
@CompoundIndexes({
    @CompoundIndex(name = "email_age", def = "{'email.id' : 1, 'age': 1}")
})
public class User {
    //
}

Transient
As you would expect, this simple annotation excludes the field from being persisted in the database.

public class User {
     
    @Transient
    private Integer yearOfBirth;
    // standard getter and setter
 
}

Field
@Field indicates the key to be used for the field in the JSON document

@Field("email")
private EmailAddress emailAddress;

References
http://www.baeldung.com/spring-data-mongodb-index-annotations-converter

Gradle Task

task cleanAll {
    group = 'minify'
    doFirst {
        tasks.cleanCSS.execute()
        tasks.cleanJS.execute()
    }
}
task cleanCSS {
    group = 'minify'
    doLast {
        String basePath = 'src/main/resources/static/stylesheets/site';
        FileTree tree = project.fileTree(dir: basePath);
        tree.include "**/*.css"
        tree.exclude "**/*.scss"
        tree.exclude "**/*.css.map"

        tree.visit { FileVisitDetails element ->
            if (!element.isDirectory()) {
                element.file.delete()
            }
        }
    }
}
task cleanJS {
    group = 'minify'
    doLast {
        String basePath = 'src/main/resources/static/javascripts/site';
        FileTree tree = project.fileTree(dir: basePath);
        tree.include "**/*.min.js"
        tree.exclude "**/*.js.map"
        tree.exclude "**/*.ts"
        tree.exclude "**/*.d.ts"

        tree.visit { FileVisitDetails element ->
            if (!element.isDirectory()) {
                element.file.delete()
            }
        }
    }
}
task sass {
    group = 'minify'
    doLast {
        String basePath = 'src/main/resources/static/stylesheets/site';
        FileTree tree = project.fileTree(dir: basePath);
        tree.include "**/*.scss"
        tree.exclude "**/*.css"
        tree.exclude "**/*.css.map"

        tree.visit { FileVisitDetails element ->
            if (!element.isDirectory()) {
                String filePath = basePath + "/" + element.getPath();

                int pos = filePath.lastIndexOf(".");
                String newFilePath = "";

                if (pos > 0) {
                    newFilePath = filePath.substring(0, pos) + ".css";
                }

                if (project.file(newFilePath).exists()) {
                    project.file(newFilePath).delete();
                }


                String cmd = String.format("node-sass $filePath $newFilePath");
                java.lang.Runtime.getRuntime().exec(cmd);
            }
        }
    }
}
task csso {
    group = 'minify'
    doLast {
        String basePath = 'src/main/resources/static/stylesheets/site';
        FileTree tree = project.fileTree(dir: basePath);
        tree.include "**/*.css"
        tree.exclude "**/*.min.css"
        tree.exclude "**/*.css.map"
        tree.exclude "**/*.scss"

        tree.visit { FileVisitDetails element ->
            if (!element.isDirectory()) {
                String filePath = basePath + "/" + element.getPath();

                int pos = filePath.lastIndexOf(".");
                String newFilePath = "";

                if (pos > 0) {
                    newFilePath = filePath.substring(0, pos) + ".min.css";
                }

                String cmd = String.format("csso -i $filePath -o $newFilePath");
                java.lang.Runtime.getRuntime().exec(cmd);
            }
        }
    }
}
task uglify {
    group = 'minify'
    doLast {
        String basePath = 'src/main/resources/static/javascripts/site';
        FileTree tree = project.fileTree(dir: basePath);
        tree.include "**/*.js"
        tree.exclude "**/*.min.js"
        tree.exclude "**/*.js.map"
        tree.exclude "**/*.ts"
        tree.exclude "**/*.d.ts"

        tree.visit { FileVisitDetails element ->
            if (!element.isDirectory()) {
                String filePath = basePath + "/" + element.getPath();

                int pos = filePath.lastIndexOf(".");
                String newFilePath = "";

                if (pos > 0) {
                    newFilePath = filePath.substring(0, pos) + ".min.js";
                }

                String cmd = String.format("uglifyjs $filePath -o $newFilePath");
                java.lang.Runtime.getRuntime().exec(cmd);
            }
        }
    }
}
sass.mustRunAfter cleanCSS
csso.mustRunAfter sass
uglify.mustRunAfter cleanJS
task minify{
    group = 'minify'
    doFirst{
        tasks.cleanCSS.execute()
        tasks.cleanJS.execute()
    }
    doLast{
        tasks.sass.execute()
        tasks.csso.execute()
        tasks.uglify.execute()
    }
}

References
https://docs.gradle.org/current/userguide/working_with_files.html
https://docs.gradle.org/current/userguide/tutorial_using_tasks.html
https://docs.gradle.org/current/userguide/custom_tasks.html
https://docs.gradle.org/current/userguide/more_about_tasks.html

Use Jetty instead of Tomcat in Java Spring Boot

configurations {
    compile.exclude module: "spring-boot-starter-tomcat"
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-jetty:1.4.2.RELEASE")
    // ...
}

Reference
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-use-jetty-instead-of-tomcat

Spring Data MongoDB : Query document

Test Data

> db.users.find()
{ "_id" : ObjectId("id"), "ic" : "1001", "name" : "ant", "age" : 10 }
{ "_id" : ObjectId("id"), "ic" : "1002", "name" : "bird", "age" : 20 }
{ "_id" : ObjectId("id"), "ic" : "1003", "name" : "cat", "age" : 30 }
{ "_id" : ObjectId("id"), "ic" : "1004", "name" : "dog", "age" : 40 }
{ "_id" : ObjectId("id"), "ic" : "1005", "name" : "elephant", "age" : 50 }
{ "_id" : ObjectId("id"), "ic" : "1006", "name" : "frog", "age" : 60 }

BasicQuery example

BasicQuery query1 = new BasicQuery("{ age : { $lt : 40 }, name : 'cat' }");
User userTest1 = mongoOperation.findOne(query1, User.class);

System.out.println("query1 - " + query1.toString());
System.out.println("userTest1 - " + userTest1);

findOne example

Query query2 = new Query();
query2.addCriteria(Criteria.where("name").is("dog").and("age").is(40));

User userTest2 = mongoOperation.findOne(query2, User.class);
System.out.println("query2 - " + query2.toString());
System.out.println("userTest2 - " + userTest2);

find and $inc example

List<Integer> listOfAge = new ArrayList<Integer>();
listOfAge.add(10);
listOfAge.add(30);
listOfAge.add(40);

Query query3 = new Query();
query3.addCriteria(Criteria.where("age").in(listOfAge));

List<User> userTest3 = mongoOperation.find(query3, User.class);
System.out.println("query3 - " + query3.toString());

for (User user : userTest3) {
	System.out.println("userTest3 - " + user);
}

find and $gt, $lt, $and example

Query query4 = new Query();
query4.addCriteria(Criteria.where("age").lt(40).and("age").gt(10));

List<User> userTest4 = mongoOperation.find(query4, User.class);
System.out.println("query4 - " + query4.toString());

for (User user : userTest4) {
	System.out.println("userTest4 - " + user);
}

You can’t use Criteria.and() to add multiple criteria into the same field, to fix it, use Criteria.andOperator(), see updated example :

Query query4 = new Query();
query4.addCriteria(
	Criteria.where("age").exists(true)
	.andOperator(
		Criteria.where("age").gt(10),
                Criteria.where("age").lt(40)
	)
);

List<User> userTest4 = mongoOperation.find(query4, User.class);
System.out.println("query4 - " + query4.toString());

for (User user : userTest4) {
	System.out.println("userTest4 - " + user);
}

find and sorting example

Query query5 = new Query();
query5.addCriteria(Criteria.where("age").gte(30));
query5.with(new Sort(Sort.Direction.DESC, "age"));

List<User> userTest5 = mongoOperation.find(query5, User.class);
System.out.println("query5 - " + query5.toString());

for (User user : userTest5) {
	System.out.println("userTest5 - " + user);
}

find and $regex example

Query query6 = new Query();
query6.addCriteria(Criteria.where("name").regex("D.*G", "i"));

List<User> userTest6 = mongoOperation.find(query6, User.class);
System.out.println("query6 - " + query6.toString());

for (User user : userTest6) {
	System.out.println("userTest6 - " + user);
}

Method 2 : Generated Query Methods

public interface UserRepository 
  extends MongoRepository<User, String>, QueryDslPredicateExecutor<User> {
    ...
}

References
https://www.mkyong.com/mongodb/spring-data-mongodb-query-document/
http://www.baeldung.com/queries-in-spring-data-mongodb