Static Import

I never liked seeing people put constants in an interface and then implementing that interface in a class so that they can have direct access to those constants. That always seemed wrong to me and now this Sun article, Static Import, verifies my intuition.

In order to get around this, people sometimes put static members into an interface and inherit from that interface. This is a bad idea. In fact, it’s such a bad idea that there’s a name for it: the Constant Interface Antipattern (see Effective Java Item 17). The problem is that a class’s use of the static members of another class is a mere implementation detail. When a class implements an interface, it becomes part of the class’s public API. Implementation details should not leak into public APIs.

The suggested method is to use a static import.

import static java.lang.Math.PI;

However the article suggests using this sparingly.

Only use it when you’d otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.

You can also do static import of methods.

import static com.betweengo.util.CollectionUtils.isEmpty;

However I would never do this, I like knowing where my static methods come from.

JSP redirect to another page

I found on this forum how to redirect to another page in JSP. One of the respondents explained it perfectly.

Well you have two options. Either you’ll do a server side forward or a client side redirect.
Server side forward has no interaction with the browser and therefore the URL on the location bar won’t change.
But if you do the HTTP redirect, the browser is instructed to load the other page and the contents of the location will change.
It’s your call which one to choose.

forward:

<% if (s1.equals(s2) ) { %>

     <jsp:forward page="s2.jsp"/>

<% } %>

redirect:

<% if (s1.equals(s2) ) {

    response.sendRedirect("s2.jsp");

} %>

Playing with Dates in Java

I always forget how to do these things so I thought I should write it down.

Changing Dates:

Here is an example of getting the date for seven days ago from now.

    Calendar sevenDaysAgo = Calendar.getInstance();
    sevenDaysAgo.add(Calendar.DATE, -7);
    sevenDaysAgo.set(Calendar.HOUR_OF_DAY, 0);
    sevenDaysAgo.set(Calendar.MINUTE, 0);
    sevenDaysAgo.set(Calendar.SECOND, 0);
    sevenDaysAgo.set(Calendar.MILLISECOND, 0);

Formatting Dates:

Here is the simple way to format a date and time.

    DateFormat.getDateTimeInstance().format(sevenDaysAgo.getTime()))

The output is:

    May 21, 2008 12:00:00 AM

Note that according to the JavaDoc, DateFormats are inherently unsafe for multithreaded use. You should not make a call to a static instance of a DateFormat nor share a single instance across thread boundaries without proper synchronization.  The same applies to Calendar.  For more information on this see Sun Bug #6231579 and Sun Bug #6178997.

Creating Dates:

Here is an example of creating a date, the birth date January 1, 1970.

    Calendar birthDate = Calendar.getInstance();
    birthDate.clear();
    birthDate.set(Calendar.YEAR, 1970);
    birthDate.set(Calendar.MONTH, 0);
    birthDate.set(Calendar.DATE, 1);

For further reading please Create a Date object using the Calendar class and of course the JavaDocs for Calendar, Date and DateFormat.

JSTL for current URI

I was wondering how do get the current URI using JSTL and found this forum thread, JSTL EL for current page URL?.

If you want the actual URI of the JSP that is being rendered:

<c:out value="${pageContext.request.requestURI}"/>

If you want the original URI, which is probably the case, then:

<c:out value="${requestScope['javax.servlet.forward.request_uri']}"/>

In DSP if you want the original URI you can use the OriginatingRequest bean which implements the HttpServletRequest.

<dsp:valueof bean="/OriginatingRequest.requestURI" />

Size of collection in a JSP/DSP page

leaf pile on Flickr

(Photo: leaf pile by oeimah)

Sometimes in a JSP/DSP page you will want to get the size of a collection and unless you are within a Range, ForEach or similar droplet you won’t have access to this value.

Struts has a nice solution using the bean:size tag.  JSTL 1.1 has a nice solution using the fn:length function.

Here is an example of how to use Struts, DSPEL and JSTL to get the size of a collection.

  <dspel:getvalueof param="book.pages" var="pages"
                    vartype="java.util.Collection"/>
  <bean:size id="numPages" name="pages"/>
  Number of Pages: <c:out value="${numPages}"/>
  Number of Pages: <dspel:valueof value="${numPages}"/>

Here is an example of how to use JSTL 1.1 and DSPEL to get the size of a collection.

 

  <dspel:getvalueof param="book.pages" var="pages"
                    vartype="java.util.Collection"/>
  Number of Pages: <c:out value="${fn:length(pages)}"/>

Accessing RepositoryItems with JSTL

Often we are accessing repository items in a JSP page like this.

  <dspel:droplet name="RQLQueryForEach" var="query">
    <dspel:param name="repository" bean="/betweengo/repository/Repository"/>
    <dspel:param name="itemDescriptor" value="Account"/>
    <dspel:param name="queryRQL" value="ALL"/>
    <dspel:setvalue param="account" paramvalue="element"/>
    <dspel:oparam name="output">
      <dspel:valueof param="account.name"/><br/>
    </dspel:oparam>
  </dspel:droplet>

With JSTL we could try to display the name like this.

      <c:out value="${query.account.name}"/>

If you are using JSP 2.0 you can display it even more simply.

      ${query.account.name}

However since account is a RepositoryItem object and there is no get method for the name property (i.e. it’s not a JavaBean object) the above will fail and produce an exception.

To get around this you can extend ATG’s RQLQueryForEach class by overriding the protected setElementParameter. In addition to setting the element parameter in the request you can set a new parameter which we will call “item”. This item is of class atg.beans.DynamicBeanMap and wraps a RepositoryItem.

public class RQLQueryForEachEL extends RQLQueryForEach {
  protected void setElementParameter(DynamoHttpServletRequest pRequest,
                                     String pElementName, Object pValue) {
    super.setElementParameter(pRequest, pElementName, pValue);
    DynamicBeanMap itemBean = new DynamicBeanMap(pValue, true);
    pRequest.setParameter("item", itemBean);
  }
}

Now we can access the repository item with JSTL like this.

      ${query.item.name}

Linked List Interview Questions

  1. Implement Insert and Delete for a Singly Linked List.
    public interface Link<E> {
    	public Link<E> getNext();
    	public void setNext(Link<E> link);
    
    	public Link<E> getPrev();
    	public void setPrev(Link<E> link);
    
    	public E getValue();
    	public void setValue(E value);
    }
    
    public class SingleLink<E> implements Link<E> {
    
    	public SingleLink(E value) { this.value = value; }
    
    	private Link<E> next;
    	private E value;
    
    	public Link<E> getNext() { return next; }
    	public void setNext(Link<E> next) { this.next = next;}
    
    	public Link<E> getPrev() { throw new UnsupportedOperationException(); }
    	public void setPrev(Link<E> prev) { throw new UnsupportedOperationException(); }
    
    	public E getValue() { return value; }
    	public void setValue(E value) { this.value = value;}
    
    	@Override
    	public boolean equals(Object obj) { return this.value.equals(obj); }
    
    	@Override
    	public String toString() { return getValue().toString(); }
    }
    
    public abstract class LinkedList<E> {
    
    	protected abstract Link<E> createHead(E value);
    	protected abstract Link<E> removeHead();
    	protected abstract Link<E> append(Link<E> tail, E value);
    	protected abstract void chain(Link<E> from, Link<E> to);
    	protected abstract void deleteAfterHead(E value);
    	protected abstract boolean isInsert(Link<E> link);
    	protected abstract boolean isEnd(Link<E> link);
    
    	public void insert(E value) {
    
    		if (head == null) {
    			createHead(value);
    			return;
    		}
    
    		Link<E> tmp = head;
    		while (!isInsert(tmp))
    			tmp = tmp.getNext();
    
    		append(tmp, value);
    	}
    
    	public void delete(E value) {
    
    		if (head == null)
    			return;
    
    		if (head.equals(value)) {
    			removeHead();
    			return;
    		}
    
    		deleteAfterHead(value);
    	}
    
    	Link<E> head;
    }
    
    public class SinglyLinkedList<E> extends LinkedList<E> {
    
    	@Override
    	protected Link<E> createHead(E value) {
    		if (value != null) {
    			head = new SingleLink<E>(value);
    		} else {
    			head = null;
    		}
    		return head;
    	}
    
    	@Override
    	protected Link<E> removeHead() {
    		if (isEnd(head.getNext())) {
    			head = null;
    			return null;
    		}
    
    		head = head.getNext();
    		return head;
    	}
    
    	@Override
    	protected Link<E> append(Link<E> tail, E value) {
    		Link<E> link = new SingleLink<E>(value);
    		tail.setNext(link);
    		return link;
    	}
    
    	@Override
    	protected void chain(Link<E> from, Link<E> to) {
    		from.setNext(to);
    	}
    
    	@Override
    	protected void deleteAfterHead(E value) {
    
    		Link<E> tmp = head.getNext();
    		Link<E> prev = head;
    		while (!isEnd(tmp)) {
    			if (tmp.equals(value)) {
    				chain(prev, tmp.getNext());
    				break;
    			}
    			prev = tmp;
    			tmp = tmp.getNext();
    		}
    	}
    
    	@Override
    	protected boolean isInsert(Link<E> link) {
    		return isEnd(link.getNext());
    	}
    
    	@Override
    	protected boolean isEnd(Link<E> link) {
    		return link == null;
    	}
    }
  2. Implement Insert and Delete for a Doubly Linked List.
    public class DoubleLink<E> extends SingleLink<E> {
    
    	public DoubleLink(E value) { super(value); }
    
    	private Link<E> prev;
    
    	@Override
    	public Link<E> getPrev() { return prev; }
    
    	@Override
    	public void setPrev(Link<E> prev) { this.prev = prev; }
    }
    
    public class DoublyLinkedList<E> extends SinglyLinkedList<E> {
    
    	@Override
    	protected Link<E> createHead(E value) {
    		if (value != null) {
    			head = new DoubleLink<E>(value);
    		} else {
    			head = null;
    		}
    		return head;
    	}
    
    	@Override
    	protected Link<E> removeHead() {
    		head = super.removeHead();
    		if (head != null) {
    			head.setPrev(null);
    		}
    
    		return head;
    	}
    
    	@Override
    	protected Link<E> append(Link<E> tail, E value) {
    		Link<E> link = new DoubleLink<E>(value);
    		tail.setNext(link);
    		link.setPrev(tail);
    		return link;
    	}
    
    	@Override
    	protected void chain(Link<E> from, Link<E> to) {
    		from.setNext(to);
    		if (to != null) {
    			to.setPrev(from);
    		}
    	}
    
    	@Override
    	protected void deleteAfterHead(E value) {
    
    		Link<E> tmp = head.getNext();
    		while (!isEnd(tmp)) {
    			if (tmp.equals(value)) {
    				chain(tmp.getPrev(), tmp.getNext());
    				break;
    			}
    			tmp = tmp.getNext();
    		}
    	}
    }
  3. Implement Insert and Delete for a Sorted Linked List.
    public class SortedLinkedList<E> extends SinglyLinkedList<E> {
    
    	@Override
    	public void insert(E value) {
    
    		if (head == null) {
    			createHead(value);
    			return;
    		}
    
    		Link<E> tmp = head;
    		Link<E> prev = null;
    		// XXX: yuck, dynamic casting to Comparable
    		while (!isEnd(tmp) &&
    	Comparable<E>) tmp.getValue()).compareTo(value) < 0) {
    			prev = tmp;
    			tmp = tmp.getNext();
    		}
    
    		Link<E> link = new SingleLink<E>(value);
    		if (prev == null) {
    			link.setNext(head);
    			head = link;
    		} else {
    			prev.setNext(link);
    			link.setNext(tmp);
    		}
    	}
    }
  4. Implement Insert and Delete for a Circular Linked List.
    public class CircularLinkedList<E> extends DoublyLinkedList<E> {
    
    	@Override
    	protected Link<E> createHead(E value) {
    		head = super.createHead(value);
    		if (head != null) {
    			head.setNext(head);
    			head.setPrev(head);
    		}
    		return head;
    	}
    	
    	@Override
    	protected Link<E> removeHead() {
    		if (head.getNext() == head) {
    			head = null;
    			return null;
    		}
    		
    		Link<E> prev = head.getPrev();
    		head = head.getNext();
    		head.setPrev(prev);
    		prev.setNext(head);
    		return head;
    	}		
    
    	@Override
    	protected Link<E> append(Link<E> tail, E value) {
    		Link<E> link = new DoubleLink<E>(value);
    		tail.setNext(link);
    		link.setPrev(tail);
    		link.setNext(head);
    		head.setPrev(link);
    		return link;
    	}
    	
    	@Override
    	protected boolean isEnd(Link link) {
    		return link == head;
    	}
    
    	@Override
    	protected boolean isInsert(Link link) {
    		return link.getNext() == head;
    	}
    }

Data Structures Interview Questions

  1. Find the largest int value in an int array (try to not use native functionality like “max()”)
    	public static int max(int [] array) {
    		int max = Integer.MIN_VALUE;
    		for (int ii = 0; ii < array.length; ii++) {
    			if (array[ii] > max)
    				max = array[ii];
    			if (max == Integer.MAX_VALUE)
    				break;
    		}
    		return max;
    	}
  2. What’s the difference between a stack and a queue?
     
    Stacks are LIFO, i.e. last in, first out. You push things on top of the stack and pop them off the stack.
    Queues are FIFO, i.e. first in, first out. You push things in one side, pop them off the other.
     
  3. Write a function to reverse a string (try to not use native functionality like strrev() or text[::-1])
             char * strrev(char * str) {
               int ii = 0, jj = strlen(str) - 1;
               char tmp;
               while (ii < jj) {
                 tmp = str[ii];
                 str[ii++] = str[jj];
                 str[jj--] = tmp;
               }
               return str;
             }
  4. Write a function that determines if two strings are anagrams. From wikipedia: an anagram is “the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once.” (“abc” “bac” “cba” are anagrams, “abc” and “bba” are not)
  5. /**
     * Returns 1 if it's an anagram, 0 otherwise.
     */
    int anagram(char * str1, char * str2) {
    
      // quick check
      if (strlen(str1) != strlen(str2)) {
        return 0;
      }
    
      // copy str2 to our tmp
      char * tmp = malloc(strlen(str2) + 1);
      strcpy(tmp, str2);
    
      int ii = 0;
      while (str1[ii] != 0) {
        char * ch = strchr (tmp, str1[ii]);
    
        // if not found return -1 to indicate not an anagram
        if (ch == 0)
          return 0;
    
        // remove this found letter from second string
        ch[0] = 0;
        if (ch == tmp) {
          tmp = ch + 1;
        } else if (*(ch+1) != 0) {
          tmp = strcat(tmp, ch+1);
    	}
    
        // go to next character
        ii++;
      }
    
      return 1;
    }

Computing Basics Interview Questions

  1. Use recursion to write a function that determines the length of a string
    int strlen(char * str) {
      if (str[0] == 0)
        return 0;
      return 1 + strlen(str + 1);
    }
  2. What’s the number after F in hexadecimal?0x10
  3. Bitwise: what is 7 | 1? 7 & 1? ~7?

    7 (0111). 1 (0001). -8 (1000).

  4. Write a script that prints the numbers from 1 to 100. But for multiples of four print “Four” instead of the number and for the multiples of seven print “Seven”. For numbers which are multiples of both four and seven print “FourSeven”.
    for (int ii = 1; ii <= 100; ii++) {
    	boolean isMultipleOfFour = (ii % 4 == 0);
    	boolean isMultipleOfSeven = (ii % 7 == 0);
    	if (isMultipleOfFour && isMultipleOfSeven)
    		System.out.println("FourSeven");
     	else if (isMultipleOfFour)
    		System.out.println("Four");
     	else if (isMultipleOfSeven)
     		System.out.println("Seven");
    	else
    		System.out.println(ii);
    }

ATG Consulting Interview

Today I had the most detailed but at same time most interesting ATG consulting interview yet. Here are the questions I was asked with answers when appropriate in italics.

  1. Which versions of ATG have you worked with?
  2. What parts of ATG’s stack have you worked with?
  3. How do you compare ATG with Ruby on Rails?
  4. What is Nucleus?
  5. What is the ATG Repository?
  6. When creating form handlers typically what ATG base class do you extend? GenericFormHandler.java
  7. When creating droplets what ATG base class do you extend? DynamoServlet.java
  8. What form handlers and methods do you use during checkout? ShoppingCartFormHandler, numerous handlers like handleMoveToConfirm, etc.
  9. What does a user typically see during checkout? Add to shopping cart, login, billing and shipping address, payment, confirm, confirmation, email confirmation, shipped email.
  10. How do you compare strings in Java? If String a = “hello” and String b= “hello” what is a == b? True, a and b both reference the same constant string.

In another interview I was asked these questions.

  1. What is HTTP? How does it work?
  2. If HTTP is stateless then how does a web application maintain state.