persistenceexample4/PersistenceExample.java
package persistenceexample4;
import java.io.IOException;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import persistenceexample4.bean.BasicDataHandler;
import persistenceexample4.bean.TableViewDefinition;
import persistenceexample4.datafactory.ReadWriteEntities;
import com.sap.ip.me.api.logging.AbstractLogging;
import com.sap.ip.me.api.logging.AppLog;
import com.sap.ip.me.api.logging.Severities;
import com.sap.ip.me.api.runtime.jsp.AbstractMEHttpServlet;
// Uses the Peristence API to store and read data
public class PersistenceExample extends AbstractMEHttpServlet implements Constants {
public static int idCounter;
private TableViewDefinition tableViewDefinition;
private BasicDataHandler dataHandler;
private String headLine;
boolean listall;
private int filter_index;
private int start_index;
private int sort_index;
private boolean sort_ascending;
private String buttontext;
private String pageTitle;
private String currentPageFooter;
private String buttontextQuery;
private String filter_string;
private String current_filter_string;
private Vector commandLine = new Vector();
/**
* Must be overwritten - return the name of the application
*/
public String getApplicationName() {
return MI_APPLICATION_NAME;
}
/**
* doIntialize - called when the servlet is activated the first time
*/
public void doInitialize() throws ServletException {
/* No resource bundle used setResourceBundle("/NoResourceBundleUsed"); */
idCounter = 0;
// Setup and initialize the Persistence Runtime
ReadWriteEntities.setupPersistenceRuntime();
// We create initial entries with the Persistence API, so that we have not to display an emtpy table
ReadWriteEntities.writeExampleEntries();
// Set list parameter to list only main entries
setListPartial();
setFilterOff();
// Set sorting variables.
sort_index = 0;
sort_ascending = true;
// Prepare a log output - Level DEBUG - Information about classloader
ClassLoader cl = getClass().getClassLoader();
AbstractLogging aLogger = AppLog.getInstance(MI_APPLICATION_NAME);
aLogger.log(Severities.DEBUG, "MIClientInfo: Create MIClientInfoServlet.doInitialize with Classloader {0}", (cl == null ? "(null)" : cl.toString()));
// Setup Commands for this example. Commands are displayed on the top of the centerpage.
// In this example we use add, delete, filter and list all commands.
setCommands();
}
/**
* doHandleEvent - called any subsequent time when an event on the web client occurs.
*/
public String doHandleEvent(String eventName, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Set the name of the JSP that has to be called when this method is finished.
// INITIAL_JSP ist defined in the interface Constants.java and refers to welcome.jsp. This JSP displays a welcome message
// and asks for your name. Welcome.jsp has a submit button which generates the event EVENT_NAME. When this event occurs,
// the tableView.jsp is called and displays system information.
// The welcome.jsp is called by default - if the servlet is called the first time or an unknown event occurs.
// Set default JSP.
String nextJSP = INITIAL_JSP;
pageTitle = "Car Inventory";
currentPageFooter = "menu.jsp";
// Set default text for headline
headLine = WELCOME_MESSAGE;
// Get bean, if there is one, in the session context, otherwise create a new instance.
getBeansFromContext(request);
//
// Events in menu.jsp
if (eventName.equals(EVENT_LIST)) {
// Toggle on listall (boolean) - if acutally true than set to false and vice versa
if (listall == true) {
setListPartial();
} else {
setListAll();
}
}
if (eventName.equals(EVENT_ADDENTRY)) {
// Event occurs when the ADD button in menu.jsp has been pressed.
// We display add.jsp as next JSP.
pageTitle = "Add car/license";
currentPageFooter = "add.jsp";
nextJSP = ADD_JSP;
}
if (eventName.equals(EVENT_QUERY)) {
// Event occurs when the FILTER button in menu.jsp has been pressed.
// We display query.jsp.
nextJSP = QUERY_JSP;
}
if (eventName.equals(EVENT_DELENTRY)) {
// Event occurs when the DELETE button in menu.jsp has been pressed.
nextJSP = deleteEntry(request);
}
if (eventName.equals(EVENT_SAVE)) {
// Event occurs when the SAVE button in menu.jsp has been pressed. It commits the changes in the database
dataHandler.commit();
}
if (eventName.equals(EVENT_SORTBYMAKE)) {
// Sort by Model has been clicked. The car attributes start with 0. Therefore we decrement I_MAKE by 1.
sort_index = I_MAKE - 1;
if (sort_ascending == true)
sort_ascending = false;
else
sort_ascending = true;
// read data according to new sort setting
dataHandler = BasicDataHandler.instance(filter_index, sort_index, sort_ascending, filter_string, listall);
}
if (eventName.equals(EVENT_SORTBYMODEL)) {
// Sort by Model has been clicked. The car attributes start with 0. Therefore we decrement I_MAKE by 1.
sort_index = I_MODEL - 1;
if (sort_ascending == true)
sort_ascending = false;
else
sort_ascending = true;
// read data according to new sort setting
dataHandler = BasicDataHandler.instance(filter_index, sort_index, sort_ascending, filter_string, listall);
}
//
// Events from add.jsp or delete.jsp (Cancel event - is handled the same for both JSP
//
if (eventName.equals(EVENT_ADDENTRYCANCEL)) {
// Event occurs when the cancel button has been pressed on the ADD ENTRY JSP. No action. Show initial screen
nextJSP = INITIAL_JSP;
}
//
// Events in add.jsp
//
if (eventName.equals(EVENT_ADDENTRYSUBMIT)) {
// Event occurs when the submit button has been pressed on the ADD ENTRY JSP
nextJSP = addEntry(request);
}
//
// Event in delete.jsp - is the OK button to acknowledge the information text
//
if (eventName.equals(EVENT_DELETEENTRYSUBMIT)) {
nextJSP = INITIAL_JSP;
}
//
// Event in query.jsp
//
if (eventName.equals(EVENT_QUERYCANCEL)) {
// Event occurs when the cancel button has been pressed on the Cancel button. No action. Show initial screen
nextJSP = INITIAL_JSP;
}
if (eventName.equals(EVENT_QUERYSUBMIT)) {
// Event occurs when the OK button has been pressed. The Filter string is set for the Query.
nextJSP = setFilter(request);
}
// Checking for navigation events
// First Page
if (eventName.equals(EVENT_FIRSTPAGE)) {
start_index = 0;
nextJSP = INITIAL_JSP;
}
// Last Page
if (eventName.equals(EVENT_LASTPAGE)) {
start_index = ((tableViewDefinition.getRowsInDataset() - 1) / MAX_TABLE_ROWS) * MAX_TABLE_ROWS;
nextJSP = INITIAL_JSP;
}
if (eventName.equals(EVENT_PAGEUP)) {
if (start_index >= MAX_TABLE_ROWS)
start_index = start_index - MAX_TABLE_ROWS;
nextJSP = INITIAL_JSP;
}
if (eventName.equals(EVENT_PAGEDOWN)) {
start_index = start_index + MAX_TABLE_ROWS;
nextJSP = INITIAL_JSP;
}
// The "input" object with type = image in menu.jsp delivers the eventname with .x and .y appended to it
// So we check the beginning of the eventname.
if (eventName.startsWith(EVENT_GOTOPAGE)) {
String inputField = (String) request.getParameter("GOTO_PAGE");
int number = Integer.parseInt(inputField);
start_index = (number - 1) * MAX_TABLE_ROWS;
// If a page is specified that is higher than the maximum pages for the dataset
// we set the last page as current page
int max_index = ((tableViewDefinition.getRowsInDataset() - 1) / MAX_TABLE_ROWS) * MAX_TABLE_ROWS;
if (start_index > max_index)
start_index = max_index;
// Check for negative page value - if so set frist page
if (start_index < 0)
start_index = 0;
nextJSP = INITIAL_JSP;
}
// Check if event comes from a table entry. If so, we display the detail page
if (getDetailPage(eventName) == true){
nextJSP = DETAIL_JSP;
}
// Load bean with values from persistence layer
loadBean();
// Put bean in the session context.
putBeansIntoContext(request);
// Exit with name of JSP.
return nextJSP;
}
/**
* @param eventName checks if the event comes from an table entry
* @returns the detail page if the event comes from a table entry
*/
private boolean getDetailPage(String eventName) {
boolean event = false;
// Check if Eventname matches one entry, first column, in the actual data set
for (int i = 0; i < tableViewDefinition.getTableRows(); i++) {
if (eventName.equals(dataHandler.getCurrentSubTableContent(i, 0))) {
event = true;
// laden der Dateildaten
tableViewDefinition.setSelected_index(i);
}
}
return event;
}
/**
* Method deleteEntry - deletes an selected entry
* @return String - next JSP to call.
*/
private String deleteEntry(HttpServletRequest request) {
String nextJSP = null;
// We loop through all entries and check
// which row has been selected. If we find a selected row we delete the entry.
// We use the request.getParameter(valueOfCheckbox) method to find out which checkbox is clicked. The valueOfCheckbox
// is stored in the first column of the databean.
// If no row is selected we display a hint to select a row first.
boolean aRowWasChecked = false;
for (int i = 1; i < tableViewDefinition.getTableRows(); i++) {
String check = (String) request.getParameter(dataHandler.getCurrentSubTableContent(i, 0));
if (check != null) {
// Check Row has been found
aRowWasChecked = true;
String car = dataHandler.getCurrentSubTableContent(i, 0);
// Delete car. License is deleted also, because we use TreeOptionType.COMPLETE in the deleteEntity method
if (car.length() > 0) {
ReadWriteEntities.deleteEntity(car);
// Load new data
dataHandler = BasicDataHandler.instance(filter_index, sort_index, sort_ascending, filter_string, listall);
}
}
}
nextJSP = INITIAL_JSP;
if (aRowWasChecked == false) {
// no row was checked - display an information message
nextJSP = DELETE_JSP;
}
return nextJSP;
}
/**
* Method addEntry. - Adds an Entry according to user input
* @return String - next JSP to call
*/
private String addEntry(HttpServletRequest request) {
// We take the content of the inputfield in the JSP named CAR and LICENCE and store in via the Peristence API
// As next JSP we set the INITIAL_JSP again.
String make = (String) request.getParameter("MAKE");
String model = (String) request.getParameter("MODEL");
String engine = (String) request.getParameter("ENGINE");
String cylinders = (String) request.getParameter("CYLINDERS");
String valves = (String) request.getParameter("VALVES");
String lic = (String) request.getParameter("LICENSE");
dataHandler.addEntry(make, model, engine, cylinders, valves, lic);
dataHandler = BasicDataHandler.instance(filter_index, sort_index, sort_ascending, filter_string, listall);
return INITIAL_JSP;
}
/**
* Method setFilter - according to user input a filter string will be set up.
* @param request
* @return String - next JSP to call
*/
private String setFilter(HttpServletRequest request) {
filter_string = (String) request.getParameter("MAKE");
if (filter_string.length() == 0) {
setFilterOff();
} else {
// The filter_index has to match the "AttributeDescriptor" in ExamplePackagePersistenceMaster. I_MAKE is the
// index for our output array, which has the entityKey at index 0. The "AttributeDescriptor" has no entityKey
// and starts with "make" right away - so we subtract 1 from the I_MAKE index.
setFilterOn(I_MAKE - 1, filter_string);
}
return INITIAL_JSP;
}
private void getBeansFromContext(HttpServletRequest request) {
// Get table defintion bean from session context. There is a bean, when this servlet has already been called once.
tableViewDefinition = (TableViewDefinition) request.getSession().getAttribute("tableViewDefinition");
// No bean in session context - create a new instance.
if (tableViewDefinition == null)
tableViewDefinition = new TableViewDefinition();
dataHandler = (BasicDataHandler) request.getSession().getAttribute("dataHandler");
// No data bean in session context - create a new instance.
if (dataHandler == null)
dataHandler = BasicDataHandler.instance(filter_index, sort_index, sort_ascending, filter_string, listall);
}
public void loadBean() {
// Set headerpanel
// The left side displays the MI icon, that canbe clicked to go back to the MI home page
tableViewDefinition.setHeaderPanelEntryLeft("<a href=\"http://127.0.0.1:4444/me\" > <img src=\"mimes/milogo.gif\" alt=\"MI Home\" ></a>");
// The right side displays the text MDK
tableViewDefinition.setHeaderPanelEntryRight("MDK");
// Setup Commands for this example. Commands are displayed on the top of the centerpage.
// In this example we use add, delete, filter and list all commands.
setCommands();
// Set footerpanel
// The left side displays the application name
tableViewDefinition.setFooterPanelEntryLeft(current_filter_string);
// The right side displays the type of the example
tableViewDefinition.setFooterPanelEntryRight(currentPageFooter);
// set commands for application - the commands have been set in the initialize method already
tableViewDefinition.setCommandLine(commandLine);
// set title of the center window
tableViewDefinition.setCenterPageTitle(pageTitle);
// Generate table header
setTableHeader();
// Generate data and set Vector in bean
dataHandler.copyDataArrayToSubArray(start_index, MAX_TABLE_ROWS);
// The following variables are necessary for the navigation
tableViewDefinition.setTableRows(MAX_TABLE_ROWS);
tableViewDefinition.setTableColumns(dataHandler.getColumns());
tableViewDefinition.setRowsInDataset(dataHandler.getDataCount());
tableViewDefinition.setCurrentIndex(start_index);
}
private void putBeansIntoContext(HttpServletRequest request) {
// Put table definition bean in session context
if (tableViewDefinition == null) {
request.getSession().removeAttribute("tableViewDefintion");
} else {
request.getSession().setAttribute("tableViewDefinition", tableViewDefinition);
}
// Put data defintion in session context
if (dataHandler == null) {
request.getSession().removeAttribute("dataHandler");
} else {
request.getSession().setAttribute("dataHandler", dataHandler);
}
}
public void setListPartial() {
listall = false;
buttontext = "List all";
}
public void setListAll() {
listall = true;
buttontext = "Car list";
}
/**
* Method setFilterOff - All Data without Filter are displayed.
*/
private void setFilterOff() {
filter_index = I_ALL;
buttontextQuery = BUTTON_QUERY_TEXT;
current_filter_string = "No Filter";
}
private void setFilterOn(int Index, String filter_string) {
buttontextQuery = BUTTON_QUERY_RESET_TEXT;
current_filter_string = "Filter: " + filter_string;
filter_index = I_MAKE - 1;
}
private void setCommands() {
// The command line contain add, delete, set filter and list all
// Add command
commandLine.removeAllElements();
commandLine.addElement("<input type=\"submit\" value=\"Add\" class=\"image\" name=\"_event_" + EVENT_ADDENTRY + "\">");
// Set Filter command
commandLine.addElement("<input type=\"submit\" value=\"" + buttontextQuery + "\" class=\"image\" name=\"_event_" + EVENT_QUERY + "\">");
// List all command
commandLine.addElement("<input type=\"submit\" value=\"" + buttontext + "\" class=\"image\" name=\"_event_" + EVENT_LIST + "\">");
// Delete command
commandLine.addElement("<input type=\"submit\" value=\"Delete\" class=\"image\" name=\"_event_" + EVENT_DELENTRY + "\">");
// Save command
commandLine.addElement("<input type=\"submit\" value=\"Save\" class=\"image\" name=\"_event_" + EVENT_SAVE + "\">");
}
// Load array in Bean with Information about the Mobile Engine, i is the index for the entries
private void setTableHeader() {
tableViewDefinition.initTableHeader(4);
// First column empty - displayes the checkbox
tableViewDefinition.setTableHeaderEntry(I_ID, " ");
/* The "Make" and "Model" headline can be clicked by the user to select which column is sorted by. That the event
* of the link is passed on to this servlet and also tells us which link has been clicked, we use the ?event=
* paramenter on the "href" tag. A image indiactes which column is active for sorting. The getMime... methods
* return either a "nosort.gif" (this column is not used for sorting) or "ascending.gif" when the column is
* used for sorting
*/
tableViewDefinition.setTableHeaderEntry(I_MAKE, "<a href=\"?event=" + EVENT_SORTBYMAKE + "\" > <img src=\"" + getMimeMakeFileName() + "\" border=\"0\">Make</a>");
tableViewDefinition.setTableHeaderEntry(I_MODEL, "<a href=\"?event=" + EVENT_SORTBYMODEL + "\" > <img src=\"" + getMimeModelFileName() + "\" border=\"0\">Model</a>");
// Engine
tableViewDefinition.setTableHeaderEntry(I_LICENSE, "License");
/* // Number of cylinders
tableHeader.addElement("C");
// Number of valves per cylinder
tableHeader.addElement("V");
tableHeader.addElement("License"); */
}
/**
* Method getMimeModelFileName. - gets the apporiate filename to indicate sorting direction for model
* @return String
*/
private String getMimeMakeFileName() {
String mime = "mimes/nosort.gif";
if (sort_index == I_MAKE - 1) {
mime = "mimes/ascending.gif";
if (sort_ascending == false)
mime = "mimes/descending.gif";
}
return mime;
}
private String getMimeModelFileName() {
String mime = "mimes/nosort.gif";
if (sort_index == I_MODEL - 1) {
mime = "mimes/ascending.gif";
if (sort_ascending == false)
mime = "mimes/descending.gif";
}
return mime;
}
}