Appendices

Appendix A – Source Code of the Plug-in

The following sample is the source code for the plug-in class described in this book.

package com.acme.phonestandardizer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.semarchy.engine.extensionpoint.DataRow;
import com.semarchy.engine.extensionpoint.IDataRow;
import com.semarchy.engine.extensionpoint.IRowTransformer;
import com.semarchy.engine.extensionpoint.IRowTransformerSetupInfo;

public class IntlPhoneStandardizer implements IRowTransformer {

	private boolean nullifyOnError;

	public IntlPhoneStandardizer() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Normalize a French phone number to E164 international format.
	 * 
	 * @param pText
	 *            Input phone number.
	 * @return Standardized phone number. If phone number cannot be
	 *         standardized, returns null (if nullifyOnError is true) or the
	 *         input phone number.
	 */
	private String normalizePhoneNumber(String pText) {

		StringBuilder normalized = new StringBuilder(pText.length());
		for (char c : pText.toCharArray()) {
			int digit = Character.digit(c, 10);
			if (digit != -1) {
				normalized.append(digit);
			}
		}

		switch (normalized.length()) {
		case 9:
			normalized.insert(0, "+33");
			break;
		case 10:
			if (normalized.charAt(0) == '0') {
				normalized.replace(0, 1, "+33");
			} else {
				return invalidPhoneNumber(pText);
			}
			break;
		case 11:
			if (normalized.charAt(0) == '3' && normalized.charAt(1) == '3') {
				normalized.insert(0, '+');
			} else {
				return invalidPhoneNumber(pText);
			}
			break;
		default:
			return invalidPhoneNumber(pText);
		}

		return normalized.toString();
	}

	/**
	 * Utility method: Returns null or pText depending on the value of the
	 * nullifyOnError variable value.
	 * 
	 * @param pText
	 *            Input text.
	 * @return Null or pText depending on the value of the nullifyOnError
	 *         variable value.
	 */
	private String invalidPhoneNumber(String pText) {
		// This method is used to return null of the original phone number
		// depending on the value of the nullify On Error parameter.
		if (nullifyOnError)
			return null;
		else
			return pText;
	}

	/**
	 * Utility class to force the nullify on error.
	 * 
	 * @param pNullifyOnError
	 */
	public void setNullify(Boolean pNullifyOnError) {
		nullifyOnError = pNullifyOnError;
	}

	/**
	 * This method transforms an input IDataRow into an output IDataRow. When
	 * implementing this method, use: - the getValue method to retrieve the
	 * input field from the inputIDataRow - the setValue method to set the
	 * output field value of the output IDataRow
	 */
	private IDataRow transformOneRow(IDataRow pDataRow) {
		// First, create the returned IDataRow.
		DataRow outputDataRow = new DataRow();
		// Make sure to set a null value for each output field in the
		// outputDataRow.
		outputDataRow.setValue("STANDARDIZEDPHONE", null);
		// The transformation is done below. It uses the normalizePhoneNumber
		// method defined in the class.
		if (pDataRow.getValue("INPUTPHONE") != null) {
			outputDataRow.setValue("STANDARDIZEDPHONE",
					normalizePhoneNumber(pDataRow.getValue("INPUTPHONE")
							.toString()));
		}
		return outputDataRow;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.semarchy.engine.extensionpoint.IRowTransformer#transform(java.util.List)
	 *      This method transforms a list of rows. In this case, it is a basic
	 *      loop calling the transformOneRow method.
	 */
	@Override
	public List<IDataRow> transform(List<IDataRow> pDataRowsBatch) {
		ArrayList<IDataRow> outputDataRowList = new ArrayList<IDataRow>();
		for (IDataRow inputRow : pDataRowsBatch) {
			outputDataRowList.add(transformOneRow(inputRow));
		}
		return outputDataRowList;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.semarchy.engine.extensionpoint.IRowTransformer#setUp(com.semarchy.engine.extensionpoint.IRowTransformerSetupInfo)
	 *      This method performs the setup of the enricher. It retrieves
	 *      parameters through a SetupInfo object.
	 */

	@Override
	public void setUp(IRowTransformerSetupInfo pSetupInfo) {
		Map<String, Object> paramList = pSetupInfo.getParameters();
		Object nullifyOnErrorParamValue = paramList.get("NULLIFYONERROR");
		if (nullifyOnErrorParamValue != null)
			setNullify(nullifyOnErrorParamValue.equals("1")); //$NON-NLS-1$
	}
	
	@Override
	public void tearDown() {

	}

}


Appendix B – Source Code of the JUnit Test Class

The following sample is the source code for the JUnit test class described in this book.

package com.acme.phonestandardizer.tests;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.acme.phonestandardizer.IntlPhoneStandardizer;
import com.semarchy.engine.extensionpoint.DataRow;
import com.semarchy.engine.extensionpoint.IDataRow;

public class TestPhoneFrance {

	@Test
	public void testTransformNullPhones() {
		checkPhoneTransform(true, null, null);
		checkPhoneTransform(false, null, null);
	}

	@Test
	public void testTransformBadPhones() {
		checkPhoneTransform(true, "abcd", null);
		checkPhoneTransform(false, "abcd", "abcd");
		checkPhoneTransform(true, "64169710", null);
		checkPhoneTransform(false, "64169710", "64169710");
		checkPhoneTransform(true, "111164169710", null);
		checkPhoneTransform(false, "111164169710", "111164169710");
		checkPhoneTransform(true, "+44664169710", null);
		checkPhoneTransform(false, "+44664169710", "+44664169710");
		checkPhoneTransform(true, "1664169710", null);
		checkPhoneTransform(false, "1664169710", "1664169710");
	}

	@Test
	public void testTransformGoodPhones() {
		checkPhoneTransform(true, "0664169710", "+33664169710");
		checkPhoneTransform(true, "664169710", "+33664169710");
		checkPhoneTransform(true, "+33664169710", "+33664169710");
		checkPhoneTransform(true, "0478339229", "+33478339229");
		checkPhoneTransform(true, "(0)4.78.33.92.29...", "+33478339229");
	}

	/**
	 * 
	 * Tests the behavior of the phone transformer. It takes three parameters
	 * corresponding to the parameter, the input and output string of the
	 * transformeR.
	 * 
	 * 
	 * @param nullifyOnError
	 * @param inputPhone
	 * @param expectedOutputPhone
	 */
	private void checkPhoneTransform(Boolean nullifyOnError, String inputPhone,
			String expectedOutputPhone) {
		
		IntlPhoneStandardizer phoneStd = new IntlPhoneStandardizer();
		phoneStd.setNullify(nullifyOnError);
		
		IDataRow inDataRow = new DataRow();
		((DataRow) inDataRow).setValue("INPUTPHONE", inputPhone);
		
		List<IDataRow> inDataRowList = new ArrayList<IDataRow>();
		inDataRowList.add(inDataRow);
		
		List<IDataRow> outDataRowList = phoneStd.transform(inDataRowList);
		
		assertEquals(expectedOutputPhone, outDataRowList.get(0).getValue("STANDARDIZEDPHONE"));
	}

}