commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Mitchell" <jmitch...@apache.org>
Subject Re: [configuration] handling exceptions in AbstractConfiguration implementations
Date Wed, 06 Oct 2004 12:14:36 GMT
Problem with having Hibernate implementations is that the license is
incompatible with the ASL.  So you'll need to keep any incompatible code
somewhere else....like I do with commons-resources at sf.net.


--
James Mitchell
Software Engineer / Open Source Evangelist
EdgeTech, Inc.
678.910.8017
AIM: jmitchtx

----- Original Message -----
From: "Ricardo Gladwell" <ricardo.gladwell@btinternet.com>
To: "Jakarta Commons Developers List" <commons-dev@jakarta.apache.org>
Sent: Wednesday, October 06, 2004 8:07 AM
Subject: Re: [configuration] handling exceptions in AbstractConfiguration
implementations


> Eric Pugh wrote:
> > Hi Ricardo..  Sounds like you are working on something I've been wanting
for
> > a long time!
>
> Of course, I was going to release it anyway so please find the
> source-code attached. Not sure it belongs in commons-configration API;
> probably better contributed to the hibernate project. If you can think
> of any improvements please mail the patches back to me for my own project
:)
>
> > In otherwords, say I am using a Configuration object in my code, and I
do
> > configuration.getDouble("key");.  If getDouble throws an exception then
I am
> > going to have these try/catch cluases all over the place, cluttering the
> > code.  and, I really except getDouble() to allows work.  If it doesn't,
my
> > application will just pass it on,not have some sort of fancy if
getDouble
> > fails, then try getString or something weird.
>
> Good point, although I'm still dubious about throwing RuntimeExceptions
> - those things shoot straight through everything like a silver bullet
> and can even crash some servlet engines.
>
>  From my perspective, I'm not bothered if the Configuration object
> throws exceptions: I wouldn't catch such exceptions in my web
> application, instead letting them fly all the way to the exception
> screen. This way, I can see them occuring as I test my application
> through the browser.
>
> Obviously, sometimes when configuring your application you just want
> your configuration to work or keep on working untill if it encounters an
> errors. However, simply allowing your application to ignore exceptions
> until they create new exception elsewhere seems like a good way to
> create hard-to-fix bugs. Surely, it would be better to relay the errors
> and let the application decide what to do with them?
>
> > I think what you can do is just wrap your HibernateException in a
> > ConfiguratoinRuntimeException and toss that.  JDBCConfiguration should
> > probably be doning the same thing.
>
> Another alternative would be to have a getExceptions() method for all
> Configurations which stores exceptions occuring and stores them for
> later reporting. A good comprimise would be to allow all Configuration
> objects to have two modes: one where exceptions are thrown as soon as
> they occur and another one which stores exceptions as I suggested.
>
> Kind regards,
> -- Ricardo Gladwell
>
> >>-----Original Message-----
> >>From: Ricardo Gladwell [mailto:ricardo.gladwell@btinternet.com]
> >>Sent: Wednesday, October 06, 2004 12:56 PM
> >>To: Jakarta Commons Developers List
> >>Subject: [configuration] handling exceptions in AbstractConfiguration
> >>implementations
> >>
> >>
> >>Hi All,
> >>
> >>I'm currently developing a sub-class of the AbstractConfiguration
> >>classthat uses Hibernate to access configuration properties
> >>(unimaginatively called Hibernate Configuration). I'm slightly concerned
> >>about the way sub-classes are suposed to handle exceptions:
> >>
> >>All the abstract method are defined as not throwing exceptions. All
> >>calls to hibernate, however, throw HibernateExceptions. So, for example,
> >>my implementation of getPropertyDirect calls the hibernate Session.get()
> >>method which can throw an exception.
> >>
> >>Looking at your implementation of the DatabaseConfiguration I can see
> >>that it simply consumes SQLExceptions thrown from the JDBC API, logging
> >>the stack trace. However, what if you want to be warned of exceptions
> >>being thrown by the underlying implementation of Configuration?
> >>
> >>I notice you already have a nestable ConfigurationException implemented.
> >>Surely, all Configuration methods should indicate they will throw this
> >>exception if they are expected to read/write data?
> >>
> >>Also, the AbstractConfiguration class does not describe this contract
> >>(logging all errors throw by underlying framework) or what should be
> >>returned in the event of an error? I assume you should return null
> >>values but this is not described anywhere.
> >>
> >>Kind regards,
> >>-- Ricardo Gladwell
>


----------------------------------------------------------------------------
----


> package net.sf.jexus.server.components;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
>
> import java.util.Iterator;
> import java.util.List;
>
> import net.sf.hibernate.HibernateException;
> import net.sf.hibernate.Session;
> import net.sf.hibernate.Transaction;
> import net.sf.jexus.server.data.object.ConfigurationProperty;
>
> import org.apache.commons.beanutils.ConvertUtils;
> import org.apache.commons.configuration.AbstractConfiguration;
>
> /**
>  * <p>Hibernate configuation class. Reads configuration infomation from a
>  * database through the <a href="http://www.hibernate.org/">Hibernate</a>
>  * O/R mapping API. Data is stored as name-value pairs, along with the
class
>  * information of data stored, using the mapping* defined by the
>  * {@link ConfigurationProperty} POJO hibernate xdoclet directives. Values
are
>  * converted to and from strings using
>  * {@link org.apache.commons.beanutils.ConvertUtils}.</p>
>  *
>  * @author <a href="mailto:ricardo.gladwell@btinternet.com">Ricardo
Gladwell</a>
>  */
> public class HibernateConfiguration extends AbstractConfiguration {
>
>     /**
>      * Logger for this class
>      */
>     private static final Log log =
LogFactory.getLog(HibernateConfiguration.class);
>
>     /**
>      * Reference to the session factory.
>      */
>     Session session;
>
>     /**
>      *
>      */
>     class KeyIterator implements Iterator {
>
>         Iterator iterator;
>         String last;
>
>         public KeyIterator(Iterator iterator) throws HibernateException {
>             this.iterator = iterator;
>         }
>
>         /**
>          * @see java.util.Iterator#hasNext()
>          */
>         public boolean hasNext() {
>             return iterator.hasNext();
>         }
>
>         /**
>          * @see java.util.Iterator#next()
>          */
>         public Object next() {
>             ConfigurationProperty config =
(ConfigurationProperty)iterator.next();
>             String key = config.getName();
>             last = key;
>             return key;
>         }
>
>         /**
>          * @see java.util.Iterator#remove()
>          */
>         public void remove() {
>             clearProperty(last);
>         }
>
>     }
>
>     /**
>      *
>      */
>     public HibernateConfiguration(Session session) {
>         super();
>         if(log.isTraceEnabled()) log.trace("HibernateConfiguration()");
>         this.session = session;
>     }
>
>     /**
>      * @see
org.apache.commons.configuration.AbstractConfiguration#getPropertyDirect(jav
a.lang.String)
>      */
>     protected Object getPropertyDirect(String key) {
>         if(log.isTraceEnabled()) log.trace("getPropertyDirect("+key+")");
>         ConfigurationProperty config = null;
>         try {
>             config = (ConfigurationProperty)
session.get(ConfigurationProperty.class,key);
>         } catch(HibernateException e) {
>             log.error("Error reading congfiguration
property=["+key+"]",e);
>             return null;
>         }
>         try {
>             Class clazz =
getClass().getClassLoader().loadClass(config.getType());
>             return ConvertUtils.convert(config.getValue(), clazz);
>         } catch(ClassNotFoundException e) {
>             log.warn("Cannot find class=["+config.getType()+"] for
property=["+key+"]",e);
>         }
>         return config.getValue();
>     }
>
>     /**
>      * @see
org.apache.commons.configuration.AbstractConfiguration#addPropertyDirect(jav
a.lang.String, java.lang.Object)
>      */
>     protected void addPropertyDirect(String key, Object value) {
>         if(log.isTraceEnabled())
log.trace("addPropertyDirect("+key+","+value+")");
>         ConfigurationProperty config = new ConfigurationProperty();
>         config.setName(key);
>         config.setValue(ConvertUtils.convert(value));
>         config.setType(value.getClass().getName());
>         try {
>             Transaction transaction = session.beginTransaction();
>             session.save(config);
>             transaction.commit();
>         } catch(HibernateException e) {
>             log.error("Error adding congfiguration property=["+key+"]",e);
>         }
>     }
>
>     /**
>      * @see org.apache.commons.configuration.Configuration#isEmpty()
>      */
>     public boolean isEmpty() {
>         if(log.isTraceEnabled()) log.trace("isEmpty()");
>         try {
>             List list = session.find("from Configuration");
>             return list.isEmpty();
>         } catch(HibernateException e) {
>             log.error("Error reading keys.",e);
>             return true;
>         }
>     }
>
>     /***
>      * @see
org.apache.commons.configuration.Configuration#containsKey(java.lang.String)
>      */
>     public boolean containsKey(String key) {
>         if(log.isTraceEnabled()) log.trace("containsKey("+key+")");
>         return (getPropertyDirect(key) != null);
>     }
>
>     /**
>      * @see
org.apache.commons.configuration.Configuration#clearProperty(java.lang.Strin
g)
>      */
>     public void clearProperty(String key) {
>         if(log.isTraceEnabled()) log.trace("clearProperty("+key+")");
>         ConfigurationProperty config = new ConfigurationProperty();
>         config.setName(key);
>         try {
>             Transaction transaction = session.beginTransaction();
>             session.delete(config);
>             transaction.commit();
>         } catch(HibernateException e) {
>             log.error("Error clearing congfiguration
property=["+key+"]",e);
>         }
>     }
>
>     /**
>      * @see org.apache.commons.configuration.Configuration#getKeys()
>      */
>     public Iterator getKeys() {
>         if(log.isTraceEnabled()) log.trace("getKeys()");
>         try {
>             List list = session.find("from Configuration");
>             return new KeyIterator(list.iterator());
>         } catch(HibernateException e) {
>             log.error("Error reading keys.",e);
>             return null;
>         }
>     }
>
> }
>


----------------------------------------------------------------------------
----


> /*
>  * Copyright 2004 Ricardo Gladwell
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
>
> package net.sf.jexus.server.data.object;
>
> /**
>  * Hibernate persistance JavaBean encapsulating information about
>  * a configuration property.
>  *
>  * @hibernate.class
>  *      table="configuration"
>  *
>  * @todo Create JUnit test cases.
>  * @author <a href="mailto:ricardo.gladwell@btinternet.com">Ricardo
Gladwell</a>
>  * @version $Revision: 1.1 $, $Date: 2004/10/05 14:03:55 $
>  */
> public class ConfigurationProperty {
>
>     /**
>      * Name of this configuration property.
>      */
>     String name;
>
>     /**
>      * String representation of the valye of this configuration property.
>      */
>     String value;
>
>     /**
>      * Fully qualified class for this configuration property's type.
>      */
>     String type;
>
>     /**
>      * Returns the key name for this configuration property.
>      *
>      * @hibernate.id
>      *      generator-class="assigned"
>      *
>      * @return Returns the name.
>      */
>     public String getName() {
>         return name;
>     }
>
>     /**
>      * Sets the key name for this configuration property.
>      * @param name The name to set.
>      */
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     /**
>      * Returns the value of this property.
>      *
>      * @hibernate.property
>      *
>      * @return Returns the value.
>      */
>     public String getValue() {
>         return value;
>     }
>
>     /**
>      * Sets the value of this property.
>      * @param value The value to set.
>      */
>     public void setValue(String value) {
>         this.value = value;
>     }
>
>     /**
>      * Returns the fully qualified class name for the type
>      * of the value for this configuration property.
>      *
>      * @hibernate.property
>      *
>      * @return Returns the type.
>      */
>     public String getType() {
>         return type;
>     }
>
>     /**
>      * Sets the fully qualified class name for the type
>      * of the value for this configuration property.
>      * @param type The type to set.
>      */
>     public void setType(String type) {
>         this.type = type;
>     }
> }
>
>


----------------------------------------------------------------------------
----


> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message