View Javadoc

1   /*
2    * $Id: StreamingEntryPoint.java 10415 2008-01-21 10:46:37Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.impl.model.resolvers;
12  
13  import org.mule.impl.NoSatisfiableMethodsException;
14  import org.mule.impl.TooManySatisfiableMethodsException;
15  import org.mule.impl.VoidResult;
16  import org.mule.impl.model.streaming.DeferredOutputStream;
17  import org.mule.impl.model.streaming.StreamingService;
18  import org.mule.providers.streaming.StreamMessageAdapter;
19  import org.mule.umo.UMOEventContext;
20  import org.mule.umo.model.UMOEntryPoint;
21  import org.mule.util.ClassUtils;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.OutputStream;
26  import java.lang.reflect.Method;
27  import java.util.List;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  /**
33   * Will discover the correct entrypoint to invoke when an event is received. The
34   * follow are checked for - 1. If the component implements
35   * {@link org.mule.impl.model.streaming.StreamingService} this will be used 2. It
36   * will look of a method that accepts an {@link java.io.InputStream} and
37   * {@link java.io.OutputStream} 3. It will look for a method that accepts an
38   * {@link java.io.InputStream} only If none of these criteria are meet, and exception
39   * will be thrown.
40   */
41  public class StreamingEntryPoint implements UMOEntryPoint
42  {
43      protected static final Log logger = LogFactory.getLog(StreamingEntryPoint.class);
44      private Method streamingMethod;
45      private boolean inAndOut = false;
46  
47      public void initialise(Object component) throws Exception
48      {
49          if (component instanceof StreamingService)
50          {
51              streamingMethod = StreamingService.class.getMethods()[0];
52          }
53          else
54          {
55              inAndOut = true;
56              List methods = ClassUtils.getSatisfiableMethods(component.getClass(), new Class[]{
57                  InputStream.class, OutputStream.class}, true, false, null);
58  
59              if (methods.size() == 0)
60              {
61                  inAndOut = false;
62                  methods = ClassUtils.getSatisfiableMethods(component.getClass(),
63                      new Class[]{InputStream.class}, true, false, null);
64              }
65  
66              if (methods.size() == 0)
67              {
68                  throw new NoSatisfiableMethodsException(component, new Class[]{InputStream.class},
69                      new NoSatisfiableMethodsException(component, new Class[]{InputStream.class,
70                          OutputStream.class}));
71              }
72              else if (methods.size() > 1)
73              {
74                  throw new TooManySatisfiableMethodsException(component, new Class[]{InputStream.class,
75                      OutputStream.class});
76              }
77              else
78              {
79                  streamingMethod = (Method) methods.get(0);
80              }
81          }
82      }
83  
84      public Object invoke(Object component, UMOEventContext context) throws Exception
85      {
86          if (streamingMethod == null)
87          {
88              initialise(component);
89          }
90  
91          StreamMessageAdapter adapter = (StreamMessageAdapter) context.getMessage().getAdapter();
92          OutputStream out = new DeferredOutputStream(context);
93  
94          try
95          {
96              Object result;
97  
98              if (component instanceof StreamingService)
99              {
100                 result = streamingMethod.invoke(component, new Object[]{adapter.getInputStream(), out,
101                     context});
102             }
103             else if (inAndOut)
104             {
105                 result = streamingMethod.invoke(component, new Object[]{adapter.getInputStream(), out});
106             }
107             else
108             {
109                 result = streamingMethod.invoke(component, new Object[]{adapter.getInputStream()});
110             }
111 
112             if (streamingMethod.getReturnType().equals(Void.TYPE))
113             {
114                 result = VoidResult.getInstance();
115             }
116 
117             return result;
118         }
119         catch (Exception e)
120         {
121             logger.warn("Failed to route streaming event via " + component + ": " + e.getMessage(), e);
122             throw e;
123         }
124         finally
125         {
126             try
127             {
128                 out.flush();
129             }
130             catch (IOException e)
131             {
132                 // ignore, should never happen
133             }
134         }
135     }
136 }