golf 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/golf.gemspec +1 -1
  2. data/lib/golf/version.rb +1 -1
  3. metadata +1 -121
  4. data/golf-java/README.markdown +0 -41
  5. data/golf-java/THANKS.markdown +0 -14
  6. data/golf-java/build/classes.zip +0 -0
  7. data/golf-java/build/com/thinkminimo/golf/GolfResource$MimeMapping$MimeMappingSingleton.class +0 -0
  8. data/golf-java/build/com/thinkminimo/golf/GolfResource$MimeMapping.class +0 -0
  9. data/golf-java/build/com/thinkminimo/golf/GolfResource.class +0 -0
  10. data/golf-java/build/com/thinkminimo/golf/GolfServlet$1.class +0 -0
  11. data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfContext.class +0 -0
  12. data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfParams.class +0 -0
  13. data/golf-java/build/com/thinkminimo/golf/GolfServlet$GolfSession.class +0 -0
  14. data/golf-java/build/com/thinkminimo/golf/GolfServlet$PermanentRedirectException.class +0 -0
  15. data/golf-java/build/com/thinkminimo/golf/GolfServlet$RedirectException.class +0 -0
  16. data/golf-java/build/com/thinkminimo/golf/GolfServlet$StoredJSVM.class +0 -0
  17. data/golf-java/build/com/thinkminimo/golf/GolfServlet.class +0 -0
  18. data/golf-java/build/com/thinkminimo/golf/JsonpTunnel.class +0 -0
  19. data/golf-java/build/com/thinkminimo/golf/Main$1.class +0 -0
  20. data/golf-java/build/com/thinkminimo/golf/Main$RingList.class +0 -0
  21. data/golf-java/build/com/thinkminimo/golf/Main.class +0 -0
  22. data/golf-java/build/com/thinkminimo/golf/ProxyServlet.class +0 -0
  23. data/golf-java/build/com/yahoo/platform/yui/compressor/CssCompressor.class +0 -0
  24. data/golf-java/build/com/yahoo/platform/yui/compressor/JarClassLoader.class +0 -0
  25. data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptCompressor.class +0 -0
  26. data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.class +0 -0
  27. data/golf-java/build/com/yahoo/platform/yui/compressor/JavaScriptToken.class +0 -0
  28. data/golf-java/build/com/yahoo/platform/yui/compressor/ScriptOrFnScope.class +0 -0
  29. data/golf-java/build/depends.zip +0 -0
  30. data/golf-java/build/golf +0 -2
  31. data/golf-java/build/org/json/JSONArray.class +0 -0
  32. data/golf-java/build/org/json/JSONException.class +0 -0
  33. data/golf-java/build/org/json/JSONObject$1.class +0 -0
  34. data/golf-java/build/org/json/JSONObject$Null.class +0 -0
  35. data/golf-java/build/org/json/JSONObject.class +0 -0
  36. data/golf-java/build/org/json/JSONString.class +0 -0
  37. data/golf-java/build/org/json/JSONStringer.class +0 -0
  38. data/golf-java/build/org/json/JSONTokener.class +0 -0
  39. data/golf-java/build/org/json/JSONWriter.class +0 -0
  40. data/golf-java/build/resources.zip +0 -0
  41. data/golf-java/build.xml +0 -174
  42. data/golf-java/dist/golf.zip +0 -0
  43. data/golf-java/lib/ant-launcher.jar +0 -0
  44. data/golf-java/lib/ant.jar +0 -0
  45. data/golf-java/lib/commons-codec-1.4.jar +0 -0
  46. data/golf-java/lib/commons-collections-3.2.1.jar +0 -0
  47. data/golf-java/lib/commons-fileupload-1.2.1.jar +0 -0
  48. data/golf-java/lib/commons-httpclient-3.1.jar +0 -0
  49. data/golf-java/lib/commons-io-1.4.jar +0 -0
  50. data/golf-java/lib/commons-lang-2.4.jar +0 -0
  51. data/golf-java/lib/commons-logging-1.1.1.jar +0 -0
  52. data/golf-java/lib/cssparser-0.9.5.jar +0 -0
  53. data/golf-java/lib/getopt-0.1-dev.jar +0 -0
  54. data/golf-java/lib/htmlunit-2.6.jar +0 -0
  55. data/golf-java/lib/htmlunit-core-js-2.6.jar +0 -0
  56. data/golf-java/lib/java-xmlbuilder-1.jar +0 -0
  57. data/golf-java/lib/jets3t-0.7.0.jar +0 -0
  58. data/golf-java/lib/jetty-6.1.15.jar +0 -0
  59. data/golf-java/lib/jetty-util-6.1.15.jar +0 -0
  60. data/golf-java/lib/log4j-1.2.15.jar +0 -0
  61. data/golf-java/lib/nekohtml-1.9.13.jar +0 -0
  62. data/golf-java/lib/sac-1.3.jar +0 -0
  63. data/golf-java/lib/serializer-2.7.1.jar +0 -0
  64. data/golf-java/lib/servlet-api-2.5-20081211.jar +0 -0
  65. data/golf-java/lib/xalan-2.7.1.jar +0 -0
  66. data/golf-java/lib/xercesImpl-2.9.1.jar +0 -0
  67. data/golf-java/lib/xml-apis-1.3.04.jar +0 -0
  68. data/golf-java/resources/app_error.html +0 -60
  69. data/golf-java/resources/error.html +0 -29
  70. data/golf-java/resources/forcebot.txt +0 -0
  71. data/golf-java/resources/forceclient.txt +0 -0
  72. data/golf-java/resources/forceproxy.txt +0 -0
  73. data/golf-java/resources/head.html +0 -0
  74. data/golf-java/resources/jquery.address.js +0 -439
  75. data/golf-java/resources/jquery.golf.js +0 -945
  76. data/golf-java/resources/jquery.js +0 -4376
  77. data/golf-java/resources/jsdetect.html +0 -23
  78. data/golf-java/resources/loading.gif +0 -0
  79. data/golf-java/resources/new.html +0 -45
  80. data/golf-java/resources/new.static.html +0 -45
  81. data/golf-java/resources/noscript.forceclient.html +0 -11
  82. data/golf-java/resources/noscript.html +0 -18
  83. data/golf-java/resources/noscript.static.html +0 -15
  84. data/golf-java/resources/project.xml +0 -21
  85. data/golf-java/resources/proxy_project.xml +0 -11
  86. data/golf-java/resources/proxy_web.xml +0 -40
  87. data/golf-java/resources/static_project.xml +0 -37
  88. data/golf-java/resources/version +0 -1
  89. data/golf-java/resources/web.xml +0 -36
  90. data/golf-java/resources/welcome2golf.html +0 -50
  91. data/golf-java/src/com/thinkminimo/golf/GolfResource.java +0 -582
  92. data/golf-java/src/com/thinkminimo/golf/GolfServlet.java +0 -1055
  93. data/golf-java/src/com/thinkminimo/golf/JsonpTunnel.java +0 -86
  94. data/golf-java/src/com/thinkminimo/golf/Main.java +0 -1299
  95. data/golf-java/src/com/thinkminimo/golf/ProxyServlet.java +0 -577
  96. data/golf-java/src/com/yahoo/platform/yui/compressor/CssCompressor.java +0 -188
  97. data/golf-java/src/com/yahoo/platform/yui/compressor/JarClassLoader.java +0 -158
  98. data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java +0 -1281
  99. data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java +0 -55
  100. data/golf-java/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java +0 -28
  101. data/golf-java/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java +0 -160
  102. data/golf-java/src/org/json/JSONArray.java +0 -934
  103. data/golf-java/src/org/json/JSONException.java +0 -27
  104. data/golf-java/src/org/json/JSONObject.java +0 -1550
  105. data/golf-java/src/org/json/JSONString.java +0 -18
  106. data/golf-java/src/org/json/JSONStringer.java +0 -78
  107. data/golf-java/src/org/json/JSONTokener.java +0 -422
  108. data/golf-java/src/org/json/JSONWriter.java +0 -323
  109. data/golf-java/test/client/golftest/README.markdown +0 -3
  110. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.css +0 -114
  111. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.html +0 -17
  112. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.js +0 -81
  113. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/asc.gif +0 -0
  114. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/bg.gif +0 -0
  115. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/desc.gif +0 -0
  116. data/golf-java/test/client/golftest/components/com/thinkminimo/golf/test/Harness.res/test/test.html +0 -1
  117. data/golf-java/test/client/golftest/controller.js +0 -131
  118. data/golf-java/test/client/golftest/forceclient.txt +0 -0
  119. data/golf-java/test/client/golftest/forceproxy.txt +0 -0
  120. data/golf-java/test/client/golftest/head.html +0 -1
  121. data/golf-java/test/client/golftest/scripts/jquery.tablesort.js +0 -75
  122. data/golf-java/test/client/golftest/styles/style.css +0 -18
  123. 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
- }