1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 import java.util.Vector;
36 
37 // __________ Implementation __________
38 
39 /**
40  * It's not allowed to call synchronoues back inside an oneway interface call.
41  * (see IOnewayLink too). So we start a thread (implemented by this class), which
42  * gets all neccessary parameters from the original called object and
43  * call it back later inside his run() method. So the execution of such oneway call
44  * will be asynchronous. It works in a generic way and can be used or any type
45  * of oneway request. Because the source and the target of this call-link knows,
46  * which method was used and which parameters must be handled.
47  *
48  * @author     Andreas Schlüns
49  * @created    17.07.2002 08:18
50  */
51 class OnewayExecutor extends Thread
52 {
53     // _______________________________
54 
55     /**
56      * const
57      * We define some request for some well known oneway interface
58      * calls here too. So they mustn't be declared more then ones.
59      * Of course it's not necessary to use it ... but why not :-)
60      */
61 
62     public static final int     REQUEST_FRAMEACTION             = 1     ;
63     public static final int     REQUEST_STATUSCHANGED           = 2     ;
64     public static final int     REQUEST_ADDSTATUSLISTENER       = 3     ;
65     public static final int     REQUEST_REMOVESTATUSLISTENER    = 4     ;
66     public static final int     REQUEST_DISPATCH                = 5     ;
67 
68     public static final boolean ENCODE_PARAMS                   = true  ;
69     public static final boolean DECODE_PARAMS                   = false ;
70 
71     // _______________________________
72 
73     /**
74      * @member  m_rLink     the object, which wish to be called back by this thread
75      * @member  m_nRequest  describes the type of the original request (means the
76      *                      called oneyway method)
77      * @member  m_lParams   list of parameters of the original request
78      */
79     private IOnewayLink m_rLink     ;
80     private int         m_nRequest  ;
81     private Vector      m_lParams   ;
82 
83     // _______________________________
84 
85     /**
86      * ctor
87      * It's initialize this thread with all neccessary parameters.
88      * It gets the object, which wish to be called back and the type
89      * and parameters of the original request.
90      *
91      * @param nRequest
92      *          The two user of this callback can define an unique number,
93      *          which identify the type of original interface method.
94      *          So the called interface object can decide, which action will be
95      *          neccessary.
96      *
97      * @param lParams
98      *          If the original method used parameters, they will be coded here in
99      *          a generic way. Only the called interface object know (it depends
100      *          from the original request - see nRequest too), how this list must
101      *          be interpreted.
102      *          Note: Atomic types (e.g. int, long) will be transported as objects
103      *          too (Integer, Long)!
104      */
105     public OnewayExecutor( IOnewayLink rLink    ,
106                            int         nRequest ,
107                            Vector      lParams  )
108     {
109         m_rLink    = rLink   ;
110         m_nRequest = nRequest;
111         m_lParams  = lParams ;
112 
113         if (m_rLink==null)
114             System.out.println("ctor ... m_rLink == null");
115         if (m_lParams==null)
116             System.out.println("ctor ... m_lParams == null");
117     }
118 
119     // _______________________________
120 
121     /**
122      * implements the thread function
123      * Here we call the internal set link object back and
124      * give him all neccessary parameters.
125      * After that we die by ouerself ...
126      */
127     public void run()
128     {
129         if (m_rLink==null)
130             System.out.println("run ... m_rLink == null");
131         if (m_lParams==null)
132             System.out.println("run ... m_lParams == null");
133 
134         if (m_rLink!=null)
135             m_rLink.execOneway( m_nRequest, m_lParams );
136     }
137 
138     // _______________________________
139 
140     /**
141      * static helper!
142      * To make convertion of the generic parameter list to the original
143      * one easier - you can use this helper methods. They know how suchlist
144      * must be coded. It's not a must to use it - but you can ...
145      */
146     public static void codeFrameAction(
147         boolean bEncode, Vector[] lParams,
148         com.sun.star.frame.FrameActionEvent[] aAction)
149     {
150         if (bEncode)
151         {
152             lParams[0] = new Vector(1);
153             lParams[0].add( (Object)(aAction[0]) );
154         }
155         else
156         {
157             aAction[0] = (com.sun.star.frame.FrameActionEvent)
158                 (lParams[0].elementAt(0));
159         }
160     }
161 
162     // _______________________________
163 
164     public static void codeStatusChanged(
165         boolean bEncode, Vector[] lParams,
166         com.sun.star.frame.FeatureStateEvent[] aStatus)
167     {
168         if (bEncode)
169         {
170             lParams[0] = new Vector(1);
171             lParams[0].add( (Object)aStatus[0] );
172         }
173         else
174         {
175             aStatus[0] = (com.sun.star.frame.FeatureStateEvent)
176                 (lParams[0].elementAt(0));
177         }
178     }
179 
180     // _______________________________
181 
182     public static void codeAddOrRemoveStatusListener(
183         boolean bEncode, Vector[] lParams,
184         com.sun.star.frame.XStatusListener[] xListener,
185         com.sun.star.util.URL[] aURL)
186     {
187         if (bEncode)
188         {
189             lParams[0] = new Vector(2);
190             lParams[0].add( (Object)xListener[0] );
191             lParams[0].add( (Object)aURL[0]      );
192         }
193         else
194         {
195             xListener[0] = (com.sun.star.frame.XStatusListener)
196                 (lParams[0].elementAt(0));
197             aURL[0] = (com.sun.star.util.URL)(lParams[0].elementAt(1));
198         }
199     }
200 
201     // _______________________________
202 
203     public static void codeDispatch(
204         boolean bEncode, Vector[] lParams,
205         com.sun.star.util.URL[] aURL,
206         com.sun.star.beans.PropertyValue[][] lArgs)
207     {
208         if (bEncode)
209         {
210             int nLength = lArgs.length+1;
211             int nPos    = 0;
212             lParams[0] = new Vector(nLength);
213 
214             lParams[0].add( (Object)aURL[0] );
215             --nLength;
216 
217             while (nLength>0)
218             {
219                 lParams[0].add( (Object)lArgs[0][nPos] );
220                 --nLength;
221                 ++nPos   ;
222             }
223         }
224         else
225         {
226             int nLength = lParams[0].size()-1;
227             int nPos    = 0;
228 
229             lArgs[0] = new com.sun.star.beans.PropertyValue[nLength];
230             aURL[0]  = (com.sun.star.util.URL)(lParams[0].elementAt(0));
231 
232             while (nPos<nLength)
233             {
234                 lArgs[0][nPos] = (com.sun.star.beans.PropertyValue)
235                     (lParams[0].elementAt(nPos+1));
236                 ++nPos;
237             }
238         }
239     }
240 }
241