Saturday, December 07, 2013

Optional boolean argument for a java method:

void testOptionalArgument(boolean ... flag) {
    if (flag == null) {
        log.info("optional flag null");
    } else {
        int length = flag.length;
        log.info("optional flag: " + flag + " length: " + length);
        if (length > 0) {
            log.info("optional flag: " + flag[0]);
        }
    }
}

Calling this method in 3 different ways:

testOptionalArgument(); // optional flag: [Z@ed3c51 length: 0
testOptionalArgument(true);  // optional flag: [Z@1131359 length: 1 optional flag: true
testOptionalArgument(false); // optional flag: [Z@15b3baf length: 1 optional flag: false


Sunday, June 02, 2013

How to remove the copy/print protection in a pdf file for free

Sometimes I download a document and to my surprise, I can't copy text from it or print the document. That protection is only the copy/print text of a pdf document, not a password protection that prevents opening the document if one doesn't have this password.

Here is a quite easy way, and free, to remove this copy/print protection. I saw it mentioned several years ago on the web, but now it is drowned in the flurry of links. It's for Windows, but you can changes the paths for Linux/MacOS.

- download and install ghostscript, the open source library for pdf http://www.ghostscript.com/
- open a console and set the current directory to the one where ghostscript was installed
- run the following line after changing the path/filename for your original file (the one with the restrictions) and the path/filename for the output file

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"
If you want to skip a few pages (like the "How to use this form", add the "-dFirstPage" option, it will output the document starting with the page specified. There is also a last page option, see the ghostscript manual.

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dFirstPage=10 -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"

Links:
http://www.ghostscript.com/download/gsdnld.html
http://www.ghostscript.com/
http://www.ghostscript.com/doc/9.07/Use.htm#PDF

Monday, April 29, 2013

on save, validation & uuid in Grails

I want to to add a "uuid" field to my domain classes exposed to the world to prevent scanning with sequential ids. Using the Hibernate id generator works, but that means that the "id" field in the domain class has to be a String, and some plugins could have assumed that the "id" property is always a Long, causing grief and hours of debug. Also, while developing, it's a lot easier for us humans to deal with short and sequential ids.
So I added a "uid" field in my domain class, but I want to catch the case where the UUID is already used. Very very small probability, but I wanted to put in place some code that could catch exceptions while saving the domain instances even for other reasons. I also didn't want to interfere with the normal controller flow.

First, I generate an app with Grails 2.2.2 and create a "Country" domain class, its controller and views. I used "grails generate-all Country" for that. The scaffolded controller assumes that the "id" is a Long, explaining why I prefer to leave the "id" alone and use another property instead. That issue might be fixed in the future.
Here is the domain class code:
package app
class Country {
    // Long id is still generated by Grails
    String uid = null
    String name
    static constraints = {
        uid unique: true
        name size: 2..25
    }
    static mapping = {
        version false
    }
    // using beforeInsert doesn't work, since validation runs before.
    def beforeValidate() {
        if (uid == null) {
            uid = UUID.randomUUID().toString() // works
            //uid = 1
            println "Country beforeValidate uid: $uid"
        }
    }
}

The "uid" property is added and null assigned to it, then it is checked in the "beforeValidate" method and not in the "beforeInsert" method. The Grails documentation specifies that the validation is run *before* saving and since the "uid" cannot be null (by default), the validation would fail if not assigned a value prior validation. Be aware too that the validation can be run several times before saving, according to the Grails documentation. By checking if the "uid" is already set, we don't do the work twice. You will notice the line: "uid=1". This is to test the "duplicate uid" catching code in the controller, see below.

The controller "save" method, the only modified one:

    def save() {
        def countryInstance = new Country(params) // (1)
        // saves returns the instance if successful, null if failed
        def saveOK = countryInstance.save(flush: true)
        if (saveOK) {
            println "save OK"
            flash.message = message(code: 'default.created.message', args: [message(code: 'country.label', default: 'Country'), countryInstance.id])
            redirect(action: "show", id: countryInstance.id)
            return
        }
        else {
            def error = countryInstance.errors.getFieldError('uid')
            if (error) {
                println "error code: $error.code"
                if (error.code == 'unique') {
                    countryInstance.uid = UUID.randomUUID().toString()
                    println "CountryController RESAVE countryInstance.uid: $countryInstance.uid"
                    if (countryInstance.save(flush: true)) {
                        println "save OK"
                        flash.message = message(code: 'default.created.message', args: [message(code: 'country.label', default: 'Country'), countryInstance.id])
                        redirect(action: "show", id: countryInstance.id)
                        return
                    }
                    else {
                        println "save NOT OK"
                        // could be another validation error
                        def errors = countryInstance.errors // all the field errors with names & codes
                        println "errors: $errors"
                        render(view: "create", model: [countryInstance: countryInstance])
                        return
                    }
                }
            } else {
                println "no UID error"
                // show the error
                def codes = countryInstance.errors.getFieldErrors().code
                println "errors.code: $errors"
                render(view: "create", model: [countryInstance: countryInstance])
                return
            }
        }
   }
The flow is:
1) a "new Country(params)" instance is created , "save" calls the validation, the Country.beforeValidation method is called, the "uid" assigned, then the real "save" is performed.
2) if the "save" is successful, nothing to do
3) if the "save" fails, there is a check to see if the "uid" property has the "unique" error, in which case, we assign another UUID and retry the save. If there is another error, there is no retry, that must be something else. Chances to generate twice an existing id are probably nil.
4) if the "save" succeeds, then it means we had an existing UUID in the DB and generated another one successfully.

To test the flow, I assigned 1 to the "uid" in the Country domain class, and watched the controller assign a UUID to it after catching the exception.

Beyond the UUID scheme, in the controller code, we can see how to catch a validation exception.It shows how to check the field in error and the type of error.

Refer to the Grails javadocs and also these:

http://grails.org/doc/latest/api/grails/validation/ValidationException.html#errors
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/validation/FieldError.html
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/support/DefaultMessageSourceResolvable.html#getCode()

This was a quick hacking/testing session, let me know if I missed something or any improvement.

Happy Grailling.


Wednesday, April 24, 2013

Google Cloud SQL with Grails

2014-06 NOTE: the following article doesn't apply anymore since Google Cloud SQL is now available publicly as a service without special authentication. see https://developers.google.com/cloud-sql/

Here are the steps to access a Google Cloud SQL database with a Grails application not hosted on Google App or Compute Engine. That means that a Grails application running on your local machine, a server or one of the cloud platform can still use the Google Cloud SQL services. First you need to enable SQL in your account and create your SQL instance and the database from the Google APIs console see https://developers.google.com/cloud-sql/docs/before_you_begin.
Then check the following docs: the Google Cloud SQL online doc for external access is at https://developers.google.com/cloud-sql/docs/external . It explains what the driver configuration is and how to get the OAuth tokens on your machine. For that download the command line tools at http://dl.google.com/cloudsql/tools/google_sql_tool.zip You need to run the command line tool once, it will ask you to use your browser to authorize access from your machine see the doc here https://developers.google.com/cloud-sql/docs/commandline .

Here are the steps:
1) enable SQL on your Google Account
2) create a SQL instance (container for your databases). You can use the console to interact with your database (click on the "SQL Prompt" tab).
3) download the command line tools, unzip them in the folder of your choice
4) run them with the name of your SQL instance (the same name that the APIs console shows)
5) follow the instructions to get the authorization code to access the SQL instance from your machine
6) the "sql>" prompt shows up.
7) use the mySQL commands to verify the connection like "show databases"...
8) copy the "google_sql.jar" file from the command line folder created earlier to the /lib folder in the grails app. It contains the jdbc driver to access the Google SQL instance
9) change the Grails datasource.groovy file with your instance and database params as:
environments {
    development {
        dataSource {
        dbCreate = "create"
pooled = false // true doesn't work with Google SQL
driverClassName = "com.google.cloud.sql.Driver"
dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
username = 'root'
password = ''
//jdbc:google:rdbms://instance_name/database_name"
url = 'jdbc:google:rdbms://yourinstancename/yourdatabasename'
        }
...

10) run your app.

Notes:
1) The driver doesn't seem to support dbCreate = "create-drop" as of April 2013. Grails fails with a "DatabaseMetaData; nested exception is
 com.google.cloud.sql.jdbc.internal.SQLFeatureNotYetImplementedException: Not implemented Yet" error. It works with "create" or "update", not so bad. If you find a way to get the dbCreate = "create-drop" mode to work, please let me know! See update below.
2) Once your app is up and running, create a user/password for it, don't use the "root" as shown above.
3) "pooled = true" doesn't work. See https://developers.google.com/cloud-sql/docs/external : "Note that connections to a cloud hosted database should be managed differently to those on a conventional server. In particular, be aware that your database instance may be taken offline while not in use, and any pooled connections would be closed. Rather than using a connection pool we recommend that a new connection is created for each new transaction since the time to create a new connection is similar to that required to test the liveness of an existing connection."

Update: thanks to Sergio Michels on the Grails Users list and Burt Beckwith's blog http://burtbeckwith.com/blog/?p=312 , the connection works now with dbCreate = "create-drop". I changed the file "myapp\grails-app\conf\spring\resources.groovy" to:


import org.springframework.jdbc.support.lob.DefaultLobHandler

beans = {
// for the Google Cloud SQL config
// see http://burtbeckwith.com/blog/?p=312
lobHandlerDetector(DefaultLobHandler)
}