clever way to avoid try catch at each line

I am currently working with XML files, and am searching to have a better way to avoid try/catch blocks in a nice way.

Here is the thing. Let's say I have an XML file.

<A>
    <BB>37</BB>
    <CC>
        <DDD>1</DDD>
    </CC>
</A> 

In fact, I turn this into an object, which means that I can do myXml.getA() and so on.

In my code, I search a lot for given elements in this object, which means that I have a lot of lines like

int ddd = myXml.getA().getCC().getDDD();

The thing is that some elements may not be there, and for example another XML element can be like that only :

<A'>
    <BB'>37</BB'>
</A'> 

So if I try to get ddd, getCC() raises a NullPointerException.

In the end, I end up coding it like that :

int ddd;
try{
    ddd = myXml.getA().getCC().getDDD();
}
catch (NullPointerException e){
ddd = 0;
}

This works but the code becomes really ugly. I am searching for a solution to have something like

int ddd = setInt(myXml.getA().getCC().getDDD(), 0);

0 being the default in case the method raises an exception.

Is there a nice way to do that ?

Up to now, I couldn't find a solution that do not raise errors.

Thx for your help !

EDIT: Just not to get XML related answers. I showed the xml part for everybody to understand the problem. In my code, I don't have access to the XML, but only the object that represents it.

To make it short, what I'd really love is some kind of isNull method to test my getters.

Answers


This is sort of an annoyance of working with jaxb. in my company, we do enough work with jaxb that it was worth writing an xjc plugin which generated "safe" versions of every getter that were guaranteed to return non-null values for any non-trivial value (immutable instances in the case that a sub-object did not really exist).

Here's an example of what our generated model entities look like:

public class ExampleUser implements Serializable {
    private final static long serialVersionUID = 20090127L;
    @XmlAttribute
    protected String name;
    @XmlAttribute
    protected String email;
    public final static ExampleUser EMPTY_INSTANCE = new ExampleUser() {
        private static final long serialVersionUID = 0L;
        @Override
        public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
        @Override
        public void setEmail(java.lang.String value) { throw new UnsupportedOperationException(); }
    };

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public String getEmail() {
        return email;
    }

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

public class ExampleAccount implements Serializable {
    private final static long serialVersionUID = 20090127L;
    protected ExampleUser user;
    @XmlElement(name = "alias")
    protected List<String> aliases;
    @XmlAttribute
    protected String id;
    @XmlAttribute
    protected String name;
    public final static ExampleAccount EMPTY_INSTANCE = new ExampleAccount() {
        private static final long serialVersionUID = 0L;
        @Override
        public void setUser(com.boomi.platform.api.ExampleUser value) { throw new UnsupportedOperationException(); }
        @Override
        public List<String> getAliases() { return java.util.Collections.emptyList(); }
        @Override
        public void setId(java.lang.String value) { throw new UnsupportedOperationException(); }
        @Override
        public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
    };

    public ExampleUser getUser() {
        return user;
    }

    public void setUser(ExampleUser value) {
        this.user = value;
    }

    public List<String> getAliases() {
        if (aliases == null) {
            aliases = new ArrayList<String>();
        }
        return this.aliases;
    }

    public String getId() {
        return id;
    }

    public void setId(String value) {
        this.id = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public ExampleUser safeGetUser() {
        return (getUser() != null) ? getUser() : ExampleUser.EMPTY_INSTANCE;
    }
}

So you could write this code without fear of NPE:

userEmail = account.safeGetUser().getEmail();

You can look at the Null objec pattern.

For example :

public class A {
    private C c;
    public C getC() {
        if (c == null) {
            c = new C(0); // the "null object"
        }
        return c;
    }
}

public class C {
    private int d;
    public C(int d) {
        this.d = d;
    }

    public int getD() {
        return d;
    }
}

But personnaly, i have a bad feeling with this code :

int ddd = myXml.getA().getCC().getDDD();

It is a strong violation of the law of Demeter. The class invoker have a too large knowledge of A, C and D. This code will be clearly difficult to adapt and maintain.


Need Your Help

Does Magnific Popup support custom events/buttons

magnific-popup

I know Magnific Popup supports certain events such as Close, Next, etc. out of the box. But does Magnific support custom buttons and events if I wanted to add my own event hooks, such as Download,

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.