001package Torello.Java;
002
003import java.io.*;
004import java.util.*;
005import java.util.stream.Stream;
006
007/**
008 * This class wraps the Google Cloud command-line tool <CODE><B>'gsutil'</B></CODE>, simply using
009 * the standard Java <CODE>java&#46;lang&#46;Process</CODE> object (in addition to Java HTML's
010 * <CODE>OSResponse</CODE>) thereby providing a simple Java-API for these operating-system calls.
011 * 
012 * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL>
013 * <EMBED ClASS='external-html' DATA-FILE-ID=OSC_WORA>
014 * <EMBED CLASS='external-html' DATA-CLASS=GSUTIL DATA-VAR=gsutil DATA-FILE-ID=OSC_ALL_FIELDS>
015 * <EMBED CLASS='external-html' DATA-FILE-ID=APPENDABLE>
016 *
017 * <!--
018 *  <EMBED CLASS="external html cannot ad this!" DATA-FILE-ID= NO! OSC_WILD_CARD_02> 
019 *  This class has a note about wild-cards built into GSUTIL
020 * -->
021 * 
022 * @see OSCommands
023 * @see OSResponse
024 */
025@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="OSC_INHERITORS")
026public class GSUTIL extends OSCommands implements Cloneable
027{
028    // Random character string.  It will only check the pointers anyway (not the string itself)
029    private static final String NO_TARGET = "?\t-$\n-ZZzz";
030
031
032    // ********************************************************************************************
033    // ********************************************************************************************
034    // Constructors
035    // ********************************************************************************************
036    // ********************************************************************************************
037
038
039    /** <EMBED CLASS='external-html' DATA-FILE-ID=OSC_CTOR_1> */
040    public GSUTIL() { super(); }
041
042    /**
043     * <EMBED CLASS='external-html' DATA-FILE-ID=OSC_CTOR_2>
044     * @param outputAppendable <EMBED CLASS='external-html' DATA-FILE-ID=OSC_APPENDABLE_PARAM>
045     * @see OSCommands#outputAppendable
046     */
047    public GSUTIL(Appendable outputAppendable)
048    { super(outputAppendable); }
049
050    /**
051     * <EMBED CLASS='external-html' DATA-FILE-ID=OSC_CTOR_3>
052     * 
053     * @param outputAppendable      <EMBED CLASS='external-html' DATA-FILE-ID=OSC_APPENDABLE_PARAM>
054     * @param commandStrAppendable  <EMBED CLASS='external-html' DATA-FILE-ID=OSC_CSA_PARAM>
055     * @param standardOutput        <EMBED CLASS='external-html' DATA-FILE-ID=OSC_STND_OUT_PARAM>
056     * @param errorOutput           <EMBED CLASS='external-html' DATA-FILE-ID=OSC_ERROR_OUT_PARAM>
057     * @see OSCommands#outputAppendable
058     * @see OSCommands#commandStrAppendable
059     * @see OSCommands#standardOutput 
060     * @see OSCommands#errorOutput 
061     */
062    public GSUTIL(
063            Appendable outputAppendable,
064            Appendable commandStrAppendable,
065            Appendable standardOutput,
066            Appendable errorOutput
067        )
068    { super(outputAppendable, commandStrAppendable, standardOutput, errorOutput); }
069
070    /**
071     * <EMBED CLASS='external-html' DATA-FILE-ID=OSC_CTOR_4>
072     * 
073     * @param standardOutput    <EMBED CLASS='external-html' DATA-FILE-ID=OSC_STND_OUT_PARAM>
074     * @param errorOutput       <EMBED CLASS='external-html' DATA-FILE-ID=OSC_ERROR_OUT_PARAM>
075     * @see OSCommands#standardOutput 
076     * @see OSCommands#errorOutput 
077     */
078    public GSUTIL(Appendable standardOutput, Appendable errorOutput)
079    { super(standardOutput, errorOutput); }
080
081    /**
082     * Used by the method {@code clone()}.
083     * @param other Another instance of this class.
084     */
085    protected GSUTIL(GSUTIL other) { super(other); }
086
087    /** {@inheritDoc} */
088    public GSUTIL clone() { return new GSUTIL(this); }
089
090
091    // ********************************************************************************************
092    // ********************************************************************************************
093    // GSUTIL RM
094    // ********************************************************************************************
095    // ********************************************************************************************
096
097
098    /**
099     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_RM>
100     * 
101     * @param s The GCS bucket-storage address of files to delete.  <B><I>Can Include</I></B>
102     * wildcards: {@code '*'} and {@code '**'}
103     * 
104     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
105     * with switches.
106     * 
107     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
108     * @throws IOException If there are any problems while invoking the operating-system command
109     * @see OSCommands#printAndRun(String[])
110     */
111    public OSResponse RM(String s, String... switches) throws IOException
112    {
113        String[] command = BUILD_COMMAND
114            (new String[] { "gsutil", "-m", "rm" }, switches, s, NO_TARGET);
115
116        return printAndRun(command);
117    }
118
119    /**
120     * Convenience Method.
121     * <BR />Invokes: {@link #RM(String[], String[])}
122     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
123     */
124    public OSResponse RM(Iterable<String> iterable, String... switches) throws IOException
125    { return RM(TO_ARRAY(iterable), switches); }
126
127    /**
128     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_RM>
129     * 
130     * @param sArr The list GCS bucket-storage address of files to delete.  <B><I>Can
131     * Include</I></B> wildcards: {@code '*'} and {@code '**'}
132     * 
133     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'} with
134     * switches.
135     * 
136     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
137     * @throws IOException If there are any problems while invoking the operating-system command
138     * @see OSCommands#printAndRun(String[])
139     */
140    public OSResponse RM(String[] sArr, String... switches) throws IOException
141    {
142        String[] command = BUILD_COMMAND
143            (new String[] { "gsutil", "-m", "rm" }, switches, sArr, NO_TARGET);
144
145        return printAndRun(command);
146    }
147
148
149    // ********************************************************************************************
150    // ********************************************************************************************
151    // GSUTIL MV
152    // ********************************************************************************************
153    // ********************************************************************************************
154
155
156    /**
157     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_MV>
158     * 
159     * @param source The GCS bucket-storage source-address.  <B><I>Can Include</I></B> wildcards:
160     * {@code '*'} and {@code '**'}
161     * 
162     * @param target The GCS bucket-storage target-address.
163     * 
164     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
165     * with switches.
166     * 
167     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
168     * @throws IOException If there are any problems while invoking the operating-system command
169     * @see OSCommands#printAndRun(String[])
170     */
171    public OSResponse MV(String source, String target, String... switches)
172        throws IOException
173    {
174        String[] command = BUILD_COMMAND
175            (new String[] { "gsutil", "-m", "mv" }, switches, source, target);
176
177        return printAndRun(command);
178    }   
179
180    /**
181     * Convenience Method.
182     * <BR />Invokes: {@link #MV(String[], String, String[])}
183     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
184     */
185    public OSResponse MV(Iterable<String> sources, String target, String... switches)
186        throws IOException
187    { return MV(TO_ARRAY(sources), target, switches); }
188
189    /**
190     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_MV>
191     * 
192     * @param sources A list of arguments that need to be copied, as an array.  <B><I>Can
193     * Include</I></B> wildcards: {@code '*'} and {@code '**'}
194     * 
195     * @param target The target/destination address for the list of files to be copied.
196     * 
197     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
198     * with switches.
199     * 
200     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
201     * @throws IOException If there are any problems while invoking the operating-system command
202     * @see OSCommands#printAndRun(String[])
203     */
204    public OSResponse MV(String[] sources, String target, String... switches)
205        throws IOException
206    {
207        String[] command = BUILD_COMMAND
208            (new String[] { "gsutil", "-m", "mv" }, switches, sources, target);
209
210        return printAndRun(command);
211    }
212
213
214    // ********************************************************************************************
215    // ********************************************************************************************
216    // GSUTIL CP 
217    // ********************************************************************************************
218    // ********************************************************************************************
219
220
221    /**
222     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CP>
223     * 
224     * @param source The GCS bucket-storage source-address, or local BASH shell source-address.
225     * <B><I>Can Include</I></B> wildcards: {@code '*'} and {@code '**'}
226     * 
227     * @param target The GCS bucket-storage target-address, or local BASH shell target-address.
228     * 
229     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
230     * with switches.
231     * 
232     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
233     * @throws IOException If there are any problems while invoking the operating-system command
234     * @see OSCommands#printAndRun(String[])
235     */
236    public OSResponse CP(String source, String target, String... switches)
237        throws IOException
238    {
239        String[] command = BUILD_COMMAND
240            (new String[] { "gsutil", "-m", "cp" }, switches, source, target);
241
242        return printAndRun(command);
243    }
244
245    /**
246     * Convenience Method.
247     * <BR />Invokes: {@link #CP(String[], String, String[])}
248     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
249     */
250    public OSResponse CP(Iterable<String> sources, String target, String... switches)
251        throws IOException
252    { return CP(TO_ARRAY(sources), target, switches); }
253
254    /**
255     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CP>
256     * 
257     * @param sources A list of arguments that need to be copied, as an array.  <B><I>Can
258     * Include</I></B> wildcards: {@code '*'} and {@code '**'}
259     * 
260     * @param target The target/destination address for the list of files to be copied.
261     * 
262     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
263     * with switches.
264     * 
265     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
266     * @throws IOException If there are any problems while invoking the operating-system command
267     * @see OSCommands#printAndRun(String[])
268     */
269    public OSResponse CP(String[] sources, String target, String... switches)
270        throws IOException
271    {
272        String[] command = BUILD_COMMAND
273            (new String[] { "gsutil", "-m", "cp" }, switches, sources, target);
274
275        return printAndRun(command);
276    }
277
278
279    // ********************************************************************************************
280    // ********************************************************************************************
281    // GSUTIL RSYNC
282    // ********************************************************************************************
283    // ********************************************************************************************
284
285
286    /**
287     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_RSYNC>
288     * 
289     * @param sources The source-address.
290     * @param target The target-address.
291     * 
292     * @param switches This may be appended to the command, providing Google's {@code 'gsutil'}
293     * with switches.
294     *
295     * <BR /><BR />'-d' : This will inform GSUTIL to remove files that are not found in the users
296     * directory, but are sitting on the Storage Bucket Server Location - <I>in the
297     * corresponding / same directory</I>
298     *
299     * <BR /><BR />'-r' : This will cause the sync to run recursively.
300     * 
301     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
302     * @throws IOException If there are any problems while invoking the operating-system command
303     * @see OSCommands#printAndRun(String[])
304    */
305    public OSResponse RSYNC(String sources, String target, String... switches)
306        throws IOException
307    {
308        String[] command = BUILD_COMMAND
309            (new String[] { "gsutil", "-m", "rsync" }, switches, sources, target);
310
311        return printAndRun(command);
312    }
313
314
315    // ********************************************************************************************
316    // ********************************************************************************************
317    // GSUTIL Make-Public
318    // ********************************************************************************************
319    // ********************************************************************************************
320
321
322    /**
323     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_MAKE_PUBLIC>
324     * 
325     * @param s1 The GCS bucket file or directory address.  Note {@code '*'} or {@code '**'} may be
326     * used here.
327     * 
328     * @param extraSwitches This may be appended to the command, providing Google's
329     * {@code 'gsutil'} with switches.  The salient arguments to set
330     * the public-visibility of a web-page have already been included.  This parameter is only
331     * important if there are other switches, in addition to the ones already used by the
332     * constructor for this command.
333     * 
334     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
335     * @throws IOException If there are any problems while invoking the operating-system command
336     * @see OSCommands#printAndRun(String[])
337     */
338    public OSResponse MP(String s1, String... extraSwitches) throws IOException
339    {
340        String[] command = BUILD_COMMAND(
341            new String[] { "gsutil", "-m", "acl", "ch", "-u", "AllUsers:R" },
342            extraSwitches, s1, NO_TARGET
343        );
344
345        return printAndRun(command);
346    }
347
348    /**
349     * Convenience Method.
350     * <BR />Invokes: {@link #MP(String[], String[])}
351     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
352     */
353    public OSResponse MP(Iterable<String> iterable, String... extraSwitches)
354        throws IOException
355    { return MP(TO_ARRAY(iterable), extraSwitches); }
356
357    /**
358     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_MAKE_PUBLIC>
359     * 
360     * @param sArr The GCS bucket file or directory addresses.  Note {@code '*'} or
361     * {@code '**'} may be used here.
362     * 
363     * @param extraSwitches This may be appended to the command, providing Google's
364     * {@code 'gsutil'} with switches.  The salient arguments to set
365     * the public-visibility of a web-page have already been included.  This parameter is only
366     * important if there are other switches, in addition to the ones already used by the
367     * constructor for this command.
368     * 
369     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
370     * @throws IOException If there are any problems while invoking the operating-system command
371     * @see OSCommands#printAndRun(String[])
372     */
373    public OSResponse MP(String[] sArr, String... extraSwitches) throws IOException
374    {
375        String[] command = BUILD_COMMAND(
376            new String[] { "gsutil", "-m", "acl", "ch", "-u", "AllUsers:R" },
377            extraSwitches, sArr, NO_TARGET
378        );
379
380        return printAndRun(command);
381    }
382
383
384    // ********************************************************************************************
385    // ********************************************************************************************
386    // GSUTIL Stop Public
387    // ********************************************************************************************
388    // ********************************************************************************************
389
390
391    /**
392     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_STOP_PUBLIC>
393     * 
394     * @param s1 The GCS bucket file or directory address.  Note {@code '*'} or {@code '**'} may be
395     * used here.
396     * 
397     * @param extraSwitches This may be appended to the command, providing Google's
398     * {@code 'gsutil'} with switches.  The salient arguments to stop
399     * the public-visibility of a web-page have already been included.  This parameter is only
400     * important if there are other switches, in addition to the ones already used by the
401     * constructor for this command.
402     * 
403     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
404     * @throws IOException If there are any problems while invoking the operating-system command
405     * @see OSCommands#printAndRun(String[])
406     */
407    public OSResponse SP(String s1, String... extraSwitches) throws IOException
408    {
409        String[] command = BUILD_COMMAND(
410            new String[] { "gsutil", "-m", "acl", "ch", "-d", "AllUsers" },
411            extraSwitches, s1, NO_TARGET
412        );
413
414        return printAndRun(command);
415    }
416
417    /**
418     * Convenience Method.
419     * <BR />Invokes: {@link #SP(String[], String[])}
420     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
421     */
422    public OSResponse SP(Iterable<String> iterable, String... extraSwitches)
423        throws IOException
424    { return SP(TO_ARRAY(iterable), extraSwitches); }
425
426    /**
427     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_STOP_PUBLIC>
428     * 
429     * @param sArr The GCS bucket file or directory address.  Note {@code '*'} or {@code '**'} may
430     * be used here.
431     * 
432     * @param extraSwitches This may be appended to the command, providing Google's
433     * {@code 'gsutil'} with switches.  The salient arguments to stop the public-visibility of a
434     * web-page have already been included.  This parameter is only important if there are other
435     * switches, in addition to the ones already used by the constructor for this command.
436     * 
437     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
438     * @throws IOException If there are any problems while invoking the operating-system command
439     * @see OSCommands#printAndRun(String[])
440     */
441    public OSResponse SP(String[] sArr, String... extraSwitches) throws IOException
442    {
443        String[] command = BUILD_COMMAND(
444            new String[] { "gsutil", "-m", "acl", "ch", "-d", "AllUsers" },
445            extraSwitches, sArr, NO_TARGET
446        );
447
448        return printAndRun(command);
449    }
450
451
452    // ********************************************************************************************
453    // ********************************************************************************************
454    // GSUTIL Set Max Age
455    // ********************************************************************************************
456    // ********************************************************************************************
457
458
459    /**
460     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_SET_MAX_AGE>
461     * 
462     * @param s1 The GCS bucket-storage address.  gs://bucket-name/directoryname/filename
463     * <BR /><B>NOTE:</B> "filename" may contain the asterisks {@code '*'} or anything that would
464     * normally be passed to gsutil on the shell command-line.
465     * 
466     * @param seconds This parameter is added to the end of the max-age= string in the cmdSMA
467     * argument list.  It represents the number of seconds a browser is allowed to cache a page.
468     * 
469     * @param extraSwitches This may be appended to the command, providing Google's
470     * {@code 'gsutil'} with switches.  The salient arguments to set the max-age of a web-page have
471     * already been included.  This parameter is only important if there are other switches, in
472     * addition to the ones already used by the constructor for this command.
473     * 
474     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
475     * @throws IOException If there are any problems while invoking the operating-system command
476     * @see OSCommands#printAndRun(String[])
477     */
478    public OSResponse SMA(String s1, int seconds, String... extraSwitches)
479        throws IOException
480    {
481        String[] command = BUILD_COMMAND(
482            new String[]
483            { 
484                "gsutil", "-m", "setmeta", "-h",
485                ("Cache-Control:public, max-age=" + seconds + "")
486            },
487            extraSwitches, s1, NO_TARGET
488        );
489
490        return printAndRun(command);
491    }
492
493    /**
494     * Convenience Method.
495     * <BR />Invokes: {@link #SMA(String[], int, String[])}.
496     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
497     */
498    public OSResponse SMA(Iterable<String> iterable, int seconds, String... extraSwitches)
499        throws IOException
500    { return SMA(TO_ARRAY(iterable), seconds, extraSwitches); }
501
502    /**
503     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_SET_MAX_AGE>
504     * 
505     * @param seconds This parameter is added to the end of the max-age= string in the cmdSMA
506     * argument list.  It represents the number of seconds a browser is allowed to cache a page.
507     * 
508     * @param extraSwitches This may be appended to the command, providing Google's
509     * {@code 'gsutil'} with switches.  The salient arguments to set the max-age of a web-page have
510     * already been included.  This parameter is only important if there are other switches, in
511     * addition to the ones already used by the constructor for this command.
512     * 
513     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
514     * @throws IOException If there are any problems while invoking the operating-system command
515     * @see OSCommands#printAndRun(String[])
516     */
517    public OSResponse SMA(String[] s1Arr, int seconds, String... extraSwitches)
518        throws IOException
519    {
520        String[] command = BUILD_COMMAND(
521            new String[] 
522            { 
523                "gsutil", "-m", "setmeta", "-h",
524                ("Cache-Control:public, max-age=" + seconds + "")
525            },
526            extraSwitches, s1Arr, NO_TARGET
527        );
528
529        return printAndRun(command);
530    }
531
532
533    // ********************************************************************************************
534    // ********************************************************************************************
535    // GSUTIL Set Content Type
536    // ********************************************************************************************
537    // ********************************************************************************************
538
539
540    /**
541     * Text-File, Plain, UTF-8.
542     * <B>NOTE:</B> May be used for calls to <B>{@code SCT(String s1, String type); }</B>
543     */
544    public static final String SCT_TEXT_UTF8 = "text/plain; charset=utf-8";
545
546    /**
547     * Text-File, HTML, UTF-8.
548     * <B>NOTE:</B> May be used for calls to <B>{@code SCT(String s1, String type); }</B>
549     */
550    public static final String SCT_HTML_UTF8 = "text/html; charset=utf-8";
551
552    /**
553     * Text-file, Java-Script, UTF-8.
554     * <B>NOTE:</B> This is to be used for calls to <B>{@code SCT(String s1, String type); }</B>
555     */
556    public static final String SCT_JAVASCRIPT_UTF8 = "application/javascript; charset=utf-8";
557
558    /**
559     * Text-file, Java-Script.
560     * <B>NOTE:</B> This is to be used for calls to <B>{@code SCT(String s1, String type); }</B>
561     */
562    public static final String SCT_JAVASCRIPT = "application/javascript";
563
564    /**
565     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_TYPE>
566     * 
567     * @param source This is the parameter is supposed to be a file, directory, or expression
568     * sequence.
569     * 
570     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
571     * that would normally be passed to gsutil on the shell command-line.
572     * 
573     * @param type This is any {@code 'String'} that may be used with Google Cloud Server.  Must
574     * pertain to "Content-Type".  There are several pre-defined content-type strings defined in this
575     * class that make reasonable values for this parameter.
576     * 
577     * @param extraSwitches This may be appended to the command, providing Google's
578     * {@code 'gsutil'} with switches.  The salient arguments to set the content-type of a web-page
579     * have already been included.  This parameter is only important if there are other switches,
580     * in addition to the ones already used by the constructor for this command.
581     * 
582     * @see #SCT_TEXT_UTF8
583     * @see #SCT_HTML_UTF8
584     * @see #SCT_JAVASCRIPT
585     * 
586     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
587     * @throws IOException If there are any problems while invoking the operating-system command
588     * @see OSCommands#printAndRun(String[])
589     */
590    public OSResponse CONTENT_TYPE(String source, String type, String... extraSwitches)
591        throws IOException
592    {
593        String[] command = BUILD_COMMAND(
594            new String[] { "gsutil", "-m", "setmeta", "-h", "Content-Type: " + type },
595            extraSwitches, source, NO_TARGET
596        );
597
598        return printAndRun(command);
599    }
600
601    /**
602     * Convenience Method.
603     * <BR />Invokes: {@link #CONTENT_TYPE(String[], String, String[])}
604     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
605     */
606    public OSResponse CONTENT_TYPE
607        (Iterable<String> iterable, String type, String... extraSwitches)
608        throws IOException
609    { return CONTENT_TYPE(TO_ARRAY(iterable), type, extraSwitches); }
610
611    /**
612     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_TYPE>
613     * 
614     * @param s1Arr The GCS bucket-storage address list.  gs://bucket-name/directoryname/filename
615     * 
616     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
617     * that would normally be passed to gsutil on the shell command-line.
618     * 
619     * @param type This is any {@code 'String'} that may be used with Google Cloud Server.  Must
620     * pertain to "Content-Type".  There are several pre-defined content-type strings defined in
621     * this class that make reasonable values for this parameter.
622     * 
623     * @param extraSwitches This may be appended to the command, providing Google's
624     * {@code 'gsutil'} with switches.  The salient arguments to set the content-type of a web-page
625     * have already been included.  This parameter is only important if there are other switches,
626     * in addition to the ones already used by the constructor for this command.
627     * 
628     * @see #SCT_TEXT_UTF8
629     * @see #SCT_HTML_UTF8
630     * @see #SCT_JAVASCRIPT
631     * 
632     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
633     * @throws IOException If there are any problems while invoking the operating-system command
634     * @see OSCommands#printAndRun(String[])
635     */
636    public OSResponse CONTENT_TYPE(String[] s1Arr, String type, String... extraSwitches)
637        throws IOException
638    {
639        String[] command = BUILD_COMMAND(
640            new String[] { "gsutil", "-m", "setmeta", "-h", "Content-Type: " + type },
641            extraSwitches, s1Arr, NO_TARGET
642        );
643
644        return printAndRun(command);
645    }
646
647
648    // ********************************************************************************************
649    // ********************************************************************************************
650    // GSUTIL CACHE-CONTROL
651    // ********************************************************************************************
652    // ********************************************************************************************
653
654
655    /**
656     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CACHE_CONT>
657     * 
658     * @param s1 This is the parameter is supposed to be a file, directory, or expression sequence
659     * 
660     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
661     * that would normally be passed to gsutil on the shell command-line. 
662     *     
663     * @param cacheControlTags This is any {@code 'String'} that may be used with Google Cloud
664     * Server.  Must pertain to "Cache-Control"
665     * 
666     * @param extraSwitches This may be appended to the command, providing Google's
667     * {@code 'gsutil'} with switches.  The salient arguments to set the cache-control of a web-page
668     * have already been included.  This parameter is only important if there are other switches,
669     * in addition to the ones already used by the constructor for this command.
670     * 
671     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
672     * @throws IOException If there are any problems while invoking the operating-system command
673     * @see OSCommands#printAndRun(String[])
674     */
675    public OSResponse CACHE_CONTROL
676        (String s1, String cacheControlTags, String... extraSwitches)
677        throws IOException
678    {
679        String[] command = BUILD_COMMAND(
680            new String[] { "gsutil", "-m", "setmeta", "-h", "Cache-Control: " + cacheControlTags },
681            extraSwitches, s1, NO_TARGET
682        );
683
684        return printAndRun(command);
685    }
686
687    /**
688     * Convenience Method.
689     * <BR />Invokes: {@link #CACHE_CONTROL(String[], String, String[])}
690     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
691     */
692    public OSResponse CACHE_CONTROL
693        (Iterable<String> iterable, String cacheControlTags, String... extraSwitches)
694        throws IOException
695    { return CACHE_CONTROL(TO_ARRAY(iterable), cacheControlTags, extraSwitches); }
696
697    /**
698     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CACHE_CONT>
699     * 
700     * @param s1Arr This is the parameter is supposed to be a file, directory, or expression
701     * sequence.
702     * 
703     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
704     * that would normally be passed to gsutil on the shell command-line.
705     * 
706     * @param cacheControlTags This is any {@code 'String'} that may be used with Google Cloud
707     * Server.  Must pertain to "Cache-Control"
708     * 
709     * @param extraSwitches This may be appended to the command, providing Google's
710     * {@code 'gsutil'} with switches.  The salient arguments to set the cache-control of a
711     * web-page have already been included.  This parameter is only important if there are other
712     * switches, in addition to the ones already used by the constructor for this command.
713     * 
714     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
715     * @throws IOException If there are any problems while invoking the operating-system command
716     * @see OSCommands#printAndRun(String[])
717     */
718    public OSResponse CACHE_CONTROL
719        (String[] s1Arr, String cacheControlTags, String... extraSwitches)
720        throws IOException
721    {
722        String[] command = BUILD_COMMAND(
723            new String[] { "gsutil", "-m", "setmeta", "-h", "Cache-Control: " + cacheControlTags },
724            extraSwitches, s1Arr, NO_TARGET
725        );
726
727        return printAndRun(command);
728    }
729
730
731    // ********************************************************************************************
732    // ********************************************************************************************
733    // GSUTIL CONTENT-ENCODING
734    // ********************************************************************************************
735    // ********************************************************************************************
736
737
738    /**
739     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_ENCODE>
740     * 
741     * @param s1 This is the parameter is supposed to be a file, directory, or expression sequence
742     * 
743     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
744     * that would normally be passed to gsutil on the shell command-line.
745     * 
746     * @param contentEncodingTags This is any {@code 'String'} that may be used with Google Cloud
747     * Server.  Must pertain to "Content-Encoding"
748     * 
749     * @param extraSwitches This may be appended to the command, providing Google's
750     * {@code 'gsutil'} with switches.  The salient arguments to set the content-encoding of a
751     * web-page have already been included.  This parameter is only important if there are other
752     * switches, in addition to the ones already used by the constructor for this command.
753     * 
754     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
755     * @throws IOException If there are any problems while invoking the operating-system command
756     * @see OSCommands#printAndRun(String[])
757     */
758    public OSResponse CONTENT_ENCODING
759        (String s1, String contentEncodingTags, String... extraSwitches)
760        throws IOException
761    {
762        String[] command = BUILD_COMMAND(
763            new String[]
764                { "gsutil", "-m", "setmeta", "-h", "Content-Encoding: " + contentEncodingTags },
765            extraSwitches, s1, NO_TARGET
766        );
767
768        return printAndRun(command);
769    }
770
771    /**
772     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_ENCODE>
773     * 
774     * @param s1Arr This is the parameter is supposed to be a file, directory, or expression
775     * sequence.
776     * 
777     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
778     * that would normally be passed to gsutil on the shell command-line.
779     * 
780     * @param contentEncodingTags This is any {@code 'String'} that may be used with Google Cloud
781     * Server.  Must pertain to "Content-Encoding"
782     * 
783     * @param extraSwitches This may be appended to the command, providing Google's
784     * {@code 'gsutil'} with switches.  The salient arguments to set the content-encoding of a
785     * web-page have already been included.  This parameter is only important if there are other
786     * switches, in addition to the ones already used by the constructor for this command.
787     * 
788     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
789     * @throws IOException If there are any problems while invoking the operating-system command
790     * @see OSCommands#printAndRun(String[])
791     */
792    public OSResponse CONTENT_ENCODING
793        (String[] s1Arr, String contentEncodingTags, String... extraSwitches)
794        throws IOException
795    {
796        String[] command = BUILD_COMMAND(
797            new String[]
798                { "gsutil", "-m", "setmeta", "-h", "Content-Encoding: " + contentEncodingTags },
799            extraSwitches, s1Arr, NO_TARGET
800        );
801
802        return printAndRun(command);
803    }
804
805    /**
806     * Convenience Method.
807     * <BR />Invokes: {@link #CONTENT_ENCODING(String[], String, String[])}
808     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
809     */
810    public OSResponse CONTENT_ENCODING
811        (Iterable<String> iterable, String contentEncodingTags, String... extraSwitches)
812        throws IOException
813    { return CONTENT_ENCODING(TO_ARRAY(iterable), contentEncodingTags, extraSwitches); }
814
815
816    // ********************************************************************************************
817    // ********************************************************************************************
818    // GSUTIL CONTENT-DISPOSITION
819    // ********************************************************************************************
820    // ********************************************************************************************
821
822
823    /**
824     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_DISP>
825     * 
826     * @param s1 This is the parameter is supposed to be a file, directory, or expression sequence
827     * 
828     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
829     * that would normally be passed to gsutil on the shell command-line.
830     * 
831     * @param contentDispositionTags This is any {@code 'String'} that may be used with Google
832     * Cloud Server.  Must pertain to "Content-Disposition"
833     * 
834     * @param extraSwitches This may be appended to the command, providing Google's
835     * {@code 'gsutil'} with switches.  The salient arguments to set the content-disposition of a
836     * web-page have already been included.  This parameter is only important if there are other
837     * switches, in addition to the ones already used by the constructor for this command.
838     * 
839     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
840     * @throws IOException If there are any problems while invoking the operating-system command
841     * @see OSCommands#printAndRun(String[])
842     */
843    public OSResponse CONTENT_DISPOSITION
844        (String s1, String contentDispositionTags, String... extraSwitches)
845        throws IOException
846    {
847        String[] command = BUILD_COMMAND(
848            new String[]
849            {
850                "gsutil", "-m", "setmeta", "-h",
851                "Content-Disposition: " + contentDispositionTags
852            },
853            extraSwitches, s1, NO_TARGET
854        );
855
856        return printAndRun(command);
857    }
858
859    /**
860     * Convenience Method.
861     * <BR />Invokes: {@link #CONTENT_DISPOSITION(String[], String, String[])}
862     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
863     */
864    public OSResponse CONTENT_DISPOSITION
865        (Iterable<String> iterable, String contentDispositionTags, String... extraSwitches)
866        throws IOException
867    { return CONTENT_DISPOSITION(TO_ARRAY(iterable), contentDispositionTags, extraSwitches); }
868
869    /**
870     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CONT_DISP>
871     * 
872     * @param s1Arr This is the parameter is supposed to be a file, directory, or expression
873     * sequence.
874     * 
875     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
876     * that would normally be passed to gsutil on the shell command-line.
877     * 
878     * @param contentDispositionTags This is any {@code 'String'} that may be used with Google
879     * Cloud Server.  Must pertain to "Content-Disposition"
880     * 
881     * @param extraSwitches This may be appended to the command, providing Google's
882     * {@code 'gsutil'} with switches.  The salient arguments to set the content-disposition of a
883     * web-page have already been included.  This parameter is only important if there are other
884     * switches, in addition to the ones already used by the constructor for this command.
885     * 
886     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
887     * @throws IOException If there are any problems while invoking the operating-system command
888     * @see OSCommands#printAndRun(String[])
889     */
890    public OSResponse CONTENT_DISPOSITION
891        (String[] s1Arr, String contentDispositionTags, String... extraSwitches)
892        throws IOException
893    {
894        String[] command = BUILD_COMMAND(
895            new String[]
896            {
897                "gsutil", "-m", "setmeta", "-h",
898                "Content-Disposition: " + contentDispositionTags
899            },
900            extraSwitches, s1Arr, NO_TARGET
901        );
902
903        return printAndRun(command);
904    }
905
906
907    // ********************************************************************************************
908    // ********************************************************************************************
909    // GSUTIL OTHER
910    // ********************************************************************************************
911    // ********************************************************************************************
912
913
914    /**
915     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CUSTOM_META>
916     * 
917     * @param s1 This is the parameter is supposed to be a file, directory, or expression sequence
918     * 
919     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
920     * that would normally be passed to gsutil on the shell command-line.
921     * 
922     * @param metaTag This is any {@code 'String'} that may be used with Google Cloud Server's
923     * {@code 'setmeta'} parameter for {@code gsutil}.
924     * 
925     * @param extraSwitches This may be appended to the command, providing Google's
926     * {@code 'gsutil'} with switches.  The salient arguments to set the meta-information of a
927     * web-page have already been included.  This parameter is only important if there are other
928     * switches, in addition to the ones already used by the constructor for this command.
929     * 
930     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
931     * @throws IOException If there are any problems while invoking the operating-system command
932     * @see OSCommands#printAndRun(String[])
933     */
934    public OSResponse CUSTOM_METADATA
935        (String s1, String metaTag, String... extraSwitches)
936        throws IOException
937    {
938        String[] command = BUILD_COMMAND(
939            new String[] { "gsutil", "-m", "setmeta", "-h", metaTag },
940            extraSwitches, s1, NO_TARGET
941        );
942
943        return printAndRun(command);
944    }
945
946    /**
947     * Convenience Method.
948     * <BR />Invokes: {@link #CUSTOM_METADATA(String[], String, String[])}
949     * <BR />Converts: {@code Iterable<String>} to {@code String[] Array}
950     */
951    public OSResponse CUSTOM_METADATA
952        (Iterable<String> iterable, String tags, String... extraSwitches)
953        throws IOException
954    { return CUSTOM_METADATA(TO_ARRAY(iterable), tags, extraSwitches); }
955
956    /**
957     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_CUSTOM_META>
958     * 
959     * @param s1Arr This is the parameter is supposed to be a file, directory, or expression
960     * sequence.
961     * 
962     * <BR /><B>NOTE:</B> The {@code 'source(s)'} may contain the asterisks {@code '*'} or anything
963     * that would normally be passed to gsutil on the shell command-line.
964     * 
965     * @param metaTag This is any {@code 'String'} that may be used with Google Cloud Server's
966     * {@code 'setmeta'} parameter for {@code gsutil}.
967     * 
968     * @param extraSwitches This may be appended to the command, providing Google's
969     * {@code 'gsutil'} with switches.  The salient arguments to set the meta-information of a
970     * web-page have already been included.  This parameter is only important if there are other
971     * switches, in addition to the ones already used by the constructor for this command.
972     * 
973     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
974     * @throws IOException If there are any problems while invoking the operating-system command
975     * @see OSCommands#printAndRun(String[])
976     */
977    public OSResponse CUSTOM_METADATA
978        (String[] s1Arr, String metaTag, String... extraSwitches)
979        throws IOException
980    {
981        String[] command = BUILD_COMMAND(
982            new String[] { "gsutil", "-m", "setmeta", "-h", metaTag },
983            extraSwitches, s1Arr, NO_TARGET
984        );
985
986        return printAndRun(command);
987    }
988
989
990    // ********************************************************************************************
991    // ********************************************************************************************
992    // GSUTIL LS
993    // ********************************************************************************************
994    // ********************************************************************************************
995
996
997    /**
998     * <EMBED CLASS='external-html' DATA-FILE-ID=GSUTIL_LS>
999     * @param s1 The GCS storage file or directory.  Note: {@code '*'} or {@code '**'} may be used.
1000     * @return <EMBED CLASS='external-html' DATA-FILE-ID=OSRET>
1001     * @see OSCommands#printAndRun(String[])
1002     */
1003    public OSResponse LS(String s1, String... switches) throws IOException
1004    {
1005        String[] command = BUILD_COMMAND(new String[] { "gsutil", "ls" }, switches, s1, NO_TARGET);
1006
1007        return printAndRun(command);
1008    }
1009
1010
1011    // ********************************************************************************************
1012    // ********************************************************************************************
1013    // HELPER ROUTINES
1014    // ********************************************************************************************
1015    // ********************************************************************************************
1016
1017
1018    private static String[] TO_ARRAY(Iterable<String> iterable)
1019    {
1020        Stream.Builder<String>  b           = Stream.builder();
1021        Iterator<String>        iterator    = iterable.iterator();
1022
1023        while (iterator.hasNext()) b.add(iterator.next());
1024
1025        return b.build().toArray(String[]::new);
1026    }
1027
1028    private static String[] BUILD_COMMAND
1029        (String[] CMD, String[] SWITCHES, String SOURCE, String TARGET)
1030    {
1031        if (SOURCE == null) throw new NullPointerException
1032            ("You have passed 'null' for a value of your source-file or directory name.");
1033
1034        for (String SWITCH : SWITCHES) if (SWITCH == null) throw new NullPointerException
1035            ("You have passed 'null' as a value for one of your var-args switches.");
1036
1037        if (TARGET == null) throw new NullPointerException
1038            ("You have passed 'null' as a value for your target file or directory name.");
1039
1040        int arrLen = CMD.length + SWITCHES.length + 1 + ((TARGET == NO_TARGET) ? 0 : 1);
1041
1042        String[] ret = new String[arrLen];
1043
1044        for (int i=0; i < CMD.length; i++)
1045            ret[i] = CMD[i];
1046
1047        for (int i=0; i < SWITCHES.length; i++)
1048            ret[CMD.length + i] = SWITCHES[i];
1049
1050        ret[CMD.length + SWITCHES.length] = SOURCE;
1051
1052        if (TARGET != NO_TARGET) ret[ret.length - 1] = TARGET;
1053
1054        return ret;
1055    }
1056
1057    private static String[] BUILD_COMMAND
1058        (String[] CMD, String[] SWITCHES, String[] SOURCES, String TARGET)
1059    {
1060        for (String SOURCE : SOURCES) if (SOURCE == null) throw new NullPointerException
1061            ("You have passed 'null' for a value for one of your source-file or directory names.");
1062
1063        for (String SWITCH : SWITCHES) if (SWITCH == null) throw new NullPointerException
1064            ("You have passed 'null' as a value for one of your var-args switches.");
1065
1066        if (TARGET == null) throw new NullPointerException
1067            ("You have passed 'null' as a value for your target file or directory name.");
1068
1069        int arrLen = CMD.length + SWITCHES.length + SOURCES.length +
1070            ((TARGET == NO_TARGET) ? 0 : 1);
1071
1072        String[] ret = new String[arrLen];
1073
1074        for (int i=0; i < CMD.length; i++)
1075            ret[i] = CMD[i];
1076
1077        for (int i=0; i < SWITCHES.length; i++)
1078            ret[CMD.length + i] = SWITCHES[i];
1079
1080        for (int i=0; i < SOURCES.length; i++) 
1081            ret[CMD.length + SWITCHES.length + i] = SOURCES[i];
1082
1083        if (TARGET != NO_TARGET) ret[ret.length - 1] = TARGET;
1084
1085        return ret;
1086    }
1087}