I have a session bean that I am using to get Categories from the ebay API for my
application. The categories are returned as an XML stream. I used SAX to write a
parser to parse the XML stream and then insert the categories into a database. I have
an entity bean that handles the insertion. What I did was pass a reference to the bean
class of the session bean in the constructor for the XML parser so I could call the method
to insert into the database after the parser has seen each category. My question is, is
this considered bad design passing a reference to the bean to the java class. It is
packaged in the same JAR with the beans. Here is the code.
***********************
THE XML PARSER
***********************
package ebaycategories;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.Attributes;
import java.io.*;
public class EbayCategoryParser extends DefaultHandler
{
//this is the bean reference
private EbayCategoryUpdaterBean updaterRef;
private SAXParserFactory factory;
private SAXParser parser;
private CategoryElement ebay;
private CategoryElement ebaytime;
private CategoryElement categories;
private CategoryElement version;
private CategoryElement updategmttime;
private CategoryElement updatetime;
private CategoryElement category;
private CategoryElement categoryid;
private CategoryElement categorylevel;
private CategoryElement categoryname;
private CategoryElement categoryparentid;
private CategoryElement isexpired;
private CategoryElement isintlautosfixed;
private CategoryElement isvirtual;
private CategoryElement leafcategory;
private EbayCategory ebayCategory;
public EbayCategoryParser(EbayCategoryUpdaterBean ref)
{
updaterRef=ref;
try
{
factory=SAXParserFactory.newInstance();
parser=factory.newSAXParser();
}
catch(Exception EX)
{
}
ebay=new CategoryElement("eBay");
ebaytime=new CategoryElement("EbayTime");
categories=new CategoryElement("Categories");
version=new CategoryElement("Version");
updategmttime=new CategoryElement("UpdateGMTTime");
updatetime=new CategoryElement("UpdateTime");
category=new CategoryElement("Category");
categoryid=new CategoryElement("CategoryId");
categorylevel=new CategoryElement("CategoryLevel");
categoryname=new CategoryElement("CategoryName");
categoryparentid=new CategoryElement("CategoryParentId");
isexpired=new CategoryElement("IsExpired");
isintlautosfixed=new CategoryElement("IsIntlAutosFixed");
isvirtual=new CategoryElement("IsVirtual");
leafcategory=new CategoryElement("LeafCategory");
}
public void parseCategories(InputStream is)
{
try
{
parser.parse(is,this);
}
catch(Exception EX)
{
}
}
public void startElement(String URI, String localName,
String qName, Attributes attributes)
throws SAXException
{
if(qName==ebay.getName())ebay.changeState();
if(qName==ebaytime.getName())ebaytime.changeState();
if(qName==categories.getName())categories.changeState();
if(qName==version.getName())version.changeState();
if(qName==updategmttime.getName())updategmttime.changeState();
if(qName==updatetime.getName())updatetime.changeState();
if(qName==category.getName())
{
ebayCategory=new EbayCategory();
category.changeState();
}
if(qName==categoryid.getName())categoryid.changeState();
if(qName==categorylevel.getName())categorylevel.changeState();
if(qName==categoryname.getName())categoryname.changeState();
if(qName==categoryparentid.getName())categoryparentid.changeState();
if(qName==isexpired.getName())isexpired.changeState();
if(qName==isintlautosfixed.getName())isintlautosfixed.changeState();
if(qName==isvirtual.getName())isvirtual.changeState();
if(qName==leafcategory.getName())leafcategory.changeState();
}
public void endElement(String URI, String localName, String qName)
throws SAXException
{
if(qName==ebay.getName())ebay.changeState();
if(qName==ebaytime.getName())ebaytime.changeState();
if(qName==categories.getName())categories.changeState();
if(qName==version.getName())version.changeState();
if(qName==updategmttime.getName())updategmttime.changeState();
if(qName==updatetime.getName())updatetime.changeState();
if(qName==category.getName())
{
//here is where it calls the method on the bean to insert the Category
updaterRef.addEbayCategory(ebayCategory);
category.changeState();
ebayCategory=null;
}
if(qName==categoryid.getName())categoryid.changeState();
if(qName==categorylevel.getName())categorylevel.changeState();
if(qName==categoryname.getName())categoryname.changeState();
if(qName==categoryparentid.getName())categoryparentid.changeState();
if(qName==isexpired.getName())isexpired.changeState();
if(qName==isintlautosfixed.getName())isintlautosfixed.changeState();
if(qName==isvirtual.getName())isvirtual.changeState();
if(qName==leafcategory.getName())leafcategory.changeState();
}
public void characters(char [] ch, int start, int length)
throws SAXException
{
String chars=new String(ch,start,length);
if(ebay.in())
{
if(categories.in())
{
if(category.in())
{
if(categoryid.in())
{
ebayCategory=new EbayCategory();
ebayCategory.setCategoryId(chars);
}
if(categorylevel.in())
{
ebayCategory.setCategoryLevel(chars);
}
if(categoryname.in())
{
ebayCategory.setCategoryName(chars);
}
if(categoryparentid.in())
{
ebayCategory.setCategoryParentId(chars);
}
if(isexpired.in())
{
if(Integer.parseInt(chars)==0)
ebayCategory.setIsExpired(false);
else
ebayCategory.setIsExpired(true);
}
if(isintlautosfixed.in())
{
if(Integer.parseInt(chars)==0)
ebayCategory.setIsIntlAutosFixedCat(false);
else
ebayCategory.setIsIntlAutosFixedCat(true);
}
if(isvirtual.in())
{
if(Integer.parseInt(chars)==0)
ebayCategory.setIsVirtual(false);
else
ebayCategory.setIsVirtual(true);
}
if(leafcategory.in())
{
if(Integer.parseInt(chars)==0)
ebayCategory.setLeafCategory(false);
else
ebayCategory.setLeafCategory(true);
}
}
}
}
}
}
class CategoryElement
{
private String name;
private boolean flag;
public CategoryElement(String name)
{
this.name=name;
flag=false;
}
public String getName()
{
return name;
}
public boolean in()
{
return flag;
}
public void changeState()
{
flag=!flag;
}
}
*****************************************
The session bean
*****************************************
package ebaycategories;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.net.ssl.HttpsURLConnection;
import java.net.*;
import java.io.*;
public class EbayCategoryUpdaterBean implements SessionBean
{
private EbayCategoryLocalHome ebayCategoryLocalHome;
//here is the parser
private EbayCategoryParser ebayCategoryParser;
private URL sandbox;
private HttpsURLConnection sandboxConn;
public void updateEbayCategories()
{
try
{
sandbox=new URL(sandboxURL);
sandboxConn=(HttpsURLConnection)sandbox.openConnection();
sandboxConn.setDoInput(true);
sandboxConn.setDoOutput(true);
sandboxConn.setRequestMethod("POST");
sandboxConn.addRequestProperty("X-EBAY-API-COMPATIBILITY-LEVEL",compatibilityLevel);
sandboxConn.addRequestProperty("X-EBAY-API-SESSION-CERTIFICATE",sessionCertificate);
sandboxConn.addRequestProperty("X-EBAY-API-DEV-NAME",devName);
sandboxConn.addRequestProperty("X-EBAY-API-APP-NAME",appName);
sandboxConn.addRequestProperty("X-EBAY-API-CERT-NAME",certName);
sandboxConn.addRequestProperty("X-EBAY-API-CALL-NAME",callName);
sandboxConn.addRequestProperty("X-EBAY-API-DETAIL-LEVEL",detailLevel);
sandboxConn.addRequestProperty("X-EBAY-API-SITEID",siteID);
sandboxConn.addRequestProperty("Content-Type",contentType);
OutputStream output = sandboxConn.getOutputStream();
PrintStream sendToSandbox = new PrintStream(output);
sendToSandbox.print(xmlFunctionCall);
sendToSandbox.close();
InputStream input = sandboxConn.getInputStream();
ebayCategoryParser.parseCategories(input);
//BufferedInputStream fromSandbox = new BufferedInputStream(input);
}
catch(Exception EX)
{
}
}
public void addEbayCategory(EbayCategory ebayCategory)
{
EbayCategoryLocal ebayCategoryLocal=null;
try
{
ebayCategoryLocal=ebayCategoryLocalHome.create(ebayCategory.getCategoryId(),
ebayCategory.getCategoryLevel(),ebayCategory.getCategoryName(),
ebayCategory.getCategoryParentId(),""+ebayCategory.isIsExpired(),
""+ebayCategory.isIsIntlAutosFixedCat(),""+ebayCategory.isIsVirtual(),
""+ebayCategory.isLeafCategory());
}
catch(javax.ejb.CreateException CEX)
{
}
}
public void ejbCreate()
{
try
{
ebayCategoryLocalHome=getEbayCategoryLocalHome();
}
catch(NamingException NEX)
{
}
//construct the parser with a reference to this bean class
ebayCategoryParser=new EbayCategoryParser(this);
}
public void ejbActivate()
{
}
public void ejbPassivate()
{
}
public void ejbRemove()
{
}
public void setSessionContext(SessionContext ctx)
{
}
private EbayCategoryLocalHome getEbayCategoryLocalHome() throws NamingException
{
final InitialContext context = new InitialContext();
return (EbayCategoryLocalHome)context.lookup("java:comp/env/ejb/local/EbayCategory");
}
//for connecting to ebay
static final String sandboxURL = "https://api.sandbox.ebay.com/ws/api.dll";
static final String DevID = "devid";
static final String AppID = "appid";
static final String CertID = "certid";
static final String compatibilityLevel = "305";
static final String sessionCertificate = DevID + ";" + AppID + ";" + CertID;
static final String devName = DevID;
static final String appName = AppID;
static final String certName = CertID;
static final String callName = "GetCategories";
static final String siteID = "0";
static final String detailLevel = "1";
static final String contentType = "text/xml";
static final String authToken = "authtoken";
static final String xmlFunctionCall =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<request>" +
"<RequestToken>"+authToken+"</RequestToken>" +
"<ErrorLevel>1</ErrorLevel>" +
"<DetailLevel>1</DetailLevel>" +
"<SiteId>0</SiteId>" +
"<verb>GetCategories</verb>" +
"<ViewAllNodes>1</ViewAllNodes>" +
"<CategorySiteId>0</CategorySiteId>" +
"</request>";
}
If anyone has an opinion on this or knows a better design I would greatly
appreciate it.
-
Passing a Session Bean reference to a Java Class. Design Questi (6 messages)
- Posted by: Kurt Humes
- Posted on: July 09 2004 12:58 EDT
Threaded Messages (6)
- Passing a Session Bean reference to a Java Class. Design Questi by Senthil Chinnaiyan on July 09 2004 14:30 EDT
- Passing a Session Bean reference to a Java Class. Design Questi by Sandhya Seetharam on July 10 2004 05:17 EDT
- Passing a Session Bean reference to a Java Class. Design Questi by Sudhir Byna on July 10 2004 05:34 EDT
- Thanks by Kurt Humes on July 10 2004 14:05 EDT
- Thanks by Senthil Chinnaiyan on July 10 2004 14:29 EDT
- Thanks by Kurt Humes on July 10 2004 15:33 EDT
-
Passing a Session Bean reference to a Java Class. Design Questi[ Go to top ]
- Posted by: Senthil Chinnaiyan
- Posted on: July 09 2004 14:30 EDT
- in response to Kurt Humes
Passing the reference of a bean to another class is not a good idea. I think, you can use this EbayCategoryParser class as a helper to EJB, to return values in a kind of object to your bean and invoke the another bean method from your bean.
Hope this helps,
Senthil. -
Passing a Session Bean reference to a Java Class. Design Questi[ Go to top ]
- Posted by: Sandhya Seetharam
- Posted on: July 10 2004 05:17 EDT
- in response to Kurt Humes
Hi,
Id really think they should be kept separate. Passing the reference of the session object is like passing control of the business logic to what is ideally a helper class. In case there is a change in the business logic wherein you need to apply further business logic prior to persisting to the database, you would be changing your helper class instead of your controller!! -
Passing a Session Bean reference to a Java Class. Design Questi[ Go to top ]
- Posted by: Sudhir Byna
- Posted on: July 10 2004 05:34 EDT
- in response to Sandhya Seetharam
You should actually look up the bean and pass the required arguments to it for doing the computation. Referrence of a bean should never be passed to another object. -
Thanks[ Go to top ]
- Posted by: Kurt Humes
- Posted on: July 10 2004 14:05 EDT
- in response to Kurt Humes
Thanks for the info. The only question I have though is since the Parser
is packaged in the same JAR as the bean and is only intended to be used
with this bean, isnt the extra overhead of looking up the bean and then
calling it through the local interface unnecessary? -
Thanks[ Go to top ]
- Posted by: Senthil Chinnaiyan
- Posted on: July 10 2004 14:29 EDT
- in response to Kurt Humes
Thanks for the info. The only question I have though is since the Parseris packaged in the same JAR as the bean and is only intended to be usedwith this bean, isnt the extra overhead of looking up the bean and thencalling it through the local interface unnecessary?
You can pass the reference to your EJB Object to your parser class and invoke the method rather than passing the bean reference.
context.getEJBLocalObject()
context.getEJBObject()
Hope this helps,
Senthil. -
Thanks[ Go to top ]
- Posted by: Kurt Humes
- Posted on: July 10 2004 15:33 EDT
- in response to Kurt Humes
That sounds like a good idea, ill give that a try.