golf 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/golf.gemspec +1 -1
- data/lib/golf/version.rb +1 -1
- metadata +1 -121
- data/golf-java/README.markdown +0 -41
- data/golf-java/THANKS.markdown +0 -14
- data/golf-java/build/classes.zip +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfResource$MimeMapping$MimeMappingSingleton.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfResource$MimeMapping.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfResource.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$1.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfContext.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfParams.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfSession.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$PermanentRedirectException.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$RedirectException.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet$StoredJSVM.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/GolfServlet.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/JsonpTunnel.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/Main$1.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/Main$RingList.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/Main.class +0 -0
- data/golf-java/build/com/thinkminimo/golf/ProxyServlet.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/CssCompressor.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/JarClassLoader.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptToken.class +0 -0
- data/golf-java/build/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class +0 -0
- data/golf-java/build/depends.zip +0 -0
- data/golf-java/build/golf +0 -2
- data/golf-java/build/org/json/JSONArray.class +0 -0
- data/golf-java/build/org/json/JSONException.class +0 -0
- data/golf-java/build/org/json/JSONObject$1.class +0 -0
- data/golf-java/build/org/json/JSONObject$Null.class +0 -0
- data/golf-java/build/org/json/JSONObject.class +0 -0
- data/golf-java/build/org/json/JSONString.class +0 -0
- data/golf-java/build/org/json/JSONStringer.class +0 -0
- data/golf-java/build/org/json/JSONTokener.class +0 -0
- data/golf-java/build/org/json/JSONWriter.class +0 -0
- data/golf-java/build/resources.zip +0 -0
- data/golf-java/build.xml +0 -174
- data/golf-java/dist/golf.zip +0 -0
- data/golf-java/lib/ant-launcher.jar +0 -0
- data/golf-java/lib/ant.jar +0 -0
- data/golf-java/lib/commons-codec-1.4.jar +0 -0
- data/golf-java/lib/commons-collections-3.2.1.jar +0 -0
- data/golf-java/lib/commons-fileupload-1.2.1.jar +0 -0
- data/golf-java/lib/commons-httpclient-3.1.jar +0 -0
- data/golf-java/lib/commons-io-1.4.jar +0 -0
- data/golf-java/lib/commons-lang-2.4.jar +0 -0
- data/golf-java/lib/commons-logging-1.1.1.jar +0 -0
- data/golf-java/lib/cssparser-0.9.5.jar +0 -0
- data/golf-java/lib/getopt-0.1-dev.jar +0 -0
- data/golf-java/lib/htmlunit-2.6.jar +0 -0
- data/golf-java/lib/htmlunit-core-js-2.6.jar +0 -0
- data/golf-java/lib/java-xmlbuilder-1.jar +0 -0
- data/golf-java/lib/jets3t-0.7.0.jar +0 -0
- data/golf-java/lib/jetty-6.1.15.jar +0 -0
- data/golf-java/lib/jetty-util-6.1.15.jar +0 -0
- data/golf-java/lib/log4j-1.2.15.jar +0 -0
- data/golf-java/lib/nekohtml-1.9.13.jar +0 -0
- data/golf-java/lib/sac-1.3.jar +0 -0
- data/golf-java/lib/serializer-2.7.1.jar +0 -0
- data/golf-java/lib/servlet-api-2.5-20081211.jar +0 -0
- data/golf-java/lib/xalan-2.7.1.jar +0 -0
- data/golf-java/lib/xercesImpl-2.9.1.jar +0 -0
- data/golf-java/lib/xml-apis-1.3.04.jar +0 -0
- data/golf-java/resources/app_error.html +0 -60
- data/golf-java/resources/error.html +0 -29
- data/golf-java/resources/forcebot.txt +0 -0
- data/golf-java/resources/forceclient.txt +0 -0
- data/golf-java/resources/forceproxy.txt +0 -0
- data/golf-java/resources/head.html +0 -0
- data/golf-java/resources/jquery.address.js +0 -439
- data/golf-java/resources/jquery.golf.js +0 -945
- data/golf-java/resources/jquery.js +0 -4376
- data/golf-java/resources/jsdetect.html +0 -23
- data/golf-java/resources/loading.gif +0 -0
- data/golf-java/resources/new.html +0 -45
- data/golf-java/resources/new.static.html +0 -45
- data/golf-java/resources/noscript.forceclient.html +0 -11
- data/golf-java/resources/noscript.html +0 -18
- data/golf-java/resources/noscript.static.html +0 -15
- data/golf-java/resources/project.xml +0 -21
- data/golf-java/resources/proxy_project.xml +0 -11
- data/golf-java/resources/proxy_web.xml +0 -40
- data/golf-java/resources/static_project.xml +0 -37
- data/golf-java/resources/version +0 -1
- data/golf-java/resources/web.xml +0 -36
- data/golf-java/resources/welcome2golf.html +0 -50
- data/golf-java/src/com/thinkminimo/golf/GolfResource.java +0 -582
- data/golf-java/src/com/thinkminimo/golf/GolfServlet.java +0 -1055
- data/golf-java/src/com/thinkminimo/golf/JsonpTunnel.java +0 -86
- data/golf-java/src/com/thinkminimo/golf/Main.java +0 -1299
- data/golf-java/src/com/thinkminimo/golf/ProxyServlet.java +0 -577
- data/golf-java/src/com/yahoo/platform/yui/compressor/CssCompressor.java +0 -188
- data/golf-java/src/com/yahoo/platform/yui/compressor/JarClassLoader.java +0 -158
- data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java +0 -1281
- data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java +0 -55
- data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java +0 -28
- data/golf-java/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java +0 -160
- data/golf-java/src/org/json/JSONArray.java +0 -934
- data/golf-java/src/org/json/JSONException.java +0 -27
- data/golf-java/src/org/json/JSONObject.java +0 -1550
- data/golf-java/src/org/json/JSONString.java +0 -18
- data/golf-java/src/org/json/JSONStringer.java +0 -78
- data/golf-java/src/org/json/JSONTokener.java +0 -422
- data/golf-java/src/org/json/JSONWriter.java +0 -323
- data/golf-java/test/client/golftest/README.markdown +0 -3
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.css +0 -114
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.html +0 -17
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.js +0 -81
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/asc.gif +0 -0
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/bg.gif +0 -0
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/desc.gif +0 -0
- data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/test/test.html +0 -1
- data/golf-java/test/client/golftest/controller.js +0 -131
- data/golf-java/test/client/golftest/forceclient.txt +0 -0
- data/golf-java/test/client/golftest/forceproxy.txt +0 -0
- data/golf-java/test/client/golftest/head.html +0 -1
- data/golf-java/test/client/golftest/scripts/jquery.tablesort.js +0 -75
- data/golf-java/test/client/golftest/styles/style.css +0 -18
- data/golf-java/test/client/golftest/test/test.html +0 -1
@@ -1,1299 +0,0 @@
|
|
1
|
-
package com.thinkminimo.golf;
|
2
|
-
|
3
|
-
import com.thinkminimo.getopt.GetOpt;
|
4
|
-
|
5
|
-
import org.json.*;
|
6
|
-
|
7
|
-
import java.io.*;
|
8
|
-
import java.util.*;
|
9
|
-
import java.util.regex.Pattern;
|
10
|
-
import java.net.URL;
|
11
|
-
import java.net.URI;
|
12
|
-
import java.net.URISyntaxException;
|
13
|
-
import java.net.URLClassLoader;
|
14
|
-
import java.rmi.server.UID;
|
15
|
-
import java.security.NoSuchAlgorithmException;
|
16
|
-
|
17
|
-
import java.lang.reflect.Method;
|
18
|
-
import java.lang.reflect.Constructor;
|
19
|
-
|
20
|
-
import net.sourceforge.htmlunit.corejs.javascript.ErrorReporter;
|
21
|
-
import net.sourceforge.htmlunit.corejs.javascript.EvaluatorException;
|
22
|
-
import com.yahoo.platform.yui.compressor.CssCompressor;
|
23
|
-
import com.yahoo.platform.yui.compressor.JavaScriptCompressor;
|
24
|
-
|
25
|
-
import javax.servlet.ServletException;
|
26
|
-
import javax.servlet.http.HttpServlet;
|
27
|
-
import javax.servlet.http.HttpServletRequest;
|
28
|
-
import javax.servlet.http.HttpServletResponse;
|
29
|
-
|
30
|
-
import org.jets3t.service.CloudFrontService;
|
31
|
-
import org.jets3t.service.S3Service;
|
32
|
-
import org.jets3t.service.S3ServiceException;
|
33
|
-
import org.jets3t.service.acl.AccessControlList;
|
34
|
-
import org.jets3t.service.acl.GroupGrantee;
|
35
|
-
import org.jets3t.service.acl.Permission;
|
36
|
-
import org.jets3t.service.model.S3Bucket;
|
37
|
-
import org.jets3t.service.model.S3Object;
|
38
|
-
import org.jets3t.service.model.cloudfront.Distribution;
|
39
|
-
import org.jets3t.service.model.cloudfront.DistributionConfig;
|
40
|
-
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
|
41
|
-
import org.jets3t.service.security.AWSCredentials;
|
42
|
-
|
43
|
-
import org.apache.tools.ant.*;
|
44
|
-
import org.apache.tools.ant.taskdefs.*;
|
45
|
-
import org.apache.tools.ant.types.resources.*;
|
46
|
-
|
47
|
-
import org.mortbay.log.Log;
|
48
|
-
import org.mortbay.jetty.Handler;
|
49
|
-
import org.mortbay.jetty.HandlerContainer;
|
50
|
-
import org.mortbay.jetty.Server;
|
51
|
-
import org.mortbay.jetty.handler.HandlerList;
|
52
|
-
import org.mortbay.jetty.handler.ContextHandlerCollection;
|
53
|
-
import org.mortbay.jetty.handler.DefaultHandler;
|
54
|
-
import org.mortbay.jetty.handler.ResourceHandler;
|
55
|
-
import org.mortbay.jetty.handler.RequestLogHandler;
|
56
|
-
import org.mortbay.jetty.servlet.Context;
|
57
|
-
import org.mortbay.jetty.servlet.ServletHolder;
|
58
|
-
import org.mortbay.jetty.servlet.DefaultServlet;
|
59
|
-
import org.mortbay.jetty.webapp.WebAppContext;
|
60
|
-
import org.mortbay.thread.QueuedThreadPool;
|
61
|
-
|
62
|
-
public class Main
|
63
|
-
{
|
64
|
-
public static class RingList<T> extends ArrayList <T> {
|
65
|
-
private int next = 0;
|
66
|
-
public T next() {
|
67
|
-
return get(next++ % size());
|
68
|
-
}
|
69
|
-
public void reset() {
|
70
|
-
next = 0;
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
public static final String AWS_URL = "s3.amazonaws.com";
|
75
|
-
public static final int NUM_CFDOMAINS = 1;
|
76
|
-
public static final int NUM_VMPOOL = 20;
|
77
|
-
public static final int NUM_VMEXPIRE = 10;
|
78
|
-
public static final int JETTY_PORT = 4653;
|
79
|
-
private static final int BUF_SIZE = 1024;
|
80
|
-
|
81
|
-
public static final String NEW_HTML = "new.html";
|
82
|
-
public static final String NEW_FC_HTML = "new.fc.html";
|
83
|
-
public static final String NEW_ST_HTML = "new.static.html";
|
84
|
-
public static final String ERROR_HTML = "error.html";
|
85
|
-
public static final String HEAD_HTML = "head.html";
|
86
|
-
public static final String JSDETECT_HTML = "jsdetect.html";
|
87
|
-
public static final String COMPONENTS_JS = "components.js";
|
88
|
-
public static final String CONTROLLER_JS = "controller.js";
|
89
|
-
public static final String JQUERY_JS = "jquery.js";
|
90
|
-
public static final String JQUERY_GOLF_JS = "jquery.golf.js";
|
91
|
-
public static final String JQUERY_HIST_JS = "jquery.address.js";
|
92
|
-
public static final String FORCEPROXY_TXT = "forceproxy.txt";
|
93
|
-
public static final String FORCECLIENT_TXT = "forceclient.txt";
|
94
|
-
public static final String FORCEBOT_TXT = "forcebot.txt";
|
95
|
-
public static final String NOSCRIPT_HTML = "noscript.html";
|
96
|
-
public static final String NOSCRIPT_FC_HTML= "noscript.forceclient.html";
|
97
|
-
public static final String NOSCRIPT_ST_HTML= "noscript.static.html";
|
98
|
-
public static final String LOADING_GIF = "loading.gif";
|
99
|
-
|
100
|
-
public static final String DIR_COMPONENTS = "components";
|
101
|
-
public static final String DIR_MODULES = "plugins";
|
102
|
-
public static final String DIR_SCRIPTS = "scripts";
|
103
|
-
public static final String DIR_STYLES = "styles";
|
104
|
-
|
105
|
-
private static GetOpt o = null;
|
106
|
-
private static RingList<String> mCfDomains = null;
|
107
|
-
private static String mNewHtml = null;
|
108
|
-
|
109
|
-
private static String mAppName = null;
|
110
|
-
private static String mAppVersion = null;
|
111
|
-
|
112
|
-
private static HashMap<String, String> mApps = null;
|
113
|
-
private static HashMap<String, String> mBackends = null;
|
114
|
-
|
115
|
-
private AWSCredentials mAwsKeys = null;
|
116
|
-
private RestS3Service mS3svc = null;
|
117
|
-
private CloudFrontService mCfsvc = null;
|
118
|
-
private S3Bucket mBucket = null;
|
119
|
-
private AccessControlList mAcl = null;
|
120
|
-
|
121
|
-
public Main(String[] argv) throws Exception {
|
122
|
-
mApps = new HashMap<String, String>();
|
123
|
-
mBackends = new HashMap<String, String>();
|
124
|
-
mCfDomains = new RingList<String>();
|
125
|
-
mAppVersion = getResourceAsString("version").replaceFirst("\n", "");
|
126
|
-
|
127
|
-
// process single flag command lines
|
128
|
-
|
129
|
-
if (argv[0].equals("--version")) {
|
130
|
-
System.out.println(mAppVersion);
|
131
|
-
System.exit(0);
|
132
|
-
}
|
133
|
-
|
134
|
-
// Command line parser setup
|
135
|
-
|
136
|
-
o = new GetOpt("golf", argv);
|
137
|
-
|
138
|
-
o.addFlag(
|
139
|
-
"version",
|
140
|
-
"Display golf application server version info and exit."
|
141
|
-
).addSection(
|
142
|
-
"GENERAL OPTIONS",
|
143
|
-
"General configuration of the golf application server. These options "+
|
144
|
-
"will be rolled into the war file (where appropriate) if deploying to "+
|
145
|
-
"production, or used in the built-in servlet container for devmode "+
|
146
|
-
"operation."
|
147
|
-
).addOpt(
|
148
|
-
"port",
|
149
|
-
"Set the port the server will listen on (optional, devmode only)."
|
150
|
-
).addOpt(
|
151
|
-
"displayname",
|
152
|
-
"The display name to use for deploying as a war file into a servlet "+
|
153
|
-
"container (optional)."
|
154
|
-
).addOpt(
|
155
|
-
"description",
|
156
|
-
"Description of app when deploying as a war file into a servlet "+
|
157
|
-
"container (optional)."
|
158
|
-
).addOpt(
|
159
|
-
"pool-size",
|
160
|
-
"How many concurrent proxymode client virtual machines to allow."
|
161
|
-
).addOpt(
|
162
|
-
"pool-expire",
|
163
|
-
"Minimum idle time (seconds) before a proxymode client virtual "+
|
164
|
-
"machine can be scavenged."
|
165
|
-
).addOpt(
|
166
|
-
"static",
|
167
|
-
"Destination directory for a static app deployment. Static apps are "+
|
168
|
-
"compiled into pure HTML+JS. There is no proxy support with this option."
|
169
|
-
).addSection(
|
170
|
-
"AMAZON WEB SERVICES CONFIGURATION OPTIONS",
|
171
|
-
"The awspublic and awsprivate options provide the golf server with "+
|
172
|
-
"your AWS credentials. This enables it to automatically upload the "+
|
173
|
-
"application to CloudFront when deploying to production. AWS is not "+
|
174
|
-
"used in devmode."
|
175
|
-
).addOpt(
|
176
|
-
"awspublic",
|
177
|
-
"The amazon aws access key ID to use for cloudfront caching (required "+
|
178
|
-
"when using AWS)."
|
179
|
-
).addOpt(
|
180
|
-
"awsprivate",
|
181
|
-
"The amazon aws secret access key corresponding to the aws access "+
|
182
|
-
"key ID specified with the --awspublic option (required when using AWS)."
|
183
|
-
).addOpt(
|
184
|
-
"cloudfronts",
|
185
|
-
"How many CloudFront distributions to create (optional). This may be "+
|
186
|
-
"useful for getting browsers to load things in parallel rather than "+
|
187
|
-
"one at a time. On the other hand, it may be useless."
|
188
|
-
).addSection(
|
189
|
-
"HTTP PROXY CONFIGURATION OPTIONS",
|
190
|
-
"The golf application server ships with a built-in HTTP proxy servlet "+
|
191
|
-
"that can be used to provide access to backend web services without "+
|
192
|
-
"needing to resort to using JSONP or the 'window.name' hack."
|
193
|
-
).addOpt(
|
194
|
-
"proxyhost",
|
195
|
-
"The remote URI that the HTTP proxy will relay requests to. This will "+
|
196
|
-
"produce a war file containing the configured proxy servlet and exit, "+
|
197
|
-
"instead of starting the embedded servlet container."
|
198
|
-
).addOpt(
|
199
|
-
"proxyparams",
|
200
|
-
"Parameters to add to the query string of every request sent by the "+
|
201
|
-
"HTTP proxy to the remote host. This can be used to pass tokens that "+
|
202
|
-
"the client shouldn't have access to, and things like that."
|
203
|
-
).addOpt(
|
204
|
-
"proxymaxupload",
|
205
|
-
"The maximum file upload size for HTTP proxy requests (optional, in "+
|
206
|
-
"bytes)."
|
207
|
-
).addSection(
|
208
|
-
"WAR FILE CONFIGURATION OPTIONS",
|
209
|
-
"The golf application server jar file is able to roll a golf "+
|
210
|
-
"application into a war file for deployment to a servlet container "+
|
211
|
-
"for production. These options govern how this is done."
|
212
|
-
).addFlag(
|
213
|
-
"compress-js",
|
214
|
-
"Whether to yuicompress javascript resource files (production only)."
|
215
|
-
).addFlag(
|
216
|
-
"compress-css",
|
217
|
-
"Whether to yuicompress css resource files (production only)."
|
218
|
-
).addFlag(
|
219
|
-
"war",
|
220
|
-
"If present, create war file instead of starting embedded servlet "+
|
221
|
-
"container."
|
222
|
-
).addArg(
|
223
|
-
"approot|proxypath",
|
224
|
-
"The location of the golf app root directory, or when building HTTP "+
|
225
|
-
"proxy, the desired name of the resulting war file (.war extension "+
|
226
|
-
"will be added). When this argument specifies a golf approot, the "+
|
227
|
-
"application context path (or war file name, in the case of the --war "+
|
228
|
-
"option) is derived from the basename of the specified directory."
|
229
|
-
).addVarArg(
|
230
|
-
"backend [backend...]",
|
231
|
-
"The backend webapp war file or approot (not used when building HTTP "+
|
232
|
-
"proxy war files). Zero or more war files or directories may be "+
|
233
|
-
"specified here. The context path they are deployed to is taken from "+
|
234
|
-
"the basename of the war file or directory."
|
235
|
-
).addExample(
|
236
|
-
"RUN LOCAL DEVMODE SERVER WITH NO BACKEND",
|
237
|
-
"java -jar golf.jar ./apps/demo",
|
238
|
-
"This starts the golf application server, running the golf application "+
|
239
|
-
"locally from the embedded servlet container. The application will be "+
|
240
|
-
"accessible at the URL http://localhost:4653/demo/, and the approot is "+
|
241
|
-
"set to the ./apps/demo/ directory."
|
242
|
-
).addExample(
|
243
|
-
"RUN LOCAL DEVMODE SERVER WITH BACKEND",
|
244
|
-
"java -jar golf.jar ./apps/demo data1.war data2.war",
|
245
|
-
"This starts the golf application server, locally, as in the previous "+
|
246
|
-
"example, accessible at the URL http://localhost:4653/demo/, etc. "+
|
247
|
-
"Additionally, data1.war and data2.war (backend applications) will be "+
|
248
|
-
"deployed to the /data1/ and /data2/ context paths."
|
249
|
-
).addExample(
|
250
|
-
"PREPARE WAR FILE FOR DEPLOYMENT TO PRODUCTION",
|
251
|
-
"java -jar golf.jar --war ./apps/demo",
|
252
|
-
"Instead of starting the local golf application server, a war file is "+
|
253
|
-
"produced containing the golf application, in this case 'demo.war' is "+
|
254
|
-
"the resulting file. This war file can then be deployed to the "+
|
255
|
-
"production servlet container."
|
256
|
-
).addExample(
|
257
|
-
"PREPARE WAR FILE FOR DEPLOYMENT TO PRODUCTION WITH AWS",
|
258
|
-
"java -jar golf.jar --displayname 'My Golf App' \\\n"+
|
259
|
-
" --awspublic GKI69AJ344JLNT92X1QQ \\\n"+
|
260
|
-
" --awsprivate ke9S3CwVzLW9B21/HrkLiQfXEpoeGHwNDTlfBW5J \\\n"+
|
261
|
-
" --war ./apps/demo",
|
262
|
-
"As in the previous example, a war file is produced instead of starting "+
|
263
|
-
"the local golf application server. Additionally, the golf application "+
|
264
|
-
"is uploaded to Amazon's s3 service, and a CloudFront distribution is "+
|
265
|
-
"created. The golf app in the resulting war file will automatically "+
|
266
|
-
"load the frontend from CloudFront, rather than from the golf server."
|
267
|
-
).addExample(
|
268
|
-
"CREATE A HTTP PROXY",
|
269
|
-
"java -jar golf.jar --proxyhost www.example.com:8080/doit/ \\\n"+
|
270
|
-
" --proxyparams 'user=myname&pass=secret' data",
|
271
|
-
"This produces a HTTP proxy servlet configured to proxy HTTP requests "+
|
272
|
-
"to the specified remote URI, instead of starting the local embedded "+
|
273
|
-
"servlet container. The resulting war file will be saved to 'data.war'."
|
274
|
-
);
|
275
|
-
|
276
|
-
// default values for command line options
|
277
|
-
|
278
|
-
o.setOpt("port", String.valueOf(JETTY_PORT));
|
279
|
-
o.setOpt("displayname", "untitled web application");
|
280
|
-
o.setOpt("description", "powered by golf: http://thinkminimo.com");
|
281
|
-
o.setOpt("devmode", "false");
|
282
|
-
o.setOpt("awspublic", null);
|
283
|
-
o.setOpt("awsprivate", null);
|
284
|
-
o.setOpt("proxyhost", null);
|
285
|
-
o.setOpt("proxyparams", "");
|
286
|
-
o.setOpt("proxymaxupload",String.valueOf(10*1024*1024));
|
287
|
-
o.setOpt("pool-size", String.valueOf(NUM_VMPOOL));
|
288
|
-
o.setOpt("pool-expire", String.valueOf(NUM_VMEXPIRE));
|
289
|
-
o.setOpt("cloudfronts", String.valueOf(NUM_CFDOMAINS));
|
290
|
-
o.setOpt("cfdomains", "[]");
|
291
|
-
o.setOpt("compress-js", "false");
|
292
|
-
o.setOpt("compress-css", "false");
|
293
|
-
o.setOpt("war", "false");
|
294
|
-
|
295
|
-
// parse command line
|
296
|
-
try {
|
297
|
-
o.go();
|
298
|
-
} catch (Exception e) {
|
299
|
-
System.exit(1);
|
300
|
-
}
|
301
|
-
|
302
|
-
// command line option validation
|
303
|
-
|
304
|
-
if (o.getOpt("port") != null) {
|
305
|
-
try {
|
306
|
-
Integer.parseInt(o.getOpt("port"));
|
307
|
-
} catch (NumberFormatException e) {
|
308
|
-
usage(e.getMessage());
|
309
|
-
}
|
310
|
-
}
|
311
|
-
|
312
|
-
// start work
|
313
|
-
|
314
|
-
mAppName = (new File(o.getOpt("approot|proxypath")))
|
315
|
-
.getCanonicalFile().getName().replaceFirst("\\.war$", "");
|
316
|
-
mApps.put(mAppName, o.getOpt("approot|proxypath"));
|
317
|
-
|
318
|
-
while (o.getExtra().size() > 0) {
|
319
|
-
String path = o.getExtra().remove(0);
|
320
|
-
File f = new File(path);
|
321
|
-
String name = f.getCanonicalFile().getName().replaceFirst("\\.war$", "");
|
322
|
-
mBackends.put(name, path);
|
323
|
-
}
|
324
|
-
|
325
|
-
try {
|
326
|
-
if (o.getOpt("proxyhost") != null)
|
327
|
-
doProxyWarfile();
|
328
|
-
else if (o.getFlag("war"))
|
329
|
-
doWarfile();
|
330
|
-
else if (o.getOpt("static") != null)
|
331
|
-
doStatic();
|
332
|
-
else
|
333
|
-
doServer();
|
334
|
-
} catch (Exception e) {
|
335
|
-
System.err.println("golf: "+e.getMessage());
|
336
|
-
System.exit(1);
|
337
|
-
}
|
338
|
-
|
339
|
-
System.exit(0);
|
340
|
-
}
|
341
|
-
|
342
|
-
public static void main(String[] argv) {
|
343
|
-
try {
|
344
|
-
Main m = new Main(argv);
|
345
|
-
} catch (Exception e) {
|
346
|
-
System.exit(1);
|
347
|
-
}
|
348
|
-
}
|
349
|
-
|
350
|
-
private void prepareAws() throws Exception {
|
351
|
-
mAwsKeys =
|
352
|
-
new AWSCredentials(o.getOpt("awspublic"), o.getOpt("awsprivate"));
|
353
|
-
mS3svc = new RestS3Service(mAwsKeys);
|
354
|
-
|
355
|
-
while (true) {
|
356
|
-
mBucket = mS3svc.getOrCreateBucket(randName(mAppName));
|
357
|
-
long nowTime = (new Date()).getTime();
|
358
|
-
long bktTime = mBucket.getCreationDate().getTime();
|
359
|
-
long oneMin = 1L * 60L * 1000L;
|
360
|
-
if (nowTime - bktTime < oneMin)
|
361
|
-
break;
|
362
|
-
}
|
363
|
-
|
364
|
-
mAcl = mS3svc.getBucketAcl(mBucket);
|
365
|
-
mAcl.grantPermission(
|
366
|
-
GroupGrantee.ALL_USERS,
|
367
|
-
Permission.PERMISSION_READ
|
368
|
-
);
|
369
|
-
|
370
|
-
mBucket.setAcl(mAcl);
|
371
|
-
mS3svc.putBucketAcl(mBucket);
|
372
|
-
}
|
373
|
-
|
374
|
-
private void doCloudFront() throws Exception {
|
375
|
-
mCfsvc = new CloudFrontService(mAwsKeys);
|
376
|
-
|
377
|
-
String orig = mBucket.getName() + "." + AWS_URL;
|
378
|
-
String cmnt;
|
379
|
-
if (o.getOpt("description") != null)
|
380
|
-
cmnt = o.getOpt("description");
|
381
|
-
else if (o.getOpt("displayname") != null)
|
382
|
-
cmnt = o.getOpt("displayname");
|
383
|
-
else
|
384
|
-
cmnt = mAppName;
|
385
|
-
|
386
|
-
JSONArray json = new JSONArray();
|
387
|
-
|
388
|
-
for (int i=0; i<Integer.valueOf(o.getOpt("cloudfronts")); i++) {
|
389
|
-
Distribution dist =
|
390
|
-
mCfsvc.createDistribution(orig, null, null, cmnt, true);
|
391
|
-
String domain = "http://"+dist.getDomainName()+"/";
|
392
|
-
mCfDomains.add(domain);
|
393
|
-
json.put(domain);
|
394
|
-
}
|
395
|
-
|
396
|
-
o.setOpt("cfdomains", json.toString());
|
397
|
-
}
|
398
|
-
|
399
|
-
private void doAws() throws Exception {
|
400
|
-
try {
|
401
|
-
System.err.print("Preparing S3 bucket....................");
|
402
|
-
if (o.getOpt("awspublic") != null && o.getOpt("awsprivate") != null) {
|
403
|
-
prepareAws();
|
404
|
-
System.err.println("done.");
|
405
|
-
} else {
|
406
|
-
System.err.println("skipped.");
|
407
|
-
}
|
408
|
-
|
409
|
-
System.err.print("Creating CloudFront distributions..");
|
410
|
-
if (o.getOpt("awspublic") != null && o.getOpt("awsprivate") != null) {
|
411
|
-
doCloudFront();
|
412
|
-
System.err.println("done.");
|
413
|
-
} else {
|
414
|
-
System.err.println("skipped.");
|
415
|
-
}
|
416
|
-
|
417
|
-
System.err.print("Compiling components...................");
|
418
|
-
cacheComponentsFile();
|
419
|
-
System.err.println("done.");
|
420
|
-
|
421
|
-
System.err.print("Creating new.html template file........");
|
422
|
-
cacheNewDotHtmlFile();
|
423
|
-
System.err.println("done.");
|
424
|
-
|
425
|
-
System.err.print("Uploading jar resources................");
|
426
|
-
if (o.getOpt("awspublic") != null && o.getOpt("awsprivate") != null) {
|
427
|
-
cacheJarResourcesAws();
|
428
|
-
System.err.println("done.");
|
429
|
-
} else {
|
430
|
-
System.err.println("skipped.");
|
431
|
-
}
|
432
|
-
|
433
|
-
System.err.print("Uploading resource files...............");
|
434
|
-
if (o.getOpt("awspublic") != null && o.getOpt("awsprivate") != null) {
|
435
|
-
cacheResourcesAws(new File(o.getOpt("approot|proxypath")), "");
|
436
|
-
System.err.println("done.");
|
437
|
-
} else {
|
438
|
-
System.err.println("skipped.");
|
439
|
-
}
|
440
|
-
} catch (Exception e) {
|
441
|
-
System.err.println("fail.");
|
442
|
-
throw new Exception(e);
|
443
|
-
}
|
444
|
-
}
|
445
|
-
|
446
|
-
private void doProxyWarfile() throws Exception {
|
447
|
-
String name = mAppName;
|
448
|
-
String host = o.getOpt("proxyhost");
|
449
|
-
int port = 80;
|
450
|
-
String path = "";
|
451
|
-
|
452
|
-
if (!host.startsWith("http://"))
|
453
|
-
host = "http://"+host;
|
454
|
-
|
455
|
-
URI uri = new URI(host);
|
456
|
-
|
457
|
-
host = uri.getHost();
|
458
|
-
port = uri.getPort() == -1 ? port : uri.getPort();
|
459
|
-
path = uri.getPath() == null ? path : uri.getPath();
|
460
|
-
|
461
|
-
doProxyAnt(name, host, port, path);
|
462
|
-
}
|
463
|
-
|
464
|
-
private void doWarfile() throws Exception {
|
465
|
-
o.setOpt("devmode", "false");
|
466
|
-
doAws();
|
467
|
-
doAnt();
|
468
|
-
}
|
469
|
-
|
470
|
-
private void doStatic() throws Exception {
|
471
|
-
cacheComponentsFile();
|
472
|
-
cacheNewDotHtmlFile();
|
473
|
-
doStaticAnt();
|
474
|
-
}
|
475
|
-
|
476
|
-
private void doServer() throws Exception {
|
477
|
-
o.setOpt("devmode", "true");
|
478
|
-
Server server = new Server(Integer.valueOf(o.getOpt("port")));
|
479
|
-
|
480
|
-
cacheComponentsFile();
|
481
|
-
cacheNewDotHtmlFile();
|
482
|
-
|
483
|
-
QueuedThreadPool threadPool = new QueuedThreadPool();
|
484
|
-
threadPool.setMaxThreads(100);
|
485
|
-
server.setThreadPool(threadPool);
|
486
|
-
|
487
|
-
ContextHandlerCollection contexts = new ContextHandlerCollection();
|
488
|
-
HandlerList handlers = new HandlerList();
|
489
|
-
|
490
|
-
for (String app: mApps.keySet()) {
|
491
|
-
Log.info("Starting app `" + app + "'");
|
492
|
-
|
493
|
-
String docRoot = mApps.get(app);
|
494
|
-
|
495
|
-
String golfPath = "/" + app;
|
496
|
-
String golfRoot = docRoot;
|
497
|
-
|
498
|
-
Context cx1 = new Context(contexts, golfPath, Context.SESSIONS);
|
499
|
-
cx1.setResourceBase(golfRoot);
|
500
|
-
cx1.setDisplayName(o.getOpt("displayname"));
|
501
|
-
ServletHolder sh1 = new ServletHolder(new GolfServlet());
|
502
|
-
|
503
|
-
// manually set init parameters
|
504
|
-
sh1.setInitParameter("devmode", o.getOpt("devmode"));
|
505
|
-
sh1.setInitParameter("poolsize", o.getOpt("pool-size"));
|
506
|
-
sh1.setInitParameter("poolexpire", o.getOpt("pool-expire"));
|
507
|
-
sh1.setInitParameter("version", mAppVersion);
|
508
|
-
|
509
|
-
cx1.addServlet(sh1, "/*");
|
510
|
-
}
|
511
|
-
|
512
|
-
for (String app: mBackends.keySet()) {
|
513
|
-
Log.info("Starting app `" + app + "'");
|
514
|
-
|
515
|
-
String docRoot = mBackends.get(app);
|
516
|
-
|
517
|
-
String golfPath = "/" + app;
|
518
|
-
String golfRoot = docRoot;
|
519
|
-
|
520
|
-
WebAppContext wac = new WebAppContext();
|
521
|
-
wac.setContextPath(golfPath);
|
522
|
-
wac.setWar(docRoot);
|
523
|
-
|
524
|
-
handlers.addHandler(wac);
|
525
|
-
}
|
526
|
-
|
527
|
-
handlers.addHandler(contexts);
|
528
|
-
handlers.addHandler(new DefaultHandler());
|
529
|
-
//handlers.addHandler(new RequestLogHandler());
|
530
|
-
|
531
|
-
server.setHandler(handlers);
|
532
|
-
server.setStopAtShutdown(true);
|
533
|
-
server.setSendServerVersion(true);
|
534
|
-
|
535
|
-
server.start();
|
536
|
-
server.join();
|
537
|
-
}
|
538
|
-
|
539
|
-
public void doProxyAnt(String name, String host, int port, String path)
|
540
|
-
throws Exception {
|
541
|
-
try {
|
542
|
-
System.err.print("Building proxy warfile.................");
|
543
|
-
|
544
|
-
File dep = cacheResourceFile("depends.zip", ".zip", null);
|
545
|
-
File cls = cacheResourceFile("classes.zip", ".zip", null);
|
546
|
-
File web = getTmpFile(".xml");
|
547
|
-
File ant = getTmpFile(".xml", new File("."));
|
548
|
-
|
549
|
-
String webStr = getResourceAsString("proxy_web.xml");
|
550
|
-
String antStr = getResourceAsString("proxy_project.xml");
|
551
|
-
|
552
|
-
String dname = "HTTP proxy servlet ("+host+":"+port+"/"+path+")";
|
553
|
-
String ddesc = "HTTP proxy servlet ("+host+":"+port+"/"+path+")";
|
554
|
-
|
555
|
-
// set init parameters in the web.xml file
|
556
|
-
webStr = webStr.replaceAll("__DISPLAYNAME__", dname)
|
557
|
-
.replaceAll("__DESCRIPTION__", ddesc)
|
558
|
-
.replaceAll("__PROXY_HOST__", host)
|
559
|
-
.replaceAll("__PROXY_PORT__", String.valueOf(port))
|
560
|
-
.replaceAll("__PROXY_PATH__", path)
|
561
|
-
.replaceAll("__PROXY_QUERY__", o.getOpt("proxyparams"))
|
562
|
-
.replaceAll("__MAX_FILE_UPLOAD_SIZE__",
|
563
|
-
o.getOpt("proxymaxupload"));
|
564
|
-
|
565
|
-
// setup the ant build file
|
566
|
-
antStr = antStr.replaceAll("__OUTFILE__", name + ".war")
|
567
|
-
.replaceAll("__WEB.XML__", web.getAbsolutePath())
|
568
|
-
.replaceAll("__DEPENDENCIES.ZIP__", dep.getAbsolutePath())
|
569
|
-
.replaceAll("__CLASSES.ZIP__", cls.getAbsolutePath());
|
570
|
-
|
571
|
-
cacheStringFile(webStr, "", web);
|
572
|
-
cacheStringFile(antStr, "", ant);
|
573
|
-
|
574
|
-
Project project = new Project();
|
575
|
-
project.init();
|
576
|
-
project.setUserProperty("ant.file" , ant.getAbsolutePath());
|
577
|
-
ProjectHelper.configureProject(project, ant);
|
578
|
-
project.executeTarget("war");
|
579
|
-
|
580
|
-
System.err.println("done.");
|
581
|
-
} catch (Exception e) {
|
582
|
-
System.err.println("fail.");
|
583
|
-
throw new Exception(e);
|
584
|
-
}
|
585
|
-
}
|
586
|
-
|
587
|
-
public void doStaticAnt() throws Exception {
|
588
|
-
try {
|
589
|
-
System.err.print("Building static............................");
|
590
|
-
|
591
|
-
File res = cacheResourceFile("resources.zip", ".zip", null);
|
592
|
-
File ant = getTmpFile(".xml", new File("."));
|
593
|
-
|
594
|
-
String antStr = getResourceAsString("static_project.xml");
|
595
|
-
|
596
|
-
// setup the ant build file
|
597
|
-
antStr = antStr.replaceAll("__OUTFILE__", o.getOpt("static"))
|
598
|
-
.replaceAll("__RESOURCES.ZIP__", res.getAbsolutePath())
|
599
|
-
.replaceAll("__APPROOT__",
|
600
|
-
o.getOpt("approot|proxypath"));
|
601
|
-
|
602
|
-
cacheStringFile(antStr, "", ant);
|
603
|
-
|
604
|
-
Project project = new Project();
|
605
|
-
project.init();
|
606
|
-
project.setUserProperty("ant.file" , ant.getAbsolutePath());
|
607
|
-
ProjectHelper.configureProject(project, ant);
|
608
|
-
project.executeTarget("static");
|
609
|
-
|
610
|
-
System.err.println("done.");
|
611
|
-
} catch (Exception e) {
|
612
|
-
System.err.println("fail.");
|
613
|
-
throw new Exception(e);
|
614
|
-
}
|
615
|
-
}
|
616
|
-
|
617
|
-
public void doAnt() throws Exception {
|
618
|
-
try {
|
619
|
-
System.err.print("Building warfile...........................");
|
620
|
-
|
621
|
-
File dep = cacheResourceFile("depends.zip", ".zip", null);
|
622
|
-
File res = cacheResourceFile("resources.zip", ".zip", null);
|
623
|
-
File cls = cacheResourceFile("classes.zip", ".zip", null);
|
624
|
-
File web = getTmpFile(".xml");
|
625
|
-
File ant = getTmpFile(".xml", new File("."));
|
626
|
-
|
627
|
-
String webStr = getResourceAsString("web.xml");
|
628
|
-
String antStr = getResourceAsString("project.xml");
|
629
|
-
|
630
|
-
// set init parameters in the web.xml file
|
631
|
-
webStr = webStr.replaceAll("__DISPLAYNAME__", o.getOpt("displayname"))
|
632
|
-
.replaceAll("__DESCRIPTION__", o.getOpt("description"))
|
633
|
-
.replaceAll("__POOLSIZE__", o.getOpt("pool-size"))
|
634
|
-
.replaceAll("__POOLEXPIRE__", o.getOpt("pool-expire"))
|
635
|
-
.replaceAll("__GOLF_VERSION__", mAppVersion)
|
636
|
-
.replaceAll("__DEVMODE__", o.getOpt("devmode"));
|
637
|
-
|
638
|
-
// setup the ant build file
|
639
|
-
antStr = antStr.replaceAll("__OUTFILE__", mAppName + ".war")
|
640
|
-
.replaceAll("__WEB.XML__", web.getAbsolutePath())
|
641
|
-
.replaceAll("__RESOURCES.ZIP__", res.getAbsolutePath())
|
642
|
-
.replaceAll("__APPROOT__",
|
643
|
-
o.getOpt("approot|proxypath"))
|
644
|
-
.replaceAll("__DEPENDENCIES.ZIP__", dep.getAbsolutePath())
|
645
|
-
.replaceAll("__CLASSES.ZIP__", cls.getAbsolutePath());
|
646
|
-
|
647
|
-
cacheStringFile(webStr, "", web);
|
648
|
-
cacheStringFile(antStr, "", ant);
|
649
|
-
|
650
|
-
Project project = new Project();
|
651
|
-
project.init();
|
652
|
-
project.setUserProperty("ant.file" , ant.getAbsolutePath());
|
653
|
-
ProjectHelper.configureProject(project, ant);
|
654
|
-
project.executeTarget("war");
|
655
|
-
|
656
|
-
System.err.println("done.");
|
657
|
-
} catch (Exception e) {
|
658
|
-
System.err.println("fail.");
|
659
|
-
throw new Exception(e);
|
660
|
-
}
|
661
|
-
}
|
662
|
-
|
663
|
-
public static File getTmpFile(String ext) throws IOException {
|
664
|
-
File f = File.createTempFile("golf_deploy.", ext);
|
665
|
-
f.deleteOnExit();
|
666
|
-
return f;
|
667
|
-
}
|
668
|
-
|
669
|
-
public static File getTmpFile(String ext, File dir) throws IOException {
|
670
|
-
File f = File.createTempFile("golf_deploy.", ext, dir);
|
671
|
-
f.deleteOnExit();
|
672
|
-
return f;
|
673
|
-
}
|
674
|
-
|
675
|
-
public String getResourceAsString(String name) throws IOException {
|
676
|
-
JavaResource res = new JavaResource(name, null);
|
677
|
-
BufferedReader in =
|
678
|
-
new BufferedReader(new InputStreamReader(res.getInputStream()));
|
679
|
-
StringBuilder s = new StringBuilder();
|
680
|
-
|
681
|
-
String tmp;
|
682
|
-
while((tmp = in.readLine()) != null)
|
683
|
-
s.append(tmp).append("\n");
|
684
|
-
|
685
|
-
return s.toString();
|
686
|
-
}
|
687
|
-
|
688
|
-
public File cacheResourceFile(String name, String ext, File f)
|
689
|
-
throws IOException {
|
690
|
-
name = name.replaceFirst("^/+", "");
|
691
|
-
byte[] b = new byte[BUF_SIZE];
|
692
|
-
|
693
|
-
if (f == null)
|
694
|
-
f = getTmpFile(ext);
|
695
|
-
|
696
|
-
BufferedInputStream in = new BufferedInputStream(
|
697
|
-
getClass().getClassLoader().getResourceAsStream(name));
|
698
|
-
BufferedOutputStream out =
|
699
|
-
new BufferedOutputStream(new FileOutputStream(f));
|
700
|
-
|
701
|
-
int nread;
|
702
|
-
while ((nread = in.read(b)) != -1)
|
703
|
-
out.write(b, 0, nread);
|
704
|
-
out.close();
|
705
|
-
|
706
|
-
return f;
|
707
|
-
}
|
708
|
-
|
709
|
-
public static File cacheStringFile(String text, String ext, File f)
|
710
|
-
throws IOException {
|
711
|
-
if (f == null)
|
712
|
-
f = getTmpFile(ext);
|
713
|
-
|
714
|
-
PrintWriter out = new PrintWriter(new FileOutputStream(f));
|
715
|
-
out.print(text);
|
716
|
-
out.close();
|
717
|
-
|
718
|
-
return f;
|
719
|
-
}
|
720
|
-
|
721
|
-
private void cacheStringAws(String str, String key) throws Exception {
|
722
|
-
cacheStringAws(str, key, null);
|
723
|
-
}
|
724
|
-
|
725
|
-
private void cacheStringAws(String str, String key, String type)
|
726
|
-
throws Exception {
|
727
|
-
key = key.replaceFirst("^/+", "");
|
728
|
-
File f = cacheStringFile(str, key.replaceFirst("^.*/", ""), null);
|
729
|
-
cacheFileAws(f, key, type);
|
730
|
-
}
|
731
|
-
|
732
|
-
private void cacheFileAws(File file, String key) throws Exception {
|
733
|
-
cacheFileAws(file, key, null);
|
734
|
-
}
|
735
|
-
|
736
|
-
private void cacheFileAws(File file, String key, String type)
|
737
|
-
throws Exception {
|
738
|
-
key = key.replaceFirst("^/+", "");
|
739
|
-
|
740
|
-
if (key.endsWith(".js") || key.endsWith(".css") || key.endsWith(".html")) {
|
741
|
-
BufferedReader inBr = new BufferedReader(new FileReader(file));
|
742
|
-
StringBuilder sb = new StringBuilder();
|
743
|
-
|
744
|
-
String s;
|
745
|
-
while ((s = inBr.readLine()) != null)
|
746
|
-
sb.append(s).append("\n");
|
747
|
-
|
748
|
-
String src = sb.toString();
|
749
|
-
|
750
|
-
if (key.endsWith(".js"))
|
751
|
-
src = injectCloudfrontUrl(compressJs(src, key));
|
752
|
-
else if (key.endsWith(".css"))
|
753
|
-
src = injectCloudfrontUrl(compressCss(src, key));
|
754
|
-
else if (key.endsWith(".html"))
|
755
|
-
src = injectCloudfrontUrl(src);
|
756
|
-
|
757
|
-
file.delete();
|
758
|
-
|
759
|
-
PrintWriter out = new PrintWriter(new FileWriter(file));
|
760
|
-
out.print(src);
|
761
|
-
out.close();
|
762
|
-
}
|
763
|
-
|
764
|
-
S3Object obj = new S3Object(mBucket, file);
|
765
|
-
obj.setKey(key);
|
766
|
-
if (type == null)
|
767
|
-
obj.setContentType(GolfResource.MimeMapping.lookup(key));
|
768
|
-
else
|
769
|
-
obj.setContentType(type);
|
770
|
-
obj.setAcl(mAcl);
|
771
|
-
mS3svc.putObject(mBucket, obj);
|
772
|
-
}
|
773
|
-
|
774
|
-
private void cacheJarResourcesAws() throws Exception {
|
775
|
-
String[] resources = {
|
776
|
-
JSDETECT_HTML,
|
777
|
-
JQUERY_JS,
|
778
|
-
JQUERY_HIST_JS,
|
779
|
-
JQUERY_GOLF_JS,
|
780
|
-
LOADING_GIF
|
781
|
-
};
|
782
|
-
for (String res : resources)
|
783
|
-
cacheJarResourceAws("/"+res);
|
784
|
-
}
|
785
|
-
|
786
|
-
private void cacheJarResourceAws(String name) throws Exception {
|
787
|
-
File f = cacheResourceFile(name, name.replaceAll("^.*/", ""), null);
|
788
|
-
cacheFileAws(f, name.replaceFirst("^/+", ""));
|
789
|
-
}
|
790
|
-
|
791
|
-
public static void cacheNewDotHtmlFile() throws Exception {
|
792
|
-
String newHtmlStr = getNewDotHtmlString(false);
|
793
|
-
File f = new File(o.getOpt("approot|proxypath"), NEW_HTML);
|
794
|
-
if (f.exists())
|
795
|
-
f.delete();
|
796
|
-
f.deleteOnExit();
|
797
|
-
PrintWriter out = new PrintWriter(new FileWriter(f));
|
798
|
-
out.print(newHtmlStr);
|
799
|
-
out.close();
|
800
|
-
|
801
|
-
newHtmlStr = getNewDotHtmlString(true);
|
802
|
-
f = new File(o.getOpt("approot|proxypath"), NEW_FC_HTML);
|
803
|
-
if (f.exists())
|
804
|
-
f.delete();
|
805
|
-
f.deleteOnExit();
|
806
|
-
out = new PrintWriter(new FileWriter(f));
|
807
|
-
out.print(newHtmlStr);
|
808
|
-
out.close();
|
809
|
-
}
|
810
|
-
|
811
|
-
public static String getNewDotHtmlString(boolean fc) throws Exception {
|
812
|
-
File cwd = new File(o.getOpt("approot|proxypath"));
|
813
|
-
boolean st = o.getOpt("static") != null;
|
814
|
-
|
815
|
-
String newHtmlSrc = st ? NEW_ST_HTML : NEW_HTML;
|
816
|
-
|
817
|
-
GolfResource newHtml = new GolfResource(cwd, newHtmlSrc);
|
818
|
-
GolfResource headHtml = new GolfResource(cwd, HEAD_HTML);
|
819
|
-
GolfResource noscriptHtml =
|
820
|
-
new GolfResource(cwd,
|
821
|
-
(fc ? NOSCRIPT_FC_HTML : (st ? NOSCRIPT_ST_HTML : NOSCRIPT_HTML)));
|
822
|
-
|
823
|
-
if (mNewHtml == null)
|
824
|
-
mNewHtml = newHtml.toString();
|
825
|
-
|
826
|
-
String newStr = mNewHtml;
|
827
|
-
String headStr = headHtml.toString();
|
828
|
-
String noscriptStr = noscriptHtml.toString();
|
829
|
-
|
830
|
-
JSONArray backends = new JSONArray(mBackends.keySet());
|
831
|
-
|
832
|
-
String result = newStr;
|
833
|
-
result = result.replaceFirst("\n *__HEAD_HTML__ *\n *",
|
834
|
-
" custom head section -->\n"+headStr+
|
835
|
-
" <!-- end custom head section ");
|
836
|
-
result = result.replaceFirst("\n *__NOSCRIPT_HTML__ *\n *",
|
837
|
-
" custom noscript section -->\n"+noscriptStr+
|
838
|
-
" <!-- end custom noscript section ");
|
839
|
-
result = result.replaceFirst("__DEVMODE__",
|
840
|
-
Boolean.toString(o.getFlag("devmode")));
|
841
|
-
result = result.replaceFirst("__RESTBACKENDS__", backends.toString());
|
842
|
-
result = result.replaceFirst("__CLOUDFRONTDOMAIN__", o.getOpt("cfdomains"));
|
843
|
-
|
844
|
-
if (st)
|
845
|
-
result = result.replaceAll("\\?path=/*", "");
|
846
|
-
|
847
|
-
return result;
|
848
|
-
}
|
849
|
-
|
850
|
-
public static void cacheComponentsFile() throws Exception {
|
851
|
-
File f = new File(o.getOpt("approot|proxypath"), COMPONENTS_JS);
|
852
|
-
if (f.exists())
|
853
|
-
f.delete();
|
854
|
-
f.deleteOnExit();
|
855
|
-
PrintWriter out = new PrintWriter(new FileWriter(f));
|
856
|
-
out.print(getComponentsString());
|
857
|
-
out.close();
|
858
|
-
}
|
859
|
-
|
860
|
-
private void cacheComponentsAws() throws Exception {
|
861
|
-
cacheStringAws(getComponentsString(), COMPONENTS_JS, "text/javascript");
|
862
|
-
}
|
863
|
-
|
864
|
-
private static String getComponentsString() throws Exception {
|
865
|
-
String ret =
|
866
|
-
"jQuery.golf.components=" + getComponentsJSON(null, null) + ";" +
|
867
|
-
"jQuery.golf.res=" + getResourcesJSON(null, null) + ";" +
|
868
|
-
"jQuery.golf.plugins=" + getScriptsJSON(DIR_MODULES, null) + ";" +
|
869
|
-
"jQuery.golf.scripts=" + getScriptsJSON(DIR_SCRIPTS, null) + ";" +
|
870
|
-
"jQuery.golf.styles=" + getStylesJSON(DIR_STYLES, null) + ";" +
|
871
|
-
"jQuery.golf.setupComponents();";
|
872
|
-
if (o.getOpt("static") != null)
|
873
|
-
ret = ret.replaceAll("\\?path=/*", "");
|
874
|
-
return ret;
|
875
|
-
}
|
876
|
-
|
877
|
-
private static String getResourcesJSON(String path, JSONObject json)
|
878
|
-
throws Exception {
|
879
|
-
boolean isNew = false;
|
880
|
-
|
881
|
-
if (path == null) path = "";
|
882
|
-
if (json == null) {
|
883
|
-
json = new JSONObject();
|
884
|
-
isNew = true;
|
885
|
-
}
|
886
|
-
|
887
|
-
File file = new File(new File(o.getOpt("approot|proxypath")), path);
|
888
|
-
|
889
|
-
if (!file.getName().startsWith(".") || file.getName().equals(".")
|
890
|
-
|| file.getName().equals("..")) {
|
891
|
-
if (file.isFile()) {
|
892
|
-
String keyName = path.replaceFirst("^/+", "");
|
893
|
-
json.put(keyName.replaceFirst("^.*/", ""), "?path=" + keyName);
|
894
|
-
} else if (file.isDirectory()) {
|
895
|
-
JSONObject dir;
|
896
|
-
if (!isNew) {
|
897
|
-
dir = new JSONObject();
|
898
|
-
json.put(file.getName(), dir);
|
899
|
-
} else {
|
900
|
-
dir = json;
|
901
|
-
}
|
902
|
-
for (String f : file.list()) {
|
903
|
-
String ppath = path + "/" + f;
|
904
|
-
getResourcesJSON(path+"/"+f, dir);
|
905
|
-
}
|
906
|
-
}
|
907
|
-
}
|
908
|
-
|
909
|
-
// these are system files that are of no use to a golf app
|
910
|
-
for (String s : new String[] {
|
911
|
-
DIR_COMPONENTS,
|
912
|
-
DIR_SCRIPTS,
|
913
|
-
DIR_STYLES,
|
914
|
-
ERROR_HTML,
|
915
|
-
HEAD_HTML,
|
916
|
-
NEW_HTML,
|
917
|
-
NEW_FC_HTML,
|
918
|
-
NOSCRIPT_FC_HTML,
|
919
|
-
NOSCRIPT_HTML,
|
920
|
-
FORCEPROXY_TXT,
|
921
|
-
FORCECLIENT_TXT,
|
922
|
-
FORCEBOT_TXT,
|
923
|
-
COMPONENTS_JS,
|
924
|
-
CONTROLLER_JS
|
925
|
-
}) json.remove(s);
|
926
|
-
|
927
|
-
return json.toString();
|
928
|
-
}
|
929
|
-
|
930
|
-
private static String getComponentsJSON(String path, JSONObject json)
|
931
|
-
throws Exception {
|
932
|
-
if (path == null) path = "";
|
933
|
-
if (json == null) json = new JSONObject();
|
934
|
-
|
935
|
-
File file =
|
936
|
-
new File(new File(o.getOpt("approot|proxypath"), DIR_COMPONENTS), path);
|
937
|
-
|
938
|
-
if (!file.getName().startsWith(".")) {
|
939
|
-
if (file.isFile()) {
|
940
|
-
if (path.endsWith(".html")) {
|
941
|
-
String cmpName = path.replaceFirst("\\.html$", "");
|
942
|
-
JSONObject cmpJson = processComponent(cmpName);
|
943
|
-
json.put((String) cmpJson.get("name"), cmpJson);
|
944
|
-
}
|
945
|
-
} else if (file.isDirectory() && !file.getName().endsWith(".res")) {
|
946
|
-
for (String f : file.list()) {
|
947
|
-
String ppath = path + "/" + f;
|
948
|
-
getComponentsJSON(path+"/"+f, json);
|
949
|
-
}
|
950
|
-
}
|
951
|
-
}
|
952
|
-
|
953
|
-
return json.toString();
|
954
|
-
}
|
955
|
-
|
956
|
-
private static String getScriptsJSON(String path, JSONObject json)
|
957
|
-
throws Exception {
|
958
|
-
if (path == null) path = "";
|
959
|
-
if (json == null) json = new JSONObject();
|
960
|
-
|
961
|
-
File file = new File(o.getOpt("approot|proxypath"), path);
|
962
|
-
|
963
|
-
if (!file.getName().startsWith(".")) {
|
964
|
-
if (file.isFile()) {
|
965
|
-
if (path.endsWith(".js")) {
|
966
|
-
String cmpName = path.replaceFirst("\\.js$", "");
|
967
|
-
String keyName =
|
968
|
-
cmpName.replaceFirst("^[a-z]+/+", "");
|
969
|
-
json.put(keyName, processScript(cmpName).put("name", keyName));
|
970
|
-
}
|
971
|
-
} else if (file.isDirectory()) {
|
972
|
-
for (String f : file.list()) {
|
973
|
-
String ppath = path + "/" + f;
|
974
|
-
getScriptsJSON(path+"/"+f, json);
|
975
|
-
}
|
976
|
-
}
|
977
|
-
}
|
978
|
-
|
979
|
-
return json.toString();
|
980
|
-
}
|
981
|
-
|
982
|
-
private static String getStylesJSON(String path, JSONObject json)
|
983
|
-
throws Exception {
|
984
|
-
if (path == null) path = "";
|
985
|
-
if (json == null) json = new JSONObject();
|
986
|
-
|
987
|
-
File file = new File(o.getOpt("approot|proxypath"), path);
|
988
|
-
|
989
|
-
if (!file.getName().startsWith(".")) {
|
990
|
-
if (file.isFile()) {
|
991
|
-
if (path.endsWith(".css")) {
|
992
|
-
String cmpName = path.replaceFirst("\\.css$", "");
|
993
|
-
String keyName =
|
994
|
-
cmpName.replaceFirst("^[a-z]+/+", "").replace("/", ".");
|
995
|
-
json.put(keyName, processStyle(cmpName).put("name", keyName));
|
996
|
-
}
|
997
|
-
} else if (file.isDirectory()) {
|
998
|
-
for (String f : file.list()) {
|
999
|
-
String ppath = path + "/" + f;
|
1000
|
-
getStylesJSON(path+"/"+f, json);
|
1001
|
-
}
|
1002
|
-
}
|
1003
|
-
}
|
1004
|
-
|
1005
|
-
return json.toString();
|
1006
|
-
}
|
1007
|
-
|
1008
|
-
public static JSONObject processComponent(String name) throws Exception {
|
1009
|
-
name = name.replaceFirst("^/+", "");
|
1010
|
-
String shortName = name.replaceFirst("(^|/)[^/]+/([^/]+)$", "$1$2");
|
1011
|
-
String className = shortName.replace('/', '-');
|
1012
|
-
String classPath = shortName.replace('/', '.');
|
1013
|
-
File cwd = new File(o.getOpt("approot|proxypath"), DIR_COMPONENTS);
|
1014
|
-
|
1015
|
-
String html = name + ".html";
|
1016
|
-
String res = name + ".res";
|
1017
|
-
|
1018
|
-
GolfResource htmlRes = new GolfResource(cwd, html);
|
1019
|
-
File resDir = new File(cwd, res);
|
1020
|
-
|
1021
|
-
JSONObject resObj =
|
1022
|
-
processComponentRes(resDir, cwd, resDir, null);
|
1023
|
-
|
1024
|
-
String resUriPath = "?path=components/"+getRelativePath(resDir, cwd);
|
1025
|
-
|
1026
|
-
String htmlStr = htmlRes.toString().replaceAll("\\?resource=", resUriPath);
|
1027
|
-
|
1028
|
-
String pat1 = "</script>";
|
1029
|
-
String pat2 = "<script +([^>]* +)*type *= *\"text/golf\"( [^>]*)*>";
|
1030
|
-
|
1031
|
-
String cmpJs1 = Pattern
|
1032
|
-
.compile("^(.*"+pat2+").*$", Pattern.DOTALL)
|
1033
|
-
.matcher(htmlStr)
|
1034
|
-
.replaceFirst("$1");
|
1035
|
-
|
1036
|
-
String cmpJs2 = Pattern
|
1037
|
-
.compile(pat1+".*$", Pattern.DOTALL)
|
1038
|
-
.matcher(
|
1039
|
-
Pattern
|
1040
|
-
.compile("^.*"+pat2, Pattern.DOTALL)
|
1041
|
-
.matcher(htmlStr)
|
1042
|
-
.replaceFirst(""))
|
1043
|
-
.replaceFirst("");
|
1044
|
-
|
1045
|
-
String cmpJs3 = Pattern
|
1046
|
-
.compile("^.*("+pat1+".*)$", Pattern.DOTALL)
|
1047
|
-
.matcher(
|
1048
|
-
Pattern
|
1049
|
-
.compile("^.*"+pat2, Pattern.DOTALL)
|
1050
|
-
.matcher(htmlStr)
|
1051
|
-
.replaceFirst(""))
|
1052
|
-
.replaceFirst("$1");
|
1053
|
-
|
1054
|
-
File jsFile = cacheStringFile(cmpJs2, "js", null);
|
1055
|
-
cmpJs2 = processComponentJs(cmpJs2, jsFile.getCanonicalPath());
|
1056
|
-
|
1057
|
-
htmlStr = cmpJs1 + "\n" + cmpJs2 + "\n" + cmpJs3;
|
1058
|
-
|
1059
|
-
JSONObject json = new JSONObject()
|
1060
|
-
.put("name", classPath)
|
1061
|
-
.put("html", htmlStr)
|
1062
|
-
.put("res", resObj);
|
1063
|
-
|
1064
|
-
return json;
|
1065
|
-
}
|
1066
|
-
|
1067
|
-
public static JSONObject processScript(String name) throws Exception {
|
1068
|
-
String dir = name.replaceAll("/.*$", "");
|
1069
|
-
name = name.replaceFirst("^[a-z]+/+", "");
|
1070
|
-
|
1071
|
-
File cwd = new File(o.getOpt("approot|proxypath"), dir);
|
1072
|
-
String js = name + ".js";
|
1073
|
-
GolfResource jsRes = new GolfResource(cwd, js);
|
1074
|
-
String jsStr = processComponentJs(jsRes.toString(), (new File(cwd, js)).getCanonicalPath());
|
1075
|
-
JSONObject json = new JSONObject().put("js", jsStr);
|
1076
|
-
|
1077
|
-
return json;
|
1078
|
-
}
|
1079
|
-
|
1080
|
-
public static JSONObject processStyle(String name) throws Exception {
|
1081
|
-
String dir = name.replaceAll("/.*$", "");
|
1082
|
-
name = name.replaceFirst("^[a-z]+/+", "");
|
1083
|
-
|
1084
|
-
File cwd = new File(o.getOpt("approot|proxypath"), dir);
|
1085
|
-
// FIXME: only in non-devmode should css be messed with like this
|
1086
|
-
//String css = (new GolfResource(cwd, name+".css")).toString()
|
1087
|
-
// .replaceAll(" *\n *", " ");
|
1088
|
-
String css = (new GolfResource(cwd, name+".css")).toString();
|
1089
|
-
JSONObject json = new JSONObject().put("css", css);
|
1090
|
-
|
1091
|
-
return json;
|
1092
|
-
}
|
1093
|
-
|
1094
|
-
public static String injectCloudfrontUrl(String text) {
|
1095
|
-
String result = text;
|
1096
|
-
if (mCfDomains.size() > 0)
|
1097
|
-
while (! result.equals(result = result.replaceFirst("\\?path=/*", mCfDomains.next())));
|
1098
|
-
return result;
|
1099
|
-
}
|
1100
|
-
|
1101
|
-
public static JSONObject processComponentRes(File f, File uriBase,
|
1102
|
-
File refBase, JSONObject res) throws URISyntaxException, JSONException {
|
1103
|
-
boolean isNew = false;
|
1104
|
-
|
1105
|
-
if (!f.exists() || f.getName().startsWith("."))
|
1106
|
-
return null;
|
1107
|
-
|
1108
|
-
if (res == null) {
|
1109
|
-
res = new JSONObject();
|
1110
|
-
isNew = true;
|
1111
|
-
}
|
1112
|
-
|
1113
|
-
String ref = getRelativePath(f, refBase);
|
1114
|
-
|
1115
|
-
if (f.isDirectory()) {
|
1116
|
-
JSONObject dir;
|
1117
|
-
if (!isNew) {
|
1118
|
-
dir = new JSONObject();
|
1119
|
-
res.put(ref.replaceFirst("/+$", ""), dir);
|
1120
|
-
} else {
|
1121
|
-
dir = res;
|
1122
|
-
}
|
1123
|
-
for (String s : f.list())
|
1124
|
-
processComponentRes(new File(f, s), uriBase, refBase, dir);
|
1125
|
-
} else {
|
1126
|
-
String rel = getRelativePath(f, uriBase);
|
1127
|
-
res.put(ref.replaceFirst("^.*/", ""), "?path=components/"+rel);
|
1128
|
-
}
|
1129
|
-
return res;
|
1130
|
-
}
|
1131
|
-
|
1132
|
-
public static String processComponentCss(String text, String className,
|
1133
|
-
String fileName) {
|
1134
|
-
String result = text;
|
1135
|
-
|
1136
|
-
// remove newlines
|
1137
|
-
result = result.replaceAll("[\\r\\n\\s]+", " ");
|
1138
|
-
// remove comments
|
1139
|
-
result = result.replaceAll("/\\*.*\\*/", "");
|
1140
|
-
result = result.trim();
|
1141
|
-
|
1142
|
-
if (!o.getFlag("devmode"))
|
1143
|
-
result = compressCss(result, fileName);
|
1144
|
-
|
1145
|
-
return result;
|
1146
|
-
}
|
1147
|
-
|
1148
|
-
public static String compressCss(String in, String filename) {
|
1149
|
-
if (!o.getFlag("compress-css"))
|
1150
|
-
return in;
|
1151
|
-
|
1152
|
-
String result = in;
|
1153
|
-
try {
|
1154
|
-
CssCompressor css = new CssCompressor(new StringReader(in));
|
1155
|
-
|
1156
|
-
StringWriter out = new StringWriter();
|
1157
|
-
css.compress(out, -1);
|
1158
|
-
result = out.toString();
|
1159
|
-
} catch (Exception e) {
|
1160
|
-
System.err.println("golf: "+filename+" not compressed: "+e.toString());
|
1161
|
-
}
|
1162
|
-
return result;
|
1163
|
-
}
|
1164
|
-
|
1165
|
-
public static String processComponentJs(String text, String filename)
|
1166
|
-
throws Exception {
|
1167
|
-
String result = text;
|
1168
|
-
|
1169
|
-
if (text.startsWith("#!")) {
|
1170
|
-
result = "";
|
1171
|
-
|
1172
|
-
ArrayList<String> shbang = parseAsShell(
|
1173
|
-
text.substring(0, text.indexOf("\n"))
|
1174
|
-
.replaceFirst("^#![\\s]*", "")
|
1175
|
-
.replaceFirst("[\\s]*$", " ")
|
1176
|
-
);
|
1177
|
-
|
1178
|
-
shbang.add(filename);
|
1179
|
-
|
1180
|
-
Process p =
|
1181
|
-
Runtime.getRuntime().exec(shbang.toArray(new String[shbang.size()]));
|
1182
|
-
|
1183
|
-
int exitVal = p.waitFor();
|
1184
|
-
|
1185
|
-
BufferedReader br = new BufferedReader(new InputStreamReader(
|
1186
|
-
(exitVal == 0 ? p.getInputStream() : p.getErrorStream())));
|
1187
|
-
|
1188
|
-
while ((text = br.readLine()) != null)
|
1189
|
-
result += text + "\n";
|
1190
|
-
|
1191
|
-
if (exitVal != 0)
|
1192
|
-
throw new Exception(result);
|
1193
|
-
}
|
1194
|
-
|
1195
|
-
if (!o.getFlag("devmode"))
|
1196
|
-
result = compressJs(result, filename);
|
1197
|
-
|
1198
|
-
return result;
|
1199
|
-
}
|
1200
|
-
|
1201
|
-
private static String compressJs(String in, String filename) {
|
1202
|
-
if (!o.getFlag("compress-js"))
|
1203
|
-
return in;
|
1204
|
-
|
1205
|
-
String result = in;
|
1206
|
-
|
1207
|
-
try {
|
1208
|
-
final String cn = filename;
|
1209
|
-
|
1210
|
-
ErrorReporter errz = new ErrorReporter() {
|
1211
|
-
public void warning(String message, String sourceName,
|
1212
|
-
int line, String lineSource, int lineOffset) {
|
1213
|
-
if (line < 0) {
|
1214
|
-
System.err.println(cn+": warning:\n"+message+"\n");
|
1215
|
-
} else {
|
1216
|
-
System.err.println(cn+": warning:\n"+line+':'+lineOffset+
|
1217
|
-
':'+message+"\n");
|
1218
|
-
}
|
1219
|
-
}
|
1220
|
-
public void error(String message, String sourceName,
|
1221
|
-
int line, String lineSource, int lineOffset) {
|
1222
|
-
if (line < 0) {
|
1223
|
-
System.err.println(cn+": error:\n"+message+"\n");
|
1224
|
-
} else {
|
1225
|
-
System.err.println(cn+": error:\n"+line+':'+lineOffset+
|
1226
|
-
':'+message+"\n");
|
1227
|
-
}
|
1228
|
-
}
|
1229
|
-
public EvaluatorException runtimeError(String message,
|
1230
|
-
String sourceName, int line, String lineSource, int lineOffset) {
|
1231
|
-
error(message, sourceName, line, lineSource, lineOffset);
|
1232
|
-
return new EvaluatorException(message);
|
1233
|
-
}
|
1234
|
-
};
|
1235
|
-
|
1236
|
-
JavaScriptCompressor js =
|
1237
|
-
new JavaScriptCompressor(new StringReader(in), errz);
|
1238
|
-
|
1239
|
-
StringWriter out = new StringWriter();
|
1240
|
-
js.compress(out, -1, false, false, false, true);
|
1241
|
-
result = out.toString().replace("\n", "\\n");
|
1242
|
-
} catch (Exception e) {
|
1243
|
-
System.err.println("golf: "+filename+" not compressed: "+e.toString());
|
1244
|
-
}
|
1245
|
-
return result;
|
1246
|
-
}
|
1247
|
-
|
1248
|
-
private void cacheResourcesAws(File file, String path) throws Exception {
|
1249
|
-
if (path.startsWith("/.") ||
|
1250
|
-
path.equals("/"+HEAD_HTML) ||
|
1251
|
-
path.equals("/"+NOSCRIPT_HTML))
|
1252
|
-
return;
|
1253
|
-
|
1254
|
-
if (file.isFile()) {
|
1255
|
-
cacheFileAws(file, path);
|
1256
|
-
} else if (file.isDirectory()) {
|
1257
|
-
for (String f : file.list()) {
|
1258
|
-
String ppath = path + (path.endsWith("/") ? f : "/" + f);
|
1259
|
-
cacheResourcesAws(new File(file, f), ppath);
|
1260
|
-
}
|
1261
|
-
}
|
1262
|
-
}
|
1263
|
-
|
1264
|
-
private static String getRelativePath(File f, File base)
|
1265
|
-
throws URISyntaxException {
|
1266
|
-
URI u1 = new URI(base.toURI().toString());
|
1267
|
-
URI u2 = new URI(f.toURI().toString());
|
1268
|
-
return u1.relativize(u2).toString();
|
1269
|
-
}
|
1270
|
-
|
1271
|
-
public static ArrayList<String> parseAsShell(String line) throws Exception {
|
1272
|
-
ArrayList<String> ret = new ArrayList<String>();
|
1273
|
-
|
1274
|
-
StreamTokenizer st = new StreamTokenizer(new StringReader(line));
|
1275
|
-
st.resetSyntax();
|
1276
|
-
st.wordChars(33, 126);
|
1277
|
-
st.whitespaceChars(' ', ' ');
|
1278
|
-
st.quoteChar('"');
|
1279
|
-
st.quoteChar('\'');
|
1280
|
-
|
1281
|
-
while (st.nextToken() != StreamTokenizer.TT_EOF)
|
1282
|
-
ret.add(st.sval);
|
1283
|
-
|
1284
|
-
return ret;
|
1285
|
-
}
|
1286
|
-
|
1287
|
-
private String randName(String base) {
|
1288
|
-
String result =
|
1289
|
-
base + "-" + (new UID()).toString().replaceFirst("^.*:([^:]+):.*$", "$1");
|
1290
|
-
return result;
|
1291
|
-
}
|
1292
|
-
|
1293
|
-
private void usage(String error) {
|
1294
|
-
if (error != null)
|
1295
|
-
System.err.println("golf: "+error);
|
1296
|
-
|
1297
|
-
o.printUsage();
|
1298
|
-
}
|
1299
|
-
}
|