Tuesday, October 11, 2011

Sample Ant Builds

Below are two Ant builds for Java Web JEE projects, using default Eclipse folder structure. Each copies some files that need to be different in the Test vs. Prod build. These were run using Ant 1.8. I'm not indicating these use "best practices," just some that worked for me.

Ant Build.xml One

<project name="myproject" default="dist" basedir=".">

<property name="project.name" value="MyProject" />
<property name="dist.dir" location="dist" />
<property name="dist.prod.dir" location="${dist.dir}/prod" />
<property name="dist.test.dir" location="${dist.dir}/test" />
<property name="conf.prod" location="conf/prod" />
<property name="conf.test" location="conf/test" />
<property name="web.dir" location="WebContent" />
<property name="web.lib" location="${web.dir}/WEB-INF/lib" />
<property name="web.script" location="${web.dir}/scripts" />

<path id="classpath">
<pathelement location="${web.lib}/jstl.jar"></pathelement>
<pathelement location="${web.lib}/standard.jar"></pathelement>
</path>

<target name="dist">
<tstamp />
<echo message="${ant.project.name}: ${ant.file}" />
<delete dir="${dist.dir}"/>
<mkdir dir="${dist.test.dir}"/>
<mkdir dir="${dist.prod.dir}"/>

<echo>Building PROD war file</echo>
<copy file="${conf.prod}/script/validate.js" tofile="${web.script}/validate.js"
overwrite="true" />
<copy file="${conf.prod}/WEB-INF/web.xml" tofile="${web.dir}/WEB-INF/web.xml"
overwrite="true" />
<war destfile="${dist.prod.dir}\${project.name}.war" webxml="${web.dir}\WEB-INF\web.xml">
<fileset dir="${web.dir}" />
</war>

<echo>Building TEST war file</echo>
<copy file="${conf.test}/script/validate.js" tofile="${web.script}/validate.js"
overwrite="true" />
<copy file="${conf.test}/WEB-INF/web.xml" tofile="${web.dir}/WEB-INF/web.xml"
overwrite="true" />
<war destfile="${dist.test.dir}\${project.name}.war" webxml="${web.dir}\WEB-INF\web.xml">
<fileset dir="${web.dir}" />
</war>
<echo>${ant.project.name} build complete</echo>
</target>

</project>


Ant Build.xml Two

<?xml version = '1.0' encoding = 'windows-1252'?>

<project name="myproject" default="make" basedir=".">

<!--Set the output directories-->
<property name="compile.outdir" value="build/classes"/>
<property name="dist.outdir" value="dist"/>

<!-- Project directories -->
<property name="src.dir" value="src"/>
<property name="web.dir" value="WebContent"/>
<property name="web.lib.dir" value="WebContent/WEB-INF/lib"/>
<property name="conf.dir" value="conf"/>
<property name="test.dir" value="test"/>
<property name="prod.dir" value="prod"/>

<!-- Project configuration -->
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>

<!-- Web application names -->
<property name="webapp.name.test" value="myproject"/>
<property name="webapp.name.prod" value="myproject"/>

<!-- Create a fileset of the webapp libraries -->
<fileset dir="${web.lib.dir}" id="webapp.lib" />

<!-- Create a fileset of the webapp libraries -->
<fileset dir="external.lib/" id="external.lib" />

<!--Set the classpath-->
<path id="classpath">
<pathelement location="${compile.outdir}"/>
<fileset refid="webapp.lib" />
<fileset refid="external.lib" />
</path>

<!--Set the source path-->
<path id="srcpath">
<pathelement location="${src.dir}"/>
</path>

<target name="init">
<tstamp/>
</target>

<target name="compile" depends="init">
<mkdir dir="${compile.outdir}"/>
<echo>My Project compile</echo>
<!--Compile Java source files-->
<javac debug="true" debuglevel="${debuglevel}" destdir="${compile.outdir}" source="${source}" target="${target}" includeantruntime="false">
<classpath refid="classpath"/>
<src refid="srcpath"/>
</javac>
<!--Copy files to output directory-->
<copy file="${src.dir}/com/mysite/myproject/dbutil/Database.properties"
tofile="${compile.outdir}/com/mysite/myproject/dbutil/Database.properties"/>
<copy file="${src.dir}/messages.properties" tofile="${compile.outdir}/messages.properties"/>
<copy file="${src.dir}/log4j.xml" tofile="${compile.outdir}/log4j.xml"/>
<copy file="${src.dir}/log4j.dtd" tofile="${compile.outdir}/log4j.dtd"/>
</target>

<target name="clean">
<!--Delete output directories-->
<delete dir="${compile.outdir}"/>
</target>

<target depends="clean" name="cleanall">
<delete dir="${dist.outdir}"/>
</target>

<target name="make" depends="compile"/>

<target name="rebuild" depends="clean,compile"/>

<macrodef name="build-war">
<attribute name="dist.conf" />
<attribute name="webapp.name" />
<sequential>
<!-- Files differ between Test and Prod in conf dir: -->
<!-- Database.properties, log4j.xml, web.xml, logon.jsp -->
<mkdir dir="${dist.outdir}/@{dist.conf}" />
<mkdir dir="${dist.outdir}/@{dist.conf}/classes" />
<copy todir="${dist.outdir}/@{dist.conf}/classes">
<fileset dir="${compile.outdir}" />
</copy>
<copy todir="${dist.outdir}/@{dist.conf}/classes" overwrite="true">
<fileset dir="${conf.dir}/@{dist.conf}/classes" />
</copy>
<copy file="${conf.dir}/@{dist.conf}/WebContent/signon.jsp"
todir="${web.dir}" overwrite="true" >
</copy>

<war destfile="${dist.outdir}/@{dist.conf}/@{webapp.name}.war" webxml="${conf.dir}/@{dist.conf}/WebContent/WEB-INF/web.xml">
<fileset dir="${web.dir}/" excludes="test*.jsp,/workqueue/reports/**/*.csv"/>
<classes dir="${dist.outdir}/@{dist.conf}/classes" excludes="" />
</war>

<delete dir="${dist.outdir}/@{dist.conf}/classes" />
</sequential>
</macrodef>

<target name="dist" depends="cleanall,rebuild">
<build-war dist.conf="${prod.dir}" webapp.name="${webapp.name.prod}" />
<build-war dist.conf="${test.dir}" webapp.name="${webapp.name.test}" />
</target>
</project>

Monday, October 10, 2011

Favorite Free Development Utilities

Here is a list of software that I've found helpful for various development tasks. Best of all, they are all free.

Text Editor: Notepad++ - if you are still using Window's default Notepad or Wordpad, you have got to get this. Text formatting and tabbed documents are two of the many features.

File Compare: ExamDiff - does a better job than WinMerge when comparing two files.

Folder Compare: WinMerge - good for comparing folder tree structure, seems to generate a lot of false hits when just comparing two files.

Screen Capture: PrintScreen by Gadwin - drag a rectangle around anything on your screen, press enter and it's on your clipboard

Quick image editing: Paint.NET - especially good if you are relying on Window's default Paint.

Load Testing: JMeter - basic web load testing

Web Service Testing: soapUI - create test XML, send it to a SOAP web service, see the XML response

Tuesday, September 27, 2011

Connecting Grails to an Oracle Database

These steps used Grails 1.3.4 and Oracle 11g.

datasource.groovy

dataSource {
pooled = true
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
dbCreate = "create-drop" // one of 'create', 'create-drop','update', or can be left out
/* create-drop - Drop and re-create the database when Grails is run
* create - Create the database if it doesn't exist, but don't modify it if it does. DELETES existing data.
* update - Create the database if it doesn't exist, and modify it if it does exist
*/
url = "jdbc:hsqldb:file:devDB;shutdown=true"
//loggingSql = true
}
}

test {
dataSource {
driverClassName = "oracle.jdbc.driver.OracleDriver"
username = "APP_USER"
password = "APP_PASSWORD"
//dbCreate = "update" LEAVE COMMENTED OUT - NOT NEEDED
url = "jdbc:oracle:thin:@servername:1521:schema"
dialect="org.hibernate.dialect.Oracle10gDialect"
//loggingSql = true
}
hibernate {
default_schema="schema"
}
}
production {
// same as test
}
}


Set up a sequence Grails can use and tell this Grails domain object which tablename and sequence to use.
DomainObject.groovy

static mapping = {
table 'APP_TABLENAME'
id generator:'sequence',params:[sequence:'APP_SEQ']
}


Here is the SQL used to create the table.

CREATE TABLE schema.APP_TABLENAME
(
ID NUMBER(10,0) NOT NULL,
FIELD1 VARCHAR2(100 CHAR) NOT NULL,
// MORE COLUMNS
LAST_UPDATED TIMESTAMP DEFAULT SYSDATE NOT NULL,
LAST_UPDATE_IP VARCHAR2(15 CHAR),
LAST_UPDATE_USER VARCHAR2(10 CHAR) DEFAULT 'import' NOT NULL,
DATE_CREATED TIMESTAMP DEFAULT SYSDATE NOT NULL,
DATE_CREATED_USER VARCHAR2(10 CHAR) DEFAULT 'import' NOT NULL ,
VERSION NUMBER(19,0)
)
TABLESPACE APP_DATA
;

ALTER TABLE schema.APP_TABLENAME ADD
CONSTRAINT APP_TABLENAME_PK PRIMARY KEY (ID)
;

CREATE SEQUENCE schema.APP_SEQ;

CREATE OR REPLACE TRIGGER schema.APP_TABLENAME_TRG
BEFORE INSERT ON schema.APP_TABLENAME
FOR EACH ROW
WHEN (new.id IS NULL)
BEGIN
SELECT APP_SEQ.NEXTVAL INTO :new.id FROM dual;
END;

Populate JSP with messages from a properties file

I had a series of JSP pages that used certain values, questions or messages. Some of these were long, and potentially subject to change by the business group.

To eliminate typing the messages in multiple places, and potentially miss one should it change in the future, I put them all in a properties file, then loaded them to the JSP that way. Here's my setup:

1) Create the messages.properties file in the Eclipse project folder 'WebContent > WEB-INF > classes'. Entries are in the 'title=Page Title' format.

2) Create a new JSP file, messages.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<fmt:bundle basename="messages">
<fmt:message key="title" var="title"/>
</fmt:bundle>


3) At the top of the JSP you wish to use the messages, just include the 'messages.jsp' file. Then reference them like any other variable.

<%@ include file="messages.jsp" %> // ADDED HERE
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>${title}</title> // USED HERE

Masking numeric values with JQuery

The JQuery plugin Masked Input is great if you want to auto-format a numeric field. for example, you can add '/' in a date field, '-' in a phone field, etc. Then the user just types in the numbers, and the field is automatically formatted.

HTML setup

<script language="javascript" type='text/javascript' src='scripts/jquery-1.6.1.min.js'></script>
<script language="javascript" type='text/javascript' src='scripts/jquery.maskedinput-1.3.min.js'></script>
<script language="javascript" type="text/javascript">
jQuery(function($){
$("#birthDate").mask("99/99/9999");
$("#phone").mask("(999) 999-9999");
$("#zip").mask("99999");
});
</script>
</head>

Custom JSTL tags

To add custom tags to your JSP page, create the tag file and put it in the Java project folder WebContent > WEB-INF > tags

In this example, we create a tag that can be used to escape user-inputted values for display on the next page.

escape.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">

<description>
calls StringEscapeUtils.escapeHtml for value
</description>
<tlib-version>1.0</tlib-version>
<short-name>escape</short-name>
<uri>escape</uri>
<function>
<name>esc</name>
<function-class>org.apache.commons.lang.StringEscapeUtils</function-class>
<function-signature>
java.lang.String escapeHtml( java.lang.String )
</function-signature>
</function>
</taglib>


In the JSP page

<%@ taglib uri="escape" prefix="es" %>

${es:esc(param.home)}

JSP and JSTL samples

Adding JSTL to your page. Formatting will vary based on version. Visit this excellent FAQ on JSTL on JavaRanch.

Perform an IF check.
<c:if test="${param.job == 'Other'}">
// conditional HTML here
</c:if>


For IF/ELSE, use Choose When/Otherwise
<c:choose>
<c:when test="${param.home != '1'}">
<input type="hidden" name="Home" value="0">
</c:when>
<c:otherwise>
<input type="hidden" name="Home" value="1">
</c:otherwise>
</c:choose>


Add the current date to your page with JSTL.

<fmt:formatDate type="date" dateStyle="long" value="<%=new java.util.Date()%>" />

Friday, September 23, 2011

JQuery examples - checkbox, labels

Here is a combination that checks if a checkbox is checked, hides and shows various fields, and changes the label for an input field. Specifically, a user can choose if an address is a foreign address, which will re-label 'City' and remove State and Zip.




Unchecked:






Checked:






JQuery code:

function handleForeign() {
if ($('#foreignAddr').is(':checked')) {
$('#foreignAddress').val("Yes");
$("label[for='city']").text("City/Province/Code");
$("label[for='state']").hide();
$('#state').hide();
$("label[for='zipcode']").hide();
$('#zipcode').hide();
} else {
$('#foreignAddress').val("");
$("label[for='city']").text("City");
$("label[for='state']").show();
$('#state').show();
$("label[for='zipcode']").show();
$('#zipcode').show();
}
}


HTML/JSP code:

<div class="row">
<div class="firstcol">
<label for="foreignAddr" class="strong">Current Address</label>
</div>
<div class="col">&nbsp;
<input name="foreignAddr" id="foreignAddr" type="checkbox" onclick="javascript:handleForeign();" />
<span class="label">Foreign Address</span>
</div>
</div>
<div class="row">
<div class="firstcol">
<label for="adddress">Street Address </label>
</div>
<div class="col">
<input name="adddress" type="text" class="required" id="adddress" size="40" maxlength="128" />
<label for="apartm">Apt/Suite/Unit </label>
<input name="apartm" type="text" class="input" id="apartm" size="4" maxlength="10">
</div>
</div>
<div class="row">
<div class="firstcol">
<label for="city">City </label>
</div>
<div class="col">
<input name="city" id="city" type="text" class="required"maxlength="50" />
<label for="state">State</label>
<select name="state" id="state" class="required">
<%@ include file="list_states.html" %>
</select>
<label for="zipcode">Zip </label>
<input name="zipcode" type="text" class="required" id="zipcode" size="5" maxlength="5" />
</div>
</div>
<div class="row">
<div class="firstcol">
<span class="label">Country </span>
</div>
<div class="col">
<select name="country" id="country" class="required">
<%@ include file="list_countries.html" %>
</select>
</div>
</div>


Here is the CSS for the columns:

div.row {
clear: both;
margin: 4px 5px 0px 5px;
min-width: 500px;
overflow: auto; /* helps with Firefox spacing issue */
}
div.firstcol {
text-align: right;
float: left;
width: 180px;
}
div.col {
text-align: left;
float: left;
width: 420px;
}

Ajax with JQuery and Java

I had a need to populate some drop-down select fields with database values for a customer form. I got it to work using JQuery 1.4.2 and Java 6.

HTML or JSP page:

<script language="javascript" type="text/javascript">
jQuery(function($){
// other initial setup
startup();
});
</script>
</head>

JavaScript

function startup() {
loadJobData();
// other initial functions
}

function loadJobData() {
$("select#jobPosition").load("MyAjax",{id: "jobtitles", ajax: 'true'});
}

Java Controller

public class MyAjaxController extends HttpServlet {

protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

private void processRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException {

String dataRequested = request.getParameter("id");
JobListData listData = new JobListData();
String displayText = listData.getData(dataRequested); // go to database, file, whereever

response.setContentType("text/xml");
PrintWriter out = response.getWriter();
out.println(displayText);
out.flush();
out.close();
}

Standard web.xml entry

<servlet>
<description>my ajax</description>
<display-name>MyAjaxController</display-name>
<servlet-name>MyAjaxController</servlet-name>
<servlet-class>com.mysite.MyAjaxController</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyAjaxController</servlet-name>
<url-pattern>/MyAjax</url-pattern>
</servlet-mapping>

Friday, September 16, 2011

Setting up SyntaxHighlighter 3 with Blogger

Initial post to set up some code syntax for blog posts, using SyntaxHighlighter.

Here is code using only the 'pre' tag:

function handleHome() {
str = $("input[name='home']:checked").val();
if (str == "NO") {
$('.homeNo').show();
} else {
$('.homeNo').hide();
}
}

Here is the same code using the tool:
function handleHome() {
str = $("input[name='home']:checked").val();
if (str == "NO") {
$('.homeNo').show();
} else {
$('.homeNo').hide();
}
}

Here is what I pasted in the Blogger > Design > Edit HTML section, just before the ending tag:

<!--SYNTAX HIGHLIGHTER BEGINS-->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'></script>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<!--SYNTAX HIGHLIGHTER ENDS-->


There it is. The one extra is the need to encode all brackets. Found this link that does that.