tags:

views:

93

answers:

2

Hi, i have created a saxparser object and xml read in java inside a POJO object that handles different types of xml files depending on what the caller specify's

this POJO gets an xml value that represents a list of contacts names and ID's while the other xml file/value represents a single contacts actual details i.e. phone number, address etc etc.

My question more about how i can remove duplicated code from the below code:

public static List<ContactName> extractContactList(String xml, int type) {

    mXMLdata = new StringReader(xml);
SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser sp = factory.newSAXParser();
            XMLReader xr = sp.getXMLReader();



            if(type == XML_MODE_PARSE_CONTACT_DESC){
                mContactDescHandler = new ContactDescXmlHandler();
                xr.setContentHandler(mContactDescHandler);
                xr.parse(new InputSource(mXMLdata));
                return mContactDescHandler.getContactDesc();
                return null;

            } else if(type == XML_MODE_PARSE_CONTACT_LIST){
                mContactListHandler = new ContactListXmlHandler();
                xr.setContentHandler(mContactListHandler);
                xr.parse(new InputSource(mXMLdata));
                return mContactListHandler.getContactNameList();
            }

As you can see i am using two different POJO'S that extend "DefaultHandler and they both use my XMLReader to do setContentHandler and parse.

is their a way in java to return a generic List<>() object as the two handlers return me different list pojo's or am i better of leaving it has it is OR seperate the two completely in different methods?

The xr.setContentHandler(mContactDescHandler); and xr.parse(new InputSource(mXMLdata)); i could definitely write it once but i think the main issue is the return type.

cheers in advance

A: 

Clean up your code so that ContactDescXmlHandler and ContactListXmlHandler both implement a common interface or inherit from a common ancestor. This interface/ancestor should have a member function like getContacts() or something. The getContacts() function is then redefined for your Desc and List classes to perform the work of either getContactDesc() or getContactNameList(). Your code would then clean up into:

(ancestor/interface) mHandler;
switch(type)
{
case XML_MODE_PARSE_CONTACT_DESC: mHandler = new ContactDescXmlHandler(); break;
case XML_MODE_PARSE_CONTACT_LIST: mHandler = new ContactListXmlHandler(); break;
default: return null;
}
xr.setContentHandler(mHandler);
xr.parse(new InputSource(mXMLdata));
return mHandler.getContacts();
Kelsey Rider
Note the difference between his return statements, you need another switch or if statement if you wanted to refactor like this.
Jorn
Hmm, maybe I wasn't clear enough...edited to explain better.
Kelsey Rider
+1  A: 

I think your code is fine; you are handling a untyped XML data stream and are creating different types from it, thus a not polymorphic switch/if statement is to be expected. As different types do need separate treatment this code is perfectly fine. Only if the two types can be altered to having a more generic parent class (like Kelsey Rider suggest) you can make the code a little bit more concise.

If this is not a returning issue in my code, I would not even try to generalize it for a moment.

Kdeveloper
So is it possible to create a interface that extends another super class?
jonney
something like public interface Contacts extends DefaulHandler{}
jonney
i could do something like that and create a member function that returns me the List object
jonney
If they both implement the same interface, you can handle them genericaly by that interface. In order to make that work, they thus need to return the same types in their methods. Thus for example: List<ContactName> getContact().
Kdeveloper