DBA Data[Home] [Help]

PACKAGE BODY: SYS.WPG_DOCLOAD

Source


1 PACKAGE BODY wpg_docload
2 AS
3 
4   --
5   -- Private types and global variables
6   --
7   -- Warning: If you change the constraint values of any of the
8   -- following global variables, be sure to make the corresponding
9   -- change in pgdocs.sql
10   v_filename VARCHAR2(256);
11   v_bcaching BOOLEAN;
12   v_blob     blob;
13   v_bfile    bfile;
14 
15   --
16   -- PROCEDURE:
17   --   download_file
18   -- DESCRIPTION:
19   --   Set the name of the file to be downloaded
20   -- PARAMS:
21   --   p_filename     IN: name of the file to be downloaded
22   --   p_bcaching     IN: browser caching enabled?
23   --
24   PROCEDURE download_file(p_filename IN VARCHAR2, p_bcaching IN BOOLEAN)
25   IS
26   BEGIN
27      v_blob := NULL;
28      v_bfile := NULL;
29      v_filename := p_filename;
30      v_bcaching := p_bcaching;
31   END download_file;
32 
33   --
34   -- PROCEDURE:
35   --   download_file
36   -- DESCRIPTION:
37   --   Set the blob to be downloaded
38   -- PARAMS:
39   --   p_filename     IN: the blob to be downloaded
40   -- NOTES: Because downloading BLOBs is more of a "self-service" operation,
41   --        automatic browser caching is not a feature, like it is for
42   --        document table downloads, therefore, no p_bcaching parameter.
43   --
44   PROCEDURE download_file(p_blob IN OUT NOCOPY blob)
45   IS
46      e_invalid_lobloc EXCEPTION;
47      PRAGMA EXCEPTION_INIT(e_invalid_lobloc, -22275);
48   BEGIN
49      IF (p_blob IS NULL)
50      THEN
51        RAISE e_invalid_lobloc;
52      END IF;
53 
54      v_blob := p_blob;
55      v_bfile := NULL;
56      v_filename := NULL;
57      v_bcaching := NULL;
58   END download_file;
59 
60   --
61   -- PROCEDURE:
62   --   download_file
63   -- DESCRIPTION:
64   --   Set the bfile to be downloaded
65   -- PARAMS:
66   --   p_filename     IN: the bfile to be downloaded
67   -- NOTES: Because downloading BFILEs is more of a "self-service" operation,
68   --        automatic browser caching is not a feature, like it is for
69   --        document table downloads, therefore, no p_bcaching parameter.
70   --
71   PROCEDURE download_file(p_bfile IN OUT bfile)
72   IS
73      dir_alias VARCHAR2(30) := NULL;
74      fname VARCHAR2(2000) := NULL;
75      len pls_integer;
76   BEGIN
77      dbms_lob.fileopen(p_bfile);
78      v_bfile := p_bfile;
79      v_blob := NULL;
80      v_filename := NULL;
81      v_bcaching := NULL;
82   EXCEPTION
83      WHEN OTHERS
84      THEN
85        v_bfile := NULL;
86        v_blob := NULL;
87        v_filename := NULL;
88        v_bcaching := NULL;
89        RAISE;
90   END download_file;
91 
92   --
93   -- FUNCTION:
94   --   encode_parameter
95   -- DESCRIPTION:
96   --   Endcode the given parameters to be decoded by the gateway
97   -- PARAMS:
98   --   p_encode_param           IN: parameter to encode
99   -- RETURN:
100   --   encoded parameter string
101   FUNCTION encode_parameter(p_encode_param IN VARCHAR2)
102                RETURN VARCHAR2
103   IS
104      param_size pls_integer;
105   BEGIN
106      param_size := LENGTHB(p_encode_param);
107      IF (param_size IS NULL) THEN
108       param_size := 0;
109      END IF;
110      RETURN param_size||'X'||p_encode_param||'X';
111 
112   END encode_parameter;
113 
114   --
115   -- PROCEDURE:
116   --   get_content_length
117   -- DESCRIPTION:
118   --   Return the length of a lob to be downloaded
119   -- PARAMS:
120   --   none.
121   -- RETURN:
122   --   lob length
123   --
124   FUNCTION get_content_length
125     RETURN pls_integer
126   IS
127   BEGIN
128      IF (v_blob IS NOT NULL)
129      THEN
130         RETURN dbms_lob.getlength(v_blob);
131      ELSIF (v_bfile IS NOT NULL)
132      THEN
133         RETURN dbms_lob.getlength(v_bfile);
134      ELSE
135         RETURN NULL;
136      END IF;
137   END;
138 
139   --
140   -- PROCEDURE:
141   --   get_download_blob
142   -- DESCRIPTION:
143   --   Return a BLOB to be downloaded to a browser.
144   -- PARAMS:
145   --   p_blob   OUT: The blob to be downloaded
146   --
147   PROCEDURE get_download_blob(p_blob OUT NOCOPY blob)
148   IS
149   BEGIN
150      p_blob := v_blob;
151      IF dbms_lob.istemporary(v_blob) = 1 THEN
152         dbms_lob.freetemporary(v_blob);
153      END IF;
154      v_blob := NULL;
155   END;
156 
157     --
158   -- PROCEDURE:
159   --   get_download_bfile
160   -- DESCRIPTION:
161   --   Return a BFILE to be downloaded to a browser.
162   -- PARAMS:
163   --   p_blob   OUT: The bfile to be downloaded
164   --
165   PROCEDURE get_download_bfile(p_bfile OUT bfile)
166   IS
167   BEGIN
168      p_bfile := v_bfile;
169      v_bfile := NULL;
170   END;
171 
172   --
173   -- PROCEDURE:
174   --   get_download_file
175   -- DESCRIPTION:
176   --   Get the name,mimetype,etc. of the file to be downloaded.
177   --   For BLOB downloads, p_doc_info is just set to 'B'.
178   -- PARAMS:
179   --   p_doc_info  OUT: encoded string containing:
180   --                    filename, last_updated,mime_type,content_type,
181   --                    dad_charset and doc_size for document table docs.
182   --                    For BLOB downloads, it is set to 'B'.
183   --
184   PROCEDURE get_download_file(p_doc_info OUT VARCHAR2)
185   IS
186     e_missing_column EXCEPTION;
187     PRAGMA exception_init(e_missing_column, -904);
188     cursor_handle INTEGER;
189     retval INTEGER;
190     sql_stmt VARCHAR2(1024);
191     new_cols VARCHAR2(60);
192     old_cols VARCHAR2(25);
193     last_updated DATE;
194     mime_type VARCHAR2(48);
195     content_type VARCHAR2(128);
196     dad_charset VARCHAR2(256);
197     doc_size NUMBER;
198     mod_date DATE;
199     mod_since VARCHAR2(256);
200     pos pls_integer;
201     lpos pls_integer;
202     mod_len pls_integer;
203     last_updated_str VARCHAR2(128);
204     p_doctable VARCHAR2(316);
205 
206   BEGIN
207     -- If we are being called by an old listener, just return the filename
208     IF (owa_util.get_cgi_env('GATEWAY_IVERSION') IS NULL)
209     THEN
210        p_doc_info := v_filename;
211        RETURN;
212     END IF;
213 
214     -- For blob downloads, all we need to do is set p_doc_info to 'B'
215     IF (v_blob IS NOT NULL)
216     THEN
217        p_doc_info := 'B';
218        RETURN;
219     -- For bfile downloads, p_doc_info is set to 'F'
220     ELSIF (v_bfile IS NOT NULL)
221     THEN
222        p_doc_info := 'F';
223        RETURN;
224     END IF;
225 
226     new_cols := 'LAST_UPDATED,MIME_TYPE,CONTENT_TYPE,DAD_CHARSET,DOC_SIZE';
227     old_cols := 'MIME_TYPE,DOC_SIZE';
228 
229     cursor_handle := sys.dbms_sys_sql.open_cursor;
230 
231     p_doctable := owa_util.get_cgi_env('DOCUMENT_TABLE');
232     IF (p_doctable IS NULL) THEN
233        p_doctable := 'wwv_document';
234     END IF;
235 
236     sql_stmt := 'select '||new_cols||' from '||dbms_assert.qualified_sql_name(p_doctable)||
237       ' where NAME=:docname';
238 
239     sys.dbms_sys_sql.parse_as_user(cursor_handle, sql_stmt, dbms_sql.v7);
240 
241     sys.dbms_sys_sql.define_column(cursor_handle, 1, last_updated);
242     sys.dbms_sys_sql.define_column(cursor_handle, 2, mime_type, 48);
243     sys.dbms_sys_sql.define_column(cursor_handle, 3, content_type, 128);
244     sys.dbms_sys_sql.define_column(cursor_handle, 4, dad_charset, 256);
245     sys.dbms_sys_sql.define_column(cursor_handle, 5, doc_size);
246     sys.dbms_sys_sql.bind_variable(cursor_handle, ':docname', v_filename);
247 
248     retval := sys.dbms_sys_sql.execute_and_fetch(cursor_handle,TRUE);
249 
250     sys.dbms_sys_sql.column_value(cursor_handle, 1, last_updated);
251     sys.dbms_sys_sql.column_value(cursor_handle, 2, mime_type);
252     sys.dbms_sys_sql.column_value(cursor_handle, 3, content_type);
253     sys.dbms_sys_sql.column_value(cursor_handle, 4, dad_charset);
254     sys.dbms_sys_sql.column_value(cursor_handle, 5, doc_size);
255 
256     sys.dbms_sys_sql.close_cursor(cursor_handle);
257 
258 
259     -- Determine if document has been modified
260     mod_since := owa_util.get_cgi_env('HTTP_IF_MODIFIED_SINCE');
261 
262     IF (mod_since IS NOT NULL AND v_bcaching = true) THEN
263        pos := instr(mod_since, ';');
264        IF (pos > 0) THEN
265           lpos := instr(substr(mod_since,pos), 'length=');
266           IF (lpos > 0) THEN
267              mod_len := substr(mod_since,lpos+pos+6);
268           END IF;
269           mod_since := substr(mod_since,1,pos-1);
270        END IF;
271 
272        BEGIN
273           mod_date := to_date(mod_since, 'Dy, DD Mon YYYY HH24:MI:SS "GMT"');
274        EXCEPTION
275          WHEN OTHERS THEN
276          BEGIN
277             mod_date := to_date(mod_since, 'Day, DD-Mon-YY HH24:MI:SS "GMT"');
278             EXCEPTION
279                WHEN OTHERS THEN
280                BEGIN
281                   mod_date := to_date(mod_since, 'Day Mon DD HH24:MI:SS YYYY');
282                   EXCEPTION
283                      WHEN OTHERS THEN
284                   NULL;
285                END;
286             END;
287        END;
288 
289        IF (mod_date = last_updated) THEN
290          IF (mod_len IS NULL OR mod_len = doc_size) THEN
291             last_updated_str := 'NOT_MODIFIED';
292          ELSE
293             last_updated_str := to_char(last_updated,
294                'Dy, DD Mon YYYY HH24:MI:SS "GMT"',
295                'NLS_DATE_LANGUAGE = American');
296          END IF;
297        ELSE
298          last_updated_str := to_char(last_updated,
299             'Dy, DD Mon YYYY HH24:MI:SS "GMT"',
300             'NLS_DATE_LANGUAGE = American');
301        END IF;
302     ELSE
303        IF (v_bcaching = TRUE) THEN
304          last_updated_str := to_char(last_updated,
305              'Dy, DD Mon YYYY HH24:MI:SS "GMT"',
306          'NLS_DATE_LANGUAGE = American');
307        ELSE
308          last_updated_str := NULL;
309        END IF;
310     END IF;
311 
312 
313     -- Set the doc_info string
314     p_doc_info := encode_parameter(v_filename);
315     p_doc_info := p_doc_info||encode_parameter(last_updated_str);
316     p_doc_info := p_doc_info||encode_parameter(mime_type);
317     p_doc_info := p_doc_info||encode_parameter(content_type);
318     p_doc_info := p_doc_info||encode_parameter(dad_charset);
319     p_doc_info := p_doc_info||encode_parameter(doc_size);
320 
321     -- Clear the filename
322     v_filename := NULL;
323 
324   EXCEPTION
325      -- looks like we have an old style document table
326      WHEN e_missing_column THEN
327        last_updated := NULL;
328        content_type := NULL;
329        dad_charset := NULL;
330 
331        sql_stmt := 'select '||old_cols||' from '||
332             dbms_assert.qualified_sql_name(p_doctable) ||
333             ' where NAME=:docname';
334        sys.dbms_sys_sql.parse_as_user(cursor_handle, sql_stmt, dbms_sql.v7);
335 
336        sys.dbms_sys_sql.define_column(cursor_handle, 1, mime_type, 48);
337        sys.dbms_sys_sql.define_column(cursor_handle, 2, doc_size);
338        sys.dbms_sys_sql.bind_variable(cursor_handle, ':docname', v_filename);
339 
340        retval := sys.dbms_sys_sql.execute_and_fetch(cursor_handle,TRUE);
341        sys.dbms_sys_sql.column_value(cursor_handle, 1, mime_type);
342        sys.dbms_sys_sql.column_value(cursor_handle, 2, doc_size);
343 
344        sys.dbms_sys_sql.close_cursor(cursor_handle);
345 
346        -- Set the doc_info string
347        p_doc_info := encode_parameter(v_filename);
348        p_doc_info := p_doc_info||encode_parameter(last_updated);
349        p_doc_info := p_doc_info||encode_parameter(mime_type);
350        p_doc_info := p_doc_info||encode_parameter(content_type);
351        p_doc_info := p_doc_info||encode_parameter(dad_charset);
352        p_doc_info := p_doc_info||encode_parameter(doc_size);
353 
354        -- Clear the filename
355        v_filename := NULL;
356 
357      WHEN OTHERS THEN
358       v_filename := NULL;
359       p_doc_info := NULL;
360       sys.dbms_sys_sql.close_cursor(cursor_handle);
361 
362   END get_download_file;
363 
364   --
365   -- PROCEDURE:
366   --   get_download_file_raw
367   -- DESCRIPTION:
368   --   Bug 3119039 This API is used to return doc_info as RAW type
369   --   to bypass any character set conversion.
370   --   Get the name,mimetype,etc. of the file to be downloaded.
371   --   For BLOB downloads, p_doc_info is just set to 'B'.
372   -- PARAMS:
373   --   p_doc_info  OUT: encoded string containing:
374   --                    filename, last_updated,mime_type,content_type,
375   --                    dad_charset and doc_size for document table docs.
376   --                    For BLOB downloads, it is set to 'B'.
377   --
378   PROCEDURE get_download_file_raw(p_doc_info OUT raw)
379   IS
380     t_doc_info VARCHAR2(4000);
381 
382   BEGIN
383     get_download_file(t_doc_info);
384 
385     p_doc_info := UTL_RAW.CAST_TO_RAW(t_doc_info);
386 
387   END get_download_file_raw;
388 
389   --
390   -- FUNCTION:
391   --   is_file_download
392   -- DESCRIPTION:
393   --   Is there a file to download?
394   -- PARAMS:
395   --   none.
396   -- RETURNS:
397   --   TRUE if there is a pending file download, FALSE otherwise.
398   --
399   FUNCTION is_file_download
400     RETURN  BOOLEAN
401   IS
402   BEGIN
403      RETURN v_filename IS NOT NULL OR v_blob IS NOT NULL OR
404        v_bfile IS NOT NULL;
405   END is_file_download;
406 
407 END wpg_docload;