Oracle Glassfish + Rest + PL/SQL = Awesome

What if you could call PL/SQL from Rest? What if you could do it on a free open-source container? Would you be interested? If so, read on. The project for Netbeans can be downloaded from https://drive.google.com/file/d/0B9yySVFbRABBcjBoaDBnZWNvMGc/edit?usp=sharing.

emplTree-restService

Let’s take the normal HR schema, the employees table. Let’s return a PL/SQL table type object of this table with the additional columns of manager first and last name and the level (using the old CONNECT BY) from a Rest web service running in Oracle Glassfish. This will give us the opportunity to convert this xml representation into a nice tree in an application (mobile or otherwise). Sound complicated? Not anymore.

The steps to accomplish this are as follows:

1. Install the required software, Netbeans, Glassfish, Oracle Standard Edition (you can use an Oracle pre-built VM), Jdeveloper, and SQLDeveloper (all Oracle free products).

2.  Install Oracle Standard Edition (because you need Java in the database) or use a pre-built Oracle VM and open up the HR schema (all fully documented from Oracle).

3.  Install SQLDeveloper and add the employee type object, employee table type object, and employee tree package.

create type employees_type
as object
( EMPLOYEE_ID NUMBER(6,0),
FIRST_NAME VARCHAR2(20 BYTE),
LAST_NAME VARCHAR2(25 BYTE),
EMAIL VARCHAR2(25 BYTE),
PHONE_NUMBER VARCHAR2(20 BYTE),
HIRE_DATE DATE,
JOB_ID VARCHAR2(10 BYTE),
SALARY NUMBER(8,2),
COMMISSION_PCT NUMBER(2,2),
MANAGER_ID NUMBER(6,0),
DEPARTMENT_ID NUMBER(4,0),
MGR_FIRST_NAME VARCHAR2(20 BYTE),
MGR_LAST_NAME VARCHAR2(25 BYTE),
LEVEL_NUM NUMBER
);

create or replace
type employees_table_type
as table of employees_type;

create or replace
package employees_tree_pkg as

procedure mgr_directs (in_employee_id in  varchar2,
out_status     out varchar2,
out_employees  out employees_table_type);

end employees_tree_pkg;

create or replace
package body employees_tree_pkg as

procedure mgr_directs (in_employee_id in  varchar2,
out_status     out varchar2,
out_employees  out employees_table_type)
is
cursor c_info (p_employee_id varchar2)
is
SELECT level,
tp.employee_id,
tp.first_name,
tp.last_name,
tp.email,
tp.phone_number,
tp.hire_date,
tp.job_id,
tp.salary,
tp.commission_pct,
tp.manager_id,
tp.department_id,
( select first_name from employees tpm where tpm.employee_id = tp.manager_id and rownum = 1 ) as MGR_FIRST_NAME,
( select last_name from employees tpm2 where tpm2.employee_id = tp.manager_id and rownum = 1) as MGR_LAST_NAME
FROM employees tp
START WITH tp.employee_id = p_employee_id
CONNECT BY tp.manager_id = PRIOR tp.employee_id
order by level;

r_info c_info%ROWTYPE;

l_employees employees_table_type := employees_table_type();
begin
out_status    := ‘S';

OPEN c_info ( in_employee_id);
LOOP
FETCH c_info INTO r_info;
EXIT
WHEN c_info%NOTFOUND;
l_employees.extend;
l_employees(l_employees.count) := employees_type(
r_info.employee_id,
r_info.first_name,
r_info.last_name,
r_info.email,
r_info.phone_number,
r_info.hire_date,
r_info.job_id,
r_info.salary,
r_info.commission_pct,
r_info.manager_id,
r_info.department_id,
r_info.mgr_first_name,
r_info.mgr_last_name,
r_info.level);

END LOOP;
CLOSE c_info;
out_employees := l_employees;

EXCEPTION
WHEN OTHERS THEN
out_status := ‘E';
end;

end employees_tree_pkg;

4.  Install Glassfish, create a domain, and add the appropriate jdbc driver from Oracle (fully documented from Oracle), and create a jdbc connection pool and jdbc connection to the Oracle database.

emplTree-glassfishJDBC

5.  Install Netbeans and get it talking with the database and Glassfish.

6.  Open up Jdeveloper and create an ADF project. Navigate to the database navigator and add the connection. Once connected, right-click the package and publish the package as a JAX-WS web service to the project. This will create reusable java classes for accessing the package.

emplTree-publishWS1

emplTree-publishWS2

7. Open up Netbeans and create a web project. Right-click the project and create a Restful web service from tables to make sure everything is communicating. You can point to the HR employees table, for instance.

8.  Drop in the classes created from the Jdeveloper project and modify the context object to point to the Glassfish JDBC JNDI connection name.

emplTree-contextChange

9.  Create a return class and the Rest class.

package com.hrtest;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class UserTreeResult implements Serializable {

private String employeeId;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private String hireDate;
private String jobId;
private String salary;
private String commissionPct;
private String managerId;
private String departmentId;
private String mgrFirstName;
private String mgrLastName;
private String levelNum;

public UserTreeResult() {
super();
}

public UserTreeResult(String employeeId, String firstName, String lastName, String email,
String phoneNumber, String hireDate, String jobId, String salary,
String commissionPct, String managerId, String departmentId, String mgrFirstName, String mgrLastName, String levelNum) {
this.employeeId = employeeId;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneNumber = phoneNumber;
this.hireDate = hireDate;
this.jobId = jobId;
this.salary = salary;
this.commissionPct = commissionPct;
this.managerId = managerId;
this.departmentId = departmentId;
this.mgrFirstName = mgrFirstName;
this.mgrLastName = mgrLastName;
this.levelNum = levelNum;
}

public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}

public String getEmployeeId() {
return this.employeeId;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getFirstName() {
return this.firstName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getLastName() {
return this.lastName;
}

public void setEmail(String email) {
this.email = email;
}

public String getEmail() {
return this.email;
}

public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}

public String getPhoneNumber() {
return this.phoneNumber;
}

public void setHireDate(String hireDate) {
this.hireDate = hireDate;
}

public String getHireDate() {
return this.hireDate;
}

public void setJobId(String jobId) {
this.jobId = jobId;
}

public String getJogId() {
return this.jobId;
}

public void setSalary(String salary) {
this.salary = salary;
}

public String getSalary() {
return this.salary;
}

public void setCommissionPct(String commissionPct) {
this.commissionPct = commissionPct;
}

public String getCommissionPct() {
return this.commissionPct;
}

public void setManagerId(String managerId) {
this.managerId = managerId;
}

public String getManagerId() {
return this.managerId;
}

public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}

public String getDepartmentId() {
return this.departmentId;
}

public void setMgrFirstName(String mgrFirstName) {
this.mgrFirstName = mgrFirstName;
}

public String getMgrFirstName() {
return this.mgrFirstName;
}

public void setMgrLastName(String mgrLastName) {
this.mgrLastName = mgrLastName;
}

public String getMgrLastName() {
return this.mgrLastName;
}

public void setLevelNum(String levelNum) {
this.levelNum = levelNum;
}

public String getLevelNum() {
return this.levelNum;
}

}

 

package com.hrtest.service;

import com.hrtest.EmployeesTreeUser;
import com.hrtest.EmployeesTypeUser;
import com.hrtest.EmployeesTypeUserArrayHolder;
import com.hrtest.UserTreeResult;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.xml.rpc.holders.StringHolder;

/**
*
* @author ajdevelops
*/
@Stateless
@Path(“com.hrtest.employeestree”)
public class EmployeesTreeFacadeREST {

@PersistenceContext(unitName = “WebApplication2PU”)
private EntityManager em;

public EmployeesTreeFacadeREST() {
super();
}

@GET
@Path(“{employeeid}”)
@Produces({“application/xml”, “application/json”})
public List<UserTreeResult> find(@PathParam(“employeeid”) String employeeId) {
StringHolder callResult = new StringHolder();
EmployeesTypeUserArrayHolder callTableResult = new EmployeesTypeUserArrayHolder();
EmployeesTypeUser[] resultArray = null;
DateFormat dateFormat = new SimpleDateFormat(“MMddyyyy”, Locale.ENGLISH);

List<UserTreeResult> resultList = null;

try {
EmployeesTreeUser dbCallUser = new EmployeesTreeUser();
dbCallUser.mgrDirects(employeeId, callResult, callTableResult);

if (callTableResult.value.length > 0) {
resultArray = callTableResult.value;

List<UserTreeResult> initializerArray = new ArrayList<UserTreeResult>();

for (int i = 0; i < resultArray.length; i++) {

UserTreeResult initializer = new UserTreeResult();

if (resultArray[i].getCommissionPct() != null) {
initializer.setCommissionPct(resultArray[i].getCommissionPct().toString());
} else {
initializer.setCommissionPct(“”);
}

if (resultArray[i].getDepartmentId() != null) {
initializer.setDepartmentId(resultArray[i].getDepartmentId().toString());
} else {
initializer.setDepartmentId(“”);
}
initializer.setEmail(resultArray[i].getEmail());

if (resultArray[i].getEmployeeId() != null) {
initializer.setEmployeeId(resultArray[i].getEmployeeId().toString());
} else {
initializer.setEmployeeId(“”);
}
initializer.setFirstName(resultArray[i].getFirstName());

if (resultArray[i].getHireDate().getTime() != null) {
initializer.setHireDate(dateFormat.format(resultArray[i].getHireDate().getTime()));
} else {
initializer.setHireDate(“”);
}

initializer.setJobId(resultArray[i].getJobId());
initializer.setLastName(resultArray[i].getLastName());

if (resultArray[i].getManagerId() != null) {
initializer.setManagerId(resultArray[i].getManagerId().toString());
} else {
initializer.setManagerId(“”);
}
initializer.setPhoneNumber(resultArray[i].getPhoneNumber());

if (resultArray[i].getSalary() != null) {
initializer.setSalary(resultArray[i].getSalary().toString());
} else {
initializer.setSalary(“”);
}

initializer.setMgrFirstName(resultArray[i].getMgrFirstName());
initializer.setMgrLastName(resultArray[i].getMgrLastName());

if (resultArray[i].getLevelNum() != null) {
initializer.setLevelNum(resultArray[i].getLevelNum().toString());
} else {
initializer.setLevelNum(“”);
}

initializerArray.add(initializer);

}

resultList = initializerArray;
} else {
UserTreeResult initializer = new UserTreeResult();
initializer.setFirstName(“No data found.”);

List<UserTreeResult> initializerArrayE = new ArrayList<UserTreeResult>();
initializerArrayE.add(initializer);

resultList = initializerArrayE;
}

} catch (SQLException ex) {

Logger.getLogger(EmployeesTreeFacadeREST.class.getName()).log(Level.SEVERE, null, ex);
} catch (RemoteException ex) {

Logger.getLogger(EmployeesTreeFacadeREST.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {

Logger.getLogger(EmployeesTreeFacadeREST.class.getName()).log(Level.SEVERE, null, ex);
}

return resultList;
}

}

10. Test and be happy when it all works! Now you’ve opened up a world of possibilities!

emplTree-netbeansTester1

Who Says that ADF Mobile Cannot PPR?

Who says that ADF Mobile cannot PPR? With a little help from Andrejus (link below), we can easily refresh a page. We have to do a little trick with pojos, datacontrols, and taskflows (all just to “wake-up” the page). In this example, I have created a concrete wall volume calculator that refreshes upon pressing the calc button. Simply put, the button calls a backing action method that pulls the values from the pageFlowScope variables, calculates the correct volume, places the volume in another pageFlowScope variable, and navigates to a mock execution method on the taskflow, that basically just shakes the page.

ConcreteWallCalc

The backing class:

import javax.el.ValueExpression;

import oracle.adfmf.framework.api.AdfmfJavaUtilities;
import oracle.adfmf.framework.model.AdfELContext;

public class BasicAMXBacking {
public BasicAMXBacking() {
}

public String actionCalc() {
String navigate = “error”;
double volume;

AdfELContext adfELContext = AdfmfJavaUtilities.getAdfELContext();

try {
ValueExpression wallHeightBinding =
AdfmfJavaUtilities.getValueExpression(“#{pageFlowScope.wallHeight}”, String.class);
String wallHeight = wallHeightBinding.getValue(adfELContext).toString();
System.out.println(“Height=” + wallHeight);

ValueExpression wallLengthBinding =
AdfmfJavaUtilities.getValueExpression(“#{pageFlowScope.wallLength}”, String.class);
String wallLength = wallLengthBinding.getValue(adfELContext).toString();
System.out.println(“Length=” + wallLength);

ValueExpression wallThicknessBinding =
AdfmfJavaUtilities.getValueExpression(“#{pageFlowScope.wallThickness}”, String.class);
String wallThickness = wallThicknessBinding.getValue(adfELContext).toString();
System.out.println(“Depth=” + wallThickness);

volume = (Double.parseDouble(wallHeight) * Double.parseDouble(wallLength) * Double.parseDouble(wallThickness))/324;

volume = (double)Math.round(volume * 100)/100;

ValueExpression volumeBinding =
AdfmfJavaUtilities.getValueExpression(“#{pageFlowScope.wallVolume}”, String.class);
volumeBinding.setValue(adfELContext, String.valueOf(volume) );

navigate = “calc”;
} catch (Exception e) {
System.out.println(“Exception” + e);
}
return navigate;
}
}

The PPRMain class:

import java.util.ArrayList;
import java.util.List;

public class PPRMain {
private static List refreshPoints = null;

public PPRMain() {
if (refreshPoints == null) {
refreshPoints = new ArrayList();
}
Execute();
}

public void Execute() {
refreshPoints.clear();

PPRSub p = new PPRSub();

double y = 90.0;
double x = 90.0;

p.setRefreshX(x);
p.setRefreshY(y);

refreshPoints.add(p);
}

public PPRSub[] get() {
PPRSub p[] = null;

p = (PPRSub[])refreshPoints.toArray(new PPRSub[refreshPoints.size()]);

return p;
}
}

The PPRSub class:

public class PPRSub {
double refreshX = 100.0;
double refreshY = 100.0;

public PPRSub() {
super();
}

public void setRefreshX(double refreshX) {
this.refreshX = refreshX;
}

public double getRefreshX() {
return refreshX;
}

public void setRefreshY(double refreshY) {
this.refreshY = refreshY;
}

public double getRefreshY() {
return refreshY;
}
}

The datacontrol:

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<DataControlConfigs xmlns=”http://xmlns.oracle.com/adfm/configuration&#8221; version=”11.1.2.64.36″ id=”DataControls”
Package=”mobile”>
<AdapterDataControl id=”PPRSub” FactoryClass=”oracle.adf.model.adapter.DataControlFactoryImpl”
ImplDef=”oracle.adf.model.adapter.bean.BeanDCDefinition” SupportsTransactions=”false”
SupportsSortCollection=”true” SupportsResetState=”false” SupportsRangesize=”false”
SupportsFindMode=”false” SupportsUpdates=”true” Definition=”mobile.PPRMain”
BeanClass=”mobile.PPRMain” xmlns=”http://xmlns.oracle.com/adfm/datacontrol”&gt;
<CreatableTypes>
<TypeInfo FullName=”mobile.PPRMain”/>
<TypeInfo FullName=”mobile.PPRSub”/>
</CreatableTypes>
<Source>
<bean-definition BeanClass=”mobile.PPRMain”
xmlns=”http://xmlns.oracle.com/adfm/adapter/bean”/&gt;
</Source>
</AdapterDataControl>
</DataControlConfigs>

The taskflow:

MobilePPRTaskflow

The project can be downloaded from https://docs.google.com/file/d/0B9yySVFbRABBVENfTnZFdUlFZWc/edit?usp=sharing.

http://andrejusb.blogspot.com/2012/12/adf-mobile-geo-location-and-google-maps.html

ADF Mobile PushNotification Bag of Goodies

This bag of goodies may help if you decide to try and implement the push notification feature to Apple and Android devices using Oracle ADF Mobile.

1)  LifeCycleListenerImpl class **notice the implements!

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

import java.util.List;

import oracle.adfmf.application.LifeCycleListener;

import oracle.adfmf.application.PushNotificationConfig;

import oracle.adfmf.framework.event.EventSource;

import oracle.adfmf.framework.event.EventSourceFactory;

import oracle.adfmf.framework.pushnotification.NativePushNotificationEventSource;

public class LifeCycleListenerImpl implements LifeCycleListener, PushNotificationConfig {

public LifeCycleListenerImpl() {

}

private Connection conn = null;

/**

* The start method will be called at the start of the application. Only the

* Application Lifecycle Event listener will be called on start up.

*/

public void start() {

try {

Statement stat = DBConnectionFactory.getConnection().createStatement();

ResultSet rs = stat.executeQuery(“SELECT * FROM YOURDATABASETABLE;”);

} catch (SQLException e) {

InitDB();

} catch (Exception e) {

System.err.println(e.getMessage());

}

EventSource evtSource =EventSourceFactory.getEventSource(NativePushNotificationEventSource.NATIVE_PUSH_NOTIFICATION_REMOTE_EVENT_SOURCE_NAME);

evtSource.addListener(new NativePushNotificationListener());

}

public String getSourceAuthorizationId() {

return CommonUtilities.SENDER_ID;

}

public long getNotificationStyle() {

return 1;

}

/**

* The stop method will be called at the termination of the application. Only

* the Application Lifecycle Event listener will be called on start up.

*

* NOTE: Depending on how the application is being shutdown, this method may

* or may not be called. Features should save off their state in the deactivate

* handler.

*/

public void stop() {

// Add code here…

}

/**

* The activate method will be called when the feature is activated. The

* Application Lifecycle Event listener will be called on application

* being started and resumed.

*/

public void activate() {

// Add code here…

}

/**

* The deactivate method will be called when the feature is deactivated. The

* Application Lifecycle Event listener will be called on application

* being hibernated.

*/

public void deactivate() {

// Add code here…

}

}

2)  Helper class

/**

* Helper class providing methods and constants common to other classes in the

* app.

*/

public final class CommonUtilities {

/**

* Google API project id registered to use GCM.

*/

static final String SENDER_ID = “Your Application ID goes here“;

}

3)  NativePushNotificationConfig class **notice the implements!

import oracle.adfmf.application.PushNotificationConfig;

public abstract class NativePushNotificationConfig implements PushNotificationConfig {

public NativePushNotificationConfig() {

}

public String getSourceAuthorizationId() {

return CommonUtilities.SENDER_ID;

}

}

4)  NativePushNotificationListener class **notice the implements!

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import javax.el.ValueExpression;

import oracle.adfmf.framework.api.AdfmfContainerUtilities;

import oracle.adfmf.framework.api.AdfmfJavaUtilities;

import oracle.adfmf.framework.event.Event;

import oracle.adfmf.framework.event.EventListener;

import oracle.adfmf.framework.exception.AdfException;

import oracle.adfmf.framework.model.AdfELContext;

import oracle.adfmf.json.JSONArray;

import oracle.adfmf.json.JSONException;

import oracle.adfmf.json.JSONObject;

public class NativePushNotificationListener implements EventListener {

public NativePushNotificationListener() {

}

public void onOpen(String openString) {

if (openString != null) {

UpdateTokenToDB(openString);

} else {

UpdateTokenToDB(“noMessageToken”);

}

}

public static void UpdateTokenToDB(String regToken) {

try {

Connection conn = DBConnectionFactory.getConnection();

conn.setAutoCommit(false);

String updateSQL =

“UPDATE YOURTOKENTABLE SET TOKEN=?”;

PreparedStatement pStmt = conn.prepareStatement(updateSQL);

pStmt.setString(1, regToken);

pStmt.execute();

conn.commit();

} catch (SQLException e) {

System.out.println(“loginMethod-xa-UpdateTokenToDB-exception” + e);

} catch (Exception e) {

System.out.println(“loginMethod-xa-UpdateTokenToDB-exception” + e);

}

}

public void onMessage(Event ece) {

AdfELContext adfELContext = AdfmfJavaUtilities.getAdfELContext();

if (ece != null) {

String outerPayload = “[” + ece.getPayload().toString() + “]”;

String message = “”;

JSONArray jsonArray;

try {

jsonArray = new JSONArray(outerPayload);

JSONObject jsonLoginOuter = jsonArray.getJSONObject(0);

if (jsonLoginOuter.getString(“message”) != null) {

message = jsonLoginOuter.getString(“message”);

System.out.println(“log: message = ” + message);

}

ValueExpression notificationPayloadBinding =

                    AdfmfJavaUtilities.getValueExpression(“#{applicationScope.notificationPayload}”, Boolean.class);

                notificationPayloadBinding.setValue(adfELContext, message);

try {

AdfmfContainerUtilities.resetFeature(“YOURFEATURE”);

}catch(AdfException e) {

}

} catch (JSONException e) {

if (e != null) {

System.out.println(“log exception: ” + e);

}

}

} else {

System.out.println(“log: no message received.”);

String message = “”;

ValueExpression notificationPayloadBinding =

AdfmfJavaUtilities.getValueExpression(“#{applicationScope.notificationPayload}”, Boolean.class);

notificationPayloadBinding.setValue(adfELContext, message);

}

}

public void onError(AdfException aec) {

}

}

Opening a Taskflow from Backing within Same Window

If you ever need to open an Oracle Adf taskflow from the backing bean and not open up a separate tab or window, this code should help:

private void launchWindow() {
FacesContext fctx = FacesContext.getCurrentInstance();
String taskflowId = “generic-task-flow”;
String taskflowDocument = “/WEB-INF/generic-task-flow.xml”;
Map<String, Object> params = new HashMap<String, Object>();
String taskflowURL = ControllerContext.getInstance().getTaskFlowURL(false, new TaskFlowId(taskflowDocument, taskflowId), params);
ExtendedRenderKitService erks = Service.getRenderKitService(fctx, ExtendedRenderKitService.class);
StringBuilder script = new StringBuilder();
  script.append(“window.open(\””+taskflowURL+”\””).append(“,\”_self\”);”);
erks.addScript(FacesContext.getCurrentInstance(), script.toString());
}

View a PDF Securely

Companies that process invoices, tickets, and checks often want to provide this information to the public via images embedded within pdf documents. The URL to access these documents may need to be hidden as well as the document name. To accomplish this in Oracle ADF, create a secure servlet for viewing the PDF document, an ADF page with an inline frame for pulling the PDF servlet and javascript for rendering in maximized view, and place this view on a  bounded taskflow that has the parameter that will be passed to the servlet (full path).

From any calling taskflow, drop the viewing pdf’s taskflow and choose the property of “Run as Dialog”.

Don’t forget to setup the parameter (a pageflow scope variable of the full path built from the backing bean).

The secure PDF servlet reference needs for the web.xml are as follows:

<servlet>
<servlet-name>ViewPdfServlet</servlet-name>
<servlet-class>view.ViewPdfServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewPdfServlet</servlet-name>
<url-pattern>/viewpdfservlet</url-pattern>
</servlet-mapping>

Also, you’ll need the following java switch if opening a PDF document over https:

-Dweblogic.security.SSL.ignoreHostnameVerification=true

The secure PDF servlet class is as follows:

package view;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.IOException;

import java.net.URL;
import java.net.URLConnection;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ViewPdfServlet extends HttpServlet {

private static final String CONTENT_TYPE = “text/html; charset=UTF-8″;
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.

public void init(ServletConfig config) throws ServletException {
super.init(config);
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String requestedFullPath = null;

if (request.getParameter(“spFullPath”) != null) {
requestedFullPath = request.getParameter(“spFullPath”).toString();
}

if (requestedFullPath == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}

response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);

BufferedInputStream input = null;
BufferedOutputStream output = null;

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};

// Install the all-trusting trust manager
SSLContext sc = null;
try {
sc = SSLContext.getInstance(“SSL”);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sc.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (KeyManagementException e) {
e.printStackTrace();
}

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};

// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

//pull from session object…
URL oracle = new URL(requestedFullPath);
URLConnection yc = oracle.openConnection();

response.setContentType(yc.getContentType());
response.setHeader(“Content-Length”, String.valueOf(yc.getContentLength()));

try {
input = new BufferedInputStream(yc.getInputStream());
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
}

private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

The project workspace location is https://docs.google.com/open?id=0B9yySVFbRABBU2d2c1hLUkJTTnc.

Resources:

http://technology.amis.nl/2011/07/28/adf-11g-show-pdf-in-a-popup/

http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/

Table Filters Made “Self-Evident”

To help make table filters more “self-evident”, skin them and add a small magnifying icon. Be careful! The skin selectors can be tricky!

af|table af|inputText::content
{
border-color: transparent;
}

.af_column_column-filter-cell  .af_inputText_content {
background-image: url(Images/BlackoutMagnify.png);
background-color: transparent;
background-repeat: no-repeat;
background-position:left;
}

.af_column_column-filter-cell:hover  .af_inputText_content {
background-image: none;
}
.af_column_column-filter-cell:focus  .af_inputText_content {
background-image: none;
}

To download the project workspace to retrieve the image and entire skin, use the following link https://docs.google.com/open?id=0B9yySVFbRABBTVE2S3JtaEFPZzg.

Oracle ADF, Skinning a Menu Item

Image

To skin a menu item in Oracle ADF, use the following example listed below:

af|toolbar,
af|commandToolbarButton::text,
af|commandMenuItem,
af|commandMenuItem::bar-item,
af|menu::bar-item-text,
af|commandMenuItem::bar-item-text,
af|menu::bar-item-text,
af|commandMenuItem::bar-item-text,
af|menu::bar-item-text,
af|commandMenuItem::bar-item-text {
background-color: #4e4e4f;
font-family:Arial, Helvetica, sans-serif;
color: white;
font-size:small;
font-weight:bold;
}

af|menu::bar-item-text:active,
af|commandMenuItem::bar-item-text:active,
af|commandMenuItem:active,
af|commandMenuItem::bar-item:active,
af|menu::bar-item-text:hover,
af|commandMenuItem::bar-item-text:hover,
af|commandMenuItem:hover,
af|commandMenuItem::bar-item:hover,
af|menu::bar-item-text:visited,
af|commandMenuItem::bar-item-text:visited,
af|commandMenuItem:visited,
af|commandMenuItem::bar-item:visited {
background-color: white;
font-family:Arial, Helvetica, sans-serif;
color: black;
font-size:small;
font-weight:bold;
}

af|toolbar:disabled,
af|commandToolbarButton:disabled::text,
af|commandMenuItem:disabled,
af|commandMenuItem:disabled::bar-item,
af|menu:disabled::bar-item-text,
af|commandMenuItem:disabled::bar-item-text,
af|menu:disabled::bar-item-text,
af|commandMenuItem:disabled::bar-item-text,
af|menu:disabled::bar-item-text,
af|commandMenuItem:disabled::bar-item-text{
background-color: white;
font-family:Arial, Helvetica, sans-serif;
color: black;
font-size:small;
font-weight:bold;
}

The project can be downloaded at https://docs.google.com/open?id=0B9yySVFbRABBTUY1emVzeWcxd1E.