DBA Data[Home] [Help]

PACKAGE BODY: SYS.JVMRJBCINV

Source


1 package body jvmrjbcinv  as
2   -- runjava back channel state
3   m_sessid VARCHAR2(100);
4   rjbc_toclient VARCHAR2(120);
5   rjbc_fromclient VARCHAR2(120);
6   rjbc_client_started BOOLEAN;
7   rjbc_action NUMBER;
8   m_flags NUMBER;
9 
10   -- support for runjava
11 
12   function rjbc_sessid return VARCHAR2 as
13   begin
14     return m_sessid;
15   end;
16 
17   function rjbc_flags  return VARCHAR2 as
18   begin
19     return m_flags;
20   end;
21 
22 
23   -- private subroutines
24   procedure rjbc_send(pipename VARCHAR2) as
25     s integer := dbms_pipe.send_message(pipename);
26     begin
27       if s <> 0 then
28          raise_application_error(-20000,
29                                  'rjbc_send pipe error:' || to_char(s));
30       end if;
31     end;
32 
33   procedure rjbc_receive(pipename VARCHAR2) as
34     s integer := dbms_pipe.receive_message(pipename);
35     begin
36       if s <> 0 then
37          raise_application_error(-20000,
38                                  'rjbc_receive pipe error:' || to_char(s));
39       end if;
40     end;
41 
42   -- rjbc_ack: acknowledge client's startup message if not previously done
43   procedure rjbc_ack as
44     begin
45       if not rjbc_client_started then
46         rjbc_receive(rjbc_fromclient);
47         dbms_pipe.reset_buffer;
48         rjbc_client_started := true;
49       end if;
50     end;
51 
52   procedure rjbc_set_pipe_names as
53   begin
54       rjbc_toclient := m_sessid||'_TO_CLIENT';
55       rjbc_fromclient := m_sessid||'_FROM_CLIENT';
56   end;
57 
58   -- entrypoints for runjava session
59 
60   -- rjbc_init: setup back channel, return id that identifies it.  Called
61   -- prior to runjava in the same session as runjava will run in.
62   -- flags non zero means dont use back channel for file content
63   -- this corresponds to the ojvmjava runjava mode server_file_system
64   function rjbc_init(flags NUMBER) return VARCHAR2 as
65     trash VARCHAR2(100);
66   begin
67     loop
68       m_sessid := sys.jvmrjbc.init;
69       rjbc_set_pipe_names;
70       begin
71         trash := dbms_pipe.remove_pipe(rjbc_toclient);
72         trash := dbms_pipe.remove_pipe(rjbc_fromclient);
73         trash := dbms_pipe.create_pipe(rjbc_toclient, private => true);
74         trash := dbms_pipe.create_pipe(rjbc_fromclient, private => true);
75         exit;
76       exception when others then
77         if sqlcode not in (-23322) then raise; end if;
78         begin
79           trash := dbms_pipe.remove_pipe(rjbc_toclient);
80         exception when others then
81           null;
82         end;
83         begin
84           trash := dbms_pipe.remove_pipe(rjbc_fromclient);
85         exception when others then
86           null;
87         end;
88         sys.jvmrjbc.done(m_sessid);
89       end;
90     end loop;
91     m_flags := flags;
92     rjbc_client_started := false;
93 
94     dbms_pipe.purge(rjbc_toclient);
95     dbms_pipe.purge(rjbc_fromclient);
96     trash :=
97     dbms_java.remove_output_to_sql('___rjbc');
98     trash :=
99     dbms_java.set_output_to_sql('___rjbc',
100                       'call sys.jvmrjbcinv.rjbc_output(:1,:2)',
101                       'TEXT NL');
102     return m_sessid;
103   end;
104 
105   -- rjbc_request: called from runjava to ask for the contents of
106   -- the file identified by pathname on the client filesystem.  Puts pathname
107   -- in the java$jvm$rjbc row then waits for client response.
108   -- rtype is not used.
109   -- status returned is 0 if the file was found, non-zero otherwise.
110   -- lob is returned containing the file content.
111   function rjbc_request(pathname VARCHAR2, rtype NUMBER, lob out BLOB)
112     return NUMBER as
113     status NUMBER;
114   begin
115     rjbc_ack;
116     sys.jvmrjbc.putpath(m_sessid, pathname);
117     dbms_pipe.pack_message(rtype);
118     rjbc_send(rjbc_toclient);
119     rjbc_receive(rjbc_fromclient);
120     dbms_pipe.unpack_message(status);
121     if status = 0 and rtype = 0 then
122       lob := sys.jvmrjbc.getlob(m_sessid);
123     end if;
124     return status;
125   end;
126 
127   -- rjbc_normalize: called from runjava to ask for the normalized, absolute
128   -- pathname on the client filesystem of the file identified by the input
129   -- argument pathname.  Puts pathname in the java$jvm$rjbc row then waits
130   ---for client response.
131   -- rtype is not used.
132   -- status returned is 0 if the file is a directory, non-zero otherwise.
133   -- This value is also not used.
134   -- normalized_pathname is returned containing the normalized path.
135   function rjbc_normalize(pathname VARCHAR2, rtype NUMBER,
136                           normalized_pathname out VARCHAR2)
137     return NUMBER as
138     status NUMBER;
139   begin
140     rjbc_ack;
141     sys.jvmrjbc.putpath(m_sessid, pathname);
142     dbms_pipe.pack_message(rtype);
143     rjbc_send(rjbc_toclient);
144     rjbc_receive(rjbc_fromclient);
145     dbms_pipe.unpack_message(status);
146     normalized_pathname := sys.jvmrjbc.getpath(m_sessid);
147     return status;
148   end;
149 
150   -- rjbc_output: set_output_to_sql entrypoint used by runjava to pass
151   -- output back to the client.
152   -- Puts text in the java$jvm$rjbc row then waits for client response.
153   procedure rjbc_output(text VARCHAR2, nl NUMBER) as
154     trash number;
155   begin
156     rjbc_ack;
157     sys.jvmrjbc.putpath(m_sessid, text);
158     if nl = 0 then
159       dbms_pipe.pack_message(3);
160     else
161       dbms_pipe.pack_message(2);
162     end if;
163     rjbc_send(rjbc_toclient);
164     rjbc_receive(rjbc_fromclient);
165     dbms_pipe.unpack_message(trash);
166   end;
167 
168   -- rjbc_done: called from client to shutdown back channel
169   procedure rjbc_done(id VARCHAR2 := null) as
170     trash VARCHAR2(100);
171   begin
172     if id is not null then
173       m_sessid := id;
174       rjbc_set_pipe_names;
175       rjbc_client_started := true;
176     end if;
177     rjbc_ack;
178     dbms_pipe.pack_message(-1);
179     rjbc_send(rjbc_toclient);
180     trash := dbms_pipe.remove_pipe(rjbc_toclient);
181     trash := dbms_pipe.remove_pipe(rjbc_fromclient);
182     sys.jvmrjbc.done(m_sessid);
183     trash :=
184     dbms_java.remove_output_to_sql('___rjbc');
185     m_sessid := null;
186   end;
187 
188   -- back channel entrypoint
189   -- rjbc_respond. Called in loop by back channel client thread to respond
190   -- to requests queued by rjbc_request, rjbc_normalize and rjbc_output.
191   -- status argument indicates result of processing the previous request.
192   -- status values are: -1 = initial call (there was no previous request)
193   --                     0 = file content found and returned
194   --                     1 = file not found
195   -- p in argument receives the normalized path for an rjbc_normalize request
196   -- l in argument receives the lob containing the file content for an
197   -- rjbc_request request.
198   -- return values indicate the kind of the new request.  These values are:
199   --   -1 = no request (ie, time to exit)
200   --    0 = file content (rjbc_request)
201   --    1 = normalize path (rjbc_normalize)
202   --    2 = newline terminated output (rjbc_output)
203   --    3 = nonnewline terminated output (rjbc_output)
204   -- For return values 0 and 1, the p out argument contains the name of the
205   -- file to be processed.  For return values 2 and 3 p contains the text
206   -- to be output.
207   function rjbc_respond(sid VARCHAR2, status NUMBER, p in out VARCHAR2, l BLOB)
208     return NUMBER as
209   begin
210     if status = -1 or m_sessid is null then
211       m_sessid := sid;
212       rjbc_set_pipe_names;
213     end if;
214     if status = 0 and rjbc_action = 0 then
215       sys.jvmrjbc.putlob(m_sessid, l);
216     end if;
217     if rjbc_action = 1 then
218       sys.jvmrjbc.putpath(m_sessid, p);
219     end if;
220     dbms_pipe.pack_message(status);
221     rjbc_send(rjbc_fromclient);
222     rjbc_receive(rjbc_toclient);
223     dbms_pipe.unpack_message(rjbc_action);
224     if rjbc_action <> -1 then
225       p := sys.jvmrjbc.getpath(m_sessid);
226     end if;
227     return rjbc_action;
228   end;
229 
230 end jvmrjbcinv;