hlship      2004/08/16 07:42:27

  Modified:    examples/src/java/org/apache/hivemind/examples
                        ExampleUtils.java
               src/documentation/content/xdocs links.ent site.xml
               framework/src/test/hivemind/test/services ComplexModule.xml
               framework/src/test/hivemind/test/services/impl
                        CountFactory.java
               examples/src/descriptor/META-INF examples.xml
               examples build.xml
  Added:       examples/src/java/org/apache/hivemind/examples
                        LoggingMain.java TargetService.java
               examples/src/documentation/content/xdocs/hivemind-examples
                        logging.xml
               examples/src/java/org/apache/hivemind/examples/impl
                        TargetServiceImpl.java
                        ProxyLoggingInterceptorFactory.java
                        ProxyLoggingInvocationHandler.java
  Removed:     src/documentation/content/xdocs interceptors.xml
  Log:
  Add new examples and new documentation about creating a logging interceptor 
using JDK proxies.
  
  Revision  Changes    Path
  1.3       +1 -1      
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/ExampleUtils.java
  
  Index: ExampleUtils.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/ExampleUtils.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ExampleUtils.java 3 Aug 2004 14:02:16 -0000       1.2
  +++ ExampleUtils.java 16 Aug 2004 14:42:24 -0000      1.3
  @@ -40,7 +40,7 @@
           // the main HiveMind framework tests), so we have to go through some 
gyrations
           // here that aren't necessary in an ordinary HiveMind application.
   
  -        String projectRoot = System.getProperty("PROJECT_ROOT");
  +        String projectRoot = System.getProperty("PROJECT_ROOT", ".");
           String path = projectRoot + "/examples/src/descriptor/META-INF/" + 
fileName;
   
           RegistryBuilder builder = new RegistryBuilder();
  
  
  
  1.1                  
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/LoggingMain.java
  
  Index: LoggingMain.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // 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 org.apache.hivemind.examples;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.Registry;
  
  public class LoggingMain
  {
  
      public static void main(String[] args)
      {
          Registry registry = ExampleUtils.buildRegistry("examples.xml");
  
          TargetService service = (TargetService) 
registry.getService(TargetService.class);
  
          System.out.println("\n*** Void method (no return value):\n");
  
          service.voidMethod("Hello");
  
          System.out.println("\n*** Ordinary method (returns a List):\n");
  
          service.buildList("HiveMind", 4);
  
          System.out.println("\n*** Exception method (throws an exception):\n");
  
          try
          {
              service.exceptionThrower();
          }
          catch (ApplicationRuntimeException ex)
          {
              // Ignore.
          }
      }
  }
  
  
  
  1.1                  
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/TargetService.java
  
  Index: TargetService.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // 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 org.apache.hivemind.examples;
  
  import java.util.List;
  
  /**
   * Used to demonstrate the [EMAIL PROTECTED] 
org.apache.hivemind.examples.impl.ProxyLoggingInterceptorFactory}.
   *
   * @author Howard Lewis Ship
   */
  public interface TargetService
  {
      public void voidMethod(String string);
  
      public List buildList(String string, int count);
  
      public void exceptionThrower();
  }
  
  
  
  1.14      +0 -1      
jakarta-hivemind/src/documentation/content/xdocs/links.ent
  
  Index: links.ent
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/src/documentation/content/xdocs/links.ent,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- links.ent 9 Aug 2004 14:53:46 -0000       1.13
  +++ links.ent 16 Aug 2004 14:42:25 -0000      1.14
  @@ -1,4 +1,3 @@
  -<!-- $Id$ -->
   <!-- 
      Copyright 2004 The Apache Software Foundation
   
  
  
  
  1.25      +1 -1      jakarta-hivemind/src/documentation/content/xdocs/site.xml
  
  Index: site.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/src/documentation/content/xdocs/site.xml,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- site.xml  6 Aug 2004 17:03:31 -0000       1.24
  +++ site.xml  16 Aug 2004 14:42:25 -0000      1.25
  @@ -53,7 +53,6 @@
                        <localization label="Localization" 
href="localization.html"/>
                        <multithreading label="Multi-Threading" 
href="multithreading.html"/>
                        <filter label="Servlets" href="filter.html"/>
  -                     <interceptors label="Creating New Interceptors" 
href="interceptors.html"/>
                        <override label="Overriding Services" 
href="override.html"/>
                </tutorials>
                
  @@ -132,6 +131,7 @@
         
         <examples.calc label="Calculator" href="calc.html"/>
         <examples.panorama label="Panorama Startup" href="panorama.html"/>
  +      <examples.logging label="Logging Interceptor" href="logging.html"/>
        
         <reports label="Reports">
           &hivemind-examples-report-menu.ent;
  
  
  
  1.7       +1 -5      
jakarta-hivemind/framework/src/test/hivemind/test/services/ComplexModule.xml
  
  Index: ComplexModule.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/services/ComplexModule.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ComplexModule.xml 9 Aug 2004 14:53:43 -0000       1.6
  +++ ComplexModule.xml 16 Aug 2004 14:42:25 -0000      1.7
  @@ -24,11 +24,7 @@
        
        <service-point id="CountFactory" 
interface="org.apache.hivemind.ServiceInterceptorFactory">
                <invoke-factory>
  -                     <construct
  -        class="hivemind.test.services.impl.CountFactory"
  -        service-id-property="serviceId">
  -                             <set-service property="factory" 
service-id="hivemind.ClassFactory"/>            
  -                     </construct>
  +                     <construct 
class="hivemind.test.services.impl.CountFactory"/>
                </invoke-factory>
        </service-point>
   </module>
  
  
  
  1.7       +0 -5      
jakarta-hivemind/framework/src/test/hivemind/test/services/impl/CountFactory.java
  
  Index: CountFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/services/impl/CountFactory.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CountFactory.java 15 Aug 2004 15:41:57 -0000      1.6
  +++ CountFactory.java 16 Aug 2004 14:42:25 -0000      1.7
  @@ -17,17 +17,12 @@
   import java.lang.reflect.InvocationHandler;
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
  -import java.lang.reflect.Modifier;
   import java.lang.reflect.Proxy;
   import java.util.List;
   
   import org.apache.hivemind.InterceptorStack;
   import org.apache.hivemind.ServiceInterceptorFactory;
  -import org.apache.hivemind.impl.ProxyUtils;
   import org.apache.hivemind.internal.Module;
  -import org.apache.hivemind.service.BodyBuilder;
  -import org.apache.hivemind.service.ClassFab;
  -import org.apache.hivemind.service.MethodSignature;
   
   /**
    * Simple factory that uses dynamic proxies to count the number of times
  
  
  
  1.1                  
jakarta-hivemind/examples/src/documentation/content/xdocs/hivemind-examples/logging.xml
  
  Index: logging.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
     Copyright 2004 The Apache Software Foundation
  
     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.
  -->
  <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" 
"./dtd/document-v12.dtd"
  [
        <!ENTITY projectroot '../'>
        <!ENTITY % common-links SYSTEM "../links.ent">
        %common-links;
  ]>
  <document>
  
    <header>
      <title>Creating a Logging Interceptor</title>
        </header>
        
    <body>
  
  <p>
  One of the most powerful features of HiveMind is the ability to create 
<em>interceptors</em> for services. Interceptors
  provide additional behavior to a service, often a <em>cross-cutting 
concern</em> such as logging or transaction management. 
  Interceptors can be thought of as "aspect oriented programming lite".
  </p>
  
  <p>
  This example shows how easy it can be to create an interceptor; it creates a 
simplified version of the
  standard &hivemind.LoggingInterceptor;.
  </p>
  
  <p>
  The <em>real</em> logging interceptor uses the <link 
href="http://www.jboss.org/products/javassist";>Javassist</link>
  bytecode enhancement framework to create a new class at runtime. This has 
some minor advantages in terms of runtime performance,
  but is much more complicated to implement and test than this example, which 
uses 
  <link 
href="http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html";>JDK 
Dynamic Proxies</link>.
  </p>
  
  <section>
    <title>The Interceptor Factory</title>
    
  <p>
  Interceptors are created by interceptor factories, which are themselves 
HiveMind services.  Interceptor factories
  implement the &api.ServiceInterceptorFactory; interface.
  </p>
  
  <p>
  Our implementation is very simple:
  </p>
  
  <source><![CDATA[package org.apache.hivemind.examples.impl;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  import java.util.List;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.hivemind.InterceptorStack;
  import org.apache.hivemind.ServiceInterceptorFactory;
  import org.apache.hivemind.internal.Module;
  
  public class ProxyLoggingInterceptorFactory implements 
ServiceInterceptorFactory
  {
  
      public void createInterceptor(InterceptorStack stack, Module 
invokingModule, List parameters)
      {
          Log log = LogFactory.getLog(stack.getServiceExtensionPointId());
  
          InvocationHandler handler = new ProxyLoggingInvocationHandler(log, 
stack.peek());
  
          Object interceptor =
              Proxy.newProxyInstance(
                  invokingModule.getClassResolver().getClassLoader(),
                  new Class[] { stack.getServiceInterface()},
                  handler);
  
          stack.push(interceptor);
      }
  }]]></source>
    
  <p>
  The <code>createInterceptor()</code> method is passed the 
&api.InterceptorStack;, the
  &api.Module; of the invoking module (the module containing the service being 
created), and any
  parameters passed to the interceptor (from inside the &interceptor; element). 
This example does not make use
  of parameters, but the real logging interceptor uses parameters to control 
which methods are, and are not, logged.
  </p>  
  
  <p>
  An interceptor's job is to <code>peek()</code> at the top object on the stack 
and create a new object, wrapped around
  the top object, that provides new behavior.  The top object on the stack may 
be the core service implementation, or
  it may be another interceptor ... all that's known for sure is that it 
implements the service interface defined
  by the &service-point;.
  </p>
  
  <p>
  The interceptor in this case is a dynamic proxy, provided by 
<code>Proxy.newProxyInstance()</code>. The key here
  is the <em>invocation handler</em>, and object (described shortly) that is 
notified any time a method on the
  interceptor proxy is invoked.
  </p>
  
  <p>
  Once the interceptor is created, it is pushed onto the stack.  More 
interceptors may build upon it, adding yet more behavior.
  </p>
    
  </section>
  
  <section>
    <title>Invocation Handler</title>
  
  <p>
  The invocation handler is where the intercepting really takes place; it is 
invoked every time a method of the
  proxy object is invoked and has a chance to add behavior before, and after 
(or even instead of!) invoking a method
  on the next object in the stack.
  </p>
  
  <source><![CDATA[package org.apache.hivemind.examples.impl;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  
  import org.apache.commons.logging.Log;
  import org.apache.hivemind.service.impl.LoggingUtils;
  
  public class ProxyLoggingInvocationHandler implements InvocationHandler
  {
      private Log _log;
      private Object _inner;
  
      public ProxyLoggingInvocationHandler(Log log, Object inner)
      {
          _log = log;
          _inner = inner;
      }
  
      public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable
      {
          boolean debug = _log.isDebugEnabled();
  
          if (debug)
              LoggingUtils.entry(_log, method.getName(), args);
  
          try
          {
              Object result = method.invoke(_inner, args);
  
              if (debug)
              {
                  if (method.getReturnType() == void.class)
                      LoggingUtils.voidExit(_log, method.getName());
                  else
                      LoggingUtils.exit(_log, method.getName(), result);
              }
  
              return result;
          }
          catch (InvocationTargetException ex)
          {
              Throwable targetException = ex.getTargetException();
  
              if (debug)
                  LoggingUtils.exception(_log, method.getName(), 
targetException);
  
              throw targetException;
          }
      }
  
  }
  ]]></source>
  
  <p>
  The <code>invoke()</code> method is the key. Using the remembered 
<code>Log</code> instance,
  and the remembered inner object (the next inner object on the interceptor 
stack ... the object that
  was <code>peek()</code>-ed).  The code for actually generating the logging 
output is inside static
  methods of the <code>LoggingUtils</code> utility class -- in this way the 
output from this interceptor is
  identical to the output when using &hivemind.LoggingInterceptor;.
  </p>
  
  <p>
  The <code>invoke()</code> method is invoked for all methods that can be 
invoked on the proxy ... this includes
  the methods of the service interface, but also includes 
<code>java.lang.Object</code> methods such
  as <code>hashCode()</code> or <code>toString()</code>.
  </p>
  
  <note>
  The &hivemind.LoggingInterceptor; will typically add its own implementation 
of <code>toString()</code>, to assist
  in debugging (it clearly identifies itself as an interceptor object, and 
identifies the service id and service interface). 
  This proxy-based implementation does not, so invoking <code>toString()</code> 
on the proxy will end up invoking the method
  on the next object.
  </note>
  </section>
  
  <section>
    <title>Declaring the interceptor factory</title>
    
  <p>
  Like any other service, an service interceptor factory must appear inside a 
HiveMind module deployment descriptor:
  </p>  
  
  <source><![CDATA[
  <service-point id="ProxyLoggingInterceptor" 
interface="org.apache.hivemind.ServiceInterceptorFactory">
    <create-instance 
class="org.apache.hivemind.examples.impl.ProxyLoggingInterceptorFactory"/>
  </service-point>]]></source>
    
  </section>
  
  <section>
    <title>Using the interceptor</title>
    
  <p>
  Using the interceptor is the same as using any other interceptor; the 
&interceptor; element simply has to point at the correct service:
  </p>  
  
  <source><![CDATA[
  <service-point id="Target" 
interface="org.apache.hivemind.examples.TargetService">
    <create-instance 
class="org.apache.hivemind.examples.impl.TargetServiceImpl"/>
    
    <interceptor service-id="ProxyLoggingInterceptor"/>
    
  </service-point>]]></source>
  
  <p>
  The <code>TargetService</code> interface defines three methods used to 
demonstrate the logging interceptor:
  </p>
  
  <source>
  <![CDATA[package org.apache.hivemind.examples;
  
  import java.util.List;
  
  public interface TargetService
  {
      public void voidMethod(String string);
  
      public List buildList(String string, int count);
  
      public void exceptionThrower();
  }
  ]]></source>
  
  <p>
  The implementation class is equally inspiring:  
  </p>
  
  <source><![CDATA[package org.apache.hivemind.examples.impl;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.examples.TargetService;
  
  public class TargetServiceImpl implements TargetService
  {
  
      public void voidMethod(String string)
      {
  
      }
  
      public List buildList(String string, int count)
      {
          List result = new ArrayList();
          
          for (int i = 0; i < count; i++)
              result.add(string);
  
          return result;
      }
  
      public void exceptionThrower()
      {
          throw new ApplicationRuntimeException("Some application exception.");
      }
  }]]></source>
  
  </section>
  
  <section>
    <title>Running the examples</title>
    
  <p>
  From the <code>examples</code> directory, run <code>ant compile</code>, then 
run <code>ant -emacs run-logging</code>:
  </p>  
  
  <source><![CDATA[
  bash-2.05b$ ant -emacs run-logging
  Buildfile: build.xml
  
  run-logging:
  Target [DEBUG] Creating SingletonProxy for service examples.Target
  
  *** Void method (no return value):
  
  Target [DEBUG] Constructing core service implementation for service 
examples.Target
  Target [DEBUG] Applying interceptor factory examples.ProxyLoggingInterceptor
  ProxyLoggingInterceptor [DEBUG] Creating SingletonProxy for service 
examples.ProxyLoggingInterceptor
  ProxyLoggingInterceptor [DEBUG] Constructing core service implementation for 
service examples.ProxyLoggingInterceptor
  Target [DEBUG] BEGIN voidMethod(Hello)
  Target [DEBUG] END voidMethod()
  
  *** Ordinary method (returns a List):
  
  Target [DEBUG] BEGIN buildList(HiveMind, 4)
  Target [DEBUG] END buildList() [[HiveMind, HiveMind, HiveMind, HiveMind]]
  
  *** Exception method (throws an exception):
  
  Target [DEBUG] BEGIN exceptionThrower()
  Target [DEBUG] EXCEPTION exceptionThrower() -- 
org.apache.hivemind.ApplicationRuntimeException
  org.apache.hivemind.ApplicationRuntimeException: Some application exception.
          at 
org.apache.hivemind.examples.impl.TargetServiceImpl.exceptionThrower(TargetServiceImpl.java:35)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:324)
          at 
org.apache.hivemind.examples.impl.ProxyLoggingInvocationHandler.invoke(ProxyLoggingInvocationHandler.java:38)
          at $Proxy0.exceptionThrower(Unknown Source)
          at 
$SingletonProxy_fe67f7e0ae_12.exceptionThrower($SingletonProxy_fe67f7e0ae_12.java)
          at org.apache.hivemind.examples.LoggingMain.main(LoggingMain.java:27)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:324)
          at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:193)
          at 
org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:130)
          at org.apache.tools.ant.taskdefs.Java.run(Java.java:705)
          at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:177)
          at org.apache.tools.ant.taskdefs.Java.execute(Java.java:83)
          at 
org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
          at org.apache.tools.ant.Task.perform(Task.java:364)
          at org.apache.tools.ant.Target.execute(Target.java:341)
          at org.apache.tools.ant.Target.performTasks(Target.java:369)
          at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
          at org.apache.tools.ant.Project.executeTargets(Project.java:1062)
          at org.apache.tools.ant.Main.runBuild(Main.java:673)
          at org.apache.tools.ant.Main.startAnt(Main.java:188)
          at org.apache.tools.ant.launch.Launcher.run(Launcher.java:196)
          at org.apache.tools.ant.launch.Launcher.main(Launcher.java:55)
  
  BUILD SUCCESSFUL
  Total time: 3 seconds
  ]]></source>
  
  <p>
  The <code>log4j.properties</code> file for the examples has enabled debug 
logging for the entire module; thus we see
  some output about the construction of the 
<code>ProxyLoggingInterceptor</code> service as it is employed to construct the 
  interceptor for the <code>Target</code> service.
  </p>
  
  </section>
  
  <section>
    <title>Conclusion</title>
    
  <p>
  Implementing a basic interceptor using HiveMind is very simple when using JDK 
Dynamic Proxies. You can easily provide code that slips
  right into the calling sequence for the methods of your services with 
surprisingly little code. In addition, the APIs do not force you
  to use any single approach; you can use JDK proxies as here, use Javassist, 
or use any approach that works for you.  And because interceptor
  factories are themselves HiveMind services, you have access to the entire 
HiveMind environment to implement your interceptor factories.
  </p>  
  
  
  </section>
  
  
    </body>
  </document>
  
  
  1.1                  
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/impl/TargetServiceImpl.java
  
  Index: TargetServiceImpl.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // 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 org.apache.hivemind.examples.impl;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.examples.TargetService;
  
  /**
   * Implementation of [EMAIL PROTECTED] 
org.apache.hivemind.examples.TargetService} used
   * to demonstrate the [EMAIL PROTECTED] 
org.apache.hivemind.examples.impl.ProxyLoggingInterceptorFactory}.
   *
   * @author Howard Lewis Ship
   */
  public class TargetServiceImpl implements TargetService
  {
  
      public void voidMethod(String string)
      {
  
      }
  
      public List buildList(String string, int count)
      {
          List result = new ArrayList();
          
          for (int i = 0; i < count; i++)
              result.add(string);
  
          return result;
      }
  
      public void exceptionThrower()
      {
          throw new ApplicationRuntimeException("Some application exception.");
      }
  
  }
  
  
  
  1.1                  
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/impl/ProxyLoggingInterceptorFactory.java
  
  Index: ProxyLoggingInterceptorFactory.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // 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 org.apache.hivemind.examples.impl;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  import java.util.List;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.hivemind.InterceptorStack;
  import org.apache.hivemind.ServiceInterceptorFactory;
  import org.apache.hivemind.internal.Module;
  
  /**
   * Creates a simple, proxy-based interceptor that mimics most (but not all) 
of the behavior
   * of [EMAIL PROTECTED] 
org.apache.hivemind.service.impl.LoggingInterceptorFactory}.
   *
   * @author Howard Lewis Ship
   */
  public class ProxyLoggingInterceptorFactory implements 
ServiceInterceptorFactory
  {
  
      public void createInterceptor(InterceptorStack stack, Module 
invokingModule, List parameters)
      {
          Log log = LogFactory.getLog(stack.getServiceExtensionPointId());
  
          InvocationHandler handler = new ProxyLoggingInvocationHandler(log, 
stack.peek());
  
          Object interceptor =
              Proxy.newProxyInstance(
                  invokingModule.getClassResolver().getClassLoader(),
                  new Class[] { stack.getServiceInterface()},
                  handler);
  
          stack.push(interceptor);
      }
  }
  
  
  
  1.1                  
jakarta-hivemind/examples/src/java/org/apache/hivemind/examples/impl/ProxyLoggingInvocationHandler.java
  
  Index: ProxyLoggingInvocationHandler.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // 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 org.apache.hivemind.examples.impl;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  
  import org.apache.commons.logging.Log;
  import org.apache.hivemind.service.impl.LoggingUtils;
  
  /**
   * An invocation handler used by [EMAIL PROTECTED] 
org.apache.hivemind.examples.impl.ProxyLoggingInterceptorFactory}.
   * Logs all method invocations, return values and exceptions.  Note that, 
unlike the real
   * LoggingInterceptor, <code>toString()</code> will just pass through to the 
inner service object
   * (typically, the core service implementation).
   *
   * @author Howard Lewis Ship
   */
  public class ProxyLoggingInvocationHandler implements InvocationHandler
  {
      private Log _log;
      private Object _inner;
  
      public ProxyLoggingInvocationHandler(Log log, Object inner)
      {
          _log = log;
          _inner = inner;
      }
  
      public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable
      {
          boolean debug = _log.isDebugEnabled();
  
          if (debug)
              LoggingUtils.entry(_log, method.getName(), args);
  
          try
          {
              Object result = method.invoke(_inner, args);
  
              if (debug)
              {
                  if (method.getReturnType() == void.class)
                      LoggingUtils.voidExit(_log, method.getName());
                  else
                      LoggingUtils.exit(_log, method.getName(), result);
              }
  
              return result;
          }
          catch (InvocationTargetException ex)
          {
              Throwable targetException = ex.getTargetException();
  
              if (debug)
                  LoggingUtils.exception(_log, method.getName(), 
targetException);
  
              throw targetException;
          }
      }
  
  }
  
  
  
  1.4       +9 -0      
jakarta-hivemind/examples/src/descriptor/META-INF/examples.xml
  
  Index: examples.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/examples/src/descriptor/META-INF/examples.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- examples.xml      9 Aug 2004 14:53:47 -0000       1.3
  +++ examples.xml      16 Aug 2004 14:42:25 -0000      1.4
  @@ -40,4 +40,13 @@
           </invoke-factory>
           <interceptor service-id="hivemind.LoggingInterceptor"/>
       </service-point>
  +    
  +    <service-point id="ProxyLoggingInterceptor" 
interface="org.apache.hivemind.ServiceInterceptorFactory">
  +      <create-instance 
class="org.apache.hivemind.examples.impl.ProxyLoggingInterceptorFactory"/>
  +    </service-point>
  +    
  +    <service-point id="Target" 
interface="org.apache.hivemind.examples.TargetService">
  +      <create-instance 
class="org.apache.hivemind.examples.impl.TargetServiceImpl"/>
  +      <interceptor service-id="ProxyLoggingInterceptor"/>
  +    </service-point>
   </module>
  
  
  
  1.8       +9 -0      jakarta-hivemind/examples/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/examples/build.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- build.xml 10 Aug 2004 14:25:21 -0000      1.7
  +++ build.xml 16 Aug 2004 14:42:26 -0000      1.8
  @@ -74,6 +74,7 @@
       <hivedoc-report doc-path-id="hivedoc.classpath" 
taskdef-path-id="hivedoc.taskdef.classpath"/>
       <clover-report/>
     </target>
  +  
     <target name="run-calculator" description="Execute the Calculator 
example.">
       <java classname="org.apache.hivemind.examples.CalculatorMain">
         <classpath refid="runtime.classpath"/>
  @@ -81,8 +82,16 @@
         <arg line="28 4.75"/>
       </java>
     </target>
  +  
     <target name="run-panorama" description="Execute the Panorama example.">
       <java classname="com.panorama.startup.PanoramaMain">
  +      <classpath refid="runtime.classpath"/>
  +      <sysproperty key="PROJECT_ROOT" value="${project.dir}"/>
  +    </java>
  +  </target>
  +  
  +  <target name="run-logging" description="Execute the 
ProxyLoggingInterceptorFactory example.">
  +    <java classname="org.apache.hivemind.examples.LoggingMain">
         <classpath refid="runtime.classpath"/>
         <sysproperty key="PROJECT_ROOT" value="${project.dir}"/>
       </java>
  
  
  

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

Reply via email to