Thursday, April 23, 2009

Java SXL Transformation

TransformerFactory tFactory = TransformerFactory.newInstance();
Source xslSource = new StreamSource(new File(CORE_DIR+"/conf/xslt","media.xsl"));
transformer = tFactory.newTransformer(xslSource);

StringReader sr = new StringReader(result);
StringWriter sw = new StringWriter();

Source xmlInput = new StreamSource();
StreamResult xmlOutput = new StreamResult(sw);

transformer.transform(xmlInput, xmlOutput);
//System.out.println(sr);
System.out.println(sw);

Wednesday, April 8, 2009

Spring Custom Extensions

  • CustomPropertyPlaceHolderConfigurer
public class CustomPropertyPlaceHolderConfigurer extends PropertyPlaceholderConfigurer{

@Override
public void setLocations(Resource[] locations) {

Resource[] newLocations =new Resource[locations.length+1];
for(int i=0;i newLocations[i]=locations[i];
}
newLocations[locations.length]= new ClassPathResource("env/"+System.getProperty(PROP_MODE)+".properties");
super.setLocations(newLocations);
}
}


  • CustomContextLoaderListener
public class CustomContextLoaderListener extends ContextLoaderListener {

private Log log = LogFactory.getLog(getClass());

@Override
public void contextInitialized(ServletContextEvent event) {

String port=null;
Parameters para = (Parameters)event.getServletContext().getAttribute(PROP_RS_PARAMS);
for(String p:Arrays.asList(para.getPorts())){
if(p.contains("public")){
port=p.substring(0,p.indexOf("/"));
break;
}
}
log.info("Startup Params: \nMODE .... "+para.getMode()+ "\nHOST .... "+para.getHost()+"\nPORT ... "+port);
System.setProperty(PROP_MODE, para.getMode());
System.setProperty(PROP_HOST_IP, para.getHost());
System.setProperty(PROP_HOST_PORT, port);
super.contextInitialized(event);
}
}

Http Client Usage

public String query(String host, int port, String queryString) throws SolrException {

HostConfiguration hostConfig = new HostConfiguration();
hostConfig.setHost(host,port);
client.setHostConfiguration(hostConfig);

GetMethod method = new GetMethod(queryString);
String buffer;
StringBuilder response;
try {

int statusCode = client.executeMethod(method);

if (statusCode != HttpStatus.SC_OK) {
log.error("Method failed: " + method.getStatusLine());
throw new HttpException(method.getStatusLine().toString());
}else{
BufferedReader in = new BufferedReader(new InputStreamReader
(method.getResponseBodyAsStream(), method.getResponseCharSet()));
response = new StringBuilder();
while( (buffer=in.readLine()) != null){
response.append(buffer);
}
}
} catch (HttpException e) {
log.error("Fatal protocol violation: ",e);
throw new SolrException(e);
} catch (IOException e) {
log.error("Fatal transport error: ", e);
throw new SolrException(e);
} finally {
method.releaseConnection();
}
return response.toString();
}

Map Utils

  • Merge Maps
public static List> mergeMaps
(List> list1, List> list2, String primKey) {

List> output = new ArrayList>(list1.size());
Object key1, key2;
Map map;
for(Map map1:list1){

key1 = map1.get(primKey);
map = new HashMap();
map.putAll(map1);
for(Map map2:list2){
key2 = map2.get(primKey);
if(key1.equals(key2)){
map.putAll(map2);
break;
}
}
output.add(map);
}
return output;
}


  • Normalize Map
/**
* If the input list is like this:
* [
* {ID=3, TAG=Tag1, NAME=Name1},
* {ID=3, TAG=Tag2, NAME=Name1},
* {ID=3, TAG=Tag3, NAME=Name1},
* {ID=4, TAG=Tag4, NAME=Name2},
* {ID=4, TAG=Tag5, NAME=Name2},
* {ID=5, TAG=Tag6, NAME=Name3}
* ]
*
* The output list would look like this:
* [
* {ID=3, TAG=[Tag1, Tag2, Tag3], NAME=Name1},
* {ID=4, TAG=[Tag4, Tag5], NAME=Name2},
* {ID=5, TAG=[Tag6], NAME=Name3}
* ]
*
* @param list
* @param primKey (E.g.: ID)
* @param joinKey (E.g.: TAG)
* @param stripOtherCols - dictates if other fields in the map (like: NAME) needs to be stripped or preserved in output.
* @return
*/
@SuppressWarnings("unchecked")
public static List> normalize
(List> list, String primKey, String joinKey, boolean stripOtherCols) {

Map> outputMap = new HashMap>();
Map innerOutputMap;

for(Map innerInputMap:list){
if( (innerOutputMap = outputMap.get( innerInputMap.get(primKey).toString() ) ) == null ){
innerOutputMap = populateInnerOutputmap(innerInputMap, primKey, joinKey, stripOtherCols);
outputMap.put(innerInputMap.get(primKey).toString(),innerOutputMap);
}
if( isNotNull(innerInputMap.get(joinKey)) ){
List itemList = (List)innerOutputMap.get(joinKey);
itemList.add( innerInputMap.get(joinKey) );
}
}
List> outputList =
(List)Arrays.asList( outputMap.values().toArray() );

return outputList;
}


  • De-normalize Key Value Pair
/**
* If the input list is like this:
* [
* {VAL=Val1, ID=3, KEY=Key1, NAME=Name1},
* {VAL=Val2, ID=3, KEY=Key2, NAME=Name1},
* {VAL=Val3, ID=3, KEY=Key3, NAME=Name1},
* {VAL=Val4, ID=4, KEY=Key4, NAME=Name1},
* {VAL=Val5, ID=4, KEY=Key5, NAME=Name1},
* {VAL=Val6, ID=5, KEY=Key6, NAME=Name1}
* ]
*
* The output list would look like this:
* [
* {ID=3, Key1=Val1, Key3=Val3, Key2=Val2, NAME=Name1},
* {ID=5, Key6=Val6, NAME=Name1},
* {ID=4, Key4=Val4, Key5=Val5, NAME=Name1}
* ]
*
* @param list
* @param primKey
* @param key
* @param val
* @param stripOtherCols - dictates if other fields in the map (like: NAME) needs to be stripped or preserved in output.
* @return
*/
@SuppressWarnings("unchecked")
public static List> denormalizeKeyValuePair
(List> list, String primKey, String key, String val, boolean stripOtherCols) {

Map> outputMap = new HashMap>();
Map innerOutputMap;

for(Map innerInputMap:list){
if( (innerOutputMap = outputMap.get( innerInputMap.get(primKey).toString() )) == null){
innerOutputMap = populateInnerOutputmap(innerInputMap, primKey, null, stripOtherCols);
outputMap.put(innerInputMap.get(primKey).toString(),innerOutputMap);
}
if( isNotNull(innerInputMap.get(key)) && isNotNull(innerInputMap.get(val))){
innerOutputMap.put((String)innerInputMap.get(key), innerInputMap.get(val));
}
}

List> outputList =
(List)Arrays.asList( outputMap.values().toArray() );

return outputList;
}

  • Populate InnerOutputmap
private static Map populateInnerOutputmap
(Map innerInputMap, String primKey, String joinKey, boolean stripOtherCols){

Map innerOutputMap = new HashMap();
if( stripOtherCols ){
innerOutputMap.put(primKey, innerInputMap.get(primKey));
}else{
innerOutputMap.putAll(innerInputMap);
}
if(joinKey != null ){
innerOutputMap.put(joinKey, new ArrayList());
}
return innerOutputMap;
}


  • isNotNull
private static boolean isNotNull(Object obj){
if(obj != null ){
//This special check for String is because of Oracle (probably all DBs have similar behavior)
//Null values are sent as String 'null'. Probably we can use something like NVL to avoind that.
//Once NVL stuff is tested, we can remove this 'null' check
if( obj instanceof String) {
if( !"null".equalsIgnoreCase( (String)obj ) & ((String)obj).length() > 0 ){
return true;
}else{
return false;
}
}else{
return true;
}
}else{
return false;
}
}

Is Host Reachable

public static boolean isHostReachable(String ip){

boolean pingable = false;
String[] ips = StringUtils.split(ip,".");
byte[] addr2 = new byte[ips.length];
for(int i=0,j; i j = Integer.parseInt(ips[i]);
addr2[i]=(byte)j;
}
try {
pingable = InetAddress.getByAddress(addr2).isReachable(1500);

} catch (UnknownHostException e) {
pingable = false;
log.error(ip + " Indexer Host not reachabe.");
} catch (IOException e) {
pingable = false;
log.error(ip + " Indexer Host not reachabe.");
}
return pingable;
}

Get Local Host LAN Address

/**
* This method is intended for Linux Systems, as Linux fails to provide the external IP
* when using InetAddress.getLocalHost(). It instead provides the loopback address.
*
* @return
* @throws UnknownHostException
*/
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
// Iterate all NICs (network interface cards)...
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {

NetworkInterface iface = ifaces.nextElement();
// Iterate all IP addresses assigned to each card...
for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {

InetAddress inetAddr = inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) {

if (inetAddr.isSiteLocalAddress()) {
// Found non-loopback site-local address. Return it immediately...
return inetAddr;
}
else if (candidateAddress == null) {
// Found non-loopback address, but not necessarily site-local.
// Store it as a candidate to be returned if site-local address is not subsequently found...
candidateAddress = inetAddr;
// Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
// only the first. For subsequent iterations, candidate will be non-null.
}
}
}
}
if (candidateAddress != null) {
// We did not find a site-local address, but we found some other non-loopback address.
// Server might have a non-site-local address assigned to its NIC (or it might be running
// IPv6 which deprecates the "site-local" concept).
// Return this non-loopback candidate address...
return candidateAddress;
}
// At this point, we did not find a non-loopback address.
// Fall back to returning whatever InetAddress.getLocalHost() returns...
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
if (jdkSuppliedAddress == null) {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
}
return jdkSuppliedAddress;
}
catch (Exception e) {
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
unknownHostException.initCause(e);
throw unknownHostException;
}
}

Spring Config

Web.xml

  • Context Param
<.context-param.>
<.param-name.>contextConfigLocation<./param-name.>
<.value.>/WEB-INF/spring/applicationContext.xml<./param-value.>
<./context-param.>
<.context-param.>
<.param-name>log4jExposeWebAppRoot<./param-name>
<.param-value>false<./param-value..>
<./context-param.>



  • Dispatcher Servlet
<.servlet>
<.servlet-name.>searchApp<./servlet-name.>
<.servlet-class.>com.ea.sw.search.web.servlet.SearchDispatcherServlet<./servlet-class.>
<.servlet-class.>org.springframework.web.servlet.DispatcherServlet<./servlet-class.>
<.init-param.>
<.param-name.>contextConfigLocation<./param-name.>
<.param-value.>/WEB-INF/spring/webContext.xml<./param-value.>
<./init-param.>
<.load-on-startup.>1<./load-on-startup.>
<./servlet.>




WebContext.xml
  • URL Mapping
<.bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping".>
<.property name="mappings".>
<.props.>
<.prop key="/all">allSearchSequentialController<./prop.>
<./props>
<./property.>
<.property name="alwaysUseFullPath".>
<.value>true<./value.>
<./property.>
<./bean.>

  • ArrayList
<.bean id="handlers" class="java.util.ArrayList".>
<.constructor-arg.>
<.list.>
<.ref bean="groupSearchHandler"/.>
<.ref bean="mediaSearchHandler"/.>
<.ref bean="personaSearchHandler"/.>
<./list.>
<./constructor-arg.>
<./bean.>

  • ArrayList - Load Properties
<.bean id="locations" class="java.util.ArrayList".>
<.constructor-arg.>
<.list.>
<.value.>classpath:default.properties<./value.>
<.value.>classpath:index.properties<./value.>
<./list.>
<./constructor-arg.>
<./bean.>

  • Property Placeholder Config
<.bean id="placeholderConfig" class="com.ea.sw.search.spring.CustomPropertyPlaceHolderConfigurer".>
<.property name="locations" ref="locations"/.>
<./bean.>

  • Application Properties
<.bean id="appProperties" class="com.ea.sw.search.util.AppProperties".>
<.property name="properties".>
<.bean class="org.springframework.beans.factory.config.PropertiesFactoryBean".>
<.property name="locations" ref="locations"/.>
<./bean.>
<./property.>
<./bean.>
  • Map
<.bean id="dateMap" class="java.util.HashMap".>
<.constructor-arg.>
<.map.>
<.entry key="m".><.value>MINUTE<./value.><./entry.>
<.entry key="h".><.value>HOUR<./value.><./entry.>
<.entry key="d".><.value>DAY<./value.><./entry.>
<.entry key="y".><.value>YEAR<./value.><./entry.>
<./map.>
<./constructor-arg.>
<./bean.>

  • Data Source
<.bean id="searchDS" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource".>
<.property name="driverClassName".><.value.>${jdbc.driverClassName}<./value.><./property.>
<.property name="url".><.value.>${jdbc.url}<./value.><./property.>
<.property name="username".><.value.>${jdbc.username}<./value.><./property.>
<.property name="password".><.value.>${jdbc.password}<./value.><./property.>
<./bean.>

  • JDBC Templae
<.bean id="searchJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate".>
<.property name="dataSource" ref="searchDS"/.>
<.property name="fetchSize" value="${jdbc.fetch.size}"/.>
<./bean.>

  • Scheduler Configurations
<.bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean".>
<.property name="triggers".>
<.list.>
<.ref bean="mediaIndexTrigger" /.>
<./list.>
<./property.>
<./bean.>

<.bean id="mediaIndexTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean".>
<.property name="startDelay" value="${media.index.start}" /.>
<.property name="repeatInterval" value="${media.cron.interval}" /.>
<.property name="jobDetail".>
<.bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean".>
<.property name="targetObject" ref="mediaIndex" /.>
<.property name="targetMethod" value="index" /.>
<.property name="concurrent" value="false" /.>
<./bean.>
<./property.>
<./bean.>

<.bean id="mediaIndex" class="com.ea.sw.search.indexer.impl.DefaultIndexImpl".>
<./bean.>