Leo Sutic wrote:
> Berin,
> 
> I've taken a look at the resolver package. It is very nice and general,
> but I fear that it is also too much as it is in CVS and there are issues
> with
> it that I do not understand.
> 
> public interface Resolver {
>  Token lookup( Query query )
> }
> 
> public interface Token {
>  Object[] references();
>  ...
> }
> 
> As I see it, the gain is that you can look up several components
> with one single call to Resolver.resolve, and then release them all
> simultaneously.
> 
> Briefly, consider those two advantages completely separate. We can have
> none, one or both of them.
> 
> LOOKUP OF SEVERAL COMPONENTS AT ONCE
> ------------------------------------
> 
> Why? I fail to see the point of this. The usage would be
> 
>  1) Fill in a query object.
>  2) lookup(query)
>  3) Extract the components from the Token based on their index in the
>     returned array of Objects.
> 
> I see no gain in number of lines of code: To lookup N components, you
> need to fill in a query object = N lines, resolve = 1 line, extract = N
> lines.
> In effect, the number of lines of code has doubled. Better to provide an
> easy
> interface for lookups and do N lookup(Query) calls.

Yes, but the advantage in the code sample in the package.html file shown
was the ability to prefill the Query with the constructor.  After we
discover if there are any objects that cannot be resolved, we remove them
from the query.

 From that point on, we can alter the attributes at runtime, and merely
do a Resolver.resolve(Query) in the critical section.

However, it is a common argument that the multiple lookup feature may be
too much solution for not enough problem.  With that said, I have no
problems with limiting it to only one object per query.

At this point, the Query object itself becomes superfluous, because its
advantages are now lost.  We can perform the same thing with a call that
has a hint parameter or something like that.

> RELEASE OF SEVERAL COMPONENTS AT ONCE
> -------------------------------------
> 
> Good. Much like the catch and finally clauses put all
> error handling into one spot, and the CM interface allows
> one to release a null component, we get all error handling into one place
> and guarantee that multiple components are released properly.
> 
> My proposal:


<snip/>

This is similar to the PreparedEnqueue concept in the excalibur.event
package.  The main difference is that all the responsibility is pushed
onto the Resolver.

so I guess we are now at an interface like this:

class Token {} // I snipped the Token impl you had, sorry :(

interface Resolver
{
     Object resolve(String key, Token token);
     Object resolve(String key, Object hint, Token token);
          // for multi-dimensional resolution, the object can be a
          // Map or equivalent

     boolean hasReference(String key);
     void release(Token token);
}


This allows a usage like this (adapted from the resolver example):

      public class SampleComponent implements Parameterizable, Resolvable, Sample
       {
           private       Resolver   m_resolver;
           private       Parameters m_params;
           private       boolean    m_hasEntityResolver;
           private       String     m_dbName;

           public SampleComponent()
           {
           }

           /**
            * Add parameters to specialize the query.
            */
           public void parameterize( Parameters params )
               throws ParameterException
           {
               m_params = params;
               m_dbName = m_params.getParameter( "dbname", "default" );
           }

           /**
            * Ensure a valid working space
            */
           public void resolver( Resolver resolver )
               throws ResolverException
           {
               m_resolver = resolver;

               m_hasEntityResolver = m_resolver.hasReference( EntityResolver.ROLE );

               // test if the required references are available
               if ( ! m_resolver.hasReference( DataSourceComponent.ROLE ) ||
                    ! m_resolver.hasReference( Parser.ROLE ) )
               {
                   throw new ResolverException("Required references not available");
               }
           }

           /**
            * Perform the work from the Sample interface
            */
           public Object doWork()
           {
               Token tok = new Token();

               try
               {
                   DataSourceComponent datasource =
                           m_resolver.lookup( DataSourceComponent.ROLE,
                                              m_dbName, tok );
                   Parser parser = m_resolver.lookup( Parser.ROLE, tok );

                   // ... do stuff with the datasource to get input stream
                   if (m_hasEntityResolver) {
                       parser.setEntityResolver(
                           (EntityResolver)m_resolver.lookup( EntityResolver.ROLE, tok 
)
                       );
                   }

                   SampleContentHandler handler = getContentHandler();
                   parser.parse(handler);
                   return handler().getObject();
               }
               catch (Exception e)
               {
                   // handle the exception
               }
               finally
               {
                   m_resolver.release( tok );
               }
           }

           /**
            * The ContentHandler for the parser.
            */
           SampleContentHandler getContentHandler()
           {
               //defined elsewhere
               return new SampleContentHandler();
           }
       }


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to