Practice: Readable eBooks on the iPad using Margins

Ubiquitous devices of all sizes have radically changed our reading experiences in the last couple of years. I have no problem in reading entire books using iBooks on the iPhone. Reading on the iPad has often been criticized for the potential strenuous effects of screen brightness. However, I most struggle with the format of the screen – it is actually wider than the normal page in a book we are used to. iBooks on the iPad mitigates this problem by including relatively wide margins on both sides of the displayed pages (iBooks on the iPhone does not have these margins).

However, when reading PDFs, for instance using GoodReader or another PDF reader application on the iPad, the result is often a too small font due, as a DINA4 page (a common format for PDF ebooks) is significantly larger than the iPad screen. One possible way to solve this problem is using calibre to reformat the ebook into a readable PDF. For this, it is best if the ebook is available in a text-based format such as RTF, MOBI or EPUB.

By right clicking onto an imported book in calibre, one can select to “Convert individually”. Firstly, the font size can be adjusted to a convenient scale. I have chosen 13 pt.

On the page “Page Setup”, the iPad profile can be chosen. To prevent the text in the PDF from becoming too ‘broad’, margins should be set. I used 80pt both for the left and right margins.

Finally, on the page “PDF Output”, the page size ‘tabloid’ can be selected.

Count lines of code and number of classes in eclipse projects

There are a number of plugins for eclipse, Maven and/or subversion, which allow the convenient and automatic determination of important project statistics such as the total lines of code in a project or the number of Java classes. However, sometimes one just needs these statistics quick and dirty and setting up sophisticated tools represents an unjustifiable overhead.

In this case, the eclipse search function is a useful tool to determine these statistics. Below are simple workflows of attaining the statistics for one or more projects.

Lines Of Code

The lines of code can be determined by searching all the Java source files in the selected resource for line breaks. The number of line breaks should approximate the lines of code.

1. Select the projects for which you want to count the lines of code in the Package Explorer.

2. Open through Menu Search / File

3. Search for the regular expression ‘\n’ in all ‘*.java’ files of the selected resources (these are the projects you selected in step 1 – be aware that the Package Explore must hold the current focus in order for this to work. If ‘selected resources’ is greyed out, reselect the projects in the package explorer in reopen the search dialog)

Note: If you would like to count only non-empty lines, you can use the expression: ‘\s+\n’ instead of ‘\n’ (Thanks, Anshul!)

4. Perform the search. The total matches reported in the Search tab at the bottom of your screen should approximate the lines of code in your Java sources. The matches reported for individual Java files, should represent the lines of codes for these files (actually the lines in the file -1 as pointed out by shahnaz below 🙂 ).

Number of Classes

The number of classes can be determined using the eclipse Java search for all declared types.

1. Select the projects for which you want determine the number of classes as shown above.

2. Select Menu / Search

3. Select the tab Java Search and search for all declared types as depicted below

4. Perform the search. The total number of declarations reported should represent the total number of classes and interface in the projects you have selected.

shahnaz

Java List Equality and Object Identity

Problem

Java lists manage inserted objects based on their equality (see List JavaDoc). In some instances, it can be confusing that this equality has a different meaning than an equal identity of objects based on their reference.

This becomes quite apparent in the following example:

final List<String> list = new ArrayList<String>(); 
final String s1 = "one"; 
final String s2 = "one"; 
list.add(s1); 
list.add(s2);     
System.out.println(list.indexOf(s2)); 

Here, we would usually expect “1” as result, since the String s2 has been inserted after the String s1 (which should have the index 0). However, Java prints “0” as answer in above example. 0 is returned since the indexOf(…) method only attempts to find an object which is equal to the passed parameter (“one”) and not the identical object to the passed object (s2).

Solution

Use the IdentityArrayList below:


/**
* Copyright 2011 Max Rohde

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mx.gwtutils;

import java.util.ArrayList;
import java.util.Collection;

/**
* An array list implemention depending on object identity (==) rather than
* equality (.equals) to identify elements.<br/>
* <br/>
* See: <a href=
* "https://nexnet.wordpress.com/2011/03/09/java-list-equality-and-object-identity/"
* >KnowledgeNetworks: Java List Equality and Object Identity</a>
*
* @author <a href="http://www.mxro.de/">Max Rohde</a>
*
* @param <E>
*/
public class IdentityArrayList<E> extends ArrayList<E> {

private static final long serialVersionUID = 1L;

@Override
public boolean remove(final Object o) {
return super.remove(this.indexOf(o)) != null;
}

@Override
public boolean contains(final Object o) {
return indexOf(o) >= 0;
}

@Override
public int indexOf(final Object o) {
for (int i = 0; i < size(); i++)
if (o == get(i))
return i;
return -1;
}

@Override
public int lastIndexOf(final Object o) {
for (int i = size() - 1; i >= 0; i--)
if (o == get(i))
return i;
return -1;
}

public IdentityArrayList() {
super();
}

public IdentityArrayList(final Collection<? extends E> c) {
super(c);
}

public IdentityArrayList(final int initialCapacity) {
super(initialCapacity);
}

}

There are a number of further implementation of List and Set in Java, which consider the object identity rather than the object equality:

IdentityArrayList part of the Sun/Oracle JDK at sun.awt.util (on java2s.com)

IdentitySet by Sebastian Thomschke (on grepcode.net)

But please note that these lists are not part of the Java JRE. Lists are often critical parts of an application (in terms of performance and reliability). Therefore, the best advice might be to tried to work around scenarios as given above, for instance by assigning unique identifiers to objects.

For HashMaps, however, a special implementation utilizing object identity rather than equality checks is provided in the JRE:

IdentityHashMap JRE 1.5.0 Java Doc

GWT Object Serialization: Problems and (some) workarounds

I made the very troublesome discovery that different rules apply for Gwt to convert Java objects to JavaScript objects and using Java objects as parameters in Gwt’s remote procedure calls (RPC). Following a list of issues arising when using Gwt RPC (but not in Java->JavaScript conversion).

Immutable Objects (final fields)

Problem:

I have already written about issues concerning immutable objects. final fields are treated as being transient and therewith ignored when serializing and deserializing objects.

Workaround:

Remove the final modifier from any fields you require. This is the only workaround I could find. Even the (possibly deprecated) deRPC does not work with final fields.

Generic Java Objects

Problem:

Gwt RPC does not like fields of the type Object. If an object with a field of the type Object is to be serialized for Gwt RPC, a SerializationException will be thrown.

Workaround:

The only possible workaround I could find is to replace Object with any other class or interface. Especially useful in this regard is the interface java.io.Serializable. This interface is implemented by many fundamental classes such as String and Integer. However, using java.io.Serializable can cause the Gwt compile to significantly increase the size of the JavaScript. Essentially, any class, which implements this interface, must be compiled into JavaScript as it might (or might not) be sent via RPC. A possible mitigation of this problem is to manually exclude classes from being prepared for serialization. This can be achieved by utilizing the rpc-blacklist property. Some examples for setting this property are given below:

<extend-configuration-property name="rpc.blacklist" value="-.*List"/>
<extend-configuration-property name="rpc.blacklist" value="-.*Map"/>
<extend-configuration-property name="rpc.blacklist" value="-.*Collection"/>
<extend-configuration-property name="rpc.blacklist" value="+java.util.HashMap"/>
<extend-configuration-property name="rpc.blacklist" value="-java.util.HashSet"/>
<extend-configuration-property name="rpc.blacklist" value="-java.util.LinkedHashMap"/>
<extend-configuration-property name="rpc.blacklist" value="+java.util.ArrayList"/>
<extend-configuration-property name="rpc.blacklist" value="-com.extjs.*"/> <!-- for GXT -->

Resources

Issue 1833: GWT doesn’t allow Object/Serializable parameter in the serializable class

Issue 4438: GWT Compiler includes unneeded classes in RPC code (+example <extend-configuration-property> definitions to reduce generated code size)

Gwt and Maven Jetty Plugin

The Maven Gwt Plugin is a powerful tool in developing Gwt applications using Maven Build Management. I have set up my development environment to code and run JUnit test in eclipse IDE (without using eclipse IAM etc but the Maven Eclipse Plugin instead), and I test gwt code using the Maven Gwt Plugin, either using the gwt:run or gwt:test goals.

In combination with the Maven Jetty Plugin it is very easy to deploy Maven dependent Gwt applications into an exploded war or a packed war. Below the required plugins plus versions as well as some sample commands.

Required Plugins

Maven War Plugin

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-war-plugin</artifactId>

<version>2.1.1</version>

Maven Gwt Plugin (see repository location)

<groupId>org.codehaus.mojo</groupId>

<artifactId>gwt-maven-plugin</artifactId>

<version>2.1.1-SNAPSHOT</version>

Maven Jetty Plugin

<groupId>org.mortbay.jetty</groupId>

<artifactId>jetty-maven-plugin</artifactId>

Pom.xml Settings

The jetty server instance will require gwt-servlet.jar. Below a convenient way to define this archive as additional dependency.

<dependency>

<groupId>com.google.gwt</groupId>

<artifactId>gwtservlet</artifactId>

<version>${gwtVersion}</version>

<scope>war</scope>

</dependency>

Maven War Plugin configuration

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-war-plugin</artifactId>

<version>2.1.1</version>

 

<configuration>

<warSourceDirectory>war</warSourceDirectory>

<webXml>src/main/webapp/WEB-INF/web.xml</webXml>

</configuration>

</plugin>

Deploying & Running

Run jetty from the exploded project contents in your project’s directory with your Gwt application.

mvn gwt:compile jetty:run –Djetty.port=9990

Deploy Gwt application to a packaged war:

mvn war:war

(should trigger goal gwt:compile)

Extract a generated war and run the exploded war contents in jetty.

mvn jetty:deploy-war –Djetty.port=9998