1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package Torello.Languages;

import java.util.*;
import java.util.regex.*;
import java.io.*;

import Torello.HTML.*;
import Torello.HTML.NodeSearch.*;

import Torello.Java.*;

import Torello.Java.Additional.URLs;

import Torello.JavaDoc.StaticFunctional;
import Torello.JavaDoc.Excuse;

/**
 * Google Cloud Services, Translation API Wrapper.
 * 
 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=GCSTAPI>
 */
@StaticFunctional(Excused="key", Excuses=Excuse.CONFIGURATION)
public class GCSTAPI
{
    private GCSTAPI() { }

    private static final String baseQ =
        "https://www.googleapis.com/language/translate/v2?key=";

    private static final Pattern P1 =
        Pattern.compile(
            "\\{\\s+\"translatedText\":\\s+\"(.*?)\"\\s+\\}",
             Pattern.DOTALL | Pattern.CASE_INSENSITIVE
        );

    /**
     * This is a key that may be obtained from Google Corporation.  Complete the form for "Cloud
     * Server Login" and then try adding the Translation package.  Google expects you to pay for
     * translation services, but single articles are usually a penny or so.  Long articles with
     * many translations can become expensive.  Set this key to a specific value to register it. 
     * 
     * <BR /><BR /><B>NOTE:</B> This class only has static methods for brevity and simplicity.  If
     * you wish to use multiple keys for different projects, well, copy the code from these two
     * methods and add them to one of your own classes - for "multi-threaded" applications.
     * <I><B>Otherwise you might also just change/update the {@code public static String key}
     * field</I></B> whenver you wish to bill your translations to a different billing project,
     * card or account. 
     * 
     * <BR /><BR /><B>ALSO NOTE:</B> Use of this Java Package will not transmit your key to me
     * (Ralph P. Torello), I'm not trying to steal your google key or account.  Obviously, I cannot
     * prove this Java Package does not make outgoing connections to any server I own, but,
     * <B>Guess What? It DOESN'T!</B> 
     * 
     * <BR /><BR /><I>If you do not set the key field here, Google Cloud Server Translate API will
     * not respond to your query.</I>  Google bills each query on a word by word basis.  See their
     * metrics on the GCS Translate API documentation website.
     */
    public static String key;

    /**
     * This method takes what is expected to be a sentence in (any) foreign language.  The
     * foreign-language used is passed as a two-character String from Google Translate' list of
     * two-character language codes.  The Target language may be any.  Usually it is
     * English/Spanish.<BR /><BR />
     * 
     * @param text Any string in a foreign language.  This is expected to be a single sentence.
     * 
     * @param srcLang Two-Character String Language Code identifying the foreign language used.
     * See the enum "LC" (Language Code)
     * 
     * @param targetLang Two-Character String Language Code of the "target" or "destination"
     * language.  See the enum "LC" (Language Code)
     * 
     * @return Translated Sentence - generated by a call to Google Cloud Server Translate API.
     * 
     * @see Torello.Languages.LC
     */
    public static String sentence(String text, LC srcLang, LC targetLang) throws IOException
    {
        StringBuffer    sb      = new StringBuffer();
        String	        json    = null;

        // REST API Query String
        String q = baseQ + key + "&source=" + srcLang.gcsLanguageCode +
            "&target=" + targetLang.gcsLanguageCode +
            "&q=" + URLs.toProperURLV2(text);

        try
        {
            json        = Scrape.scrapePage(Scrape.openConn_UTF8(q)).toString();
            Matcher m   = P1.matcher(json);

            // Since only a Single text-string was queried, it is better to return the result
            // as a single string.

            while (m.find()) sb.append(m.group(1) + "\n");

            return sb.toString();
        }
        catch (Exception e)
        {
            System.out.println(
                '\n' +
                "TextTranslate.sentence(q=\n" + q + '\n' +
                "TextTranslate.sentence(text=\n" + text + '\n' +
                "TextTranslate.sentence(json=\n" + json
            );

            throw e;
        }
    }

    /**
     * This is similar to sentence, but the input is expected to be a series of individual
     * vocabulary words.  The source and target/destination language codes are necessary.  A Vector
     * of equal length to the original input Vector is returned.  It contains each vocabulary word
     * from the original Vector in the destination/target language.
     * 
     * @param words Any string in a foreign language.  This is expected to be a single sentence.
     * 
     * @param srcLang Two-Character String Language Code identifying the foreign language used.
     * See the enum "LC" (Language Code)
     * 
     * @param targetLang Two-Character String Language Code of the "target" or "destination"
     * language.  See the enum "LC" (Language Code)
     * 
     * @return Translated Sentence - generated by a call to Google Cloud Server Translate API.
     * 
     * @see Torello.HTML.Scrape
     * @see Torello.Languages.LC
     */
    public static Vector<String> wordByWord(Vector<String> words, LC srcLang, LC targetLang)
        throws IOException
    {
        int             i       = 0;
        int             len     = words.size();
        Vector<String>  ret     = new Vector<String>();
        String          q       = null;
        String          json    = null;

        while (i < len)
        {
            try
            {
                q = baseQ + key + "&source=" + srcLang.gcsLanguageCode +
                        "&target=" + targetLang.gcsLanguageCode;

                for (int j=0; (j < 50) && ((j + i) < len); j++)
                    q += "&q=" + URLs.toProperURLV2(words.elementAt(j + i));

                i += 50;

                json = Scrape.scrapePage(Scrape.openConn_UTF8(q)).toString();
                Matcher	m = P1.matcher(json);

                while (m.find()) ret.addElement(m.group(1).trim());
            }
            catch (Exception e)
            {
                System.out.println(
                    '\n' +
                    "TextTranslate.wordByWord, q=\n" + q + '\n' +
                    "TextTranslate.wordByWord, json=\n" + json
                );

                throw e;
            }
        }

        return ret;
    }
}