Through SAP JCO we can gather SAP information within Java. I’ll explain the basics here while I’m revealing a library piece by piece.
SAP Connection
First we need to connect to SAP. Therefore create a connectionpool
public SAPPool(){
// create pool
JCO.addClientPool(
((String) properties.get(SAP_POOL_NAME), // Alias for this pool
Integer.parseInt((String) properties.get(SAP_NR_CONNECTIONS)),// nr of connections
(String) properties.get(SAP_CLIENT), // SAP client
(String) properties.get(SAP_USERID), // userid
(String) properties.get(SAP_PASSWORD), // password
(String) properties.get(SAP_LANGUAGE), // language
(String) properties.get(SAP_HOST_NAME), // host name
(String) properties.get(SAP_SYSTEM_NUMBER) // system number
);
//...
Next you create a repository
//...
// Create a new repository
repository = JCO.createRepository((String) properties
.get(SAP_REPOSITORY_NAME), ((String) properties
.get(SAP_POOL_NAME));
} //end of ctor
To reference a function through your repository
public IFunctionTemplate getSAPFunction(String functionName){
repository.getFunctionTemplate(functionName);
}
Also you can get the client
public JCO.Client getSAPClient(){
JCO.getClient(poolName)
}
And very important is not to forget to release it again
public void releaseClient(){
JCO.releaseClient(client)
}
Because It’s so important not to forget releasing your resources again and because of some other default handling of calling SAP functions we’ll use an abstract class. Read more about my interface vs abstract class post to understand why.
What are the defaults?
get function let’s do this in the ctor which takes the functionName as an argument. Also we preserve some references towards the input, output and tables parameterLists (SAPPool references to class holding the previous posted code)
public BaseSAPFunction(String functionName){
IFunctionTemplate ftemplate = SAPPool.getSAPFunction(functionName);
function = new JCO.Function(ftemplate);
input = function.getImportParameterList();
output = function.getExportParameterList();
tables = function.getTableParameterList();
}
set input next we need to set the input parameters. In the BaseClass I did so by having an abstract method handling this. In the actual implementation the input parameterlist can be referenced. The actual implementation will follow in calling a function.
public abstract void setInput();
execute function for actual execution of function first get a client on which you can invoke the execute function like this
public void executeFunction(){
client = SAPPool.getSAPClient();
client.execute(function);
}
handle results this will also be abstract here because this depends on the actual implementation. Here it returns an Object for compatibility with non 1.5 code. This implies that you’ll need to cast it the right way. If you can ensure you’ll have only 1.5 using this library then use generics. Again the actual implementation will follow in calling a function.
public abstract Object getData();
release client is done by executing
SAPPool.releaseClient();
All together this wil be chained in the right order with some general execute function like the following
public Object execute() {
setInput(); //see implementation for details
executeFunction();
Object obj = getData(); //see implementation for details
SAPPool.releaseClient();
return obj;
}
calling a function
Now for calling a specific function I extend the previous explained BaseSAPFunction. Then I only need to make a ctor calling the super ctor with functionName as argument and implement the 2 abstract methods (and maybe some helpers). Classes using this function invoke the execute() method and cast the Object. That’s it.
public class SomeSAPFunctionCall extends BaseSAPFunction{
public SomeSAPFunctionCall(){
super("ZBAPI_SOME_FUNCTION");
}
public void setInput(){
input.setValue("fieldValue", fieldName);
//more here
}
public void getData(){
SomeDTO dto = new SomeDTO();
JCO.table table = tables.getTable("TABLE_NAME");
if(table != null) {
do{
dto.setAString(table.getString("A_STRING"));
dto.setAnInt(table.getInt("AN_INTEGER"));
//more here
} while(table.nextRow());
}
return dto;
}
}
usage
SomeDTO dto = (SomeDTO)new SomeSAPFunctionCall().execute();