From 5d3a57eeeb2c88d81857987bd6142a40b6968381 Mon Sep 17 00:00:00 2001 From: David Huynh Date: Mon, 8 Mar 2010 02:34:25 +0000 Subject: [PATCH] Implemented project import and export commands (from/to .tar files). git-svn-id: http://google-refine.googlecode.com/svn/trunk@234 7d457c2a-affb-35e4-300a-418c747d4874 --- .classpath | 1 + gridworks.bat | 84 +++++----- lib/apache-tools-tar.jar | Bin 0 -> 21515 bytes .../metaweb/gridworks/GridworksServlet.java | 4 + .../com/metaweb/gridworks/ProjectManager.java | 32 ++++ .../commands/edit/CreateProjectCommand.java | 23 +-- .../commands/edit/ExportProjectCommand.java | 94 +++++++++++ .../commands/edit/ImportProjectCommand.java | 157 ++++++++++++++++++ .../com/metaweb/gridworks/model/Project.java | 6 +- .../gridworks/util/ParsingUtilities.java | 24 +++ src/main/webapp/index.html | 2 +- src/main/webapp/scripts/project/menu-bar.js | 27 ++- src/main/webapp/styles/index.css | 5 + 13 files changed, 392 insertions(+), 67 deletions(-) create mode 100644 lib/apache-tools-tar.jar create mode 100644 src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java create mode 100644 src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java diff --git a/.classpath b/.classpath index 80c2952c7..16370e936 100644 --- a/.classpath +++ b/.classpath @@ -16,5 +16,6 @@ + diff --git a/gridworks.bat b/gridworks.bat index 988e89587..e7f9acdcd 100644 --- a/gridworks.bat +++ b/gridworks.bat @@ -8,7 +8,7 @@ rem rem JAVA_OPTIONS rem Extra options to pass to the JVM rem - + if "%OS%"=="Windows_NT" @setlocal if "%OS%"=="WINNT" @setlocal @@ -22,26 +22,26 @@ echo where [options] include: echo. echo /h print this message and exit echo. -echo /p the port that Gridworks will listen to -echo default: 3333 -echo. -echo /i the host interface gridworks should bind to -echo default: 127.0.0.1 -echo. -echo /w path to the webapp -echo default src\main\webapp -echo. -echo /d enable JVM debugging (on port 8000) +echo /p the port that Gridworks will listen to +echo default: 3333 +echo. +echo /i the host interface gridworks should bind to +echo default: 127.0.0.1 +echo. +echo /w path to the webapp +echo default src\main\webapp +echo. +echo /d enable JVM debugging (on port 8000) echo. echo /x enable JMX monitoring (for jconsole and friends) echo. -echo and is one of -echo. -echo build ..................... Build Gridworks -echo run ....................... Run Gridworks -echo. -echo clean ..................... Clean compiled classes -echo distclean ................. Remove all generated files +echo and is one of +echo. +echo build ..................... Build Gridworks +echo run ....................... Run Gridworks +echo. +echo clean ..................... Clean compiled classes +echo distclean ................. Remove all generated files echo. goto end @@ -73,16 +73,16 @@ goto endArgumentParsing :arg-p set GRIDWORKS_PORT=%2 goto shift2loop - -:arg-i -set GRIDWORKS_HOST=%2 -goto shift2loop - -:arg-w -set GRIDWORKS_WEBAPP=%2 -goto shift2loop - -:arg-d + +:arg-i +set GRIDWORKS_HOST=%2 +goto shift2loop + +:arg-w +set GRIDWORKS_WEBAPP=%2 +goto shift2loop + +:arg-d set OPTS=%OPTS% -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n goto shift2loop @@ -108,43 +108,43 @@ if not "%GRIDWORKS_PORT%" == "" goto gotPort set GRIDWORKS_PORT=3333 :gotPort set OPTS=%OPTS% -Dgridworks.port=%GRIDWORKS_PORT% - + if not "%GRIDWORKS_HOST%" == "" goto gotHost set GRIDWORKS_HOST=127.0.0.1 :gotHOST set OPTS=%OPTS% -Dgridworks.host=%GRIDWORKS_HOST% - + if not "%GRIDWORKS_WEBAPP%" == "" goto gotHost set GRIDWORKS_WEBAPP=src\main\webapp :gotHOST set OPTS=%OPTS% -Dgridworks.webapp=%GRIDWORKS_WEBAPP% - + if not "%GRIDWORKS_BUILD_DIR%" == "" goto gotBuildDir set GRIDWORKS_BUILD_DIR=build :gotBuildDir - + if not "%GRIDWORKS_LIB_DIR%" == "" goto gotLibDir set GRIDWORKS_LIB_DIR=lib :gotLibDir rem ----- Respond to the action ---------------------------------------------------------- - + set ACTION=%1 if ""%ACTION%"" == ""build"" goto doAnt if ""%ACTION%"" == ""clean"" goto doAnt if ""%ACTION%"" == ""distclean"" goto doAnt if ""%ACTION%"" == ""run"" goto doRun - -goto usage + +goto usage :doRun -set CLASSPATH="%GRIDWORKS_BUILD_DIR%\classes;%GRIDWORKS_LIB_DIR%\*" -"%JAVA_HOME%\bin\java.exe" -cp %CLASSPATH% %OPTS% -Djava.library.path=lib/native/windows com.metaweb.gridworks.Gridworks -goto end - -:doAnt -ant -f build.xml -Dbuild.dir="%GRIDWORKS_BUILD_DI%" -Ddist.dir="%GRIDWORKS_DIST_DIR%" -Dversion="%VERSION%" %ACTION% -goto end +set CLASSPATH="%GRIDWORKS_BUILD_DIR%\classes;%GRIDWORKS_LIB_DIR%\*" +"%JAVA_HOME%\bin\java.exe" -cp %CLASSPATH% %OPTS% -Djava.library.path=lib/native/windows com.metaweb.gridworks.Gridworks +goto end + +:doAnt +ant -f build.xml -Dbuild.dir="%GRIDWORKS_BUILD_DIR%" -Ddist.dir="%GRIDWORKS_DIST_DIR%" -Dversion="%VERSION%" %ACTION% +goto end :end diff --git a/lib/apache-tools-tar.jar b/lib/apache-tools-tar.jar new file mode 100644 index 0000000000000000000000000000000000000000..fecb8382557985ab592f234d41ee1424f7aafe62 GIT binary patch literal 21515 zcmaI7V~{R9)GgS?)3$BfKJC-CZQHhO+qP|-wr$()dGE}v(T^|L$)8jum8xWA@3nU1 zr9i<@fuR1YB*|vHK>x3T3IqluBdRP!Cn+n&AR{CzDJH6LNYqlz~S+$I-)48@#Z{QM`8E|;_#CKL4H;%+% zu2%Oqi4LSfvSW0tpR(a9RJryT_?cRQ`$@RV9bc;||FZy5@ewhobq&+3<$zQA{JR8e z9(3Hu#kj+cqcZhdpfsdfhR%kw!^r8Qk^0O4{#{Rf z!h3SDLK9uxn`XZ5z4P`7j+E}`3yzQ@&`^F6m(6a%f^K2QfEWhy8Bxx8%+|gsO$W&S zjY!Vn4aRQYN0}72LO^*meqqms7)L(j5`eN6eZvOOMK1~tGC@Yk!9`fuY6Zws*)+na z2mMifr8lzj_oFPN&}eQq`e)b$?G?0lRlkNJ~XxFF6TAtTRnTx0Mw4PD`~SG{uo70am_2waPT^rR-c< zUKNxLw(HV=*569Xh6HYgGx> zWCBOPu`;&a$;{cAq{Xi`(@b=;`53JUyY=Ee_LeopJTO{NphxF)X*8_Px=$ zfdpWSHEP=pgN&fLsi6`^jiw40$Vs%xZ@{txw7*?zDCc!ihBN-4*m`KxYhl z2i=6OhkxY?GUEsFOSAmbNRwPpevBgVD#@4}cjIymioipMOcPO`ffQk6IKg(&LJUcN zhv|&Q$bfQp$ErxeJ>yIAD1$8}7zbyJVSld4E4jeD!6PyGfrdipq|()=k6{Je@EY>X zmE>(h8&*ZgLkPQb2G1?m86hrcB@e4=(8x$wQ7&j)46t& zll;L#63|kJdH}jn^dTamABdj|rtU>co53UVmNi`(HCtEAL$FN> ziktm{vtGDWoE9-*#psOoFRZvA`2xSm5=N3dY&>H>3iuhK6mXzUfV3`{%x);H`mECm z%qEug{t!Ip%`$2|j<;Xrp>Ww3R9@BBTEV0o~2g z^lLn0)9|_MnK-p;E`$6e0@36t$FA?8YSydJ;$KpWsDtga3u_4g5+pU(TBOwB9l?!u zQgFWp1b`1@AXcA-2h-YDu96A)Gf{#CxL?6k^X*Zsu5F52AY&6gf0HKZ^-I>+&f?`U z*x-|aGd7lN)2z+XW0e7-U{`JXa)EOuBIwUxOO_#sC=U^oM4?%~e<&4QjGB*&!a}al z;}yLl)kPdIM>?9`ZPg45s;L#E%MaY_#agFt~DPu6KU!! zp|onRkeMgT9ID&r(&Q(q{;tu&%%kMTF|eAOxCsqsRLt4nL-ND6OG`GFT`928`@O8Y zhln9zSYsFBZuF=rk*tOy_MW^kflF)#v_oMrioLfid_*3FeH~Sb4x9c!IPFy*d2LTZ zc+ih*9HGSL8W9cP=H!1U+7~|=j<2?A#apL9y5QmZ$qH)?PShs}`Bo%|-A$*=uViVz zqkPSkDunGxrwYl5`G~O(w*-ZQ^SZg7hrr<&8fXm{9Lo8yqd4GH%duL&6N!x2z6D}Z z(3qtNi25*wDNbp7;+5{ND>X-a2-+&Fa z7rNES9AkJZG3W-j(k8iJe@#+X8s#8l6vN{>`2aWhJIeva8Rz%`IVLpLo`AwPr%YqIX8W&}MbhzC+* z5Y|jt{S6S{!juX1#cH%O?I9Yv(}WVS(E#X;=Vt8{r>ZP!atSR*oJ9)&^JNNNwGtu2 zhyvjxVmw5Fu={FqNd9G|#WM<2GNh$v`tiVNAfws%W5=u$Z70TOzjYe=J}uPNoe#pbR?10b9&L@=wSO+l&aY_Agp0(m-X_7lecrq# z_cv1-sg(+RRsG8)6wg(~-l^Z%{)tDN)-4%g9@4_aMz&940>L3rLb@IWZXp*ZsS2@z zk)}>Kl#l<<^15V!Qy53lPHv5^tc118m3**TzCGJT5Z~nipo7odMrAE4IFrC3dQYC8 zfxXmv_|8r7A^{0em1!Gj_b`~6LU|`VA~w8HS7QDqewx*r`am?GZ&f{WWHi(E$i05y z16^$*nwj;iWC$0{f31lMpn!J00(>@{s7=dkQl)ekp)c{^nuCQnAsJTGi<|5Q;k0xO zy~z5<)8oZS(Y)Y>2v$ZIK8S<6r&n2^JCeNP2wpkpSv4u<~>a4vXeM5MePmzMsRu7jmk&v>qj(FNO-TkPD}B5S|`RGx9{xJBm*@uAqLK;({VOa7`e9)9UoZ#B440X*~Q- zhR%Q3X<_CFg~>_@AOfwxt`FHbI0i0;K7v0ZhcvBmJUD>rS{3KBI(3uHU~kJFCvVvM zDVYsbRO$#@d_?;MlfWEyzUw`((8ZUAlhpyEg-O~I0+cG!I0H51OW-g$=f8tQjIxhM zQ1j^e|JxF|OVVksNzHZ$3E0$BjJRZA6_D(vtVz#3tf_!8ED=YlA!wrT}v zApVx}N=ioZPnGtE=k5_C&rvD43-2+1?U>Qj*D61+%b(E_w?qaL$u#WI^err)+Df9p zY1zB-;u{9Uste%_S;t4A`WkZE5M@K1zk)s;?bBaq!L;X2V|=x{&k-;|67~SaNiqXT zVuu)?RQIDpc-ycV7?j4p@K*f{| zxxIZsMJUZT>g*@(1q1nWA`SXyu7pGEzIXjm6p|$8DLoFLx`yBfwFPS^h79jcd2o)> z43wxCT?xTLKp+W+-W&RC2_G*J1y@l;(vU%qF^Z)W(lWa@&yW|wpvKzJk$(`$BV=`t z2N|1LWDIb)5R6j{wf0-`i&4zMbhydWHB(#f#W2sYgU~?iSsFk_=gO>+D2sruqVnP_ z<61H+e0uIA2IqGI6grcXQ_eXjFo0ZZMS5&LF%Rv-2SwNlDj7rnF8nbM7ezPhI#yqs zNQt<^#FMrsfv1ciG}P0+A`y;3tSX~yy_+`<$NF628$YWV7y|9){CUT-Oyed%OhtH! zl=RL*5g=)N$$`fEqV09iFumo^x`Q)60e(G$XV-y>nDU~2??sA&g z`PY(0tj$rl?ko~F+QOHgnE8b{fG_4%V@zH`UDyLTP1 zCOi1_k_P(qHR(%)?|(9r|G8?O&{9ZD{h;_cdEhmC1)_J?=E&ez-_^bVEgUfs@A|O! z7gl5aZ)RaNM+c@(!`zs>lqJeTvC;We4o8LE*G|eYPdPpL<2+hC0o_+B_JLLX*bZki zkEqYcp_eshK!l!qf#92fDr7CCePcFE0^&h-pgmeT`ki`>7Nd+malBLIjm+#EDgZ5n z-!wk9i(i08;PdI_L$C$8Q1@nSj4 z%C1&Tc1i8+>p82f?w+u+;I&urQTI&uX6wfo{&hwyX#bnC^TE|uHEMy?_HJW}Y`YhQ z6lztByOS!A3igW#Sp?NoDs6n12Zub!VtYBwDzJuU^Iwy;@e$vVx@%86YpR>C7!g3A zG#8BhfyIfrU&JJdx=`X!JB%{*bF|%VJv)!=I`y$Bta#Vo*`(Fa@!$hwW@lSQE77wk zjy}V6)JsyF;c&;~0TlKdftmdSOQ3Y@ z@H4FI9?EgT-O=fl6IYJE{x#mOKa|LLHx8qSNS^awVzBe(HPpVCq%aiok^=?QuBJCG zZTvBkuTZ!@%hyFl7>44GK+Hf?0{UuvVU3Vs6A|7W7RZ`Da2=?UF7Dl@AvcsJ4ER$lO??S1IXl(#*o#(`$s($5DB`EJ7A zUf>Og7<+ou36-qWF{`03WVd(1ns{$!?m&hpdrA;0IsS@_jT(wjxCH)&!lvx%Yg$_& z>BNhY9gi#P8EJk*9}8(n`A-rT%#Jr;fDUBI@kh61% zxIx^;)+Ou9Wte*6q_1~>tOykB+vY72Jh<_;8FWh`*XoBsRQ6zos*y6A@Wikyc>3ps z%~$0{X4m%Y#t1aWKebby-hieluzZ1(gfH3xYYKDxpDcl<%+Uq1*_n8HS8rG0t4vJ1aRnQ;!gi@PDa&jj~ z+VuU|&$3H@jLopKkpZ5)3To@=!~QHI=@ht~2u12eB9yi3_O=YRHJoF0L+mva#2kZC z^d3@MDJd(2fka0}@1;CZL>aDj1~Ppn!L9 z<7o|L-A{Zo0~42jL8?SQ@rsl|W7}o4K;$pW=Q;9sS?gKEQ&xT3V~Aj$oh6j-?eu)+ z`}z;6A^#T@D_j&%po#_rH1Qwx`u|X|RFVH*u9xILD%Q@?jKRR(z{uQ$!P(Bv+KIv0 zz>z`Oz){87!rF=6$lAck$w%edPDusxH|M3dy2J>_9@6MijANjt8+DYHkTX9iZGasL zN6Ve*YGKDFq_*ao&VgwjGfY946;m3OjTuGBh;^Q!TT=X&(jZ6tKv|V@F|@ot`yi63MhmKRkLh=)jRf zl{p87J-d!^r9L_%I~JSGcS@=gAb2pm*2^;FC5`|SE)?()pxt`5q2abQlZ-3ys0J3T zb8fwHjdADp8VzF(+L4SBOz=zuhKOp8`PVEbVc|-njL|gjA1BCEsG}qgi!H{2qn?Z9 zjdUmF9Me;ugc|_t(Y4?VSF+PptpAEX1rzs*O9Yc8HpdYF(yIi0f5pg7g|KDdGvn7lEFeIYkRyxd|{c#ZZ5~ zDw=CP{2Lv?wVI&lDnO%*gqb{IL}WdRjxIN|7SdA-X(gCz4QD|1p{%ybQPR;TD9rhBC-*jX)fbCIkCr z1}}aZS<8Ym$bV&qaP?;(SL)=!31og`soP?k>kV}^KU3ml97esGpYf1%HZIi^qsUI; z#PpGD)x%rt>Z%@>%1_}Yu&6_k==@4i0TZ4*cl_Ler`4wMmU&E; z$yJ=@$x0RDBxbzoVI~8T;^>K$y2W|kWD@-CQD*bdPdh%-Nq78`C=ZhzV5&JfWU^-b zb^2B<{R1sCMx;H$+_1PlB;At>R!fpO7Vc^V-CCT$^?>YZ5dQ~at-I(cci7kEGe2>k zRkdI7(H{GsN^M!jn7%E6ky=3rn~OA~9nC6XY(Y#J#066{qZ-O}_hMuxfGC}uJ9sWw zKUXlRqj=!ep9r{GK_{O2ciI_ZwKs3hqwpFc7bn5cqQ;>odRam0by%}QA(KF7>=EU$ zv))-stNg3wJ}eU`=kJx#H1FiMLn0qqC+I1lr%4W)?fmJP<>#S=M_IOoVMfvRU zd&C?HLiYcFT-?cWyuVl%VC>xQwO?zXn#wjTTX_U)6$txbH3U=Kv# z_(AWWShokuKgzm_%dfHIn3l9#_~ekn&u_v;qf*?WSYb#gRbyP_g>;;?@JEY!8S0S8 z@PNqK<{6as9=t;B*Qf_oOrt2uQ)Z{aOTo@={(GS}VjG2ZLa8gFC+^%MFTsQs(p#or zDtpvU{bW=0`l@o^`hVMCO%W!fdnL-u0CqO=E3$iYGY!%XKfK+=8r!?ai4_?NV`cX3v7b~G`t`M(~47`;6Lp6;OqfVOLLP%q@;*jh%$zZ{)6Q2iL})&w>7Q3BpkFnbxkF4)J-VFqO z2!2N*sr@DM>LS`TJnL)LscLi9EhSTMBa@f`b(vxwTQ+qjmbK$RodSKCyF`5rN=;Qf zfR^b=>mOU;>p($$m67-5WtHbDY|B(Ns&ed*{gio$IJ9VWnF0H)W?)hybqE|u{zOMm zmYG zARKv$kd$^0vr!_0t33cl6p#>jY5R@qN|~rvDf8@$!Zbb*_`1 zhdOko)l6&1r8yn}=2nbbsL>(DIm8<^GxBkR=M*YzO3dFx(>p|UCgXC2apg(d$g!=p zXklLZ!V&87XM@Ti5qUR?2!HpdO6ScmF@qYIvkdy9yfb`O`rnSKxB8)?lh;pSj|__g zDNI|%jBF+lyRcS5BuUpO81fcK6;H7_VU{-Lv14E2$JjNVo|J3s*t%*E1I|E<1gLEk zbUejn8CV$+%upKfN>%b4P)e4@e+)rY5cBWdDQSDrk7tka7C!t;bCFd zj)X1XRO?-AZ0fxjx%sSww+kN=sia6BPI1f!nUTTrhtH4D(4yH{D0q->Eu-1ZZPRcU z${myFvWXK5a>KO8PuX+^);2=j-P~ABGi)?1PQrA`9W|Ks8v((cf2JYDr3s9F2X*eWW3z{`UB<$-mO4qzcbtp_aI~TbJgdN< zf28ITK)qd5QD0tQOlEAtZpHGL+m?qt``pC`y)&6~;OrW3EtR#W@uQAygM@i0TFcma zr;&YvVXClwP|w!Y$rX&p+_JEdzk8-%^>*+lIMxMx+WR3RoMYFExZ<EF5;qhwn-3L_U8lVF5l#h4zm zfw>2;rgqiwdt$bQM{Y82hD^b-hNh##-v@NXE8Op&M1J3w{N@hhKL!M)*J2rZ*Q3sT zK6PFkrXMz44yE3vcs(A4FM23Ge!x9T(zCSUNUC=yDc$FPYGMSa`2Oquvyzx;{@IKe zWmj3Mo>Y7B7ss!|R;2HWjw#OiRCH#zG)D717Fe<}dK^dZ*tr6_S*Cnta#R-3 zzaS^(v^@@x*&e4mS>!h8@2#+(b%j1z=bv;~uhP=nPPr#4MG{9wo`WHF_BSW(l&fJq zHzlG?S3T(oc6l3p5pAYUXCWlJy&YTUd6tjdDCV?o9y%IrL+er9-d(FL6WJ!SZDzae zK6@F3-d!Ggnk)j}kk&0W9_urU&$59+1@baVwtqToq#6mQk#k z>Otk^EJl_^$sVi*sAw-tyQxlNk`^5znMq8@JU#aK0sDi0y=Fi@k=#>0IJA)iVH^~w zl}jq*P1a)(7C^CPrv5@&psAM0=2n~+U-RDV4PlilS$v}fdg>K~luJcY&OZ@}Jeh6P zEVw-;@bc@nYUk?f)p!Lu)6zrX2ASKFVZcOdL_mBDZq~Sa~U&QJjB78jfNNz3zpcblW}epNvID{(Bci ze&k4M5i0uG3`q3BOzZZ>WSHF)L-OU35@nD@N=*cFwH`@_jpc#lN*sknu`p$rG5U_+ zXhPf`F-i2<$Y<*r(|qhH2G{=a@1$6MF}oG(&nvuH(Jct7CfyIHQE!6m%KW^Ox2Z)Q z-<*VgS19p{Hzyyy_HpM7;G6nVLOHXeZ?nU3-^}ZeOPe_NIk;H>%Uuh&FJa!;M0USG zKPtxfWFt_UCASwWMJRpT&xe?661e~-e&;g1s(W|+3PpP(EIk099*9zpPMaGyHDt4> zaSvg;RtdhxHgwO?>Cb8pY^J%Vcv-%!&+)((@Ph+J@obV7r!IIKfU~5{RuF; zL&_Z+bH@t1V~0;Vg!&1RO9lm<6jqNNKw^_!S59!G>~pMIFIKHIs1(DZ&JV5PPAO7# z&@K|IET2?KE1$RQ!7gI2Y`D-=$+uNKT+Xp9gt#&E09LjGv>)0#P`eFzbL1UPhvF=m zZ)72qP-iI4F5b|p40ZEUX4HUq^W`ov#2eqU9+?n`HSt|CcE1SM;{~2Fjxts0fWKsS zknj&!&|e)W#$fW?8%YSSvx<(Zg- z3#&wi1+A0JY>6r3A!K&x(HXAPG5;V(*5SQ=pJrx5N>NprDQhnoC^@+8PJ^rQif)_e zB9G#Fry;faaBjVHkzcIj64tT6D)wk}c4kev^IJ;)2{6;Zby6)Z`cS~XBaF6bhr;ek1 zx=vx|_T|!FPEqL7i;j>@$lf!%(s$j@(mh+O*ia+LPtbBMkulzAc{36@Gw%s#R|^ zG~s-e;Bxj`Wztt_*PQv>4)P&uR&^s?l~EeVCa&7ku=U|zoJf8VndPdLN=p!IGCHM1 z3o`1A<3VhBECWpoO#-A{*fT%nUD#Qfqtj^7YL8gHQfc>4PRBOiu^PdvJiM2K+iU&; zPAC1oD}ilKH^56wn~-`PO8U5^Jb=+@wJ?QZS-#)|k)k{-2e77O?4O1k*Bv7rPJRm8 z1MQFc174%Lt`$8?nrk!7X&UL?(;=z9Hn3lMUXVLG8Sp{2H%lqi-fAS`Izb8-nnzWa z^5yI-xT|KYZX@Sqb(nr;z=mP75RdsYBo+gz<{aU`B>FtCkk5S42^WY*yPUsE2nT&X zF#jutxn)abwSff!LO}nYVi@ZGA%>B2asK}WF(GPJ&e|$yKeDEY8PaxoRFYCjbLT9J zlACjX3s^0REfx})We81CRt-yy!*+RIEE(MwaUEuPO|R=-c|CnSvl**DpI?;zaBoGB9snBT ziJMA$z4oTD>PF-U^~y;AMV02z#7XmVTC1y;B+J%ifR@3%%D&a0%Dl+(i}^G&#U0v7 zaAuaPwH+**_WIny!d78EHkzrO)Uc8&r|mV|*g|QPY5}7F&H6@TnZ@SH3WNbAILXx7 ze6#qb;MGwRb)j}-@cxFH8#TsFjRqCacT;at ziV8q>XrkXPiU03b$u3+;lahE2;K-It@5EyfkUU!oiFZ~_NmIWGvxJn%O3lS0Ney>l zAv>uN|Iq_*8$~2z5hH&#BGDcrn>cvz}3b@mOk6eANlPdtZXxn=1f#Yb}; zM$UmGrQvU{7n5~RC7NxT5u^eHb8iY_ow(Nv?N={CE`~j;Q){tfbD~6raL@KzPa|D; zgTmN^EJL6dsF%}0{I$MVgqRU*2%MFziAn6BS_H^Q#Pa0lyd)~vfllGAQP6;6n{7rI zHCo#>`?ot61lW|9Nn@a7UMSdu8%Ndc%a^U2i9$OdxKhz#!YCR!rIKXWu-h|*uW~^q zDNI?L@9Y%nkhZcZiWs*Ah+Uy-dBJK2<~SBg!D)vA#gHweB7D}51-XW>lum)c*tDVD z@Yd68odW5*wpp|si3H+vM1Fij@CVU^Yuwl{BWS=m(0HgDXy}U-n?wIu4uk6C&98k} zjKn^J5I!mZb+ySwQs-;o_Gt$&A;42kXHB!r(cq&GPrJ7*ABqN+X{fc-UVu!H?)wSy zc4*pLdMcE;C-nz&HJp}v@LLo4A)g=9oCPhe-1AgY zvGbM;H>M;Ncj8LE`AEM8Eg&&sylj`h6%J#H?7dHtowW-=qI9@`=J56Y< zg|IA#tm0!LPy{LE)AeOSq^>zw@v8&B;eL(~E-4lpASpWUseX{@q-#)!-k>o`B$;J# zjZ4)(cT(=RC><2A(=ErnR(oD=y)i@9&}W^V8~xs>OgW`7-(^w`PaNUbGrIU<#%rBIuXU^ZJyHeZi)snA$XF0m9tmT zuA&v3*sEXocvQbaNe{@xQ^sM?`|P^m3IT^wAk%5*_yv}Fn3X}{{Nte~BURH53*Fo{ zrL?6Qx2x!SO6vTk^Q3?OLD8`o8!j=WpCJ#dt{;wqoi_^L1m!Kl&wj&n9}h54q(1E@ zo4jDZq3xWgAjy&sh4G;HM0+w~RDZrJd?KsbSD$ zm0-xdwvyAgSS{hLaCAgj9bL&5C*_nn`?VHGw(W2?gp|N$cC((`^-hQbo8f!7^-p;i z%xsOlS7&zsw{1xkZwGSnA**<5?@fCUoHq<(d3c>WB(R*qm5nL(TKoi1Ox?fmazumB`xbnCF`aY)iPGq${Q&y-Kz-g zh+>;XYM_lQXOcvQ&6D;yj5s+Deo}d}r0f=^;I!5kX-_;FM^4hif$Ky2)N~?51z|OZ zZ(=n&u4M^n&B>646Q!{?s~i1LR-MBazRIf3=v0SwMSOZWM$(;(fQ2}~&v)`=k zWA|I&bl#0$P{BRF)nke6R=jpTlX}$Bm>3*y1}0&-S;A+caK$4vS5E|@AH@+ZXd-7} z;EL>4vBmp)`UHd{*syS6H>AQ?-mK?R22MR57-02_u3QCzTS(eFY{1%D(R?g0^%_L& z7&@c!JQ84gRiEG#v9>s(A>~vZrDPz+j#$|}c-1+B#XHV7Uky{|;t=eQz9bVjZV+>^ z5zf)98TU%e_NZEO%`gvyT9eJxhp|=wQ3$ihd9z40vn)X*<^#|t*WkGQl<*0?_zVY7 zx`WqmOept&o3W~^j=Fv5Zdp3JBi7&n+Bt}O(1$mM2sCyHYPqsWm{+PR?Y>E2*&~YK<(oCM@I_D z%~piXV={8{tu-07ouC<02t53}@^1s(Ej8tKmsra@-CFG$$Tj71J8rK!BJofWwEN1u zzL7Ra&q{-vQZ;IOqqx;{)8{U!z+swikOoj0Jf{xTrx~1bAziH&1bRvzNMU5rR=Lx1++l* zqeYV&0!)z|G590Lrz7#Br&n8Ma39YDrW`~^_<_3Ks^1ClT!u(9tJS+OLWd#elvKRG zkgm1w$o=P^yLkD;IaK1xJ!7i*Rtt%q4t&rdu?tyh)i)QW?tXhNM*%J0_-A_7k==k- z=6l#L@c;5n=lV?4L;yfQcqspqZ%Xk$_@=^kwoc9lw$A@sV%1sLbX<@}h1hGUif;~V zeO8w%$&DK}v|8SgK#?$VLoN%5eJ({w5TZ`vBzm*geFNf8{-^`9m)j%X-MCDK>-+us z5*2~lST+}$6U&B;zVll9+~8Q?#E*$#m5!E8Pj_II9iqgua#o#tuy`Y36*FLE{F*KM z)}@ws%(Rti55H3OTIoID(vt>bl$$wfXS9? zIs&Y+3pj#Z@1`Ll``sfIcgburH3gD6-*PVEJ>59t(bo;Uc=t3eb5Ft;e-5Xmo)UDP zb&h2O;~^f)D>?3glamnQ-THTAsDY2&&@KoHi%fqDuS{usG4pIrnsBYJyY5t8H~XAa zc_*KH;fbD2jX`|BmaE^ip(3Bt>AA1wxhP~*NSZ0$1C}9d71S| z;_LhVKc)FE0*9wlU?89c(EsV|{7=%nsI9Z3$NyGkG+^A5mot24GbBx!--XHdsgKA3 z!5QN~jwqzae?Xv<9a^?mR%+&6vwvr&88gm4cxSkF-)Goxf!_wCg%Z99?l-D#@tn*BGbzUD|g7) zPo_-Uj)nAV1MclBdzw%^ihv=rEnDXVnX+YR$t?l>T$3KMTcki3sRkXO9C~OlHJ?WJ z`gH-8TYs86gYI4CCHxq%cNywQqn>C#qIDe$AX?z7yEWr~O!d(&!j(DKR`G7>sd{`i$M ztntouv0!c^u2m41tPz|;1#g1P|CfIy>eWp#?9cG(r_WvCuQo?bUes(9-!ck{*OdkG zommm3xmCHGyfX-eQvav2H-TE|iU9F&C9r|5eZ6;pFH4u%$A7YUf zV2fyER$s@`N>#i!gDrmzsL+8R&)^J&lV&&bfq0nK=mX}6T%xti2Rg(JXIW>h3UH^q z(n1SgTu5go3H5>C5B;tL0XsBpT%3yGn)_YfQP#HQkPmkdDHgycP4o)-(a%qsYz_r& z$R*Sv+{i#ESgVw0<*}xbS+li2Km*aoDp3Ci#vE@Vd898gT&* znGT+;4)Df&#c>D9Gq5$cQRg6;|K2EcP4Q{DICX;Hj|;W!zT#2kS75$U0_tM= z%a!F7+!p%P?5RnXrg6f`C@E3Z*zTJH%I;y8Pv_RK>1039#G!F_x~xA$r3w%!5ljXubZ8yB3rm{#x&mO)E6{vE4;>dTW>N zn?h{T;5?_GuP(VqIWWJbRm9y)i=u>(#vLI2mb#WZ-Yco#>9GWr>+T-hB*avBZO!u? zfU{XG!-YIVbJ4($sB+jniGOsa9CQE4c|()B$KA!<1+>)SiuHJ~XAE0vQI-e!ysRKV zyQTQ0!FGrI5<%?C)7Bnjl{KnHyCnM7zZtECY=fU{9vg+IL@3ou4% z%)`b^AsSUvg&77WDVoa-Fb|)Gl|-cx$f2$LrDQCq|D3Muo&IHBpkC49C8XQ-t+_{7 zts6$1gRuPSVe~ihI`pKUBeIBTQsyvsnm}V4rj{GyZLek0Mp)>nJd*K--bGTQr@0Rk ztYbv4Ko|}rpFM4_b3+Xrxn03LyNJDvDBpi&8*;_LWv15+@@vVRpu)J9GGOjvgjfEh zMaMF1P#t7icY$h>J%??bU%`95m z(=08C`8}=ANUdx!JtbCQDIW8-Vy#YqOTdSzNvKK0kE(GxtZ@irlWiWATzQ{Z8COj? zWJ?FApqHMvATN|yIAfhZuyzJMwOBkkPwz40;b>}K@?+}<6IylieBz%IV=HxaRy>PgEpgr(%CTQjCb!h!Wq+l2nSDA-Lfwtn`E;6Z~`p&=4IH}Sy5yyq?m9ic62 za|dJ}L=rtwZ=CB&EbzHOC9pz0hSrBs7>W202K1oVYuzHk7Z-I9=8X4qQSpMik`%$Y zM_%NXR>+~;+06}`VWA0w@db=<26@67(e*~Sa7sbV+`HV-4d3I!AMkEJ*swRuE`ska z-?>W*3ooqmo;oy={$ZFvv2^<4bHG5LXi-7 zpjW}eZ&P|+f6#Jtq#+waiyQf!M%%3eDy5?6%21ZGd3L{X9F~yjUi@Z$BxbB0W<(0D z(A=~l=vVrru5rT$N9eGeI_(dh?pJcJ2PntBKn9_}nB`ZX=`ZqsFf{mPCvtDazfM1& zW5*)CYhe2m%Jsh4EXbJ%b{9^s)a?m1n+8=v+J@zhOHYGXS}thb_T{xE!g9;UIcg;l zr%7LX%9Y|rkFo$3Tf*#;?Yf>v`Rb$Tz(uE}BT1*t8Ov~KeZ1Iz&@p&m;g0-9t>McS z(8r%~lv$NcpKY-fP0A4z(KK=3I(g7Kbilss1$;Pue|hxw%s?{cx^U=&PaI&EEqzeS zhJL6(NuDnu{Wpn;jmn7H1Xcqrnyf=!^3Z4`kzG#;G8@0s z!V-;anfh<);q3uW7}I$Tt?W2!(_< z%t*{s;@#Oub0>5W1Y^;s663igjhw$io_+}x3ptF#Iu_Juq$>Ct6JTrlG1rdjxlJMQcrnUrA-u0e%z4eu-Cd3ExUa^?CZ+asNjnR~;19yT8F8 zM7pFT7Z#C@1tpZuWkn>HPD$w$B^Sh{c3DDckgi2?K{}TF64DCNvUG|F{$zf4My_|f zbDzJ?nK|$C$C)!{-uLswiBUl3dAIL?Wpl!#+#`(i^0+uMs*7PM>Wi@Yk&*+OSn~t| zZ`A-V;IRpWyKj|v$EOSL8;7e@=N?bvvL;GHYp$)df$#enUVX&iyqw7MpJ!ro7{rGc zp`fL;MxzYBZz_iS>vo0+G)RR*t0UitO4fL(hW z@iO51d8x2SL(ATv;4VY-1h+;!)g7uwq?6ZhvcMpOK90?OgU2}~X&!U%lT`?Ar9MQZ zp^o{?_s)GcI5+M&iXyh{;cT#^VO-gj3 z2)Sq;Ng|p}>$-O8jhkQO_3@K_MwiAGc0@O_>%Lh8B?2puzBj=$9u)andlNz1emYt; z>(s#FJ2Hfo%gkiOw~V*>(_Rp`X0*B*lTRrY9{;H1bJa})7fG2k9WPnaV0n|d^0PEi z^ZterQ)p&!W~SwX_j-M2XsLyq~$7rpjaQ`G0nlBaZc4YECkVJ%9U4Nc+Shf zaX;an1|hLz_h@}T)j<6Qj2E_;yE4WakHJ)f7VNac$>49JQ8I6t+Bx(G$Y1ws6gfw4 z@CXeWyQ|*t>5NeD79QU6zKz+7F?|G{$#fYLbCVqyeGBq1wHTPl8&LQf;=>a~{p@K? z4JqKp=v)9y>9gf27p7MCx!@#nJL0l!xqQGKNboUWZl^`y>wIg=cOF;<9f6vYRJ*tF*8jhiQVDvylU$(R*P3r}knfp@(onA;n5d`=NN z{_a$kThr9ZU2c{otbO3oS_W5$ci)AJ`M{>}j6_ zY%42%4t>6d&y39IWN(i_(o_hl>9&CaSG0oKF5^CZ?Mv#(24 zS<&B^w2eh(?mjcsdx2Y4ko_6k6K|tTMp9;wll?&K2gAkuDeHOf=Y4WKymxH>ZHB=0 zU*=EpUbeP2?*BhT$kX@p)cweE?qZw3(8ft@K{@b%ReivkN;UqKI#H@x$hE6kYD94c z79xIX1Q98oEAYDlby=A;HFdNluS%2kfL8#-E;J<}Ubv!~>FM)fs{sG+8JkbFjjQLH zwry4bDUg6v4-uc!(mB`qebzoqE4Z!Ud!BePlko&-V!T@H{RBxQL9kl&uEEI7 z&i)#Rm`&YFW=Yjh_=KvC%W3^4yu+wJjB@&}Q0XJy$PPXx%jdkK(`8i26s)F1n%bjc zd73=K9fS7LjaalETRtZ+jui}`YF&F5QC51CJw;U9c};1SYRYAY%_3|uO29G8EgotU z7rlC=-bC512nMbuS>liB;8>vwW;ieLMpYBnIWC$g%Qo#jO%6`EvTB#_9M=&Jk58@? zsjeSYeIIczXUuf=7C9{2IZIKoY*VXtib?Ip8hkYdlBgRHuX|r*KE!QI$5j?uXONJ1 zqwa@|Gj)&NI|~jmDZU9I;_EtNP||&fns4qzJVdt@fpdktyFbfFNx*A5PsJP5O2nrO z5jU_-Qb&hh0W8Lg8;qNjS=<{$R4FmOW78g_b4+#^K-nkT4wQ{RA~~c;9FmHSKD(jvb3VT zzxJw=_B|8#;Id$iBJvQbPul^2l)gtW?BQx7;Ig7^>pSMvElAI})Da%)3Id$8!Ts!6 zqZ)vgRaJzy=RXFV@z3b`iWIpdUZ)V6(Mb-q+V55HB)?L`ybhzsVJ8wK?BmlRhnf1g zlR7$fhFGx9 zo($z8P4_A1N??}$P(beILiM|>r9{|guA>z!pbEGu81qCZeENwfu@@<9W>XMHosNhoUvNB7W>jBGKA@S2J1sm*ik0zg2|a~TOV}u9CyI}Z zJ(GII823XtM&hwr(<3!ST5O>aAgVsaiRkUohsAb1 zRshp&QovyWB~CctP)9J`LSOJ>?SXPzlRsBs_rg1uBgTdSq;*ch7GekZi8pcTm zjn9z&!p1>AVqU`$w)S>FT4%VbF}?uUmKgqKHZVOYR3TtYmAf$A#kwk3=|OX&BsR

}ZugYS#*oQtG^oW|n5#xuoqAtLDImJ`#np1c{KHIvX@IPoAY&(S?vHgoVb z_A(zYc)xB!>T1Z-Jic>V?C6K8Cfz7TEFX}r9tO{&^!r3(y`<4C{KoR+{7Y$otb2TS zBH>=*(z1VuRoc*t&;1UA0fz9##jzeHFue0fvh#NS^rBe6(kHANqs?HZ=L)C3_*iIF8$sR+jH&uc$L`5UDvlr^2DrTAFQar>1_x!%f}~)30?hp7 z@qv6u=}+03eSNjd*c4B86}5CLjnA46wPJEYVMBzyg!AN)_}8v{NKq*00j7XyfL;*O>`98SawgTwk;}=p5dY zNN^pMyk)qjZ24Y@Pg&klS5`n-Eg@AGncc#F;E$8MMast<{U|1oe!58e8NZeZ-80g8 z^aCtj8PPWa2rUuw>V{-d_SFKtX!^#hbqUlz88nHPZe}WP>5*sFup+oT;6Dlz#~YB< z`?mn|w$qKF;JLPv=3jP!h-g3h!A@{c?QE38hCBtvO?=C(rRMHtr-%&(QdQU+?LYXb zrx2yxp0`xhSfHDA#XTe7Si!nE7oBCAhrwAbk$j2w zn|iH7^&XgcomEpWwT|{0OUD|zX@^x|X1~tcWYp_zDyGnQDqC{e7B?sgKqZsyY zDELI2zs=(*uTp6I5($BAx;4E*6=xSD&wv)*37`LfcZ;yisGNB0+a0c=;?M0-a`g+5 zn%VS?aOSf2vBmyC&)NjL3E){{F~5HC#ak*m=^EV{fuWO4qLRPdxB=#@w#W?xZwZ-tAQO~l2Ob1{ zjP~%hpRk-8oa!oDpVDa=Bs{YGVDr#?G6eRtb>ra%|2c{_n$H?~dvO-seY}=`tfuP7 zl`9@I9hnu@%t|@ZOcm2Cn)NgIu~X>>K}u-pg5@l?dZqEV-ArIRKIMGQP%J0X4XV3WDmM4XBj4$ppq<@JxxcD7 z?mO`l53R;$9|qFRKSG72{fE1O6bo}Z^(5zNY-(rL<2AaXMf_1phBG6H@wKawNuY{4`Q+K8yLt@>>cFxd6GQw%~kBEh<2}b?-gHWk7d+?oZ|T&BH^^6 z(*&@pQu0qs2|u|bF8NNDrV_j`U-Q_0MGL=@>h^FLNyi2y`xmxbiPl|t|ZbH+~UrDH7iSH%Q)?k9m=!n4#cQ6)*Ow)(_p zE}U;cmML|_n+vvKon!~Ej4Q%%OdXqbk7t81ohIMz&Gea8zRB?Ov1qO%)Q%2d(LZYy zdrLUA6Rj(MTQ?kmz^`d|S-iMfmniYt0V-(w6w29(WTL`P`lvhRPf=bFg!&46weZV~ znMpbCMN$c~pCvbu?jTQv37c&wzoM5YTU*e=!Nhxl25S~HHJYU-4PRIU6 zP^X)mkp7rxKmC= 0 ? pairString.substring(0, equal) : ""; - String value = equal >= 0 ? ParsingUtilities.decode(pairString.substring(equal + 1)) : ""; - - options.put(name, value); - } - } - return options; - } - protected void internalImport( HttpServletRequest request, Project project, diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java new file mode 100644 index 000000000..e96bdb622 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java @@ -0,0 +1,94 @@ +package com.metaweb.gridworks.commands.edit; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarOutputStream; + +import com.metaweb.gridworks.ProjectManager; +import com.metaweb.gridworks.commands.Command; +import com.metaweb.gridworks.model.Project; + +public class ExportProjectCommand extends Command { + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + try { + Project project = getProject(request); + ProjectManager.singleton.ensureProjectSaved(project.id); + + response.setHeader("Content-Type", "application/x-tar"); + + OutputStream os = response.getOutputStream(); + try { + tarToOutputStream( + ProjectManager.singleton.getProjectDir(project.id), + os + ); + } finally { + os.close(); + } + } catch (Exception e) { + respondException(response, e); + } + } + + protected void tarToOutputStream(File dir, OutputStream os) throws IOException { + TarOutputStream tos = new TarOutputStream(os); + try { + tarDir("", dir, tos); + } finally { + tos.close(); + } + } + + protected void tarDir(String relative, File dir, TarOutputStream tos) throws IOException { + File[] files = dir.listFiles(); + for (File file : files) { + if (!file.isHidden()) { + String path = relative + file.getName(); + + if (file.isDirectory()) { + tarDir(path + File.separator, file, tos); + } else { + TarEntry entry = new TarEntry(path); + + entry.setMode(TarEntry.DEFAULT_FILE_MODE); + entry.setSize(file.length()); + entry.setModTime(file.lastModified()); + + tos.putNextEntry(entry); + + copyFile(file, tos); + + tos.closeEntry(); + } + } + } + } + + protected void copyFile(File file, OutputStream os) throws IOException { + final int buffersize = 4096; + + FileInputStream fis = new FileInputStream(file); + try { + byte[] buf = new byte[buffersize]; + int count; + + while((count = fis.read(buf, 0, buffersize)) != -1) { + os.write(buf, 0, count); + } + } finally { + fis.close(); + } + } +} diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java new file mode 100644 index 000000000..1c5f429e9 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java @@ -0,0 +1,157 @@ +package com.metaweb.gridworks.commands.edit; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Properties; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarInputStream; + +import com.metaweb.gridworks.ProjectManager; +import com.metaweb.gridworks.commands.Command; +import com.metaweb.gridworks.model.Project; +import com.metaweb.gridworks.util.ParsingUtilities; +import com.oreilly.servlet.multipart.FilePart; +import com.oreilly.servlet.multipart.MultipartParser; +import com.oreilly.servlet.multipart.ParamPart; +import com.oreilly.servlet.multipart.Part; + +public class ImportProjectCommand extends Command { + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + try { + Properties options = ParsingUtilities.parseUrlParameters(request); + long projectID = Project.generateID(); + + internalImport(request, options, projectID); + + ProjectManager.singleton.importProject(projectID); + if (options.containsKey("project-name")) { + String projectName = options.getProperty("project-name"); + if (projectName != null && projectName.length() > 0) { + ProjectManager.singleton.getProjectMetadata(projectID).setName(projectName); + } + } + + redirect(response, "/project.html?project=" + projectID); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void internalImport( + HttpServletRequest request, + Properties options, + long projectID + ) throws Exception { + MultipartParser parser = null; + try { + parser = new MultipartParser(request, 20 * 1024 * 1024); + } catch (Exception e) { + // silent + } + + if (parser != null) { + Part part = null; + String url = null; + + while ((part = parser.readNextPart()) != null) { + if (part.isFile()) { + FilePart filePart = (FilePart) part; + InputStream inputStream = filePart.getInputStream(); + try { + internalImportInputStream(projectID, inputStream); + } finally { + inputStream.close(); + } + } else if (part.isParam()) { + ParamPart paramPart = (ParamPart) part; + String paramName = paramPart.getName(); + if (paramName.equals("url")) { + url = paramPart.getStringValue(); + } else { + options.put(paramName, paramPart.getStringValue()); + } + } + } + + if (url != null && url.length() > 0) { + internalImportURL(request, options, projectID, url); + } + } + } + + protected void internalImportURL( + HttpServletRequest request, + Properties options, + long projectID, + String urlString + ) throws Exception { + URL url = new URL(urlString); + URLConnection connection = null; + + try { + connection = url.openConnection(); + connection.setConnectTimeout(5000); + connection.connect(); + } catch (Exception e) { + throw new Exception("Cannot connect to " + urlString, e); + } + + InputStream inputStream = null; + try { + inputStream = connection.getInputStream(); + } catch (Exception e) { + throw new Exception("Cannot retrieve content from " + url, e); + } + + try { + internalImportInputStream(projectID, inputStream); + } finally { + inputStream.close(); + } + } + + protected void internalImportInputStream(long projectID, InputStream inputStream) throws IOException { + File destDir = ProjectManager.singleton.getProjectDir(projectID); + destDir.mkdirs(); + + untar(destDir, inputStream); + } + + protected void untar(File destDir, InputStream inputStream) throws IOException { + TarInputStream tin = new TarInputStream(inputStream); + TarEntry tarEntry = null; + + while ((tarEntry = tin.getNextEntry()) != null) { + File destEntry = new File(destDir, tarEntry.getName()); + File parent = destEntry.getParentFile(); + + if (!parent.exists()) { + parent.mkdirs(); + } + + if (tarEntry.isDirectory()) { + destEntry.mkdirs(); + } else { + FileOutputStream fout = new FileOutputStream(destEntry); + try { + tin.copyEntryContents(fout); + } finally { + fout.close(); + } + } + } + } +} diff --git a/src/main/java/com/metaweb/gridworks/model/Project.java b/src/main/java/com/metaweb/gridworks/model/Project.java index ec1812e96..2f4a264ba 100644 --- a/src/main/java/com/metaweb/gridworks/model/Project.java +++ b/src/main/java/com/metaweb/gridworks/model/Project.java @@ -38,8 +38,12 @@ public class Project { transient public ProcessManager processManager = new ProcessManager(); transient public Date lastSave = new Date(); + static public long generateID() { + return System.currentTimeMillis() + Math.round(Math.random() * 1000000000000L); + } + public Project() { - id = System.currentTimeMillis() + Math.round(Math.random() * 1000000000000L); + id = generateID(); history = new History(this); } diff --git a/src/main/java/com/metaweb/gridworks/util/ParsingUtilities.java b/src/main/java/com/metaweb/gridworks/util/ParsingUtilities.java index 990ae7e90..46eda1cc7 100644 --- a/src/main/java/com/metaweb/gridworks/util/ParsingUtilities.java +++ b/src/main/java/com/metaweb/gridworks/util/ParsingUtilities.java @@ -8,6 +8,9 @@ import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.net.URLCodec; @@ -19,6 +22,27 @@ import org.json.JSONTokener; public class ParsingUtilities { static public SimpleDateFormat s_sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + static public Properties parseUrlParameters(HttpServletRequest request) { + Properties options = new Properties(); + + String query = request.getQueryString(); + if (query != null) { + if (query.startsWith("?")) { + query = query.substring(1); + } + + String[] pairs = query.split("&"); + for (String pairString : pairs) { + int equal = pairString.indexOf('='); + String name = equal >= 0 ? pairString.substring(0, equal) : ""; + String value = equal >= 0 ? ParsingUtilities.decode(pairString.substring(equal + 1)) : ""; + + options.put(name, value); + } + } + return options; + } + static public String inputStreamToString(InputStream is) throws IOException { Reader reader = new InputStreamReader(is, "UTF-8"); try { diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index a20aafd5b..b2b75e05c 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -1 +1 @@ - Gridworks

Gridworks
Gridworks
Data File:
Project Name:
Load up to: data rows (optional)
Skip: initial data rows (optional)
\ No newline at end of file + Gridworks
Gridworks
Gridworks

Upload Data File

Data File:
Project Name:
Load up to: data rows (optional)
Skip: initial data rows (optional)

Import Existing Project

Project TAR File:
Re-name Project: (optional)
\ No newline at end of file diff --git a/src/main/webapp/scripts/project/menu-bar.js b/src/main/webapp/scripts/project/menu-bar.js index d1a62d536..1d000b57f 100644 --- a/src/main/webapp/scripts/project/menu-bar.js +++ b/src/main/webapp/scripts/project/menu-bar.js @@ -12,7 +12,7 @@ MenuBar.prototype._initializeUI = function() { var self = this; - this._createTopLevelMenuItem("Data Set", [ + this._createTopLevelMenuItem("Project", [ { "label": "Export Filtered Rows", "submenu": [ @@ -25,6 +25,10 @@ MenuBar.prototype._initializeUI = function() { "click": function() { self._doExportRows("tripleloader", "txt"); } } ] + }, + { + "label": "Export Project", + "click": function() { self._exportProject(); } } ]); this._createTopLevelMenuItem("Schemas", [ @@ -161,6 +165,27 @@ MenuBar.prototype._doExportRows = function(format, ext) { document.body.removeChild(form); }; +MenuBar.prototype._exportProject = function() { + var name = theProject.metadata.name.replace(/\W/g, ' ').replace(/\s+/g, '-'); + var form = document.createElement("form"); + $(form) + .css("display", "none") + .attr("method", "post") + .attr("action", "/command/export-project/" + name + ".gridworks.tar") + .attr("target", "gridworks-export"); + $('') + .attr("name", "project") + .attr("value", theProject.id) + .appendTo(form); + + document.body.appendChild(form); + + window.open("about:blank", "gridworks-export"); + form.submit(); + + document.body.removeChild(form); +}; + MenuBar.prototype._doAutoSchemaAlignment = function() { //SchemaAlignment.autoAlign(); }; diff --git a/src/main/webapp/styles/index.css b/src/main/webapp/styles/index.css index a3fb98c3f..7c8abf744 100644 --- a/src/main/webapp/styles/index.css +++ b/src/main/webapp/styles/index.css @@ -53,6 +53,11 @@ padding-bottom: 0px; } +#create-project-panel h1 { + font-size: 120%; + margin: 1em 0; +} + #projects { white-space: pre; }