SlideShare a Scribd company logo
1 of 17
Download to read offline
Simplified Queries of SAP Tables from Java
By Jay Brown and Steve Renard (Colgate-Palmolive)
This article discusses how to easily query SAP tables in your SAP Portal applications. It is divided into
two parts; the first part discusses the implementation and use of the Java classes that expose the SAP data.
The second part discusses enhancing the backend function to suit your company’s functionality and
security needs.
Any Java based SAP Enterprise Portal application that communicates with R/3 will almost certainly use
RFCs and BAPIs to perform its work on the backend system. Suppose you want to write an ESS
application to allow an employee to change her HR personal data. You would most likely use the standard
BAPI_PERSDATA_CHANGE function module to make the changes in SAP. This BAPI, like most, has
parameters that have a defined set of valid values, which are stored in SAP tables.
As an example, let’s use the BAPI_PERSDATA_CHANGE Import Parameter MARITALSTATUS, which
specified the employee’s marital status. In your application, you would provide a drop-down list control
with the various values (“Married”, “Single”, etc). This import parameter’s valid values are stored in the
Marital Status Designators table, which is table T502T. In your application, you may choose to supply this
field’s valid options in a couple of ways:
1. Hard-code the values in the application. In the beginning, this would seem to be the fastest solution.
In the long term, this is a very bad idea. If new values are added or deleted, you will need to modify
your code.
2. Code a custom RFC to perform the SELECT statement against the desired R/3 table. This is a more
traditional way that keeps your application’s options in sync with the back-end system’s.
Unfortunately, this can become a maintenance burden as more tables need to be read and more custom
RFCs need to be developed.
To handle this problem, we attempted to use the Function Module RFC_READ_TABLE. This RFC will
query the specified table in the R/3 system and return the results in an unformatted table. Optionally, you
may also specify the field names to return, the number of rows to return, as well as a selection (WHERE)
clause. Because the result set is unformatted, the data need to be parsed for them to be usable. Ideally, we
would like a JCO Table to be created that accurately reflects the table structure and data from the response.
Having the data in a JCO Table allows us to use it in many tasks, such as displaying the data in a tableView
control on the Portal. Below is a simple illustration of how the table data are returned:
As you can see, the requested table’s fields are returned as a single row in the DATA table. Fortunately,
the FIELDS table describes the data table, so we can parse out each field.
We decided to develop a wrapper class called R3Table to hide the gory details of the
RFC_READ_TABLE function module. We have also made our own custom version of
RFC_READ_TABLE, called ZRFC_READ_TABLE. You can use R3Table class even if you don’t
implement your own custom version of ZRFC_READ_TABLE, but you’ll probably want to when you read
more about it the section RFC_READ_TABLE vs. ZRFC_READ_TABLE later in this document. If you
decide to implement the ZRFC_READ_TABLE, be sure to change the READ_TABLE_FUNCTION_NAME
static variable (in R3Table.java) to contain the name of your custom function “ZRFC_READ_TABLE”.
The R3Table factory class is a subclass of JCO.Table. To use it, you must invoke one of the getInstance
methods to create an instance of the class. There are many forms of the getInstance method to allow you to
specify the fields to return, the maximum number of rows to return, the starting row, and the where clause.
Refer to the JavaDoc for details. The most basic getInstance documentation is listed below.
Public static R3Table getInstance(com.sap.mw.jco.JCO.Client client,
Java.lang.String tableName)
throws R3TableException,
com.sap.mw.jco.JCO.Exception
Method getInstance – Short Form. Instantiates a R3Table class populated with the
data selected from the specified table. Returns ALL rows, ALL fields, without
skipping.
Parameters:
Client – An already connected JCO.Client.
tableName - SAP Table to query.
For example, to load ALL rows and fields from SAP Table T502T:
...
client = clientService.getJCOClient("SAP_HR_SYS", request);
client.connect();
R3Table table = R3Table.getInstance(client, "T502T");
...
Returns:
R3Table
Example.
The following basic example gets and connects a JCO Client to the SAP_HR_SYS system. After
successfully connecting, it gets an instance of R3Table populated with all rows and fields from the T502T
table on the SAP_HR_SYS system.
try {
IportalComponentRequest request = (IportalComponentRequest)
this.getRequest();
JCO.Client client = null;
IJCOClientService clientService = (IJCOClientService)
request.getService(IJCOClientService.KEY);
Client = clientService.getJCOClient("SAP_HR_SYS", request);
Client.connect();
R3Table table = R3Table.getInstance(client, "T502T");
System.out.println(table.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (client != null)
client.disconnect();
}
Output: The R3Table.toString() output shows the information about the R3Table populated from the
T502T table.
Fetch Function: RFC_READ_TABLE
Where Clause:
Max Rows: All
Delimiter: |
Query Response Time (ms): 531
Skip Count: 0
Fields: FTEXT, MANDT, SPRSL, FAMST
-----------
| TABLE 'T502T'
-----------
| MA| | | FTEXT|
-----------
|012|3|4|567890|
-----------
|151|1|0|Single|
|151|1|1|Marr. |
|151|1|2|Wid. |
|151|1|3|Div. |
|151|1|4|NM |
|151|1|5|Sep. |
... ...
To use R3Table in the real world, you would want to pass its data along to an HTMLB control such as a
dropdownListBox or tableView. To do this, you simply construct one of the List Model classes (see
below) and pass it to your control. The R3TableDemo example below illustrates this by constructing a
JCOTableViewModel and passing it to an HTMLB tableView control.
Flow of R3TableDemo Portal Component
The R3TableDemo IView
This IView simply gets an instance of an R3Table filled with data from the T502T table, and creates a
JCOTableViewModel object that will be used by the tableView control in the JSP file.
Code excerpt. See full example code at the end of this document.
In your Bean In your JSP
// Getter method for tableListModel
public JCOTableViewModel
getTableListModel() {
R3Table table =
R3Table.getInstance(client,tName);
Return new JCOTableViewModel(table);
}
<hbj:tableView
id="tview"
model="myBean.tableListModel"
design="ALTERNATING"
headerVisible="TRUE"
footerVisible="FALSE"
fillUpEmptyRows="FALSE"
navigationMode="BYPAGE"
selectionMode="NONE"
headerText="Contents of TABLE"
visibleFirstRow="1"
visibleRowCount="10"
rowCount="10"
width="75%"/>
List Models on the PDK that use JCO Table:
http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/JCOChartModel.html
http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/JCOListModel.html
http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/table/JCOTableViewModel.html
RFC_READ_TABLE vs. ZRFC_READ_TABLE
There are a few reasons why you might want to consider making your own copy of the function
RFC_READ_TABLE in your R/3 system(s). The most compelling of these reasons is security. If the users
of your external applications are only making connections to R/3 under their own R/3 user IDs, then you
must give fairly broad access to each of these users when using RFC_READ_TABLE. Rather than giving
out this broad access to a large group of people, another option would be to use 2 types of connections
within your application—one connection under the user’s own ID for normal RFC or BAPI calls that are
required, and the other connection under a generic ID for calling RFC_READ_TABLE. Neither of these
options is appealing. A third more attractive option that is much easier to implement is to create your own
copy of RFC_READ_TABLE and make some minor modifications. Below are 3 reasons to consider
creating your own copy of RFC_READ_TABLE in your R/3 system(s), along with some details on a
couple of changes you might want to consider.
1. Security
The very first action of the function RFC_READ_TABLE is to call another function named,
VIEW_AUTHORITY_CHECK. At first glance, this seems harmless. The name of the table to be read is
passed, along with a view option of ‘S’ (which one would assume to represent, “viewing,” or, “reading”).
However, if you drill-down into the function VIEW_AUTHORITY_CHECK and look through its source
code, you will discover that it is ultimately doing a check on the authorization object S_TABU_DIS.
The security object S_TABU_DIS checks against the user’s authorization to perform an action (read,
change, create records, etc.) on tables belonging to a particular table class—It is not checking authorization
for an individual table. What this means for you as an application developer is that the users of your
application will need to have access to the table class or classes to which the table or tables belong, for any
tables that are being read by RFC_READ_TABLE. A single table class can have thousands of tables as
members, so in some cases you must give your users read access to thousands of tables so they can simply
read a single table. This is something your security group will certainly frown upon if they understand the
security object S_TABU_DIS, or if you bring it to their attention. As mentioned above, you could use a
generic ID for R/3 connections when calling RFC_READ_TABLE, but as a long term solution looking
forward to many applications using RFC_READ_TABLE, this would require a lot of extra work.
2. DATA_BUFFER_EXCEEDED
The function RFC_READ_TABLE reads table records into a table with the structure TAB512. As the
name somewhat indicates, this table has a single field with the length of 512 characters. This means you
are limited to reading a combination of fields from your table that does not exceed 512 characters in width.
In most cases, if you are limiting your call to the specific fields you need, this should not be a problem.
However, you should be aware of this limitation. Exceeding 512 characters in width will result in an
exception of DATA_BUFFER_EXCEEDED.
3. As of 4.6c, RFC_READ_TABLE is not Released to Customers
O.K…. This last reason is pretty weak. The fact that a function module is not released seldom stops
anyone from using it. If its interface changes in the future, though, just keep in mind, “I told you so.”
Copying ZRFC_READ_TABLE and Changes You may want to Consider
Since RFC_READ_TABLE is the only function that belongs to the function group SDTX, it is a piece of
cake to copy. Simply go to transaction SE38, and copy the program SAPLSDTX. When you are prompted
for a new function group name, enter ZSDTX. If you have never copied a function group like this before,
you should not be alarmed that you are creating a new program that does not begin with, “Z.” The function
group you create will have the name, SAPLZSDTX. As part of the copy process, you will be directed to
now copy the functions that belong to the group. Since there is only 1 function, this is very simple. Just
enter the name ZRFC_READ_TABLE. Again, since there is only 1 function in this group, you do not need
to worry about cross references between functions in your new group, which gets pretty complicated for
larger function groups.
Security Changes
After activating your new group, you should have a fully functional copied function module with the name,
ZRFC_READ_TABLE. Now you are free to make any changes you desire. The first change you should
consider on the authorization check that is performed. Rather than calling the function
VIEW_AUTHORITY_CHECK, you might want to create your own authorization object that is checked by
individual table, and use it instead. For example, replace the following code:
--------------------------------------------------------------------------------------------------------------------------------
call function 'VIEW_AUTHORITY_CHECK'
exporting
view_action = 'S'
view_name = query_table
exceptions
no_authority = 2
no_clientindependent_authority = 3
table_not_found = 4.
if sy-subrc = 2 or sy-subrc = 3.
raise not_authorized.
elseif sy-subrc = 1.
raise table_not_available.
endif.
--------------------------------------------------------------------------------------------------------------------------------
…with this:
--------------------------------------------------------------------------------------------------------------------------------
DATA: tabname LIKE dd02l-tabname.
SELECT SINGLE tabname FROM dd02l INTO tabname
WHERE tabname EQ query_table
AND as4local EQ 'A'.
IF sy-subrc NE 0. RAISE table_not_available. ENDIF.
AUTHORITY-CHECK OBJECT 'Z_TABL_MNT'
ID 'ACTVT' FIELD '03'
ID 'TABLE' FIELD query_table.
IF sy-subrc NE 0. RAISE not_authorized. ENDIF.
--------------------------------------------------------------------------------------------------------------------------------
The authorization object Z_TABL_MNT could be defined as follows:
This list of permitted activities is completely up to you. If you are only using this security object for
ZRFC_READ_TABLE, you only need a permitted activity of display. However, this security object might
be useful in many other places, so you could add a full list of activities.
Avoiding the Exception DATA_BUFFER_EXCEEDED
If you need more space than the allotted 512 characters for you table records, you can change the reference
type of the function’s table parameter DATA from TAB512 to some other similar structure having a single,
larger character field. Anyone familiar with searching the R/3 data dictionary (transaction SE11) should be
able to find a similar table with a larger character field in a matter of a few minutes. Simply swap the
newfound table or structure into the reference type for DATA using the function builder (transaction.
SE37). If you cannot find a suitable standard table or structure for your needs, you can simply create your
own using SE11. You should keep in mind that as you increase the size of your record buffer, the
performance of your function will wane. That can be a very critical issue for web applications.
We welcome any suggestions of other standard function modules that could be used for the purpose of
generically reading tables from applications external to R/3, or any standard security object that could be
used for limiting read access by individual tables.
steve_renard@colpal.com
jay_brown@colpal.com
R3Table.java
package com.colpal.util.portal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.IMetaData;
import com.sap.mw.jco.IRepository;
import com.sap.mw.jco.JCO;
/**
* @version 1.0, 08/20/2003
* @author J. Brown
* Colgate-Palmolive
* <p>
* Utility class to facilitate simple access to SAP Tables.
*
* The intention of this class is to enable Enterprise Portal applications
* to load drop-down values into fields at runtime instead of hard-coding the
* values in the application.
* </p>
*
*<blockquote><pre>
*The steps to use this class are as follows:
*<ol>
*<li>Obtain a JCO.Client to the desired SAP.
*<li>Connect the Client.
*<li>Use one of the getInstance() methods of this class to create a R3Table loaded with
your favorite data.
*<li>Create a Model, such as JCOListModel to be used in your JSP.
*</ol>
*
*...
*client = clientService.getJCOClient("SAP_HR_SYS", request);
*client.connect();
*R3Table table = R3Table.getInstance(client, "T002");
*...
*</pre></blockquote>
*
*
* JCOChartModel
* JCOListModel
* JCOTableViewModel
*
*/
public class R3Table extends com.sap.mw.jco.JCO.Table {
public static final String READ_TABLE_FUNCTION_NAME = "RFC_READ_TABLE";
public static final String DATA_DELIMITER = "|";
private long queryDuration = 0;
private String tableName = "";
private String whereClause = "";
private int maxRows = 0;
private int skipCount = 0;
private HashMap desiredFields = null;
/**
* Private class to track field size and offset.
*/
private class FieldInfo {
FieldInfo(String _name, int _offset, int _length, String _type) {
this._name = _name;
this._endindex = _offset + _length;
this._offset = _offset;
this._length = _length;
this._type = _type;
}
int _endindex;
String _name;
int _offset;
int _length;
String _type;
}
/**
* Method shouldIKeepField.
* Determines if the specified field name should be recorded.
*
* @param fieldName
* @return boolean
*/
private boolean shouldIKeepField(String fieldName) {
// if null (none specified), we want all fields
if (desiredFields == null)
return true;
// if we have a list and the field name is there.
if (desiredFields.containsKey(fieldName.toUpperCase()))
return true;
return false;
}
/**
* Method getFieldInfo.
* @param table
*/
private void getFieldInfo(JCO.Table table) {
table.firstRow();
HashMap fieldList = new HashMap(table.getNumColumns());
do {
String fn = table.getField("FIELDNAME").getString().toUpperCase();
if (shouldIKeepField(fn)) {
FieldInfo fi = new FieldInfo(table.getField("FIELDNAME").getString(),
table.getField("OFFSET").getInt(),
table.getField("LENGTH").getInt(),
table.getField("TYPE").getString());
fieldList.put(fn,fi);
}
} while(table.nextRow());
desiredFields = fieldList;
}
/**
* Method recordDesiredFields.
* Records the desired field names that should come back from the RFC call.
* @param fieldList
*/
private void recordDesiredFields(String fieldList) {
StringTokenizer st = new StringTokenizer(fieldList,", ");
if (st.hasMoreTokens()) {
desiredFields = new HashMap();
while (st.hasMoreTokens()) {
String fn = st.nextToken().toUpperCase();
if (!desiredFields.containsKey(fn))
desiredFields.put(fn, null);
}
}
}
/**
* Method processRows.
* Loops through the raw JCO.Table rows and parses the field values into their
* corresponding fields in the current table.
*
* @param table
* @throws Exception
*/
private void processRows(JCO.Table table) throws JCO.Exception {
Object[] fieldList = desiredFields.values().toArray();
for (int i=0; i < table.getNumRows();i++) {
table.setRow(i);
String row = table.getField("WA").getString();
appendRow();
for (int f=0;f<fieldList.length;f++) {
FieldInfo fi = (FieldInfo)fieldList[f];
int endIndex = fi._endindex;
if (endIndex > row.length())
endIndex = row.length();
String val = row.substring(fi._offset, endIndex);
setValue(val.trim(), fi._name);
}
}
}
/**
* Private Constructor, use static method R3Table.getInstance to
* create an instance of this class.
*
* @see com.sap.mw.jco.JCO.MetaData#MetaData(IMetaData)
*/
private R3Table(IMetaData imd) {
super(imd);
}
/**
* Returns a string representation of the object,
* which is a result of R3Table info + a call to JCO.Table.toString().
* <br>
* <pre>
* Fetch Function: RFC_READ_TABLE
* Where Clause:
* Max Rows: 5
* Delimiter: |
* Query Response Time (ms): 172
* Skip Count: 4
* Fields: LAND1, NATIO, MANDT, LANDX, SPRAS
* -------------------------------------
* | TABLE 'T005T'
* -------------------------------------
* | MA| | LA| LANDX | NATIO |
* -------------------------------------
* |012|3|456|789012345678901|234567890123456|
* -------------------------------------
* |151|1|AI |Anguilla |Anguilla |
* |151|1|AL |Albania |Albanian |
* |151|1|AM |Armenia |Armenian |
* |151|1|AN |Dutch Antilles |Dutch |
* |151|1|AO |Angola |Angolan |
* -------------------------------------
* </pre>
*
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer retStr = new StringBuffer();
retStr.append("Fetch Function: " + READ_TABLE_FUNCTION_NAME + "n");
retStr.append("Where Clause: " + whereClause + "n");
retStr.append("Max Rows: " + (maxRows >0 ? "" + maxRows : "All") + "n" );
retStr.append("Delimiter: " + DATA_DELIMITER + "n" );
retStr.append("Query Response Time (ms): " + queryDuration + "n");
retStr.append("Skip Count: " + skipCount + "n");
retStr.append("Fields: ");
if (desiredFields != null) {
for (Iterator i = desiredFields.keySet().iterator() ; i.hasNext() ;) {
retStr.append(i.next());
if (i.hasNext())
retStr.append(", ");
}
}
else {
retStr.append("ALL");
}
retStr.append("n");
return retStr.toString() + super.toString();
}
/**
* Method executeQuery.
* Connects to the R/3 system associated with client and fetches the raw table data.
* @param repository
* @param client
* @throws R3TableException
* @throws Exception
*/
private void executeQuery(IRepository repository, JCO.Client client) throws
R3TableException, JCO.Exception {
IFunctionTemplate rfc = null;
JCO.Table rawData = null;
JCO.Table fieldData = null;
JCO.Table options = null;
rfc = repository.getFunctionTemplate(READ_TABLE_FUNCTION_NAME);
JCO.Function function = new JCO.Function(rfc);
JCO.ParameterList importList = function.getImportParameterList();
importList.setValue(tableName, "QUERY_TABLE");
importList.setValue(DATA_DELIMITER, "DELIMITER");
importList.setValue(" ", "NO_DATA");
if (maxRows > 0)
importList.setValue(maxRows, "ROWCOUNT");
if (skipCount > 0)
importList.setValue(skipCount, "ROWSKIPS");
if (whereClause.length() > 0) {
options = function.getTableParameterList().getTable("OPTIONS");
options.appendRow();
options.setValue(whereClause, "TEXT");
}
client.execute(function);
rawData = function.getTableParameterList().getTable("DATA");
fieldData = function.getTableParameterList().getTable("FIELDS");
getFieldInfo(fieldData);
processRows(rawData);
}
/**
* Method getInstance - Short Form. Instantiates an R3Table class populated with the
data selected from the specified table.
* Returns ALL rows, ALL fields, without skipping.
* @param client An already connected JCO.Client.
* @param tableName SAP Table to query.
*
*<p>
*For example, to load ALL rows and fields from SAP Table T502T
*<blockquote><pre>
*...
*client = clientService.getJCOClient("SAP_HR_SYS", request);
*client.connect();
*R3Table table = R3Table.getInstance(client, "T502T");
*...
*</pre></blockquote>
*<p>
*
*
* @return R3Table
*
* @throws R3TableException
* @throws com.sap.mw.jco.JCO.Exception
*/
public static R3Table getInstance(JCO.Client client, String tableName) throws
R3TableException, JCO.Exception {
return getInstance(client, tableName, "", "", 0, 0);
}
/**
* Method getInstance - Medium Form. Instantiates an R3Table class populated with the
data selected from the specified table.
* Returns ALL rows, ALL fields, without skipping.
* @param client An already connected JCO.Client.
* @param tableName ABAP Table to query.
* @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code>
* @return R3Table
*
* @throws R3TableException
* @throws com.sap.mw.jco.JCO.Exception
*/
public static R3Table getInstance(JCO.Client client, String tableName, String
whereClause) throws R3TableException, JCO.Exception {
return getInstance(client, tableName, whereClause, "", 0, 0);
}
/**
* Method getInstance - Medium Form. Instantiates an R3Table class populated with the
data selected from the specified table.
* Returns ALL rows, without skipping.
* @param client An already connected JCO.Client.
* @param tableName ABAP Table to query.
* @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code>
* @param desiredFields A List of Field Names delimited by commas. An empty String
indicates ALL fields.
* @return R3Table
*
* @throws R3TableException
* @throws com.sap.mw.jco.JCO.Exception
*/
public static R3Table getInstance(JCO.Client client, String tableName, String
whereClause, String desiredFields) throws R3TableException, JCO.Exception {
return getInstance(client, tableName, whereClause, desiredFields, 0, 0);
}
/**
* Method getInstance - Long Form. Instantiates an R3Table class populated with the data
selected from the specified table.
* Returns specified number of rows, without skipping.
* @param client An already connected JCO.Client.
* @param tableName ABAP Table to query.
* @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code>
* @param desiredFields A List of Field Names delimited by commas. An empty String
indicates ALL fields.
* @param maxRows The maximum number of row to return.
* @return R3Table
*
* @throws R3TableException
* @throws com.sap.mw.jco.JCO.Exception
*/
public static R3Table getInstance(JCO.Client client, String tableName, String
whereClause, String desiredFields, int maxRows) throws R3TableException, JCO.Exception {
return getInstance(client, tableName, whereClause, desiredFields, 0, maxRows);
}
/**
* Method getInstance - Long Form. Instantiates an R3Table class populated with the data
selected from the specified table.
* @param client An already connected JCO.Client.
* @param tableName ABAP Table to query.
* @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code>
* @param desiredFields A List of Field Names delimited by commas. An empty String
indicates ALL fields.
* @param skipCount The number of rows to skip. 0 indicates no skipping.
* @param maxRows The maximum number of row to return.
* @return R3Table
*
* @throws R3TableException
* @throws com.sap.mw.jco.JCO.Exception
*/
public static R3Table getInstance(JCO.Client client, String tableName, String
whereClause, String desiredFields, int skipCount, int maxRows) throws R3TableException,
JCO.Exception {
R3Table retTable;
IRepository repository = JCO.createRepository("repository." + client.toString(),
client);
retTable = new R3Table(repository.getTableDefinition(tableName));
retTable.setMaxRows(maxRows);
retTable.setWhereClause(whereClause);
retTable.setTableName(tableName);
retTable.recordDesiredFields(desiredFields);
retTable.setSkipCount(skipCount);
long st = System.currentTimeMillis();
retTable.executeQuery(repository, client);
long et = System.currentTimeMillis();
retTable.setQueryDuration(et - st);
return retTable;
}
// ************* Private setters ***************
private void setMaxRows(int maxRows) {
this.maxRows = maxRows;
}
private void setQueryDuration(long queryDuration) {
this.queryDuration = queryDuration;
}
private void setTableName(String tableName) {
this.tableName = tableName;
}
private void setWhereClause(String whereClause) {
this.whereClause = whereClause;
}
private void setSkipCount(int skipCount) {
this.skipCount = skipCount;
}
}
demoBean.java
package com.colpal.demo.R3Table;
import com.sapportals.htmlb.IListModel;
import com.sapportals.htmlb.table.JCOTableViewModel;
import com.colpal.util.portal.*;
import com.sap.mw.jco.JCO;
import java.io.Serializable;
public class demoBean implements Serializable {
private JCOTableViewModel tableListModel = null;
private R3Table table = null;
private boolean error = false;
private String lastMessage = "";
private boolean bHasData = false;
public boolean isError() {
return error;
}
public boolean hasData() {
return bHasData;
}
public void loadTable(JCO.Client client, String tableName) {
setLastMessage("");
error = false;
try {
table = R3Table.getInstance(client, tableName);
bHasData = true;
}
catch (Exception e) {
setLastMessage(e.getMessage());
error = true;
}
}
/**
* Returns the tableListModel.
* @return TableViewModel
*/
public JCOTableViewModel getTableListModel() {
return new JCOTableViewModel(table);
}
/**
* Sets the tableListModel
*/
public void setTableListModel(JCOTableViewModel employmentListModel) {
this.tableListModel = employmentListModel;
}
/**
* Returns the lastMessage.
* @return String
*/
public String getLastMessage() {
return lastMessage;
}
/**
* Sets the lastMessage.
* @param lastMessage The lastMessage to set
*/
public void setLastMessage(String lastMessage) {
this.lastMessage = lastMessage;
}
}
page1.jsp
<%@ taglib uri="tagLib" prefix="hbj" %>
<jsp:useBean id="myBean" scope="session" class="com.colpal.demo.R3Table.demoBean" />
<hbj:content id="myContext" >
<hbj:page title="PageTitle">
<hbj:form id="myFormId" >
<hbj:textView id="dispID" text="R3Table Demo" design="EMPHASIZED"/>
<% if (myBean.hasData()) {%>
<hbj:tableView
id="tview"
model="myBean.tableListModel"
design="ALTERNATING"
headerVisible="TRUE"
footerVisible="FALSE"
fillUpEmptyRows="FALSE"
navigationMode="BYPAGE"
selectionMode="NONE"
headerText="Contents of TABLE"
visibleFirstRow="1"
visibleRowCount="10"
rowCount="10"
width="75%"/>
<%}%>
<!-- Table to align button -->
<hbj:formLayout width="100%">
<hbj:formLayoutRow>
<hbj:formLayoutCell width="60px" align="LEFT">
<hbj:inputField id="tableName" visible="true" type="String"/>
</hbj:formLayoutCell>
<hbj:formLayoutCell>
<hbj:button id="load" text="Load Table" width="100"
tooltip="Click here."
onClick="loadTable" disabled="false" design="STANDARD"/>
</hbj:formLayoutCell>
</hbj:formLayoutRow>
</hbj:formLayout>
<%
String ImageURL = componentRequest.getWebResourcePath()+ "/images/";
%>
<%if (myBean.isError()){%>
<hbj:image id="Error" src="<%= ImageURL +"error.gif" %>"
alt="error.gif"/>&nbsp;<font color="RED"><hbj:textView wrapping="TRUE" id="ErrorMessage"
layout="NATIVE" text= "<%=myBean.getLastMessage()%>" design="STANDARD"/></font>
<%}%>
</hbj:form>
</hbj:page>
</hbj:content>
AppController.java
package com.colpal.demo.R3Table;
import com.colpal.demo.R3Table.demoBean;
import com.sapportals.htmlb.*;
import com.sapportals.htmlb.enum.*;
import com.sapportals.htmlb.event.*;
import com.sapportals.htmlb.page.*;
import com.sapportals.portal.htmlb.page.*;
import com.sapportals.portal.prt.component.*;
import com.sapportals.portal.prt.service.jco.IJCOClientService;
import com.colpal.util.portal.*;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.IRepository;
import com.sap.mw.jco.*;
public class AppController extends PageProcessorComponent {
public DynPage getPage(){
return new AppControllerDynPage();
}
public static class AppControllerDynPage extends JSPDynPage{
private demoBean myBean = null;
public void getBeanFromFramework() {
IPortalComponentSession componentSession =
((IPortalComponentRequest)getRequest()).getComponentSession();
Object o = componentSession.getValue("myBean");
if(o==null || !(o instanceof demoBean)){
myBean = new demoBean();
componentSession.putValue("myBean",myBean);
}
else {
myBean = (demoBean) o;
}
}
public void doInitialization() {
getBeanFromFramework();
}
public void onLoadTable(Event event) {
IPortalComponentRequest request = (IPortalComponentRequest) this.getRequest();
JCO.Client client = null;
IJCOClientService clientService = (IJCOClientService)
request.getService(IJCOClientService.KEY);
getBeanFromFramework();
String tableName = null;
Component component = getComponentByName("tableName");
if (component != null)
if (component instanceof InputField)
tableName = ((InputField)component).getValueAsDataType().toString();
if (tableName != null) {
try {
client = clientService.getJCOClient("SAP_GHD_151", request);
client.connect();
myBean.loadTable(client,tableName.toUpperCase());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (client != null)
client.disconnect();
}
}
}
public void doProcessAfterInput() throws PageException {
}
public void doProcessBeforeOutput() throws PageException {
this.setJspName("page1.jsp");
}
}
}

More Related Content

What's hot

Forall & bulk binds
Forall & bulk bindsForall & bulk binds
Forall & bulk bindsNawaz Sk
 
Application sql issues_and_tuning
Application sql issues_and_tuningApplication sql issues_and_tuning
Application sql issues_and_tuningAnil Pandey
 
Maximizing SAP ABAP Performance
Maximizing SAP ABAP PerformanceMaximizing SAP ABAP Performance
Maximizing SAP ABAP PerformancePeterHBrown
 
Top 35-interview-questions-on-sap-abap
Top 35-interview-questions-on-sap-abapTop 35-interview-questions-on-sap-abap
Top 35-interview-questions-on-sap-abapprathamesh4865
 
The Database Environment Chapter 8
The Database Environment Chapter 8The Database Environment Chapter 8
The Database Environment Chapter 8Jeanie Arnoco
 
SAP ABAP Interview questions
SAP ABAP Interview questionsSAP ABAP Interview questions
SAP ABAP Interview questionsIT LearnMore
 
How to debug a fast formula
How to debug a fast formulaHow to debug a fast formula
How to debug a fast formulaFeras Ahmad
 
1000 solved questions
1000 solved questions1000 solved questions
1000 solved questionsKranthi Kumar
 
ETL - Data Load QA New Training Guide
ETL - Data Load QA New Training GuideETL - Data Load QA New Training Guide
ETL - Data Load QA New Training GuideMarcus Call
 
Using SP Metal for faster share point development
Using SP Metal for faster share point developmentUsing SP Metal for faster share point development
Using SP Metal for faster share point developmentPranav Sharma
 
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...Massimo Cenci
 
Sql interview questions
Sql interview questionsSql interview questions
Sql interview questionsnagesh Rao
 
Partitioning tables and indexing them
Partitioning tables and indexing them Partitioning tables and indexing them
Partitioning tables and indexing them Hemant K Chitale
 

What's hot (20)

Forall & bulk binds
Forall & bulk bindsForall & bulk binds
Forall & bulk binds
 
Application sql issues_and_tuning
Application sql issues_and_tuningApplication sql issues_and_tuning
Application sql issues_and_tuning
 
Maximizing SAP ABAP Performance
Maximizing SAP ABAP PerformanceMaximizing SAP ABAP Performance
Maximizing SAP ABAP Performance
 
Top 35-interview-questions-on-sap-abap
Top 35-interview-questions-on-sap-abapTop 35-interview-questions-on-sap-abap
Top 35-interview-questions-on-sap-abap
 
The Database Environment Chapter 8
The Database Environment Chapter 8The Database Environment Chapter 8
The Database Environment Chapter 8
 
SAP ABAP Interview questions
SAP ABAP Interview questionsSAP ABAP Interview questions
SAP ABAP Interview questions
 
Sq lite module7
Sq lite module7Sq lite module7
Sq lite module7
 
How to debug a fast formula
How to debug a fast formulaHow to debug a fast formula
How to debug a fast formula
 
Chap16 scr
Chap16 scrChap16 scr
Chap16 scr
 
Chap03 scr
Chap03 scrChap03 scr
Chap03 scr
 
Plsql 9i vol2
Plsql 9i vol2Plsql 9i vol2
Plsql 9i vol2
 
Apps1
Apps1Apps1
Apps1
 
1000 solved questions
1000 solved questions1000 solved questions
1000 solved questions
 
ETL - Data Load QA New Training Guide
ETL - Data Load QA New Training GuideETL - Data Load QA New Training Guide
ETL - Data Load QA New Training Guide
 
Using SP Metal for faster share point development
Using SP Metal for faster share point developmentUsing SP Metal for faster share point development
Using SP Metal for faster share point development
 
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...
Recipe 16 of Data Warehouse and Business Intelligence - The monitoring of the...
 
Sql interview questions
Sql interview questionsSql interview questions
Sql interview questions
 
Partitioning tables and indexing them
Partitioning tables and indexing them Partitioning tables and indexing them
Partitioning tables and indexing them
 
Sq lite module6
Sq lite module6Sq lite module6
Sq lite module6
 
Abap faq
Abap faqAbap faq
Abap faq
 

Viewers also liked

Sap afs-tables-and-tcodes-list
Sap afs-tables-and-tcodes-listSap afs-tables-and-tcodes-list
Sap afs-tables-and-tcodes-listSanjeev Malik
 
Sap hr transaction codes all
Sap hr transaction codes allSap hr transaction codes all
Sap hr transaction codes allYomiGiddy
 
List of hr tables
List of hr tablesList of hr tables
List of hr tablesjaffa123
 
HR ABAP Technical Overview | http://sapdocs.info/
HR ABAP Technical Overview | http://sapdocs.info/HR ABAP Technical Overview | http://sapdocs.info/
HR ABAP Technical Overview | http://sapdocs.info/sapdocs. info
 
Sap hr overview 58 slides
Sap hr overview 58 slidesSap hr overview 58 slides
Sap hr overview 58 slidesBunty Jain
 
HR ABAP Programming Training Material | http://sapdocs.info
HR ABAP Programming Training Material | http://sapdocs.infoHR ABAP Programming Training Material | http://sapdocs.info
HR ABAP Programming Training Material | http://sapdocs.infosapdocs. info
 
SAP ABAP HR TRAINING
SAP ABAP HR TRAININGSAP ABAP HR TRAINING
SAP ABAP HR TRAININGJoshiRavin
 

Viewers also liked (7)

Sap afs-tables-and-tcodes-list
Sap afs-tables-and-tcodes-listSap afs-tables-and-tcodes-list
Sap afs-tables-and-tcodes-list
 
Sap hr transaction codes all
Sap hr transaction codes allSap hr transaction codes all
Sap hr transaction codes all
 
List of hr tables
List of hr tablesList of hr tables
List of hr tables
 
HR ABAP Technical Overview | http://sapdocs.info/
HR ABAP Technical Overview | http://sapdocs.info/HR ABAP Technical Overview | http://sapdocs.info/
HR ABAP Technical Overview | http://sapdocs.info/
 
Sap hr overview 58 slides
Sap hr overview 58 slidesSap hr overview 58 slides
Sap hr overview 58 slides
 
HR ABAP Programming Training Material | http://sapdocs.info
HR ABAP Programming Training Material | http://sapdocs.infoHR ABAP Programming Training Material | http://sapdocs.info
HR ABAP Programming Training Material | http://sapdocs.info
 
SAP ABAP HR TRAINING
SAP ABAP HR TRAININGSAP ABAP HR TRAINING
SAP ABAP HR TRAINING
 

Similar to Testing File

Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperVinay Kumar
 
SAP ABAP Latest Interview Questions
SAP ABAP Latest  Interview Questions SAP ABAP Latest  Interview Questions
SAP ABAP Latest Interview Questions piyushchawala
 
Oracle DBA interview_questions
Oracle DBA interview_questionsOracle DBA interview_questions
Oracle DBA interview_questionsNaveen P
 
Stop hardcoding follow parameterization
Stop hardcoding  follow parameterizationStop hardcoding  follow parameterization
Stop hardcoding follow parameterizationPreeti Sagar
 
Sql interview question part 7
Sql interview question part 7Sql interview question part 7
Sql interview question part 7kaashiv1
 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataPaulo Fagundes
 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewDave Segleau
 
SCWCD : Servlet web applications : CHAP : 3
SCWCD : Servlet web applications : CHAP : 3SCWCD : Servlet web applications : CHAP : 3
SCWCD : Servlet web applications : CHAP : 3Ben Abdallah Helmi
 
Steps for upgrading the database to 10g release 2
Steps for upgrading the database to 10g release 2Steps for upgrading the database to 10g release 2
Steps for upgrading the database to 10g release 2nesmaddy
 
Workload Management with MicroStrategy Software and IBM DB2 9.5
Workload Management with MicroStrategy Software and IBM DB2 9.5Workload Management with MicroStrategy Software and IBM DB2 9.5
Workload Management with MicroStrategy Software and IBM DB2 9.5BiBoard.Org
 
Ruby On Rails Siddhesh
Ruby On Rails SiddheshRuby On Rails Siddhesh
Ruby On Rails SiddheshSiddhesh Bhobe
 
SCWCD : Servlet web applications : CHAP 3
SCWCD : Servlet web applications : CHAP 3SCWCD : Servlet web applications : CHAP 3
SCWCD : Servlet web applications : CHAP 3Ben Abdallah Helmi
 
Asp.net interview questions
Asp.net interview questionsAsp.net interview questions
Asp.net interview questionsAkhil Mittal
 
pega training with project level Trainingwhatsup@8142976573
pega training  with project level Trainingwhatsup@8142976573pega training  with project level Trainingwhatsup@8142976573
pega training with project level Trainingwhatsup@8142976573Santhoo Vardan
 
pega training whatsup@8142976573
pega training whatsup@8142976573pega training whatsup@8142976573
pega training whatsup@8142976573Santhoo Vardan
 

Similar to Testing File (20)

Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paper
 
1000 sap-interview-qa
1000 sap-interview-qa1000 sap-interview-qa
1000 sap-interview-qa
 
SAP ABAP Latest Interview Questions
SAP ABAP Latest  Interview Questions SAP ABAP Latest  Interview Questions
SAP ABAP Latest Interview Questions
 
Oracle DBA interview_questions
Oracle DBA interview_questionsOracle DBA interview_questions
Oracle DBA interview_questions
 
Rail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendranRail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendran
 
Stop hardcoding follow parameterization
Stop hardcoding  follow parameterizationStop hardcoding  follow parameterization
Stop hardcoding follow parameterization
 
Ebook7
Ebook7Ebook7
Ebook7
 
Sql interview question part 7
Sql interview question part 7Sql interview question part 7
Sql interview question part 7
 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big Data
 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overview
 
ADO.NET by ASP.NET Development Company in india
ADO.NET by ASP.NET  Development Company in indiaADO.NET by ASP.NET  Development Company in india
ADO.NET by ASP.NET Development Company in india
 
SCWCD : Servlet web applications : CHAP : 3
SCWCD : Servlet web applications : CHAP : 3SCWCD : Servlet web applications : CHAP : 3
SCWCD : Servlet web applications : CHAP : 3
 
Steps for upgrading the database to 10g release 2
Steps for upgrading the database to 10g release 2Steps for upgrading the database to 10g release 2
Steps for upgrading the database to 10g release 2
 
Workload Management with MicroStrategy Software and IBM DB2 9.5
Workload Management with MicroStrategy Software and IBM DB2 9.5Workload Management with MicroStrategy Software and IBM DB2 9.5
Workload Management with MicroStrategy Software and IBM DB2 9.5
 
Ruby On Rails Siddhesh
Ruby On Rails SiddheshRuby On Rails Siddhesh
Ruby On Rails Siddhesh
 
SCWCD : Servlet web applications : CHAP 3
SCWCD : Servlet web applications : CHAP 3SCWCD : Servlet web applications : CHAP 3
SCWCD : Servlet web applications : CHAP 3
 
Asp.net interview questions
Asp.net interview questionsAsp.net interview questions
Asp.net interview questions
 
pega training with project level Trainingwhatsup@8142976573
pega training  with project level Trainingwhatsup@8142976573pega training  with project level Trainingwhatsup@8142976573
pega training with project level Trainingwhatsup@8142976573
 
pega training whatsup@8142976573
pega training whatsup@8142976573pega training whatsup@8142976573
pega training whatsup@8142976573
 
Struts N E W
Struts N E WStruts N E W
Struts N E W
 

Recently uploaded

VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service Saharanpur
VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service SaharanpurVIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service Saharanpur
VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service SaharanpurSuhani Kapoor
 
Call Girls Delhi {Rohini} 9711199012 high profile service
Call Girls Delhi {Rohini} 9711199012 high profile serviceCall Girls Delhi {Rohini} 9711199012 high profile service
Call Girls Delhi {Rohini} 9711199012 high profile servicerehmti665
 
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...srsj9000
 
定制(USF学位证)旧金山大学毕业证成绩单原版一比一
定制(USF学位证)旧金山大学毕业证成绩单原版一比一定制(USF学位证)旧金山大学毕业证成绩单原版一比一
定制(USF学位证)旧金山大学毕业证成绩单原版一比一ss ss
 
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一ss ss
 
Pallawi 9167673311 Call Girls in Thane , Independent Escort Service Thane
Pallawi 9167673311  Call Girls in Thane , Independent Escort Service ThanePallawi 9167673311  Call Girls in Thane , Independent Escort Service Thane
Pallawi 9167673311 Call Girls in Thane , Independent Escort Service ThanePooja Nehwal
 
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝soniya singh
 
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一zul5vf0pq
 
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsapps
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /WhatsappsBeautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsapps
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsappssapnasaifi408
 
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up Number
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up NumberCall Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up Number
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up NumberMs Riya
 
Papular No 1 Online Istikhara Amil Baba Pakistan Amil Baba In Karachi Amil B...
Papular No 1 Online Istikhara Amil Baba Pakistan  Amil Baba In Karachi Amil B...Papular No 1 Online Istikhara Amil Baba Pakistan  Amil Baba In Karachi Amil B...
Papular No 1 Online Istikhara Amil Baba Pakistan Amil Baba In Karachi Amil B...Authentic No 1 Amil Baba In Pakistan
 
萨斯喀彻温大学毕业证学位证成绩单-购买流程
萨斯喀彻温大学毕业证学位证成绩单-购买流程萨斯喀彻温大学毕业证学位证成绩单-购买流程
萨斯喀彻温大学毕业证学位证成绩单-购买流程1k98h0e1
 
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...Suhani Kapoor
 
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCR
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCRReal Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCR
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCRdollysharma2066
 
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一ga6c6bdl
 
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一(办理学位证)韩国汉阳大学毕业证成绩单原版一比一
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一C SSS
 
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...nagunakhan
 
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一ss ss
 
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...ur8mqw8e
 
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 

Recently uploaded (20)

VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service Saharanpur
VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service SaharanpurVIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service Saharanpur
VIP Call Girl Saharanpur Aashi 8250192130 Independent Escort Service Saharanpur
 
Call Girls Delhi {Rohini} 9711199012 high profile service
Call Girls Delhi {Rohini} 9711199012 high profile serviceCall Girls Delhi {Rohini} 9711199012 high profile service
Call Girls Delhi {Rohini} 9711199012 high profile service
 
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...
Hifi Defence Colony Call Girls Service WhatsApp -> 9999965857 Available 24x7 ...
 
定制(USF学位证)旧金山大学毕业证成绩单原版一比一
定制(USF学位证)旧金山大学毕业证成绩单原版一比一定制(USF学位证)旧金山大学毕业证成绩单原版一比一
定制(USF学位证)旧金山大学毕业证成绩单原版一比一
 
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一
定制(Salford学位证)索尔福德大学毕业证成绩单原版一比一
 
Pallawi 9167673311 Call Girls in Thane , Independent Escort Service Thane
Pallawi 9167673311  Call Girls in Thane , Independent Escort Service ThanePallawi 9167673311  Call Girls in Thane , Independent Escort Service Thane
Pallawi 9167673311 Call Girls in Thane , Independent Escort Service Thane
 
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝
Call Girls in Dwarka Sub City 💯Call Us 🔝8264348440🔝
 
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一
定制加拿大滑铁卢大学毕业证(Waterloo毕业证书)成绩单(文凭)原版一比一
 
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsapps
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /WhatsappsBeautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsapps
Beautiful Sapna Call Girls CP 9711199012 ☎ Call /Whatsapps
 
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up Number
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up NumberCall Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up Number
Call Girls Delhi {Rs-10000 Laxmi Nagar] 9711199012 Whats Up Number
 
Papular No 1 Online Istikhara Amil Baba Pakistan Amil Baba In Karachi Amil B...
Papular No 1 Online Istikhara Amil Baba Pakistan  Amil Baba In Karachi Amil B...Papular No 1 Online Istikhara Amil Baba Pakistan  Amil Baba In Karachi Amil B...
Papular No 1 Online Istikhara Amil Baba Pakistan Amil Baba In Karachi Amil B...
 
萨斯喀彻温大学毕业证学位证成绩单-购买流程
萨斯喀彻温大学毕业证学位证成绩单-购买流程萨斯喀彻温大学毕业证学位证成绩单-购买流程
萨斯喀彻温大学毕业证学位证成绩单-购买流程
 
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...
VIP Call Girls Kavuri Hills ( Hyderabad ) Phone 8250192130 | ₹5k To 25k With ...
 
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCR
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCRReal Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCR
Real Sure (Call Girl) in I.G.I. Airport 8377087607 Hot Call Girls In Delhi NCR
 
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一
如何办理萨省大学毕业证(UofS毕业证)成绩单留信学历认证原版一比一
 
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一(办理学位证)韩国汉阳大学毕业证成绩单原版一比一
(办理学位证)韩国汉阳大学毕业证成绩单原版一比一
 
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...
Slim Call Girls Service Badshah Nagar * 9548273370 Naughty Call Girls Service...
 
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一
定制(RHUL学位证)伦敦大学皇家霍洛威学院毕业证成绩单原版一比一
 
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...
《伯明翰城市大学毕业证成绩单购买》学历证书学位证书区别《复刻原版1:1伯明翰城市大学毕业证书|修改BCU成绩单PDF版》Q微信741003700《BCU学...
 
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(PARI) Alandi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 

Testing File

  • 1. Simplified Queries of SAP Tables from Java By Jay Brown and Steve Renard (Colgate-Palmolive) This article discusses how to easily query SAP tables in your SAP Portal applications. It is divided into two parts; the first part discusses the implementation and use of the Java classes that expose the SAP data. The second part discusses enhancing the backend function to suit your company’s functionality and security needs. Any Java based SAP Enterprise Portal application that communicates with R/3 will almost certainly use RFCs and BAPIs to perform its work on the backend system. Suppose you want to write an ESS application to allow an employee to change her HR personal data. You would most likely use the standard BAPI_PERSDATA_CHANGE function module to make the changes in SAP. This BAPI, like most, has parameters that have a defined set of valid values, which are stored in SAP tables. As an example, let’s use the BAPI_PERSDATA_CHANGE Import Parameter MARITALSTATUS, which specified the employee’s marital status. In your application, you would provide a drop-down list control with the various values (“Married”, “Single”, etc). This import parameter’s valid values are stored in the Marital Status Designators table, which is table T502T. In your application, you may choose to supply this field’s valid options in a couple of ways: 1. Hard-code the values in the application. In the beginning, this would seem to be the fastest solution. In the long term, this is a very bad idea. If new values are added or deleted, you will need to modify your code. 2. Code a custom RFC to perform the SELECT statement against the desired R/3 table. This is a more traditional way that keeps your application’s options in sync with the back-end system’s. Unfortunately, this can become a maintenance burden as more tables need to be read and more custom RFCs need to be developed. To handle this problem, we attempted to use the Function Module RFC_READ_TABLE. This RFC will query the specified table in the R/3 system and return the results in an unformatted table. Optionally, you may also specify the field names to return, the number of rows to return, as well as a selection (WHERE) clause. Because the result set is unformatted, the data need to be parsed for them to be usable. Ideally, we would like a JCO Table to be created that accurately reflects the table structure and data from the response. Having the data in a JCO Table allows us to use it in many tasks, such as displaying the data in a tableView control on the Portal. Below is a simple illustration of how the table data are returned:
  • 2. As you can see, the requested table’s fields are returned as a single row in the DATA table. Fortunately, the FIELDS table describes the data table, so we can parse out each field. We decided to develop a wrapper class called R3Table to hide the gory details of the RFC_READ_TABLE function module. We have also made our own custom version of RFC_READ_TABLE, called ZRFC_READ_TABLE. You can use R3Table class even if you don’t implement your own custom version of ZRFC_READ_TABLE, but you’ll probably want to when you read more about it the section RFC_READ_TABLE vs. ZRFC_READ_TABLE later in this document. If you decide to implement the ZRFC_READ_TABLE, be sure to change the READ_TABLE_FUNCTION_NAME static variable (in R3Table.java) to contain the name of your custom function “ZRFC_READ_TABLE”. The R3Table factory class is a subclass of JCO.Table. To use it, you must invoke one of the getInstance methods to create an instance of the class. There are many forms of the getInstance method to allow you to specify the fields to return, the maximum number of rows to return, the starting row, and the where clause. Refer to the JavaDoc for details. The most basic getInstance documentation is listed below. Public static R3Table getInstance(com.sap.mw.jco.JCO.Client client, Java.lang.String tableName) throws R3TableException, com.sap.mw.jco.JCO.Exception Method getInstance – Short Form. Instantiates a R3Table class populated with the data selected from the specified table. Returns ALL rows, ALL fields, without skipping. Parameters: Client – An already connected JCO.Client. tableName - SAP Table to query. For example, to load ALL rows and fields from SAP Table T502T: ... client = clientService.getJCOClient("SAP_HR_SYS", request); client.connect(); R3Table table = R3Table.getInstance(client, "T502T"); ... Returns: R3Table Example. The following basic example gets and connects a JCO Client to the SAP_HR_SYS system. After successfully connecting, it gets an instance of R3Table populated with all rows and fields from the T502T table on the SAP_HR_SYS system. try { IportalComponentRequest request = (IportalComponentRequest) this.getRequest(); JCO.Client client = null; IJCOClientService clientService = (IJCOClientService) request.getService(IJCOClientService.KEY);
  • 3. Client = clientService.getJCOClient("SAP_HR_SYS", request); Client.connect(); R3Table table = R3Table.getInstance(client, "T502T"); System.out.println(table.toString()); } catch (Exception e) { e.printStackTrace(); } finally { if (client != null) client.disconnect(); } Output: The R3Table.toString() output shows the information about the R3Table populated from the T502T table. Fetch Function: RFC_READ_TABLE Where Clause: Max Rows: All Delimiter: | Query Response Time (ms): 531 Skip Count: 0 Fields: FTEXT, MANDT, SPRSL, FAMST ----------- | TABLE 'T502T' ----------- | MA| | | FTEXT| ----------- |012|3|4|567890| ----------- |151|1|0|Single| |151|1|1|Marr. | |151|1|2|Wid. | |151|1|3|Div. | |151|1|4|NM | |151|1|5|Sep. | ... ... To use R3Table in the real world, you would want to pass its data along to an HTMLB control such as a dropdownListBox or tableView. To do this, you simply construct one of the List Model classes (see below) and pass it to your control. The R3TableDemo example below illustrates this by constructing a JCOTableViewModel and passing it to an HTMLB tableView control. Flow of R3TableDemo Portal Component
  • 4. The R3TableDemo IView This IView simply gets an instance of an R3Table filled with data from the T502T table, and creates a JCOTableViewModel object that will be used by the tableView control in the JSP file. Code excerpt. See full example code at the end of this document. In your Bean In your JSP // Getter method for tableListModel public JCOTableViewModel getTableListModel() { R3Table table = R3Table.getInstance(client,tName); Return new JCOTableViewModel(table); } <hbj:tableView id="tview" model="myBean.tableListModel" design="ALTERNATING" headerVisible="TRUE" footerVisible="FALSE" fillUpEmptyRows="FALSE" navigationMode="BYPAGE" selectionMode="NONE" headerText="Contents of TABLE" visibleFirstRow="1" visibleRowCount="10" rowCount="10" width="75%"/> List Models on the PDK that use JCO Table: http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/JCOChartModel.html http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/JCOListModel.html http://localhost:8080/irj/services/htmlb/docs/api/com/sapportals/htmlb/table/JCOTableViewModel.html
  • 5. RFC_READ_TABLE vs. ZRFC_READ_TABLE There are a few reasons why you might want to consider making your own copy of the function RFC_READ_TABLE in your R/3 system(s). The most compelling of these reasons is security. If the users of your external applications are only making connections to R/3 under their own R/3 user IDs, then you must give fairly broad access to each of these users when using RFC_READ_TABLE. Rather than giving out this broad access to a large group of people, another option would be to use 2 types of connections within your application—one connection under the user’s own ID for normal RFC or BAPI calls that are required, and the other connection under a generic ID for calling RFC_READ_TABLE. Neither of these options is appealing. A third more attractive option that is much easier to implement is to create your own copy of RFC_READ_TABLE and make some minor modifications. Below are 3 reasons to consider creating your own copy of RFC_READ_TABLE in your R/3 system(s), along with some details on a couple of changes you might want to consider. 1. Security The very first action of the function RFC_READ_TABLE is to call another function named, VIEW_AUTHORITY_CHECK. At first glance, this seems harmless. The name of the table to be read is passed, along with a view option of ‘S’ (which one would assume to represent, “viewing,” or, “reading”). However, if you drill-down into the function VIEW_AUTHORITY_CHECK and look through its source code, you will discover that it is ultimately doing a check on the authorization object S_TABU_DIS. The security object S_TABU_DIS checks against the user’s authorization to perform an action (read, change, create records, etc.) on tables belonging to a particular table class—It is not checking authorization for an individual table. What this means for you as an application developer is that the users of your application will need to have access to the table class or classes to which the table or tables belong, for any tables that are being read by RFC_READ_TABLE. A single table class can have thousands of tables as members, so in some cases you must give your users read access to thousands of tables so they can simply read a single table. This is something your security group will certainly frown upon if they understand the security object S_TABU_DIS, or if you bring it to their attention. As mentioned above, you could use a generic ID for R/3 connections when calling RFC_READ_TABLE, but as a long term solution looking forward to many applications using RFC_READ_TABLE, this would require a lot of extra work. 2. DATA_BUFFER_EXCEEDED The function RFC_READ_TABLE reads table records into a table with the structure TAB512. As the name somewhat indicates, this table has a single field with the length of 512 characters. This means you are limited to reading a combination of fields from your table that does not exceed 512 characters in width. In most cases, if you are limiting your call to the specific fields you need, this should not be a problem. However, you should be aware of this limitation. Exceeding 512 characters in width will result in an exception of DATA_BUFFER_EXCEEDED. 3. As of 4.6c, RFC_READ_TABLE is not Released to Customers O.K…. This last reason is pretty weak. The fact that a function module is not released seldom stops anyone from using it. If its interface changes in the future, though, just keep in mind, “I told you so.” Copying ZRFC_READ_TABLE and Changes You may want to Consider Since RFC_READ_TABLE is the only function that belongs to the function group SDTX, it is a piece of cake to copy. Simply go to transaction SE38, and copy the program SAPLSDTX. When you are prompted for a new function group name, enter ZSDTX. If you have never copied a function group like this before, you should not be alarmed that you are creating a new program that does not begin with, “Z.” The function group you create will have the name, SAPLZSDTX. As part of the copy process, you will be directed to now copy the functions that belong to the group. Since there is only 1 function, this is very simple. Just enter the name ZRFC_READ_TABLE. Again, since there is only 1 function in this group, you do not need to worry about cross references between functions in your new group, which gets pretty complicated for larger function groups.
  • 6. Security Changes After activating your new group, you should have a fully functional copied function module with the name, ZRFC_READ_TABLE. Now you are free to make any changes you desire. The first change you should consider on the authorization check that is performed. Rather than calling the function VIEW_AUTHORITY_CHECK, you might want to create your own authorization object that is checked by individual table, and use it instead. For example, replace the following code: -------------------------------------------------------------------------------------------------------------------------------- call function 'VIEW_AUTHORITY_CHECK' exporting view_action = 'S' view_name = query_table exceptions no_authority = 2 no_clientindependent_authority = 3 table_not_found = 4. if sy-subrc = 2 or sy-subrc = 3. raise not_authorized. elseif sy-subrc = 1. raise table_not_available. endif. -------------------------------------------------------------------------------------------------------------------------------- …with this: -------------------------------------------------------------------------------------------------------------------------------- DATA: tabname LIKE dd02l-tabname. SELECT SINGLE tabname FROM dd02l INTO tabname WHERE tabname EQ query_table AND as4local EQ 'A'. IF sy-subrc NE 0. RAISE table_not_available. ENDIF. AUTHORITY-CHECK OBJECT 'Z_TABL_MNT' ID 'ACTVT' FIELD '03' ID 'TABLE' FIELD query_table. IF sy-subrc NE 0. RAISE not_authorized. ENDIF. -------------------------------------------------------------------------------------------------------------------------------- The authorization object Z_TABL_MNT could be defined as follows:
  • 7. This list of permitted activities is completely up to you. If you are only using this security object for ZRFC_READ_TABLE, you only need a permitted activity of display. However, this security object might be useful in many other places, so you could add a full list of activities. Avoiding the Exception DATA_BUFFER_EXCEEDED If you need more space than the allotted 512 characters for you table records, you can change the reference type of the function’s table parameter DATA from TAB512 to some other similar structure having a single, larger character field. Anyone familiar with searching the R/3 data dictionary (transaction SE11) should be able to find a similar table with a larger character field in a matter of a few minutes. Simply swap the newfound table or structure into the reference type for DATA using the function builder (transaction. SE37). If you cannot find a suitable standard table or structure for your needs, you can simply create your own using SE11. You should keep in mind that as you increase the size of your record buffer, the performance of your function will wane. That can be a very critical issue for web applications. We welcome any suggestions of other standard function modules that could be used for the purpose of generically reading tables from applications external to R/3, or any standard security object that could be used for limiting read access by individual tables. steve_renard@colpal.com jay_brown@colpal.com
  • 8. R3Table.java package com.colpal.util.portal; import java.util.HashMap; import java.util.Iterator; import java.util.StringTokenizer; import com.sap.mw.jco.IFunctionTemplate; import com.sap.mw.jco.IMetaData; import com.sap.mw.jco.IRepository; import com.sap.mw.jco.JCO; /** * @version 1.0, 08/20/2003 * @author J. Brown * Colgate-Palmolive * <p> * Utility class to facilitate simple access to SAP Tables. * * The intention of this class is to enable Enterprise Portal applications * to load drop-down values into fields at runtime instead of hard-coding the * values in the application. * </p> * *<blockquote><pre> *The steps to use this class are as follows: *<ol> *<li>Obtain a JCO.Client to the desired SAP. *<li>Connect the Client. *<li>Use one of the getInstance() methods of this class to create a R3Table loaded with your favorite data. *<li>Create a Model, such as JCOListModel to be used in your JSP. *</ol> * *... *client = clientService.getJCOClient("SAP_HR_SYS", request); *client.connect(); *R3Table table = R3Table.getInstance(client, "T002"); *... *</pre></blockquote> * * * JCOChartModel * JCOListModel * JCOTableViewModel * */ public class R3Table extends com.sap.mw.jco.JCO.Table { public static final String READ_TABLE_FUNCTION_NAME = "RFC_READ_TABLE"; public static final String DATA_DELIMITER = "|"; private long queryDuration = 0; private String tableName = ""; private String whereClause = ""; private int maxRows = 0; private int skipCount = 0; private HashMap desiredFields = null; /** * Private class to track field size and offset. */ private class FieldInfo { FieldInfo(String _name, int _offset, int _length, String _type) { this._name = _name; this._endindex = _offset + _length; this._offset = _offset; this._length = _length; this._type = _type; } int _endindex; String _name; int _offset; int _length; String _type; } /** * Method shouldIKeepField. * Determines if the specified field name should be recorded. *
  • 9. * @param fieldName * @return boolean */ private boolean shouldIKeepField(String fieldName) { // if null (none specified), we want all fields if (desiredFields == null) return true; // if we have a list and the field name is there. if (desiredFields.containsKey(fieldName.toUpperCase())) return true; return false; } /** * Method getFieldInfo. * @param table */ private void getFieldInfo(JCO.Table table) { table.firstRow(); HashMap fieldList = new HashMap(table.getNumColumns()); do { String fn = table.getField("FIELDNAME").getString().toUpperCase(); if (shouldIKeepField(fn)) { FieldInfo fi = new FieldInfo(table.getField("FIELDNAME").getString(), table.getField("OFFSET").getInt(), table.getField("LENGTH").getInt(), table.getField("TYPE").getString()); fieldList.put(fn,fi); } } while(table.nextRow()); desiredFields = fieldList; } /** * Method recordDesiredFields. * Records the desired field names that should come back from the RFC call. * @param fieldList */ private void recordDesiredFields(String fieldList) { StringTokenizer st = new StringTokenizer(fieldList,", "); if (st.hasMoreTokens()) { desiredFields = new HashMap(); while (st.hasMoreTokens()) { String fn = st.nextToken().toUpperCase(); if (!desiredFields.containsKey(fn)) desiredFields.put(fn, null); } } } /** * Method processRows. * Loops through the raw JCO.Table rows and parses the field values into their * corresponding fields in the current table. * * @param table * @throws Exception */ private void processRows(JCO.Table table) throws JCO.Exception { Object[] fieldList = desiredFields.values().toArray(); for (int i=0; i < table.getNumRows();i++) { table.setRow(i); String row = table.getField("WA").getString(); appendRow(); for (int f=0;f<fieldList.length;f++) { FieldInfo fi = (FieldInfo)fieldList[f]; int endIndex = fi._endindex; if (endIndex > row.length()) endIndex = row.length(); String val = row.substring(fi._offset, endIndex); setValue(val.trim(), fi._name); } }
  • 10. } /** * Private Constructor, use static method R3Table.getInstance to * create an instance of this class. * * @see com.sap.mw.jco.JCO.MetaData#MetaData(IMetaData) */ private R3Table(IMetaData imd) { super(imd); } /** * Returns a string representation of the object, * which is a result of R3Table info + a call to JCO.Table.toString(). * <br> * <pre> * Fetch Function: RFC_READ_TABLE * Where Clause: * Max Rows: 5 * Delimiter: | * Query Response Time (ms): 172 * Skip Count: 4 * Fields: LAND1, NATIO, MANDT, LANDX, SPRAS * ------------------------------------- * | TABLE 'T005T' * ------------------------------------- * | MA| | LA| LANDX | NATIO | * ------------------------------------- * |012|3|456|789012345678901|234567890123456| * ------------------------------------- * |151|1|AI |Anguilla |Anguilla | * |151|1|AL |Albania |Albanian | * |151|1|AM |Armenia |Armenian | * |151|1|AN |Dutch Antilles |Dutch | * |151|1|AO |Angola |Angolan | * ------------------------------------- * </pre> * * @see java.lang.Object#toString() */ public String toString() { StringBuffer retStr = new StringBuffer(); retStr.append("Fetch Function: " + READ_TABLE_FUNCTION_NAME + "n"); retStr.append("Where Clause: " + whereClause + "n"); retStr.append("Max Rows: " + (maxRows >0 ? "" + maxRows : "All") + "n" ); retStr.append("Delimiter: " + DATA_DELIMITER + "n" ); retStr.append("Query Response Time (ms): " + queryDuration + "n"); retStr.append("Skip Count: " + skipCount + "n"); retStr.append("Fields: "); if (desiredFields != null) { for (Iterator i = desiredFields.keySet().iterator() ; i.hasNext() ;) { retStr.append(i.next()); if (i.hasNext()) retStr.append(", "); } } else { retStr.append("ALL"); } retStr.append("n"); return retStr.toString() + super.toString(); } /** * Method executeQuery. * Connects to the R/3 system associated with client and fetches the raw table data. * @param repository * @param client * @throws R3TableException * @throws Exception */ private void executeQuery(IRepository repository, JCO.Client client) throws R3TableException, JCO.Exception { IFunctionTemplate rfc = null; JCO.Table rawData = null;
  • 11. JCO.Table fieldData = null; JCO.Table options = null; rfc = repository.getFunctionTemplate(READ_TABLE_FUNCTION_NAME); JCO.Function function = new JCO.Function(rfc); JCO.ParameterList importList = function.getImportParameterList(); importList.setValue(tableName, "QUERY_TABLE"); importList.setValue(DATA_DELIMITER, "DELIMITER"); importList.setValue(" ", "NO_DATA"); if (maxRows > 0) importList.setValue(maxRows, "ROWCOUNT"); if (skipCount > 0) importList.setValue(skipCount, "ROWSKIPS"); if (whereClause.length() > 0) { options = function.getTableParameterList().getTable("OPTIONS"); options.appendRow(); options.setValue(whereClause, "TEXT"); } client.execute(function); rawData = function.getTableParameterList().getTable("DATA"); fieldData = function.getTableParameterList().getTable("FIELDS"); getFieldInfo(fieldData); processRows(rawData); } /** * Method getInstance - Short Form. Instantiates an R3Table class populated with the data selected from the specified table. * Returns ALL rows, ALL fields, without skipping. * @param client An already connected JCO.Client. * @param tableName SAP Table to query. * *<p> *For example, to load ALL rows and fields from SAP Table T502T *<blockquote><pre> *... *client = clientService.getJCOClient("SAP_HR_SYS", request); *client.connect(); *R3Table table = R3Table.getInstance(client, "T502T"); *... *</pre></blockquote> *<p> * * * @return R3Table * * @throws R3TableException * @throws com.sap.mw.jco.JCO.Exception */ public static R3Table getInstance(JCO.Client client, String tableName) throws R3TableException, JCO.Exception { return getInstance(client, tableName, "", "", 0, 0); } /** * Method getInstance - Medium Form. Instantiates an R3Table class populated with the data selected from the specified table. * Returns ALL rows, ALL fields, without skipping. * @param client An already connected JCO.Client. * @param tableName ABAP Table to query. * @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code> * @return R3Table * * @throws R3TableException * @throws com.sap.mw.jco.JCO.Exception */ public static R3Table getInstance(JCO.Client client, String tableName, String whereClause) throws R3TableException, JCO.Exception { return getInstance(client, tableName, whereClause, "", 0, 0); }
  • 12. /** * Method getInstance - Medium Form. Instantiates an R3Table class populated with the data selected from the specified table. * Returns ALL rows, without skipping. * @param client An already connected JCO.Client. * @param tableName ABAP Table to query. * @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code> * @param desiredFields A List of Field Names delimited by commas. An empty String indicates ALL fields. * @return R3Table * * @throws R3TableException * @throws com.sap.mw.jco.JCO.Exception */ public static R3Table getInstance(JCO.Client client, String tableName, String whereClause, String desiredFields) throws R3TableException, JCO.Exception { return getInstance(client, tableName, whereClause, desiredFields, 0, 0); } /** * Method getInstance - Long Form. Instantiates an R3Table class populated with the data selected from the specified table. * Returns specified number of rows, without skipping. * @param client An already connected JCO.Client. * @param tableName ABAP Table to query. * @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code> * @param desiredFields A List of Field Names delimited by commas. An empty String indicates ALL fields. * @param maxRows The maximum number of row to return. * @return R3Table * * @throws R3TableException * @throws com.sap.mw.jco.JCO.Exception */ public static R3Table getInstance(JCO.Client client, String tableName, String whereClause, String desiredFields, int maxRows) throws R3TableException, JCO.Exception { return getInstance(client, tableName, whereClause, desiredFields, 0, maxRows); } /** * Method getInstance - Long Form. Instantiates an R3Table class populated with the data selected from the specified table. * @param client An already connected JCO.Client. * @param tableName ABAP Table to query. * @param whereClause ABAP WHERE CLAUSE such as <code>SPRAS = 'Q' OR SPRAS = 'T'</code> * @param desiredFields A List of Field Names delimited by commas. An empty String indicates ALL fields. * @param skipCount The number of rows to skip. 0 indicates no skipping. * @param maxRows The maximum number of row to return. * @return R3Table * * @throws R3TableException * @throws com.sap.mw.jco.JCO.Exception */ public static R3Table getInstance(JCO.Client client, String tableName, String whereClause, String desiredFields, int skipCount, int maxRows) throws R3TableException, JCO.Exception { R3Table retTable; IRepository repository = JCO.createRepository("repository." + client.toString(), client); retTable = new R3Table(repository.getTableDefinition(tableName)); retTable.setMaxRows(maxRows); retTable.setWhereClause(whereClause); retTable.setTableName(tableName); retTable.recordDesiredFields(desiredFields); retTable.setSkipCount(skipCount); long st = System.currentTimeMillis(); retTable.executeQuery(repository, client); long et = System.currentTimeMillis(); retTable.setQueryDuration(et - st); return retTable; }
  • 13. // ************* Private setters *************** private void setMaxRows(int maxRows) { this.maxRows = maxRows; } private void setQueryDuration(long queryDuration) { this.queryDuration = queryDuration; } private void setTableName(String tableName) { this.tableName = tableName; } private void setWhereClause(String whereClause) { this.whereClause = whereClause; } private void setSkipCount(int skipCount) { this.skipCount = skipCount; } }
  • 14. demoBean.java package com.colpal.demo.R3Table; import com.sapportals.htmlb.IListModel; import com.sapportals.htmlb.table.JCOTableViewModel; import com.colpal.util.portal.*; import com.sap.mw.jco.JCO; import java.io.Serializable; public class demoBean implements Serializable { private JCOTableViewModel tableListModel = null; private R3Table table = null; private boolean error = false; private String lastMessage = ""; private boolean bHasData = false; public boolean isError() { return error; } public boolean hasData() { return bHasData; } public void loadTable(JCO.Client client, String tableName) { setLastMessage(""); error = false; try { table = R3Table.getInstance(client, tableName); bHasData = true; } catch (Exception e) { setLastMessage(e.getMessage()); error = true; } } /** * Returns the tableListModel. * @return TableViewModel */ public JCOTableViewModel getTableListModel() { return new JCOTableViewModel(table); } /** * Sets the tableListModel */ public void setTableListModel(JCOTableViewModel employmentListModel) { this.tableListModel = employmentListModel; } /** * Returns the lastMessage. * @return String */ public String getLastMessage() { return lastMessage; } /** * Sets the lastMessage. * @param lastMessage The lastMessage to set */ public void setLastMessage(String lastMessage) { this.lastMessage = lastMessage; } } page1.jsp <%@ taglib uri="tagLib" prefix="hbj" %> <jsp:useBean id="myBean" scope="session" class="com.colpal.demo.R3Table.demoBean" /> <hbj:content id="myContext" > <hbj:page title="PageTitle"> <hbj:form id="myFormId" > <hbj:textView id="dispID" text="R3Table Demo" design="EMPHASIZED"/>
  • 15. <% if (myBean.hasData()) {%> <hbj:tableView id="tview" model="myBean.tableListModel" design="ALTERNATING" headerVisible="TRUE" footerVisible="FALSE" fillUpEmptyRows="FALSE" navigationMode="BYPAGE" selectionMode="NONE" headerText="Contents of TABLE" visibleFirstRow="1" visibleRowCount="10" rowCount="10" width="75%"/> <%}%> <!-- Table to align button --> <hbj:formLayout width="100%"> <hbj:formLayoutRow> <hbj:formLayoutCell width="60px" align="LEFT"> <hbj:inputField id="tableName" visible="true" type="String"/> </hbj:formLayoutCell> <hbj:formLayoutCell> <hbj:button id="load" text="Load Table" width="100" tooltip="Click here." onClick="loadTable" disabled="false" design="STANDARD"/> </hbj:formLayoutCell> </hbj:formLayoutRow> </hbj:formLayout> <% String ImageURL = componentRequest.getWebResourcePath()+ "/images/"; %> <%if (myBean.isError()){%> <hbj:image id="Error" src="<%= ImageURL +"error.gif" %>" alt="error.gif"/>&nbsp;<font color="RED"><hbj:textView wrapping="TRUE" id="ErrorMessage" layout="NATIVE" text= "<%=myBean.getLastMessage()%>" design="STANDARD"/></font> <%}%> </hbj:form> </hbj:page> </hbj:content>
  • 16. AppController.java package com.colpal.demo.R3Table; import com.colpal.demo.R3Table.demoBean; import com.sapportals.htmlb.*; import com.sapportals.htmlb.enum.*; import com.sapportals.htmlb.event.*; import com.sapportals.htmlb.page.*; import com.sapportals.portal.htmlb.page.*; import com.sapportals.portal.prt.component.*; import com.sapportals.portal.prt.service.jco.IJCOClientService; import com.colpal.util.portal.*; import com.sap.mw.jco.JCO; import com.sap.mw.jco.IFunctionTemplate; import com.sap.mw.jco.IRepository; import com.sap.mw.jco.*; public class AppController extends PageProcessorComponent { public DynPage getPage(){ return new AppControllerDynPage(); } public static class AppControllerDynPage extends JSPDynPage{ private demoBean myBean = null; public void getBeanFromFramework() { IPortalComponentSession componentSession = ((IPortalComponentRequest)getRequest()).getComponentSession(); Object o = componentSession.getValue("myBean"); if(o==null || !(o instanceof demoBean)){ myBean = new demoBean(); componentSession.putValue("myBean",myBean); } else { myBean = (demoBean) o; } } public void doInitialization() { getBeanFromFramework(); } public void onLoadTable(Event event) { IPortalComponentRequest request = (IPortalComponentRequest) this.getRequest(); JCO.Client client = null; IJCOClientService clientService = (IJCOClientService) request.getService(IJCOClientService.KEY); getBeanFromFramework(); String tableName = null; Component component = getComponentByName("tableName"); if (component != null) if (component instanceof InputField) tableName = ((InputField)component).getValueAsDataType().toString(); if (tableName != null) { try { client = clientService.getJCOClient("SAP_GHD_151", request); client.connect(); myBean.loadTable(client,tableName.toUpperCase()); } catch (Exception e) { e.printStackTrace(); } finally { if (client != null) client.disconnect(); } }
  • 17. } public void doProcessAfterInput() throws PageException { } public void doProcessBeforeOutput() throws PageException { this.setJspName("page1.jsp"); } } }