Monday, January 30, 2012

Thread Safe Blocking List

In Java Concurrent Package there are many useful concurrent synchronizer classes such as BlockingQueue, Semaphore, CountDownLatch and CyclicBarrier. But what if we want an bounded List with insertion order preserved where if the upper limit of the List is met new insertions must be blocked until some elements are removed. The following BlockingList implementation does exactly that. This List uses a Semaphore to synchronize the flow of adding and removing. When the maximum amount of elements are in the List and another call to add is made, the add will be blocked until an element is removed from the List.
import java.util.*;
import java.util.concurrent.*;

/**
 * @author Shazin Sadakath
 *
 */

public class BlockingList<T> {
    private final Semaphore semaphore;
    private final List<T> list = Collections.synchronizedList(new ArrayList<T>());

    public BlockingList(int max) {
        semaphore = new Semaphore(max);        
    }    

    public boolean add(T t) throws InterruptedException {
        semaphore.acquire();
        boolean result = false;
        try {
            result = list.add(t);
        } finally {
            if(!result) {
                semaphore.release();
            }
        }
        return result;
    }

    public T remove(int index) {
        T result = null;
        try {
            result = list.remove(index);
        } finally {
            if(result != null) {
                semaphore.release();
            }
        }
        return result;
    }

    public T get(int index) {
        return list.get(index);
    }

    public int indexOf(T t) {
        return list.indexOf(t);
    }

    public T removeIfPresent(T t) {
        T result = null;
        synchronized(list) {
            if(list.contains(t)) {
                result = remove(indexOf(t));
            }
        }
        return result;
    }

    public boolean putIfAbsent(T t) throws InterruptedException {
        boolean result = false;
        synchronized(list) {
            if(!list.contains(t) && semaphore.availablePermits() != 0) {
                result = add(t);
            }
        }    
        return result;
    }
}

Wednesday, January 18, 2012

IBM CMOD Folder Field Default Value Retrieval Using ODWEK API

IBM Content Manager on Demand (CMOD) is a Enterprise Content Management system which enables to archive resource files and retrieve them whenever required. It has two different methods to access the resources.

  1. A Set of Executable Files (.EXE or .OUT) which can be used to manage the resources.
  2. On Demand Web Enable Kit (ODWEK) which is an API which can be used by any external application.
ODWEK is used by IBM Webi (Web Interface of CMOD) to manage the resources.

As part of my work I had to retrieve Default values of Fields specified in each Application Group in their respective Folder so that any external application can make use of the Default Values.

After some googling and trial and error I found out that it can be done using the ODCriteria.getSearchValues() method which would return a String array of Default values per field. The following code does the required.

import java.util.Enumeration;

import com.ibm.edms.od.ODConfig;
import com.ibm.edms.od.ODCriteria;
import com.ibm.edms.od.ODFolder;
import com.ibm.edms.od.ODServer;
/**
 * ODWEK Testing Class
 * 
 * @author Shazin Sadakath
 *
 */
public class ODWEKTest {
    
    
    public static void main(String[] args) {
        ODConfig odConfig = new ODConfig();        
        ODServer server = new ODServer(odConfig);
        server.setUserId("administrator");
        server.setPassword("1234567");
        server.setPort(12238);
        server.setServerName("localhost");
        
        try {
            server.initialize("ODPing");        
            server.logon();
            Enumeration<ODFolder> folders = server.getFolders(); 
            if(folders != null) {
                while(folders.hasMoreElements()) {
                    ODFolder folder = folders.nextElement();
                    try {
                        folder.open();
                    } catch(Exception e) {
                        continue;
                    }
                    System.out.println("Folder : "+folder.getName());
                    Enumeration<ODCriteria> fields = folder.getCriteria();
                    while(fields.hasMoreElements()) {
                        ODCriteria field = fields.nextElement();
                        System.out.println("\tField : "+field.getName());
                        String[] fixedValues = field.getSearchValues();                        
                        if(fixedValues != null) {
                            for(String dv:fixedValues) {
                                System.out.println("\t\tDefault Value : "+dv);
                            }
                        }
                    }
                    folder.close();
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                server.logoff();
            } catch (Exception e) {                
                e.printStackTrace();
            }
            server.terminate();
        }
    }
}

ODApi.jar is required and java.library.path VM Argument must be set to point to the ODWEK Installation Directory in order to load required Libraries