package ora.jwsnut.chapter6.contextbookservice;
import java.security.Principal;
import java.util.Date;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.holders.StringHolder;
import javax.xml.rpc.server.ServletEndpointContext;
import javax.xml.rpc.server.ServiceLifecycle;
/**
* Implementation class for the context-handling book web service.
*/
public class ContextBookServiceServant implements ContextBookQuery, ServiceLifecycle {
// Name of the HttpSession attribute holding the upper-case flag
private static final String UPPER_CASE = "UpperCaseBookTitles";
// ServletEndpointContext object
private ServletEndpointContext endpointContext;
// Name of an authorized user.
private String userName;
// Records whether book names should be sorted
private boolean sorted;
/* -- Implementation of the ServiceLifeCycle interface -- */
public void init(Object context) throws ServiceException {
endpointContext = (ServletEndpointContext)context;
// Get the authorized user name from the init parameters
ServletContext servletContext = endpointContext.getServletContext();
userName = servletContext.getInitParameter("UserName");
// Get alphabetic sorting flag from JNDI
try {
InitialContext namingCtx = new InitialContext();
Object value = namingCtx.lookup("java:comp/env/sorted");
sorted = value instanceof Boolean ? ((Boolean)value).booleanValue() : false;
ContextBookServiceServantData.setSorted(sorted);
} catch (NamingException ex) {
servletContext.log("Exception while accessing naming context", ex);
}
}
/**
* Called when the service instance is no longer required.
*/
public void destroy() {
// Nothing to do
}
/* -- Implementation of the ContextBookQuery interface -- */
/**
* Sets whether book titles returned by the
* getBookTitle() method should be in upper case.
* @param cond <code>true</code> if all book titles should
* be in upper case, <code>false</code> for title case.
*/
public void setUpperCase(boolean cond) {
HttpSession session = endpointContext.getHttpSession();
if (session != null) {
session.setAttribute(UPPER_CASE, cond ? Boolean.TRUE : Boolean.FALSE);
}
}
/**
* Returns whether book titles are being forced to
* upper case.
* @return <code>true</code> if book titles are forced to
* upper case, <code>false</code> if not.
*/
public boolean isUpperCase() {
HttpSession session = endpointContext.getHttpSession();
if (session != null) {
Boolean upperCase = (Boolean)session.getAttribute(UPPER_CASE);
return upperCase == null ? false : upperCase.booleanValue();
}
// No session - upper case mode not allowed
return false;
}
/**
* Gets the number of books known to the service
* @return the number of books known to the service.
*/
public int getBookCount() {
String[] titles = ContextBookServiceServantData.getBookTitles();
return titles == null || !checkAccess() ? 0 : titles.length;
}
/**
* Gets the title of a given book.
* @param index the index of the book whose title is required
* @return the title of the given book, or <code>null</code> if
* the index is not valid.
*/
public String getBookTitle(int index) {
String[] bookTitles = ContextBookServiceServantData.getBookTitles();
if (bookTitles == null || index < 0 || index >= bookTitles.length || !checkAccess()) {
return null;
}
return isUpperCase() ? bookTitles[index].toUpperCase() : bookTitles[index];
}
/**
* Gets the author for a books with a given title
* @param title the titles of the book
* @param author an output parameter that will be set to the author of the given book
* @throws ContextBookServiceException if the book title is unknown
*/
public void getBookAuthor(String title, StringHolder author) throws ContextBookServiceException {
String authorName = ContextBookServiceServantData.getBookAuthor(title);
if (authorName == null || !checkAccess()) {
throw new ContextBookServiceException("Unknown author: " + title);
}
author.value = authorName;
}
/**
* Makes a log entry.
* @param value the value to be logged.
*/
public void log(String value) {
if (checkAccess()) {
endpointContext.getServletContext().log(new Date() + ": " + value);
}
}
/**
* Check whether the calling user is authenticated.
*/
private boolean checkAccess() {
boolean allowed = true;
if (userName != null) {
// Authentication is configured.
Principal principal = endpointContext.getUserPrincipal();
allowed = principal != null && userName.equals(principal.getName());
}
return allowed;
}
}
|