Friday, September 9, 2016

Find the most repeating character in a string

Following snipper will return most repeated character in a string

public char getMax(String str) {
    char maxChar = ' ';
    int maxCnt = 0;
    char [] charmax = new char[Character.MAX_VALUE+1];
    for(int i = str.length()-1; i>=0; i--) {
        char ch = str.charAt(i);
        int num = ++charmax[ch];
        if(num >= maxCnt) {
            maxCnt = charmax[ch];
            maxChar = ch;
        }
    }
    return maxChar;
}


Thursday, September 8, 2016

Validate String parathesis

Simple program to validate parenthesis in a string. e.g. "(12(ab(dkc)))" is valid but "(12(ab)(dkc)))" is not

The simple solution is to use stack to push the "(" character and pop the same when you have ")"

import java.util.Stack;

public class StringValidation {
public Boolean isValid(String str) {
Boolean isValid = true;
Stack stack = new Stack<>();
char[] chars = str.toCharArray();
for (char achar : chars) {
if (achar == '(') {
stack.push(achar);
}
if (achar == ')') {
if (stack.isEmpty()) return false;
stack.pop();
}
}
if (!stack.isEmpty()) return false;
return isValid;
}
public static void main(String [] args) {
String str1 = "(12(ab(dkc)))";
                String str2 = "(12(a)b(dkc)))";
StringValidation ex = new StringValidation();
System.out.println("str1: " + ex.isValid(str1));
                System.out.println("str2: " + ex.isValid(str2));
}
}

Tuesday, September 6, 2016

Run Groovy script as Rest service

We have a requirement to call the arbitrary groovy script and the server execute the script and sends back the JSON response.

Groovy shell is not thread safe and we either need to synchronize access to the groovy shell's evaluate method or pre-initialize the groovy shell instances in object pool. We have used object pool since each shell is associated with predefined initialization.

Also GSON is used to format the groovy output into JSON format and the json string can be returned  to the client. The groovy script can return any object and the same object is formatted to JSON and will send back to the client.

public class GroovyRequest {

private String client;
private String type;
private String script;
private String user;

public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
}

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("processGroovy")
public Response getJsonData(GroovyRequest req) {
String script = req.getScript();
String type = req.getType();
String client = req.getClient();
String user = req.getUser();
Response response = null;
response = processRequest(client, type, script, user, MediaType.APPLICATION_JSON);
return response;
}

private Response processRequest(String client, String type, String script, String user, String responseType) {
String gvyOutput = null;
Response response = null;
mLogger.log(Level.INFO, "Client: {0} type: {1} Script: {2}", new Object[] {client, type, script});
if (client == null || client.equals("") ||
type == null || type.equals("") ||
script == null || script.equals("") ){
//user == null || user.equals("")) {
gvyOutput = "Please correct the request parameters";
response =  Response.status(200).type(MediaType.TEXT_PLAIN).entity(gvyOutput).build();
return response;
}

if (responseType == null) {
responseType = MediaType.TEXT_PLAIN;
}
        GroovyShell shell = null;
try {
mLogger.info("---------------------------------------------------\n GroovyPool: total: " + groovyPool.getMaxTotal() + " maxIdle: " + groovyPool.getMaxIdle() + " createdCount: " + groovyPool.getCreatedCount() +
" \n MinEvictableIdleTimeMillis: " + groovyPool.getMinEvictableIdleTimeMillis() + " TimeBetweenEvictionRunsMillis: " + groovyPool.getTimeBetweenEvictionRunsMillis() +
" \n NumActive: " + groovyPool.getNumActive() + " NumIdle: " + groovyPool.getNumIdle());
            shell = groovyPool.borrowObject();
gvyOutput = (String) shell.evaluate(script);
response =  Response.status(200).type(responseType).entity(gvyOutput).build();
} catch (Exception ex) {
gvyOutput = "Error processing request: " + ex.getMessage();
response =  Response.status(200).type(responseType).entity(gvyOutput).build();
} finally {
            if(shell != null) {
                groovyPool.returnObject(shell);
            }
        }
return response;



Wednesday, August 31, 2016

Documentum custom dfs jar generation

Documentum provides documentum foundation services (DFS) jars to talk to the CMS for querying, uploading files. This functionality broke after we have upgraded to JBOSS EAP6 with CXF webservice stack.

We have generated the DFS client using the webservice urls

By using CXF wsconsume
C:\dev\dctm_client>C:\tools\jboss-eap-6.2.0\bin\wsconsume.bat -k http://ecmsvc-sys.xxy.com/emc-dfs/services/core/ObjectService?WSDL -b simple-binding.xml
C:\dev\dctm_client>C:\tools\jboss-eap-6.2.0\bin\wsconsume.bat -k http://ecmsvc-sys.xxy.com/emc-dfs/services/core/SchemaService?WSDL -b simple-binding.xml
C:\dev\dctm_client>C:\tools\jboss-eap-6.2.0\bin\wsconsume.bat -k http://ecmsvc-sys.xxy.com/emc-dfs/services/core/QueryService?WSDL -b simple-binding.xml
C:\dev\dctm_client>C:\tools\jboss-eap-6.2.0\bin\wsconsume.bat -k http://ecmsvc-sys.xxy.com/emc-dfs/services/core/runtime/ContextRegistryService?wsdl -b simple-binding.xml


By using native JAXWS wsimport
c:\Java\jdk1.7.0_60\bin\wsimport.exe http://ecmsvc-sys.xxy.com/emc-dfs/services/core/runtime/ContextRegistryService?wsdl -keep -nocompile -b simple-binding.xml
c:\Java\jdk1.7.0_60\bin\wsimport.exe http://ecmsvc-sys.xxy.com/emc-dfs/services/core/SchemaService?WSDL -keep -nocompile -b simple-binding.xml
c:\Java\jdk1.7.0_60\bin\wsimport.exe http://ecmsvc-sys.xxy.com/emc-dfs/services/core/ObjectService?WSDL -keep -nocompile -b simple-binding.xml
c:\Java\jdk1.7.0_60\bin\wsimport.exe http://ecmsvc-sys.xxy.com/emc-dfs/services/core/QueryService?WSDL -keep -nocompile -b simple-binding.xml

And sample-binding.xml
<jaxb:bindings
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
    xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
    jaxb:extensionBindingPrefixes="xjc">
    <jaxb:globalBindings>
        <xjc:simple />
    </jaxb:globalBindings>
</jaxb:bindings>

After generating client and bundled into jar (below pom.xml) dfs services worked perfectly with Jboss EAP6. Also the manual steps can be automated by using maven wsimport and wsconsume plugins.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.emc.dfs</groupId>
<artifactId>dfs-cxf-client</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1-redhat-2</version>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.11</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>redhat-techpreview-all-repository</id>
<name>Red Hat Tech Preview repository (all)</name>
<url>http://maven.repository.redhat.com/techpreview/all/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>redhat-techpreview-all-repository</id>
<name>Red Hat Tech Preview repository (all)</name>
<url>http://maven.repository.redhat.com/techpreview/all/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>${project.build.directory}/dfs-cxf-client-1.0.jar</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


To invoke operations on the ObjectService helper use

ObjectServiceHelper helper = new ObjectServiceHelper(dctmCtx.getSvrUser(), dctmCtx.getSvrPwd(),
dctmCtx.getRepositoryName(), dctmCtx.getCtxRegistryUrl(), dctmCtx.getCtxRoot(), ContentTransferMode.BASE_64);
ObjectServicePort serPort =  helper.getServicePort();
And do the actual DFS service operations on the ObjectServicePort
serPort.createPath()
serPort.create(DataPackage)

Delete Coherence Cache entries

To remove the cache entries based on the cache filters...

1. Coherence QueryMap interface provides keySet with filter
   Filter dtfilter = new EqualsFilter("getDate", dt);
   Set kset = cache.keySet(dtfilter );
   for (Object obj : kset) {
     cache.remove(obj);
   }
 
   Cache.remove returns the previous value associated with the key. This is not very efficient.
 
2. Best way to delete the cache entries 
Filter dtfilter = new EqualsFilter("getDate", dt);
this.invokeAll(dtfilter , new ConditionalRemove(AlwaysFilter.INSTANCE));

This code is very efficient and it will not return back any old data. 

How to make spring beans thread safe.

The interviewer question how make spring beans thread safe

Spring beans are singleton. This means there is only one bean instance per spring container.
So by default spring beans are not thread safe. To make them thread safe, one way to do this to
create separate spring bean instance every time the bean is accessed (@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) or scope="prototype" in xml config file)

But the interviewer insisted how to make them threadsafe with out changing the configuration and he gave the hint saying the beans are accessed in the servlet environment.

If the bean is singleton, only way to make them thread safe is to use local variables instead of class instance variables. Or if we need instance variables, only way to make the bean thread safe is to use synchronization or by using the locks.

The interviewer gave another solution to make the beans have no instance variables and all the required data to be preloaded and accessed from HTTP session. However HTTP session is not thread safe. This solution will not work.

Reference: https://coderanch.com/t/361845/Servlets/java/HttpSession-thread-safe

Java List Interview Questions

1. Remove Elements from List 

Lets say if I have a list with 6 elements like this
   ["John", "Smith", "John", "Kris", "John", "Bob"]. Remove the elements from the list with the "John"

Easiest solution is to use iterator

e.g.

List<String> alist = new ArrayList<String>(Arrays.asList("John", "Smith", "John", "Kris", "John", "Bob"));
Iterator<String> iter = alist.iterator();
while(iter.hasNext()) {
String name = (String) iter.next();
if (name.equals("John")) iter.remove();
}
System.out.println("alist: " + alist);


Another solution is to use for loop with looping backwards

for (int i=alist.size()-1; i>=0; i--) {
String name = alist.get(i);
if (name.equals("John")) alist.remove(i);
}
System.out.println("alist: " + alist);

2. How to find an element from List with complexity O(1)

Lets say you have Person Class and with the id_, person obj is uniquely identified

class Person {
private int id_;
String name_;
String email_;

 public Person(int id) {
   id_ = id;
 }

public Person(int id, String name, String email) {
id_ = id;
name_ = name;
email_ = email;
}

public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Person)) return false;
Person pobj = (Person) obj;
if (this.id_ == pobj.id_) return true;
else return false;
}

public int hashCode() {
return super.hashCode() + id_;
}

public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}

}

List<Person> plist = new ArrayList<Person>();
Person p1 = new Person(123, "John Smith", "js@xyz.com");
Person p2 = new Person(124, "Bob Harris", "bh@xyz.com");
Person p3 = new Person(125, "Will Smith", "ws@xyz.com");

plist.add(p1); plist.add(p2); plist.add(p3);


You have reference to the very big person list (lets say plist) and you know the key of one object (lets say 124). How to retrieve the object with the key you have

one Option is to loop through the list and find it

public Person findPerson(List plist, int id) { 
  for (int i=0; i<plist.size(); i++) {
  Person p = plist.get(i);
  if (p.getId() == 124) {
    return p;
  }
}

This has the worst case complexity of O(n). The interviewer asked whether it can be improved with O(1). I said I don't know the answer as list complexity is O(n)

He told me the solution as follows

private Person getPerson(List<Person> plist, int id) {
Person p = new Person(id, "xy", "xy@xyz.com");
int idx = plist.indexOf(p);
return plist.get(idx);

}

but the big problem is list.indexOf(obj) has complexity of O(n). So his solution complexity O(n+1).