pax_global_header00006660000000000000000000000064116555470060014523gustar00rootroot0000000000000052 comment=a1312f151d29f09c5163b7d7e42ce1c0d3158c61 felix-gogo-runtime-0.10.0/000077500000000000000000000000001165554700600153225ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/DEPENDENCIES000066400000000000000000000012551165554700600170760ustar00rootroot00000000000000Apache Felix Gogo Runtime Copyright 2011 The Apache Software Foundation This software was developed at the Apache Software Foundation (http://www.apache.org) and may have dependencies on other Apache software licensed under Apache License 2.0. I. Included Third-Party Software This product includes software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0. II. Used Third-Party Software This product uses software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0. III. License Summary - Apache License 2.0 felix-gogo-runtime-0.10.0/LICENSE000066400000000000000000000261361165554700600163370ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. felix-gogo-runtime-0.10.0/NOTICE000066400000000000000000000005751165554700600162350ustar00rootroot00000000000000Apache Felix Gogo Runtime Copyright 2011 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0. This product includes software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0. felix-gogo-runtime-0.10.0/doc/000077500000000000000000000000001165554700600160675ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/000077500000000000000000000000001165554700600227155ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/apache.png000066400000000000000000000277221165554700600246560ustar00rootroot00000000000000PNG  IHDR<!X[iCCPICC ProfilexXy8o>aLvBȾ}߳K/BDB!DDdH)%%ʒ/4?{]zz_s>yu6^o %!T{S7 0 t%X`@ƛB ~|[2{Ӵ<" X8}#pDR"$x Mu7@ᅪﳍM@гCs:"^|}#!llHH/k )H/ zݲ7@Obp'@(럜1rr??OIf4QlYm:U h &FQ@. +$eލa?˸W`A{ψlW>a"cb %2/tC.kRUYQcQߥ!/k a(dgil1lŸՐK^n.NNN.nnoGNxx.xy#w7IO ZVEyE}19eKOT={81N)..'OڧfX2?mixF/K;[Zj9y*T/j\2l\hvŲ5J|JnoWDފWw'&ntmz}bGMd@˷'mmYO:p]SϚ(PzɫAק0i{dXmx]{W >0N;5i:I2-2=LדssϙZZ[aWJ͵ޟk›[i4FP>L/ V" ka.>10=hB©{[E6d=%2%>ʠe4<})RqV5USQ`Ик]멧10l3*1>aB6/omi>ekyߪ:-QIy +ugay}7ՇHt5!I8ɸ@Tzra1hᨡ聘؞' MoTt4XT҉i'3O)9#ŗu-t<]*va+js_L]}wmz_qWI[iƛue5UnWVWݽ}N[󻃵F;r6>k{ i[i}YAwsJk^h?SW/k_P^ ;yp;{Q_z>6WON^*?}/E3%_+fk~\uiuȪC1g6ol:ŽPkNL]}##Ε"pi!vnkx+ <ݼC;ն^paOP^-]"bq&xɗRge2erq " =JJ-H8**+j:j)5ôص]u ut'NKr6xL'qGXX Y[iY-X۶%+8\stsbwqNuuZ{ Mm½Gg!ԡfuUboI8@ ^  ShԫQ\QĜSgOhH:L:ę4wXdTLiO[eHb85}=LroY睾e%< W>_6z}xdtZBa{U;j~rӨO_0PQvsV'QmMOC;=^ٗ"7zoGJ'j?--D/ .o,h۳^ o /@'2[Gu@dP HP`$8< @8F<CfQ(q~uu5BGЕQ +,҅ݦ[WOor:C1&+c=w7Ƭ\"RQϪɶ±ӂ3W 0w;/zMR~[ ]. {2 6Ȉ̊VKKܓҗI\ Ӗˏ+)R"VީVZzE󠖅>!1DT~~s XSWmlMo8r::>?]O$IgW!p"b1J3:-f(N,>1ȃc6џLJ:u4w [lnyB@˼__+,>VrӻGU@u\;u\Os~˫6|Ugֳ^)pcDԉiN+-Z"W*n-w{֎_'~% HkC0#>!yH-YDQN8T)j͇6EǠУ%& N3ˠ{AޗvR&3C-#'c,8 ̤T,\ɢoAeűMqHsLN{u_+ܮ$e{B ޛ/ )ClZEdN 1v l%}UTUW>iti>Һ]S[wC̠ʰΨ;9,,1E2Í>F(cjŸS@׫ 7P!HA0 T"Gۻ:=+eor$FQdH>L"P"ITiY(QV(/ Qw:(Y IDATxiTOUݭ٧gavVgQQ}&W#1OOШD#*5.K!3 ̾LwOO]$yGE}m9u{:Uwc FD0t:QO#Rv`?~$-)c|n}(Z]N3|馛vsbuejGWOt:RP1.d29K/M5,F_A;7ʎOw`2ҩ\WM*B`B(^4 B!vm6+ J=KSᯁѠ&Ktwe,\{뫭=E5kGW^( YxqggW1k׬=gWx">e]vr>+.?<wPj}֙fYUTjXPWc7mJ8$#E <8C pL1b @F8;@ƈ%)ezfyR2m/ Av'˺Il8ѱ=>txƞ6hE[|X,F)bDfhhhXx^1tG-]9\.Q9j? h!g10>Τ lҧz~_JTU=#qi^UUB' sŢѨ$I&iR1VU->p8H&8+M~`rYeEp$El6G` :0RE8.F!oӦLf V?bњ9):p a"2VGD I(1uC(!0#%DP[ & f#>Ꙅ8[lig"Qߐ̵Xp95.ҹhIƪI΂] b $!Tp +ZM5kڶg׮sf{b<_ӴwVq7VTT,XiΝAϾnԷ 7`4_uU{l /ʺu Gȷm0̞3'UhѢ믿׭[6>GmxI^-7~֭Zd˖[O<1ꩧB/vm[,Y}۶WSO>q۳gς p\ 7D֭[bh=6'<ݰ/D! . ʇͿd"(]w5t\Ŷֶ︳e˗~koơw7|.@Oou8Vʍ7x폯Mڵkɒ \vzGƏDxϽ& -{V5aGggGWcKRB`SGh0f-âXTZ%ܸ1FzܱdOP!LtH.fLbxJSG\%,1+)BtMB%zk,?T;hKu1lI W/ 4:==r qF̒ab"OuY/QpםwګoVSsQ5!dsJJK|n騼dW*۷o{g-ZЃj333 ڵk?)xg;g5sĜذaoWMӶ=Ha:ۻdrr;ax7|H4w`\O] ݥX*/}C͏bdpc=HG!d i6*(g?%A8g;?2xA)t}YɊXI%& kL4בt0R{0>{y+;xC~tq[XqxX8L'WD⬙3].c,'7gxx8"әi4KJJR$Y֜WLOO5kj={öR 'sΝ;w~tvtv̞=rwG'M557d`Uscu_jsι缳r$8{k>cFMMMM$mjj6Mf޻ݽw1n 0U(ZEQ'LW^y3O?s$aVV^|~EKQUMӎ6x=n`0LFn7m?&vӦM[R[o`0ftuwqǗ'hpg 'Lt:'M{ʻY ]Q|jSH5`y(- Ym~<m8Rޟ%>t21sy"P2Ywڈ(6I퉭|)uue]E.رբ(.sW*V]=6զt._섉*^zX,>e"r9ӗ.]zZiU..H~щTϟ.~SJSEQDIL͛W^^v뭷zh)'Çi9,w UUڵk>#.L&ׯ[{񊢫W`\|L=Cܼ^}ĉ3ϚGa Gnj)yg=眺ں>۝H$ƌj|EeK/8~iuS H8F"Ta[[۬Yjc$W^yu30Ƽ^ŗ^2iҤp80/?d4_)Ui QQyjN0K/˝#f{o婒e,9sftď YYY [ce< 0[ݕΘ1hYdƍ Bt3p3]B\-&%,B"G ԡuR:YIN4a|us2;Ž#akm;Khp'Ip^/v!قDq~JP7A #&i-Do A x<K614( |Sb /웜߻Ƃܱ-+9I8NOOQ9.򺺺Gyo\`~ߥa,/[gd|.ZZZlr]w 7ol&L0¹f;kֹu}iC1c!͝[QVv:y9eeps[e>ov<_pEǍ(z lܸ>W?oeedtMM?77_-B{L3"u'S=أ ,\z{***jҎ5rrrFz衻{ܹ BTmccc{{{j1^hѯ~K/t`plDa4]8(>?,+/p8FcjzzSOrWNqKo4aY gF*QK8g؞Ua0$"M(Έrnuޭz&荶C8dsH3]0Cm|la *bA@LBIOƤ60] ѻ!IP>/wEԞ3UcCxgTD be#m=|j+;44400PQQ=Ѓ"[~۔ɓͻa@ \'cU?UVX5pݲ,QMNUFl^RZ53$0ƚ322OCCCY,^z/jW_}MV" =ҩS뎭0ˏ=h!-- fpw|u+s+/ˍR@OM6=S(=R3a>"%9D,X#sMFf'CE5yHXi|pH#MH;*RD4,S4>L4ڄ|1%.U ]JYHC>AUkD8τAp&b rMB$'Wj?*Jd5PsR"/P ve`W.3Mi6uY>tJuON!$]շZoN՟=2L'Ĉpk=Xh:|aL}ĒgrHX`Q}90v4ӡl JH! 3pTQ̣ʃ*R) f* Qq6-@\B4RtzHib&dĈq?o#= - <3)U)@x)g);K"cc,|0t柟뚔_x``o5IEj9rZBG?0SZ nbKjB-hrh,xtHaA "!& !@>6Pp -W !Ԝմ LU`*0!q*023?g3A0ubKԨ\ Q$2m;"{y[ D"Ѽ2SS+{9kAC`Mt $n QhmmMÁ~K4<9;ƬCxÁP|,{@M}x+a^\ŨjRީg0  CD+ IrJI .I1-#hDeF$Z*~:(8Җ1Fr1: #6T1N$ }i-XJ0uE΃-ʺLwPrqX0$"EݚODr(8,{YPBR&gU(PCgJ.I+R=[n bNϒ,&?$Ix7;#A;w M Yjܹ_=ؒ`u}XƟa׺m[3c}2o1+I6LpMD1*#;y@H&F0rYlr! Y<ŒuNcqS]$ƴͯGd~5E1I04MUy#aoG2DӃ"; ""ڼHtٙ\$h#YSS 9RUsMY& ge9 Fx4Ãn6}f~40zQBG3gA;('@ըJ41'HN&) !A'+J&IDATqGs P46 ~'8t?fIENDB`felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/button.html000066400000000000000000000004711165554700600251200ustar00rootroot00000000000000 felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/button_data/000077500000000000000000000000001165554700600252215ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/button_data/2010-na-125x125.png000066400000000000000000000137471165554700600276460ustar00rootroot00000000000000PNG  IHDR}}^tIME+M pHYsnu>gAMA aPLTEܰaocqziwhvuq~ᓝ{ϊx-(&:53|yw&!LHF"\[Z2-+'# da_JFC VRQFA>wrnyvtvsqqnl*%#㹷~}B>;QMKifd;86a][TQN$ZVT61.~{y\YWnki}tnOHrctZL?yD9kUiH:eVOLC<8=9Oy66VUHQwzmHVOI:FFKRK0mjNIOR%8DN7:4I%;%=%J7&E"I!I5E7Mq3#L%HoPίfVxLgY8x%6+Qf,&P!JA&F#U"Mi#7%Y"V$YLprh

b:$ۙZ߆ ܷln>!sO)ݐ Aqs'Zu;1/h^q ~A U8?W{aE&$7ccϚ0S|f'kASMݎP%y'c(FsvĔcKRis1P˄Уcʜ?d!Pt-y+ =֊ES)w_d]K;(pS1%2VLP.gN{qC9;.:X8{#h3zD'tGD ] =+?ɛsM-;[.SW E¨3.(ȋLCIWroB:yDxx"CdCd!wͬӃmvy<=Ih~/-݄(ׄ?{G7tw젝< \j/c-c8~ s_dy5a꠩_Fyw-_Ϛ]5ߚv7 ga< }b0mٖzEڵI5+k=4ntC7X"OOf>^Z=%{m;kVMZzuwY6-n%Ǝ^K=ػ\*HS+7oKI^ŶU5k显% :ǖV։geo9nKOOZbê[Yo<~$\# ejZm)Wl.3DPjsXQmqByQJӍ*$tnEE) -yʚ{YOk.hsE%e sy4KtA)MVEJ?-sܻ%7aLQ?(:ZP$SJ ȀnK+*%eONӢ+74Vt ?\:_[X(V(;hZ,NU<$'mK߾jwDR;/{/(.;P\\[\|V)uv@%{~NNZ_ (ĵ7hZ#$gɊs:'ѡ[^!uLb EºܫW} :+;I!Y2e-"iBsɓ]zFGqKV'gnEn ܙڟj U>^U^ w(Aw7䵹MRhbTCWwI˲G<Η*reں ʡ5//'xk J$R7 gg佇v1O'+1~;V\\TR\X{ϡCO>tb}qOLYkˮoOMKٰ!;[,f_f+3Bir?C EсⒽwڳ{ϞCt]eͲ5o]zźm┴ sYX!]3;'C&ߺk={wyy{rs$$|lV\vʤuVߐ1%%g}sj盾cj%YX SFff\#3npXX6kGGGXIR/Y.ՁK)-ŷ'Y,Riz9َ5^K ŵб'O"4|FM4K$~lklbj: ?N{6V't^,=;Ojm"zfVL#Efpb=#͵r^`/- P!6Y9P[M`Gt_QGE\P2 ( vs4EYGQ@܂Y>Žchކ_Б=й(MX1-]>!_v@/"Oc81wflX5JF|q|1$R]T-*7:q. !,(f6 -T}s[Wf[8Bsc8.8"KB GV"ۍax-@1*]͛猜Utk:tw}v 2B^a'u Z=&*qܽ|O٢@@\K81͒gG@'1C|{zH>ƾ~&V0ko@\s!E]ݨyTqpH4( tzj;تeݯTǁ<]wy;Ly{*w;z1QSclΘ{Ag4Cwj 5B#{.O!ޟPGT't~ҵGG[U`h#:x#]3\uuOk@L}RGnXZh<)u84HϘ@0ɠ?d>AHw Mg2LFc:Zс>` P?2y_E5< j>ሣ&(`t3\#G C@!3t]qhD;Ƿ vGukqtwI: h\KuFMg⪉G,i$GS=]RNSuCM Bg3ƍhUݐQ3'CcBҏitt :=ODtA1Tј qjC1 2-juOM}1?GkB6AτBC B:)uT{ݵOFÆN=Ee; qֆ M5tk;ZPuݐiZ"Gt=lOFM績zqzOl-j.Q0~tU1nY&\rAmlҷNG؁zY;?w7|t>1 uIENDB`felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/logo.png000066400000000000000000000351171165554700600243720ustar00rootroot00000000000000PNG  IHDR?[iCCPICC ProfilexXy8o>aLvBȾ}߳K/BDB!DDdH)%%ʒ/4?{]zz_s>yu6^o %!T{S7 0 t%X`@ƛB ~|[2{Ӵ<" X8}#pDR"$x Mu7@ᅪﳍM@гCs:"^|}#!llHH/k )H/ zݲ7@Obp'@(럜1rr??OIf4QlYm:U h &FQ@. +$eލa?˸W`A{ψlW>a"cb %2/tC.kRUYQcQߥ!/k a(dgil1lŸՐK^n.NNN.nnoGNxx.xy#w7IO ZVEyE}19eKOT={81N)..'OڧfX2?mixF/K;[Zj9y*T/j\2l\hvŲ5J|JnoWDފWw'&ntmz}bGMd@˷'mmYO:p]SϚ(PzɫAק0i{dXmx]{W >0N;5i:I2-2=LדssϙZZ[aWJ͵ޟk›[i4FP>L/ V" ka.>10=hB©{[E6d=%2%>ʠe4<})RqV5USQ`Ик]멧10l3*1>aB6/omi>ekyߪ:-QIy +ugay}7ՇHt5!I8ɸ@Tzra1hᨡ聘؞' MoTt4XT҉i'3O)9#ŗu-t<]*va+js_L]}wmz_qWI[iƛue5UnWVWݽ}N[󻃵F;r6>k{ i[i}YAwsJk^h?SW/k_P^ ;yp;{Q_z>6WON^*?}/E3%_+fk~\uiuȪC1g6ol:ŽPkNL]}##Ε"pi!vnkx+ <ݼC;ն^paOP^-]"bq&xɗRge2erq " =JJ-H8**+j:j)5ôص]u ut'NKr6xL'qGXX Y[iY-X۶%+8\stsbwqNuuZ{ Mm½Gg!ԡfuUboI8@ ^  ShԫQ\QĜSgOhH:L:ę4wXdTLiO[eHb85}=LroY睾e%< W>_6z}xdtZBa{U;j~rӨO_0PQvsV'QmMOC;=^ٗ"7zoGJ'j?--D/ .o,h۳^ o /@'2[Gu@dP HP`$8< @8F<CfQ(q~uu5BGЕQ +,҅ݦ[WOor:C1&+c=w7Ƭ\"RQϪɶ±ӂ3W 0w;/zMR~[ ]. {2 6Ȉ̊VKKܓҗI\ Ӗˏ+)R"VީVZzE󠖅>!1DT~~s XSWmlMo8r::>?]O$IgW!p"b1J3:-f(N,>1ȃc6џLJ:u4w [lnyB@˼__+,>VrӻGU@u\;u\Os~˫6|Ugֳ^)pcDԉiN+-Z"W*n-w{֎_'~% HkC0#>!yH-YDQN8T)j͇6EǠУ%& N3ˠ{AޗvR&3C-#'c,8 ̤T,\ɢoAeűMqHsLN{u_+ܮ$e{B ޛ/ )ClZEdN 1v l%}UTUW>iti>Һ]S[wC̠ʰΨ;9,,1E2Í>F(cjŸS@׫ 7P!HA0 T"Gۻ:=+eor$FQdH>L"P"ITiY(QV(/ Qw:(Y IDATx}wUZkrTfdE"JDchl5h|D|+j4 F, A(]@@230S8w.d!q:{ۨo V7wֵ;"`Ӽ99i^{R/s=_׵G40rr[|bߣ^v=pU=F\EA$CƐH L>epug̎ߣ8^~WԵo.d+@[$ rx%C%{▀q'wKƟ[=Yۿ-ic1tJ%D "PIQ$&1D1n p=v٩~W/>asnR\!@ƎmݶAlk\y'jWWn ?1UCG* ܺYY6P QU}Ϭxz!ڎ朼$=#LƤ`(\W[7}4'ePG#-=3Ѵuk7Th:X 3kFHx< iYDN n <ῶ@V tuȺ{/>,.~>āH1*yq!@7ag~qCScca hNvzFf"ѯZBY@5ڶ [#.UAȅ?~dF~H ,<C`L,t)*,Q~nH `W}y GVӋ  ,(,Pݞ⒒E=Z ZZ~#PWw@2IvvQÑw ,A'&!mtVT/[j7afXʣV?(mHtPo414&FW)x_/ɮOXHPG?l 5**_W5OK!RSc3\‚#{\Vx|Yqeijl@#͏Vey}Ʌ@Ö/Z<&2'L:%;7OpNH SO:GlA0 AkҋQZq}JAV@hqmwbwt˧i}GM[(3D*G# z!p[K"+$Z QS]䷰KRdYu\;:<uWDeV]mi[RP(d$+W*P%+;;q @8nq3=74v`K1)M6ނ~`]恈 Pb$d剟S=ET;3Ɓи襢{otCe\W7\4zCLCU=uu1EU뚢@x-cMMkcL -M{1ILOܟj۰mG2}6 oUN7W4RS8 Ȁ83v W?ux綐d.7k'? :L(}8,]ց`+S "D-fy벱h,ynݶy0DHuԕ1{]Se`'#JOOD C4Y^ C!  rncp0\f-H7@' /RGi> ii>wİ-y$gnvYsz0AXqW 4 TDYxԴ0z=^1LH~]XV!_UQr%Sd9+d~p}GDG   (m߸!DDH3wxӟ/R԰MYm&Xx4kHldglZfcX?vGql~[6o$o} fiI;2p3e,)N@9dΙ6o̰e&h/^/XHD:x {pl~ 8`D9 gd9' #3k}A'' a??s B ""X(7\4!b<(Wz)aNGBK@ԲO 6ďtSq/F;(cȑ]'-w+'ͭ0"xxYMvʼn!1E6S<H$j]]ݪUl(//oѣF0`$hkk۾} ֭[qƗ_~s=Z4OVI8fe5?CPDӔ_8QUQjHy/H &18$r| 2jC n)x .W*jhh:u޽{o-?~ /0x^iC*1{kŅw̫oc.KEEկ0(X o۰n3Gz]\~?9f>QJ)T]h*h``+’w-[YeG>s[[G}pf@ZZڄ z.0S)G\!w# b5k\s5xljw0潽Ʋ9{qgDb76r0(fUw t G]~=C 3zycRdv]cQf˖Yi}Bm7xUK.;8nc&kmm}R)ׯ߱cĉ{%,;MOܒ%w;D(!od[n;vč8>j׭Gջ*C~B6fSԖ–1)nɺ-3*-^~;ۍ8hР1cdgg#UW]u|[0Ɯ؇TN9~߫7~[k(3!`R(d>Q  +۞H&a*K>Rdv@4 lPiy^QC:.*M,tg2IVJi.9bV=e4w8?gϮp L3ysӨLˣ[i 쀵F#! Ub2ܭ1>۽{wy+¹,,,,,<߀sZxb0NO+ܬljC]U2WZq!!ZhfE򆸬0 b(|mD<eL烥nѧȭګ澺`G Z ]6qCEL T"Dm0+AZHXaa; \e_PĆsC38@]"zh[ֶbgݵkW駟^rssOsPy~M嘙P 5~D‡&zfO|]'(=N,1";QJ ":a_^ k.ջ ۏylln0aC#ÉK쳏x뭷z뭷W2eO>9N;믿/?fK/?~饗.^˗/ӟ .xw8>-Z+;sY_u첀ۦyO3]"f0*)7d\~-@X-N m:Ŷ?~@9>WWv[#kʠ,H,缲ܜv)*f d(fW;g_wȼKq'.P$]r>Vxi=I g͚yninw߾}uJ***f͚ {Xݷm^QQѼyR)ixmmmI?r4]wݕ$M7?|'pڪGa~CvyaE| $E>E_2nx8VqxFcc2shDᒸ@a$T2ӥCy7Cg֞@ C4*=>#7U=c8LKKK/_^VVbŊ]f͚rʲ˗=:y;ܰaCj?s_~;vܹcǎ N<95|onO7̙3磏>ZrєT\z饷v[*eϞ=r󿬬GM[XXsϥnckEqu>yb%[<|7Is~g۶mKR-ZtYg?馛L;D|ghǞ:K3%| SrAB! < ^;ʹCq#[&]I*knݸ òڇeFL0i`GDDK.׸@Lk-Jd]b^+wz:m2T]?^N^^×UUUG |>H$0jH|x}gn4nHbSL% @Fk*8HߠkGm4 cn RdR>Gz4`^–aBKC%l%**1Hqi,r"bI^EJ5Z@U~w3QQQ1vn[]`_j„ FFQ%RDה {KLQQ##Œj0#r3#aȒiCĭbg+ B[Ʉucvi*Yqb* Q笻5z0NZwr,`DDPexJZ/{С>8&{[555rK䂈__q9jsOsg,)^{Z: ,ӸwlQJ(DAjC}0kbe%KALCw Hɾ1~LzjETWvf{$#0xi(ʍ7ޘJBxꩧȪ֛o;a ߹mC[ ~E]$II2o޼n6/N)NZT]绻FQ .,,~7|6]tPC`l65-06gVN8a =601J8h??}p9 6ۀ7??FvI:yY#Tis9Sxŋ˖-{饗~󟗖>s ,{Rg}6wܲTʄ Ν/---ߞjO(Yi@FJL\km3w  ĴF<[J57et ,It@ A0pqhEَBEi|E^TemK UwVYgAB)K;e˱X@.Ĝr^|ų:=m۶TT*4M{_|>۝ ^tΝ;Clʕ+?v+n[j;3\+Vp֙q4I} gN47BZCK x;K[h2}>: 4:plld8X<m}#+m`Jۧj݆c%9L v7sl:_a+馛oI^^?ߍ8w\'1%k)oyT)ENi,`:v5 Px>ѮHL5:ra7icL"H{5:]6nf99';~(Ίs~Lׯo_7\z}RÕ<O^^gΜy%t$;n;pV7ibС[+V8pK!DVV֓O>yfs9?ロ\qxӧr>=f]H0)*{N ظlR$0T28J0 $\IB. ` >a"H"{b{!dBpq|,&1ĐH8v X]rSɷFDݎ $egggggcʆ=dȐ#Z9$Sۦi䜧҅l,+5i$u?k٦=O)r$I^_^14A.2@ $ $\W寧;ds0 HdkRsDQ2pl o^'ۤx89Qcpזnɥq{=jS3XL(Nw WX- 3AvWv|#\FFӉEsym&@[U)0{\EC[(L#‚*`(^‘yk 䰪gDF$s&K*ZdJb۠Ȓ[ Y"2IK0Ȑ$* t~l n/?G=_-WJQdKɯLu9ìsb/ X"M~rըMMMQKV$GHUi]}mg},3Kak>>ʇŐl$6LP_6ukCr*Kq"* :./Ҥ 8\rᦪMmAݒSY1& q"HrӋ2:pC~mӾd_"leɌI1mH tnrI~^÷W6nZmq;_hKyia93'M/bSsl}S|K^;-0"1bQXK*Ic ytr|q!cFH32ᠴ[4;fa@,y|"c8>vIENDB`felix-gogo-runtime-0.10.0/doc/apache-felix-gogo-Dateien/site.css000066400000000000000000000030471165554700600243770ustar00rootroot00000000000000/* @override http://felix.apache.org/site/media.data/site.css */ body { background-color: #ffffff; color: #3b3b3b; font-family: Tahoma, Arial, sans-serif; font-size: 10pt; line-height: 140% } h1, h2, h3, h4, h5, h6 { font-weight: normal; color: #000000; line-height: 100%; margin-top: 0px} h1 { font-size: 200% } h2 { font-size: 175% } h3 { font-size: 150% } h4 { font-size: 140% } h5 { font-size: 130% } h6 { font-size: 120% } a { color: #1980af } a:visited { color: #1980af } a:hover { color: #1faae9 } .title { position: absolute; left: 1px; right: 1px; top:25px; height: 81px; background: url(http://felix.apache.org/site/media.data/gradient.png) repeat-x; background-position: bottom; } .logo { position: absolute; width: 15em; height: 81px; text-align: center; } .header { text-align: right; margin-right: 20pt; margin-top: 30pt;} .menu { border-top: 10px solid #f9bb00; position: absolute; top: 107px; left: 1px; width: 15em; bottom: 0px; padding: 0px; background-color: #fcfcfc } .menu ul { background-color: #fdf5d9; list-style: none; padding-left: 4em; margin-top: 0px; padding-top: 2em; padding-bottom: 2em; margin-left: 0px; color: #4a4a43} .menu a { text-decoration: none; color: #4a4a43 } .main { position: absolute; border-top: 10px solid #cde0ea; top: 107px; left: 15em; right: 1px; margin-left: 2px; padding-right: 4em; padding-left: 1em; padding-top: 1em;} .code { background-color: #eeeeee; border: solid 1px black; padding: 0.5em } .code-keyword { color: #880000 } .code-quote { color: #008800 } .code-object { color: #0000dd } .code-java { margin: 0em }felix-gogo-runtime-0.10.0/doc/apache-felix-gogo.html000066400000000000000000000072151165554700600222410ustar00rootroot00000000000000 Apache Felix - Apache Felix Gogo

Apache

Apache Felix Gogo

Apache Felix Gogo is a subproject of Apache Felix implementing the OSGi RFC 147, which describes a standard shell for OSGi-based environments. See RFC 147 Overview for more information.

Using Gogo with the Felix Framework

The Gogo subproject consists of three bundles:

  1. runtime - implements the core command processing functionality.
  2. shell - provides a simple textual user interface to interact with the command processor.
  3. command - implements a set of basic commands.

As of the Apache Felix Framework 3.0.0, Gogo is included as the default shell in the framework distribution. To use it, you just start the framework like normal:

$ cd felix-framework-3.0.0
$ java -jar bin/felix.jar
_______________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (3.0.0)
    1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
    2|Active     |    1|Apache Felix Gogo Command (0.6.0)
    3|Active     |    1|Apache Felix Gogo Runtime (0.6.0)
    4|Active     |    1|Apache Felix Gogo Shell (0.6.0)
g! 

Gogo shell integration in the framework distribution is also discussed in the framework usage document

felix-gogo-runtime-0.10.0/doc/changelog.txt000066400000000000000000000052201165554700600205560ustar00rootroot00000000000000Changes 0.8.0 to 0.10.0 ---------------------- ** Bug * [FELIX-2870] - ConcurrentModificationException in gogo runtime * [FELIX-2894] - Gogo does not handles options but not parameters * [FELIX-2927] - [gogo] coercion mechanism invokes foo(String) instead of foo(int) - even with explicit int argument Changes 0.6.1 to 0.8.0 ---------------------- ** Bug * [FELIX-2723] - When the execution of a closure with pipes is interrupted, pipes should be interrupted too ** New Feature * [FELIX-2761] - Add a way to listen to execution of command lines * [FELIX-2764] - Publish OSGi EventAdmin events when executing a command line Changes 0.6.0 to 0.6.1 ---------------------- ** Bug * [FELIX-1473] - [gogo] The syntax does not provide a way to call methods on a string * [FELIX-2432] - [gogo] NPE/coercion failure when null first parameter to method expecting arry * [FELIX-2545] - [gogo] runtime should close all open sessions when it is stopped * [FELIX-2606] - Gogo isn't decoupled from OSGi anymore ** Improvement * [FELIX-2396] - Ability to have callbacks when accessing session variables * [FELIX-2433] - [gogo] allow command expansion inside double quotes * [FELIX-2607] - Introduce a specific exception when a command is not foundGogo Runtime 0.6.1 Gogo Runtime 0.6.0 ------------------ ** Bug * [FELIX-1473] - [gogo] The syntax does not provide a way to call methods on a string * [FELIX-1474] - [gogo] result of commands is implicitly written to pipe * [FELIX-1493] - [gogo] automatic expansion of $args in Closure stops direct access to $args list * [FELIX-2337] - [gogo] no way to access array[] elements produced by assignment * [FELIX-2375] - [gogo] when supplied args can't be coerced, the error message prints the arg values, rather than their types * [FELIX-2380] - [gogo] lock contention in piped writer when reader doesn't read all input ** Improvement * [FELIX-1487] - Support for commands on multiple lines * [FELIX-2328] - [gogo] tidy-up runtime to remove optional code etc * [FELIX-2339] - [gogo] add support for running scripts * [FELIX-2342] - [gogo] remove old felix command adaptor ** New Feature * [FELIX-2363] - [Gogo] Add annotations for creating commands with optional and out-of-order arguments ** Task * [FELIX-1670] - [gogo] launcher bundle not required * [FELIX-1889] - Gogo should depend on the official OSGi jars * [FELIX-2334] - [Gogo] Use org.apache.felix as Maven groupId * [FELIX-2367] - [Gogo] Use org.apache.felix namespace to avoid any perceived legal issues felix-gogo-runtime-0.10.0/pom.xml000066400000000000000000000103471165554700600166440ustar00rootroot00000000000000 org.apache.felix gogo-parent 0.6.0 ../gogo-parent/pom.xml 4.0.0 bundle Apache Felix Gogo Runtime org.apache.felix.gogo.runtime 0.10.0 org.osgi org.osgi.core 4.0.0 provided org.osgi org.osgi.compendium 4.0.0 provided junit junit test org.apache.felix maven-bundle-plugin true org.apache.felix.service.command; org.apache.felix.service.threadio; version=${project.version}; status="provisional"; mandatory:="status", org.apache.felix.gogo.api; version=${project.version} org.osgi.service.event*; resolution:=optional, org.osgi.service.log*; resolution:=optional, org.osgi.service.packageadmin*; resolution:=optional, org.osgi.service.startlevel*; resolution:=optional, * org.apache.felix.gogo.runtime* ${pom.artifactId} The Apache Software Foundation org.apache.felix.gogo.runtime.activator.Activator {maven-resources},META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@))) <_removeheaders>Private-Package,Ignore-Package,Include-Resource scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.runtime-0.10.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.runtime-0.10.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.runtime-0.10.0 felix-gogo-runtime-0.10.0/src/000077500000000000000000000000001165554700600161115ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/000077500000000000000000000000001165554700600170355ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/000077500000000000000000000000001165554700600177565ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/000077500000000000000000000000001165554700600205455ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/000077500000000000000000000000001165554700600217665ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/000077500000000000000000000000001165554700600230755ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/000077500000000000000000000000001165554700600240305ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/api/000077500000000000000000000000001165554700600246015ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/api/CommandSessionListener.java000066400000000000000000000025641165554700600321030ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.api; import org.apache.felix.service.command.CommandSession; /** * Listener for command executions. * * Such listeners must be registered in the OSGi registry and will be called * by the CommandProcessor when a command line is executed in a given session. */ public interface CommandSessionListener { void beforeExecute(CommandSession session, CharSequence command); void afterExecute(CommandSession session, CharSequence command, Exception exception); void afterExecute(CommandSession session, CharSequence command, Object result); } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/000077500000000000000000000000001165554700600255135ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/Closure.java000066400000000000000000000444131165554700600300000ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.io.EOFException; import java.util.AbstractList; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.felix.gogo.runtime.Tokenizer.Type; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Function; public class Closure implements Function, Evaluate { public static final String LOCATION = ".location"; private static final String DEFAULT_LOCK = ".defaultLock"; private static final long serialVersionUID = 1L; private static final ThreadLocal location = new ThreadLocal(); private final CommandSessionImpl session; private final Closure parent; private final CharSequence source; private final List>> program; private final Object script; private Token errTok; private Token errTok2; private List parms = null; private List parmv = null; public Closure(CommandSessionImpl session, Closure parent, CharSequence source) throws Exception { this.session = session; this.parent = parent; this.source = source; script = session.get("0"); // by convention, $0 is script name try { program = new Parser(source).program(); } catch (Exception e) { throw setLocation(e); } } public CommandSessionImpl session() { return session; } private Exception setLocation(Exception e) { if (session.get(DEFAULT_LOCK) == null) { String loc = location.get(); if (null == loc) { loc = (null == script ? "" : script + ":"); if (e instanceof SyntaxError) { SyntaxError se = (SyntaxError) e; loc += se.line() + "." + se.column(); } else if (null != errTok) { loc += errTok.line + "." + errTok.column; } location.set(loc); } else if (null != script && !loc.contains(":")) { location.set(script + ":" + loc); } session.put(LOCATION, location.get()); } if (e instanceof EOFError) { // map to public exception, so interactive clients can provide more input EOFException eofe = new EOFException(e.getMessage()); eofe.initCause(e); return eofe; } return e; } // implements Function interface public Object execute(CommandSession x, List values) throws Exception { try { location.remove(); session.variables.remove(LOCATION); return execute(values); } catch (Exception e) { throw setLocation(e); } } @SuppressWarnings("unchecked") private Object execute(List values) throws Exception { if (null != values) { parmv = values; parms = new ArgList(parmv); } else if (null != parent) { // inherit parent closure parameters parms = parent.parms; parmv = parent.parmv; } else { // inherit session parameters Object args = session.get("args"); if (null != args && args instanceof List) { parmv = (List) args; parms = new ArgList(parmv); } } Pipe last = null; Object[] mark = Pipe.mark(); for (List> pipeline : program) { ArrayList pipes = new ArrayList(); for (List statement : pipeline) { Pipe current = new Pipe(this, statement); if (pipes.isEmpty()) { if (current.out == null) { current.setIn(session.in); current.setOut(session.out); current.setErr(session.err); } } else { Pipe previous = pipes.get(pipes.size() - 1); previous.connect(current); } pipes.add(current); } if (pipes.size() == 1) { pipes.get(0).run(); } else if (pipes.size() > 1) { for (Pipe pipe : pipes) { pipe.start(); } try { for (Pipe pipe : pipes) { pipe.join(); } } catch (InterruptedException e) { for (Pipe pipe : pipes) { pipe.interrupt(); } throw e; } } last = pipes.remove(pipes.size() - 1); for (Pipe pipe : pipes) { if (pipe.exception != null) { // can't throw exception, as result is defined by last pipe Object oloc = session.get(LOCATION); String loc = (String.valueOf(oloc).contains(":") ? oloc + ": " : "pipe: "); session.err.println(loc + pipe.exception); session.put("pipe-exception", pipe.exception); } } if (last.exception != null) { Pipe.reset(mark); throw last.exception; } } Pipe.reset(mark); // reset IO in case same thread used for new client return last == null ? null : last.result; } private Object eval(Object v) { String s = v.toString(); if ("null".equals(s)) { v = null; } else if ("false".equals(s)) { v = false; } else if ("true".equals(s)) { v = true; } else { try { v = s; v = Double.parseDouble(s); // if it parses as double v = Long.parseLong(s); // see whether it is integral } catch (NumberFormatException e) { } } return v; } public Object eval(final Token t) throws Exception { Object v = null; switch (t.type) { case WORD: v = Tokenizer.expand(t, this); if (t == v) { v = eval(v); } break; case CLOSURE: v = new Closure(session, this, t); break; case EXECUTION: v = new Closure(session, this, t).execute(session, parms); break; case ARRAY: v = array(t); break; case ASSIGN: v = t.type; break; default: throw new SyntaxError(t.line, t.column, "unexpected token: " + t.type); } return v; } /* * executeStatement handles the following cases: * '=' word // simple assignment * '=' word word.. // complex assignment * word.. // command invocation * // value of * word.. // method call */ public Object executeStatement(List statement) throws Exception { Object echo = session.get("echo"); String xtrace = null; if (echo != null && !"false".equals(echo.toString())) { // set -x execution trace StringBuilder buf = new StringBuilder("+"); for (Token token : statement) { buf.append(' '); buf.append(token.source()); } xtrace = buf.toString(); session.err.println(xtrace); } List values = new ArrayList(); errTok = statement.get(0); if ((statement.size() > 3) && Type.ASSIGN.equals(statement.get(1).type)) { errTok2 = statement.get(2); } for (Token t : statement) { Object v = eval(t); if ((Type.EXECUTION == t.type) && (statement.size() == 1)) { return v; } if (parms == v && parms != null) { values.addAll(parms); // explode $args array } else { values.add(v); } } Object cmd = values.remove(0); if (cmd == null) { if (values.isEmpty()) { return null; } throw new RuntimeException("Command name evaluates to null: " + errTok); } if (cmd instanceof CharSequence && values.size() > 0 && Type.ASSIGN.equals(values.get(0))) { values.remove(0); String scmd = cmd.toString(); Object value; if (values.size() == 0) { return session.variables.remove(scmd); } if (values.size() == 1) { value = values.get(0); } else { cmd = values.remove(0); if (null == cmd) { throw new RuntimeException("Command name evaluates to null: " + errTok2); } trace2(xtrace, cmd, values); value = bareword(statement.get(2)) ? executeCmd(cmd.toString(), values) : executeMethod(cmd, values); } return assignment(scmd, value); } trace2(xtrace, cmd, values); return bareword(statement.get(0)) ? executeCmd(cmd.toString(), values) : executeMethod(cmd, values); } // second level expanded execution trace private void trace2(String trace1, Object cmd, List values) { if ("verbose".equals(session.get("echo"))) { StringBuilder buf = new StringBuilder("+ " + cmd); for (Object value : values) { buf.append(' '); buf.append(value); } String trace2 = buf.toString(); if (!trace2.equals(trace1)) { session.err.println("+" + trace2); } } } private boolean bareword(Token t) throws Exception { return ((t.type == Type.WORD) && (t == Tokenizer.expand(t, this)) && (eval((Object) t) instanceof String)); } private Object executeCmd(String scmd, List values) throws Exception { String scopedFunction = scmd; Object x = get(scmd); if (!(x instanceof Function)) { if (scmd.indexOf(':') < 0) { scopedFunction = "*:" + scmd; } x = get(scopedFunction); if (x == null || !(x instanceof Function)) { // try default command handler if (session.get(DEFAULT_LOCK) == null) { x = get("default"); if (x == null) { x = get("*:default"); } if (x instanceof Function) { try { session.put(DEFAULT_LOCK, true); values.add(0, scmd); return ((Function) x).execute(session, values); } finally { session.variables.remove(DEFAULT_LOCK); } } } throw new CommandNotFoundException(scmd); } } return ((Function) x).execute(session, values); } private Object executeMethod(Object cmd, List values) throws Exception { if (values.isEmpty()) { return cmd; } boolean dot = values.size() > 1 && ".".equals(String.valueOf(values.get(0))); // FELIX-1473 - allow method chaining using dot pseudo-operator, e.g. // (bundle 0) . loadClass java.net.InetAddress . localhost . hostname // (((bundle 0) loadClass java.net.InetAddress ) localhost ) hostname if (dot) { Object target = cmd; ArrayList args = new ArrayList(); values.remove(0); for (Object arg : values) { if (".".equals(arg)) { target = Reflective.invoke(session, target, args.remove(0).toString(), args); args.clear(); } else { args.add(arg); } } if (args.size() == 0) { return target; } return Reflective.invoke(session, target, args.remove(0).toString(), args); } else if (cmd.getClass().isArray() && values.size() == 1) { Object[] cmdv = (Object[]) cmd; String index = values.get(0).toString(); return "length".equals(index) ? cmdv.length : cmdv[Integer.parseInt(index)]; } else { return Reflective.invoke(session, cmd, values.remove(0).toString(), values); } } private Object assignment(String name, Object value) { session.variables.put(name, value); return value; } private Object array(Token array) throws Exception { List list = new ArrayList(); Map map = new LinkedHashMap(); (new Parser(array)).array(list, map); if (map.isEmpty()) { List olist = new ArrayList(); for (Token t : list) { Object oval = eval(t); if (oval.getClass().isArray()) { for (Object o : (Object[]) oval) { olist.add(o); } } else { olist.add(oval); } } return olist; } else { Map omap = new LinkedHashMap(); for (Entry e : map.entrySet()) { Token key = e.getKey(); Object k = eval(key); if (!(k instanceof String)) { throw new SyntaxError(key.line, key.column, "map key null or not String: " + key); } omap.put(k, eval(e.getValue())); } return omap; } } public Object get(String name) { if (parms != null) { if ("args".equals(name)) { return parms; } if ("argv".equals(name)) { return parmv; } if ("it".equals(name)) { return parms.get(0); } if (name.length() == 1 && Character.isDigit(name.charAt(0))) { int i = name.charAt(0) - '0'; if (i > 0) { return parms.get(i - 1); } } } return session.get(name); } public Object put(String key, Object value) { return session.variables.put(key, value); } @Override public String toString() { return source.toString().trim().replaceAll("\n+", "\n").replaceAll( "([^\\\\{(\\[])\n", "\\1;").replaceAll("[ \\\\\t\n]+", " "); } /** * List that overrides toString() for implicit $args expansion. * Also checks for index out of bounds, so that $1 evaluates to null * rather than throwing IndexOutOfBoundsException. * e.g. x = { a$args }; x 1 2 => a1 2 and not a[1, 2] */ class ArgList extends AbstractList { private List list; public ArgList(List args) { this.list = args; } @Override public String toString() { StringBuilder buf = new StringBuilder(); for (Object o : list) { if (buf.length() > 0) buf.append(' '); buf.append(o); } return buf.toString(); } @Override public Object get(int index) { return index < list.size() ? list.get(index) : null; } @Override public Object remove(int index) { return list.remove(index); } @Override public int size() { return list.size(); } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/CommandNotFoundException.java000066400000000000000000000023511165554700600332710ustar00rootroot00000000000000/** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.felix.gogo.runtime; /** * Thrown if an unknown command is entered into a shell or passed on the command line */ public class CommandNotFoundException extends IllegalArgumentException { private final String command; public CommandNotFoundException(String command) { super("Command not found: " + command); this.command = command; } public String getCommand() { return command; } }felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/CommandProcessorImpl.java000066400000000000000000000214061165554700600324610ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.io.InputStream; import java.io.PrintStream; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArraySet; import org.apache.felix.gogo.api.CommandSessionListener; import org.apache.felix.service.command.CommandProcessor; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Converter; import org.apache.felix.service.command.Function; import org.apache.felix.service.threadio.ThreadIO; public class CommandProcessorImpl implements CommandProcessor { protected final Set converters = new HashSet(); protected final Set listeners = new CopyOnWriteArraySet(); protected final Map commands = new LinkedHashMap(); protected final Map constants = new HashMap(); protected final ThreadIO threadIO; protected final WeakHashMap sessions = new WeakHashMap(); public CommandProcessorImpl(ThreadIO tio) { threadIO = tio; } public CommandSession createSession(InputStream in, PrintStream out, PrintStream err) { CommandSessionImpl session = new CommandSessionImpl(this, in, out, err); sessions.put(session, null); return session; } public void stop() { for (CommandSession session : sessions.keySet()) { session.close(); } } public void addConverter(Converter c) { converters.add(c); } public void removeConverter(Converter c) { converters.remove(c); } public void addListener(CommandSessionListener l) { listeners.add(l); } public void removeListener(CommandSessionListener l) { listeners.remove(l); } public Set getCommands() { return Collections.unmodifiableSet(commands.keySet()); } Function getCommand(String name, final Object path) { int colon = name.indexOf(':'); if (colon < 0) { return null; } name = name.toLowerCase(); String cfunction = name.substring(colon); boolean anyScope = (colon == 1 && name.charAt(0) == '*'); Object cmd = commands.get(name); if (null == cmd && anyScope) { String scopePath = (null == path ? "*" : path.toString()); for (String scope : scopePath.split(":")) { if (scope.equals("*")) { synchronized (commands) { for (Entry entry : commands.entrySet()) { if (entry.getKey().endsWith(cfunction)) { cmd = entry.getValue(); break; } } } } else { cmd = commands.get(scope + cfunction); } if (cmd != null) { break; } } } if ((null == cmd) || (cmd instanceof Function)) { return (Function) cmd; } return new CommandProxy(cmd, cfunction.substring(1)); } public void addCommand(String scope, Object target) { Class tc = (target instanceof Class) ? (Class) target : target.getClass(); addCommand(scope, target, tc); } public void addCommand(String scope, Object target, Class functions) { if (target == null) { return; } String[] names = getFunctions(functions); for (String function : names) { addCommand(scope, target, function); } } public Object addConstant(String name, Object target) { return constants.put(name, target); } public Object removeConstant(String name) { return constants.remove(name); } public void addCommand(String scope, Object target, String function) { synchronized (commands) { commands.put((scope + ":" + function).toLowerCase(), target); } } public void removeCommand(String scope, String function) { String func = (scope + ":" + function).toLowerCase(); synchronized (commands) { commands.remove(func); } } public void removeCommand(Object target) { synchronized (commands) { for (Iterator i = commands.values().iterator(); i.hasNext();) { if (i.next() == target) { i.remove(); } } } } private String[] getFunctions(Class target) { String[] functions; Set list = new TreeSet(); Method methods[] = target.getMethods(); for (Method m : methods) { if (m.getDeclaringClass().equals(Object.class)) { continue; } list.add(m.getName()); if (m.getName().startsWith("get")) { String s = m.getName().substring(3); if (s.length() > 0) { list.add(s.substring(0, 1).toLowerCase() + s.substring(1)); } } } functions = list.toArray(new String[list.size()]); return functions; } protected void put(String name, Object target) { synchronized (commands) { commands.put(name, target); } } public Object convert(Class desiredType, Object in) { for (Converter c : converters) { try { Object converted = c.convert(desiredType, in); if (converted != null) { return converted; } } catch (Exception e) { e.printStackTrace(); } } return null; } // eval is needed to force expansions to be treated as commands (FELIX-1473) public Object eval(CommandSession session, Object[] argv) throws Exception { StringBuilder buf = new StringBuilder(); for (Object arg : argv) { if (buf.length() > 0) buf.append(' '); buf.append(arg); } return session.execute(buf); } void beforeExecute(CommandSession session, CharSequence commandline) { for (CommandSessionListener l : listeners) { try { l.beforeExecute(session, commandline); } catch (Throwable t) { // Ignore } } } void afterExecute(CommandSession session, CharSequence commandline, Exception exception) { for (CommandSessionListener l : listeners) { try { l.afterExecute(session, commandline, exception); } catch (Throwable t) { // Ignore } } } void afterExecute(CommandSession session, CharSequence commandline, Object result) { for (CommandSessionListener l : listeners) { try { l.afterExecute(session, commandline, result); } catch (Throwable t) { // Ignore } } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/CommandProxy.java000066400000000000000000000050501165554700600307760ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.util.List; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Function; import org.osgi.framework.ServiceReference; import org.osgi.framework.BundleContext; public class CommandProxy implements Function { private BundleContext context; private ServiceReference reference; private String function; private Object target; public CommandProxy(BundleContext context, ServiceReference reference, String function) { this.context = context; this.reference = reference; this.function = function; } public CommandProxy(Object target, String function) { this.function = function; this.target = target; } public Object getTarget() { return (context != null ? context.getService(reference) : target); } public void ungetTarget() { if (context != null) { try { context.ungetService(reference); } catch (IllegalStateException e) { // ignore - probably due to shutdown // java.lang.IllegalStateException: BundleContext is no longer valid } } } public Object execute(CommandSession session, List arguments) throws Exception { Object tgt = getTarget(); try { if (tgt instanceof Function) { return ((Function) tgt).execute(session, arguments); } else { return Reflective.invoke(session, tgt, function, arguments); } } finally { ungetTarget(); } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/CommandSessionImpl.java000066400000000000000000000300271165554700600321240ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // DWB8: throw IllegatlStateException if session used after closed (as per rfc132) // DWB9: there is no API to list all variables: https://www.osgi.org/bugzilla/show_bug.cgi?id=49 // DWB10: add SCOPE support: https://www.osgi.org/bugzilla/show_bug.cgi?id=51 package org.apache.felix.gogo.runtime; import java.io.InputStream; import java.io.PrintStream; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collection; import java.util.Dictionary; import java.util.Enumeration; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Converter; import org.apache.felix.service.command.Function; import org.apache.felix.service.threadio.ThreadIO; public class CommandSessionImpl implements CommandSession, Converter { public static final String SESSION_CLOSED = "session is closed"; public static final String VARIABLES = ".variables"; public static final String COMMANDS = ".commands"; private static final String COLUMN = "%-20s %s\n"; protected InputStream in; protected PrintStream out; PrintStream err; private final CommandProcessorImpl processor; protected final Map variables = new HashMap(); private boolean closed; protected CommandSessionImpl(CommandProcessorImpl shell, InputStream in, PrintStream out, PrintStream err) { this.processor = shell; this.in = in; this.out = out; this.err = err; } ThreadIO threadIO() { return processor.threadIO; } public void close() { this.closed = true; } public Object execute(CharSequence commandline) throws Exception { assert processor != null; assert processor.threadIO != null; if (closed) { throw new IllegalStateException(SESSION_CLOSED); } processor.beforeExecute(this, commandline); try { Closure impl = new Closure(this, null, commandline); Object result = impl.execute(this, null); processor.afterExecute(this, commandline, result); return result; } catch (Exception e) { processor.afterExecute(this, commandline, e); throw e; } } public InputStream getKeyboard() { return in; } public Object get(String name) { // there is no API to list all variables, so overload name == null if (name == null || VARIABLES.equals(name)) { return variables.keySet(); } if (COMMANDS.equals(name)) { return processor.getCommands(); } if( processor.constants.containsKey(name) ) { return processor.constants.get(name); } if (variables.containsKey("#" + name)) { Object f = variables.get("#" + name); if (f instanceof Function) { try { f = ((Function) f).execute(this, null); } catch (Exception e) { // Ignore } } return f; } if (variables.containsKey(name)) { return variables.get(name); } return processor.getCommand(name, variables.get("SCOPE")); } public void put(String name, Object value) { variables.put(name, value); } public PrintStream getConsole() { return out; } @SuppressWarnings("unchecked") public CharSequence format(Object target, int level, Converter escape) throws Exception { if (target == null) { return "null"; } if (target instanceof CharSequence) { return (CharSequence) target; } for (Converter c : processor.converters) { CharSequence s = c.format(target, level, this); if (s != null) { return s; } } if (target.getClass().isArray()) { if (target.getClass().getComponentType().isPrimitive()) { if (target.getClass().getComponentType() == boolean.class) { return Arrays.toString((boolean[]) target); } else { if (target.getClass().getComponentType() == byte.class) { return Arrays.toString((byte[]) target); } else { if (target.getClass().getComponentType() == short.class) { return Arrays.toString((short[]) target); } else { if (target.getClass().getComponentType() == int.class) { return Arrays.toString((int[]) target); } else { if (target.getClass().getComponentType() == long.class) { return Arrays.toString((long[]) target); } else { if (target.getClass().getComponentType() == float.class) { return Arrays.toString((float[]) target); } else { if (target.getClass().getComponentType() == double.class) { return Arrays.toString((double[]) target); } else { if (target.getClass().getComponentType() == char.class) { return Arrays.toString((char[]) target); } } } } } } } } } target = Arrays.asList((Object[]) target); } if (target instanceof Collection) { if (level == Converter.INSPECT) { StringBuilder sb = new StringBuilder(); Collection c = (Collection) target; for (Object o : c) { sb.append(format(o, level + 1, this)); sb.append("\n"); } return sb; } else { if (level == Converter.LINE) { StringBuilder sb = new StringBuilder(); Collection c = (Collection) target; sb.append("["); for (Object o : c) { if (sb.length() > 1) { sb.append(", "); } sb.append(format(o, level + 1, this)); } sb.append("]"); return sb; } } } if (target instanceof Dictionary) { Map result = new HashMap(); for (Enumeration e = ((Dictionary) target).keys(); e.hasMoreElements();) { Object key = e.nextElement(); result.put(key, ((Dictionary) target).get(key)); } target = result; } if (target instanceof Map) { if (level == Converter.INSPECT) { StringBuilder sb = new StringBuilder(); Map c = (Map) target; for (Map.Entry entry : c.entrySet()) { CharSequence key = format(entry.getKey(), level + 1, this); sb.append(key); for (int i = key.length(); i < 20; i++) { sb.append(' '); } sb.append(format(entry.getValue(), level + 1, this)); sb.append("\n"); } return sb; } else { if (level == Converter.LINE) { StringBuilder sb = new StringBuilder(); Map c = (Map) target; sb.append("["); for (Map.Entry entry : c.entrySet()) { if (sb.length() > 1) { sb.append(", "); } sb.append(format(entry, level + 1, this)); } sb.append("]"); return sb; } } } if (level == Converter.INSPECT) { return inspect(target); } else { return target.toString(); } } CharSequence inspect(Object b) { boolean found = false; Formatter f = new Formatter(); Method methods[] = b.getClass().getMethods(); for (Method m : methods) { try { String name = m.getName(); if (m.getName().startsWith("get") && !m.getName().equals("getClass") && m.getParameterTypes().length == 0 && Modifier.isPublic(m.getModifiers())) { found = true; name = name.substring(3); m.setAccessible(true); Object value = m.invoke(b, (Object[]) null); f.format(COLUMN, name, format(value, Converter.LINE, this)); } } catch (IllegalAccessException e) { // Ignore } catch (Exception e) { e.printStackTrace(); } } if (found) { return (StringBuilder) f.out(); } else { return b.toString(); } } public Object convert(Class desiredType, Object in) { return processor.convert(desiredType, in); } public CharSequence format(Object result, int inspect) { try { return format(result, inspect, this); } catch (Exception e) { return ">> program() { List>> program = new ArrayList>>(); while (tz.next() != Type.EOT) { program.add(pipeline()); switch (tz.type()) { case SEMICOLON: case NEWLINE: continue; } break; } if (tz.next() != Type.EOT) throw new RuntimeException("Program has trailing text: " + tz.value()); return program; } private List> pipeline() { List> pipeline = new ArrayList>(); while (true) { pipeline.add(command()); switch (tz.type()) { case PIPE: if (tz.next() == Type.EOT) { Token t = tz.token(); throw new EOFError(t.line, t.column, "unexpected EOT after pipe '|'"); } break; default: return pipeline; } } } private List command() { List command = new ArrayList(); while (true) { Token t = tz.token(); switch (t.type) { case WORD: case CLOSURE: case EXECUTION: case ARRAY: case ASSIGN: break; default: throw new SyntaxError(t.line, t.column, "unexpected token: " + t.type); } command.add(t); switch (tz.next()) { case PIPE: case SEMICOLON: case NEWLINE: case EOT: return command; } } } public void array(List list, Map map) throws Exception { Token lt = null; boolean isMap = false; while (tz.next() != Type.EOT) { if (isMap) { Token key = lt; lt = null; if (null == key) { key = tz.token(); if (tz.next() != Type.ASSIGN) { Token t = tz.token(); throw new SyntaxError(t.line, t.column, "map expected '=', found: " + t); } tz.next(); } Token k = (list.isEmpty() ? key : list.remove(0)); Token v = tz.token(); map.put(k, v); } else { switch (tz.type()) { case WORD: case CLOSURE: case EXECUTION: case ARRAY: lt = tz.token(); list.add(lt); break; case ASSIGN: if (list.size() == 1) { isMap = true; break; } // fall through default: lt = tz.token(); throw new SyntaxError(lt.line, lt.column, "unexpected token in list: " + lt); } } } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/Pipe.java000066400000000000000000000100101165554700600272430ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintStream; import java.lang.reflect.Method; import java.util.List; import org.apache.felix.service.command.Converter; public class Pipe extends Thread { static final ThreadLocal tIn = new ThreadLocal(); static final ThreadLocal tOut = new ThreadLocal(); static final ThreadLocal tErr = new ThreadLocal(); InputStream in; PrintStream out; PrintStream err; PipedOutputStream pout; Closure closure; Exception exception; Object result; List statement; public static Object[] mark() { Object[] mark = { tIn.get(), tOut.get(), tErr.get() }; return mark; } public static void reset(Object[] mark) { tIn.set((InputStream) mark[0]); tOut.set((PrintStream) mark[1]); tErr.set((PrintStream) mark[2]); } public Pipe(Closure closure, List statement) { super("pipe-" + statement); this.closure = closure; this.statement = statement; in = tIn.get(); out = tOut.get(); err = tErr.get(); } public String toString() { return "pipe<" + statement + "> out=" + out; } public void setIn(InputStream in) { this.in = in; } public void setOut(PrintStream out) { this.out = out; } public void setErr(PrintStream err) { this.err = err; } public Pipe connect(Pipe next) throws IOException { next.setOut(out); next.setErr(err); pout = new PipedOutputStream(); next.setIn(new PipedInputStream(pout)); out = new PrintStream(pout); return next; } public void run() { tIn.set(in); tOut.set(out); tErr.set(err); closure.session().threadIO().setStreams(in, out, err); try { result = closure.executeStatement(statement); if (result != null && pout != null) { if (!Boolean.FALSE.equals(closure.session().get(".FormatPipe"))) { out.println(closure.session().format(result, Converter.INSPECT)); } } } catch (Exception e) { exception = e; } finally { out.flush(); closure.session().threadIO().close(); try { if (pout != null) { pout.close(); } if (in instanceof PipedInputStream) { in.close(); // avoid writer waiting when reader has given up (FELIX-2380) Method m = in.getClass().getDeclaredMethod("receivedLast", (Class[]) null); m.setAccessible(true); m.invoke(in, (Object[]) null); } } catch (Exception e) { e.printStackTrace(); } } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/Reflective.java000066400000000000000000000335061165554700600304550ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Parameter; public final class Reflective { public final static Object NO_MATCH = new Object(); public final static String MAIN = "_main"; public final static Set KEYWORDS = new HashSet( Arrays.asList(new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while" })); /** * invokes the named method on the given target using the supplied args, * which are converted if necessary. * @param session * @param target * @param name * @param args * @return the result of the invoked method * @throws Exception */ public static Object invoke(CommandSession session, Object target, String name, List args) throws Exception { Method[] methods = target.getClass().getMethods(); name = name.toLowerCase(); String get = "get" + name; String is = "is" + name; String set = "set" + name; if (KEYWORDS.contains(name)) { name = "_" + name; } if (target instanceof Class) { Method[] staticMethods = ((Class) target).getMethods(); for (Method m : staticMethods) { String mname = m.getName().toLowerCase(); if (mname.equals(name) || mname.equals(get) || mname.equals(set) || mname.equals(is) || mname.equals(MAIN)) { methods = staticMethods; break; } } } Method bestMethod = null; Object[] bestArgs = null; int lowestMatch = Integer.MAX_VALUE; ArrayList[]> possibleTypes = new ArrayList[]>(); for (Method m : methods) { String mname = m.getName().toLowerCase(); if (mname.equals(name) || mname.equals(get) || mname.equals(set) || mname.equals(is) || mname.equals(MAIN)) { Class[] types = m.getParameterTypes(); ArrayList xargs = new ArrayList(args); // pass command name as argv[0] to main, so it can handle // multiple commands if (mname.equals(MAIN)) { xargs.add(0, name); } Object[] parms = new Object[types.length]; int match = coerce(session, target, m, types, parms, xargs); if (match < 0) { // coerce failed possibleTypes.add(types); } else { if (match < lowestMatch) { lowestMatch = match; bestMethod = m; bestArgs = parms; } if (match == 0) break; // can't get better score } } } if (bestMethod != null) { bestMethod.setAccessible(true); try { return bestMethod.invoke(target, bestArgs); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof Exception) { throw (Exception) cause; } throw e; } } else { ArrayList list = new ArrayList(); for (Class[] types : possibleTypes) { StringBuilder buf = new StringBuilder(); buf.append('('); for (Class type : types) { if (buf.length() > 1) { buf.append(", "); } buf.append(type.getSimpleName()); } buf.append(')'); list.add(buf.toString()); } StringBuilder params = new StringBuilder(); for (Object arg : args) { if (params.length() > 1) { params.append(", "); } params.append(arg == null ? "null" : arg.getClass().getSimpleName()); } throw new IllegalArgumentException(String.format( "Cannot coerce %s(%s) to any of %s", name, params, list)); } } /** * transform name/value parameters into ordered argument list. * params: --param2, value2, --flag1, arg3 * args: true, value2, arg3 * @param method * @param params * @return new ordered list of args. */ private static List transformParameters(Method method, List in) { Annotation[][] pas = method.getParameterAnnotations(); ArrayList out = new ArrayList(); ArrayList parms = new ArrayList(in); for (Annotation as[] : pas) { for (Annotation a : as) { if (a instanceof Parameter) { int i = -1; Parameter p = (Parameter) a; for (String name : p.names()) { i = parms.indexOf(name); if (i >= 0) break; } if (i >= 0) { // parameter present parms.remove(i); Object value = p.presentValue(); if (Parameter.UNSPECIFIED.equals(value)) { if (i >= parms.size()) return null; // missing parameter, so try other methods value = parms.remove(i); } out.add(value); } else { out.add(p.absentValue()); } } } } out.addAll(parms); return out; } /** * Complex routein to convert the arguments given from the command line to * the arguments of the method call. First, an attempt is made to convert * each argument. If this fails, a check is made to see if varargs can be * applied. This happens when the last method argument is an array. * * @param session * @param target * @param m * @param types * @param out * @param in * @return -1 if arguments can't be coerced; 0 if no coercion was necessary; > 0 if coercion was needed. */ private static int coerce(CommandSession session, Object target, Method m, Class types[], Object out[], List in) { in = transformParameters(m, in); if (in == null) { // missing parameter argument? return -1; } int[] convert = { 0 }; // Check if the command takes a session if ((types.length > 0) && types[0].isInterface() && types[0].isAssignableFrom(session.getClass())) { in.add(0, session); } int i = 0; while (i < out.length) { out[i] = null; // Try to convert one argument if (in.size() == 0) { out[i] = NO_MATCH; } else { out[i] = coerce(session, types[i], in.get(0), convert); if (out[i] == null && types[i].isArray() && in.size() > 0) { // don't coerce null to array FELIX-2432 out[i] = NO_MATCH; } if (out[i] != NO_MATCH) { in.remove(0); } } if (out[i] == NO_MATCH) { // No match, check for varargs if (types[i].isArray() && (i == types.length - 1)) { // Try to parse the remaining arguments in an array Class ctype = types[i].getComponentType(); int asize = in.size(); Object array = Array.newInstance(ctype, asize); int n = i; while (in.size() > 0) { Object t = coerce(session, ctype, in.remove(0), convert); if (t == NO_MATCH) { return -1; } Array.set(array, i - n, t); i++; } out[n] = array; /* * 1. prefer f() to f(T[]) with empty array * 2. prefer f(T) to f(T[1]) * 3. prefer f(T) to f(Object[1]) even if there is a conversion cost for T * * 1 & 2 require to add 1 to conversion cost, but 3 also needs to match * the conversion cost for T. */ return convert[0] + 1 + (asize * 2); } return -1; } i++; } if (in.isEmpty()) return convert[0]; return -1; } /** * converts given argument to specified type and increments convert[0] if any conversion was needed. * @param session * @param type * @param arg * @param convert convert[0] is incremented according to the conversion needed, * to allow the "best" conversion to be determined. * @return converted arg or NO_MATCH if no conversion possible. */ private static Object coerce(CommandSession session, Class type, Object arg, int[] convert) { if (arg == null) { return null; } if (type.isAssignableFrom(arg.getClass())) { return arg; } if (type.isArray()) { return NO_MATCH; } if (type.isPrimitive() && arg instanceof Long) { // no-cost conversions between integer types Number num = (Number) arg; if (type == short.class) { return num.shortValue(); } if (type == int.class) { return num.intValue(); } if (type == long.class) { return num.longValue(); } } // all following conversions cost 2 points convert[0] += 2; Object converted = session.convert(type, arg); if (converted != null) { return converted; } String string = arg.toString(); if (type.isAssignableFrom(String.class)) { return string; } if (type.isPrimitive()) { type = primitiveToObject(type); } try { return type.getConstructor(String.class).newInstance(string); } catch (Exception e) { } if (type == Character.class && string.length() == 1) { return string.charAt(0); } return NO_MATCH; } private static Class primitiveToObject(Class type) { if (type == boolean.class) { return Boolean.class; } if (type == byte.class) { return Byte.class; } if (type == char.class) { return Character.class; } if (type == short.class) { return Short.class; } if (type == int.class) { return Integer.class; } if (type == float.class) { return Float.class; } if (type == double.class) { return Double.class; } if (type == long.class) { return Long.class; } return null; } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/SyntaxError.java000066400000000000000000000024071165554700600306610ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; public class SyntaxError extends RuntimeException { private static final long serialVersionUID = 1L; private final int line; private final int column; public SyntaxError(int line, int column, String message) { super(message); this.line = line; this.column = column; } public int column() { return column; } public int line() { return line; } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/Token.java000066400000000000000000000041661165554700600274450ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import org.apache.felix.gogo.runtime.Tokenizer.Type; public class Token implements CharSequence { Type type; CharSequence value; short line; short column; public Token(Type type, CharSequence value, short line, short column) { this.type = type; this.value = value; this.line = line; this.column = column; } @Override public String toString() { //return type + "<" + value + ">"; return null == value ? type.toString() : value.toString(); } public char charAt(int index) { return value.charAt(index); } public int length() { return (null == value ? 0 : value.length()); } public CharSequence subSequence(int start, int end) { return value.subSequence(start, end); } public String source() { switch (type) { case WORD: return value.toString(); case CLOSURE: return "{" + value + "}"; case EXECUTION: return "(" + value + ")"; case ARRAY: return "[" + value + "]"; default: return type.toString(); } } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/Tokenizer.java000066400000000000000000000463341165554700600303420ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; /** * Bash-like tokenizer. * * Single and double quotes are just like Bash - single quotes escape everything * (including backslashes), newlines are allowed in quotes. * backslash-newline indicates a line continuation and is removed. * * Variable expansion is just like Bash: $NAME or ${NAME[[:][-+=?WORD]}, * except it can yield any Object. Variables expanded within double-quotes, * or adjacent to a String are converted to String. * * Unlike bash, indirect variable expansion is supported using ${$NAME}. * * Only a single variable assignment is recognized, with '=' being the second token. * (Bash allows name1=value1 name2=value2 ... command args) * * Comments can only start where white space is allowed: * # or // starts a line comment, /* starts a block comment. * The following common uses do NOT start comments: * ls http://example.com#anchor * ls $dir/*.java * * @see http://wiki.bash-hackers.org/syntax/basicgrammar */ public class Tokenizer { public enum Type { ASSIGN('='), PIPE('|'), SEMICOLON(';'), NEWLINE, ARRAY, CLOSURE, EXECUTION, WORD, EOT; private char c; Type() { } Type(char c) { this.c = c; } @Override public String toString() { return (c == 0 ? super.toString() : "'" + c + "'"); } } private static final boolean DEBUG = false; private static final char EOT = (char) -1; private final CharSequence text; private final Evaluate evaluate; private final boolean inArray; private final boolean inQuote; private Type type = Type.NEWLINE; private CharSequence value; private Token token; private short line; private short column; private char ch; private int index; private boolean firstWord; public Tokenizer(CharSequence text) { this(text, null, false); } public Tokenizer(CharSequence text, Evaluate evaluate, boolean inQuote) { this.text = text; this.evaluate = evaluate; this.inQuote = inQuote; index = 0; line = column = 1; boolean array = false; if (text instanceof Token) { Token t = (Token) text; line = t.line; column = t.column; array = (Type.ARRAY == t.type); } inArray = array; getch(); if (DEBUG) { if (inArray) System.err.println("Tokenizer[" + text + "]"); else System.err.println("Tokenizer<" + text + ">"); } } public Type type() { return type; } public CharSequence value() { return value; } public Token token() { return token; } public Type next() { final Type prevType = type; token = null; value = null; short tLine; short tColumn; while (true) { skipSpace(); tLine = line; tColumn = column; switch (ch) { case EOT: type = Type.EOT; break; case '\n': getch(); if (inArray) continue; // only return NEWLINE once and not if not preceded by ; or | switch (prevType) { case PIPE: case SEMICOLON: case NEWLINE: continue; default: type = Type.NEWLINE; break; } break; case '{': case '(': case '[': value = group(); getch(); break; case ';': getch(); type = Type.SEMICOLON; break; case '|': getch(); type = Type.PIPE; break; case '=': if (firstWord || inArray) { getch(); type = Type.ASSIGN; break; } // fall through default: value = word(); type = Type.WORD; } firstWord = (Type.WORD == type && (Type.WORD != prevType && Type.ASSIGN != prevType)); token = new Token(type, value, tLine, tColumn); if (DEBUG) { System.err.print("<" + type + ">"); if (Type.EOT == type) { System.err.println(); } } return type; } } private CharSequence word() { int start = index - 1; int skipCR = 0; do { switch (ch) { case '\n': if (index >= 2 && text.charAt(index - 2) == '\r') skipCR = 1; // fall through case '=': if ((Type.WORD == type || Type.ASSIGN == type) && '=' == ch && !inArray) continue; // fall through case ' ': case '\t': case '|': case ';': return text.subSequence(start, index - 1 - skipCR); case '{': group(); break; case '\\': escape(); break; case '\'': case '"': skipQuote(); break; } } while (getch() != EOT); return text.subSequence(start, index - 1); } private CharSequence group() { final char push = ch; final char pop; switch (ch) { case '{': type = Type.CLOSURE; pop = '}'; break; case '(': type = Type.EXECUTION; pop = ')'; break; case '[': type = Type.ARRAY; pop = ']'; break; default: assert false; pop = 0; } short sLine = line; short sCol = column; int start = index; int depth = 1; while (true) { boolean comment = false; switch (ch) { case '{': case '(': case '[': case '\n': comment = true; break; } if (getch() == EOT) { throw new EOFError(sLine, sCol, "unexpected EOT looking for matching '" + pop + "'"); } // don't recognize comments that start within a word if (comment || isBlank(ch)) skipSpace(); switch (ch) { case '"': case '\'': skipQuote(); break; case '\\': ch = escape(); break; default: if (push == ch) depth++; else if (pop == ch && --depth == 0) return text.subSequence(start, index - 1); } } } private char escape() { assert '\\' == ch; switch (getch()) { case 'u': getch(); getch(); getch(); getch(); if (EOT == ch) { throw new EOFError(line, column, "unexpected EOT in \\u escape"); } String u = text.subSequence(index - 4, index).toString(); try { return (char) Integer.parseInt(u, 16); } catch (NumberFormatException e) { throw new SyntaxError(line, column, "bad unicode escape: \\u" + u); } case EOT: throw new EOFError(line, column, "unexpected EOT in \\ escape"); case '\n': return '\0'; // line continuation case '\\': case '\'': case '"': case '$': return ch; default: return ch; } } private void skipQuote() { assert '\'' == ch || '"' == ch; final char quote = ch; final short sLine = line; final short sCol = column; while (getch() != EOT) { if (quote == ch) return; if ((quote == '"') && ('\\' == ch)) escape(); } throw new EOFError(sLine, sCol, "unexpected EOT looking for matching quote: " + quote); } private void skipSpace() { while (true) { while (isBlank(ch)) { getch(); } // skip continuation lines, but not other escapes if (('\\' == ch) && (peek() == '\n')) { getch(); getch(); continue; } // skip comments if (('/' == ch) || ('#' == ch)) { if (('#' == ch) || (peek() == '/')) { while ((getch() != EOT) && ('\n' != ch)) { } continue; } else if ('*' == peek()) { short sLine = line; short sCol = column; getch(); while ((getch() != EOT) && !(('*' == ch) && (peek() == '/'))) { } if (EOT == ch) { throw new EOFError(sLine, sCol, "unexpected EOT looking for closing comment: */"); } getch(); getch(); continue; } } break; } } private boolean isBlank(char ch) { return ' ' == ch || '\t' == ch; } private boolean isName(char ch) { return Character.isJavaIdentifierPart(ch) && (ch != '$') || ('.' == ch); } /** * expand variables, quotes and escapes in word. * @param vars * @return * @throws Exception */ public static Object expand(CharSequence word, Evaluate eval) throws Exception { return expand(word, eval, false); } private static Object expand(CharSequence word, Evaluate eval, boolean inQuote) throws Exception { final String special = "$\\\"'"; int i = word.length(); while ((--i >= 0) && (special.indexOf(word.charAt(i)) == -1)) { } // shortcut if word doesn't contain any special characters if (i < 0) return word; return new Tokenizer(word, eval, inQuote).expand(); } public Object expand(CharSequence word, short line, short column) throws Exception { return expand(new Token(Type.WORD, word, line, column), evaluate, inQuote); } private Token word(CharSequence value) { return new Token(Type.WORD, value, line, column); } private Object expand() throws Exception { StringBuilder buf = new StringBuilder(); while (ch != EOT) { int start = index; switch (ch) { case '$': Object val = expandVar(); if (EOT == ch && buf.length() == 0) { return val; } if (null != val) { buf.append(val); } continue; // expandVar() has already read next char case '\\': ch = (inQuote && ("u$\\\n\"".indexOf(peek()) == -1)) ? '\\' : escape(); if (ch != '\0') // ignore line continuation { buf.append(ch); } break; case '"': Token ww = word(null); skipQuote(); ww.value = text.subSequence(start, index - 1); value = ww; Object expand = expand(value, evaluate, true); if (eot() && buf.length() == 0 && value == expand) { // FELIX-2468 avoid returning CharSequence implementation return ww.value.toString(); } if (null != expand) { buf.append(expand.toString()); } break; case '\'': if (!inQuote) { skipQuote(); value = text.subSequence(start, index - 1); if (eot() && buf.length() == 0) { return value; } buf.append(value); break; } // else fall through default: buf.append(ch); } getch(); } return buf.toString(); } private Object expandVar() throws Exception { assert '$' == ch; Object val; if (getch() != '{') { if ('(' == ch) { // support $(...) FELIX-2433 short sLine = line; short sCol = column; val = evaluate.eval(new Token(Type.EXECUTION, group(), sLine, sCol)); getch(); } else { int start = index - 1; while (isName(ch)) { getch(); } if (index - 1 == start) { val = "$"; } else { String name = text.subSequence(start, index - 1).toString(); val = evaluate.get(name); } } } else { // ${NAME[[:]-+=?]WORD} short sLine = line; short sCol = column; CharSequence group = group(); char c; int i = 0; while (i < group.length()) { switch (group.charAt(i)) { case ':': case '-': case '+': case '=': case '?': break; default: ++i; continue; } break; } sCol += i; String name = String.valueOf(expand(group.subSequence(0, i), sLine, sCol)); for (int j = 0; j < name.length(); ++j) { if (!isName(name.charAt(j))) { throw new SyntaxError(sLine, sCol, "bad name: ${" + group + "}"); } } val = evaluate.get(name); if (i < group.length()) { c = group.charAt(i++); if (':' == c) { c = (i < group.length() ? group.charAt(i++) : EOT); } CharSequence word = group.subSequence(i, group.length()); switch (c) { case '-': case '=': if (null == val) { val = expand(word, evaluate, false); if ('=' == c) { evaluate.put(name, val); } } break; case '+': if (null != val) { val = expand(word, evaluate, false); } break; case '?': if (null == val) { val = expand(word, evaluate, false); if (null == val || val.toString().length() == 0) { val = "parameter not set"; } throw new IllegalArgumentException(name + ": " + val); } break; default: throw new SyntaxError(sLine, sCol, "bad substitution: ${" + group + "}"); } } getch(); } return val; } /** * returns true if getch() will return EOT * @return */ private boolean eot() { return index >= text.length(); } private char getch() { return ch = getch(false); } private char peek() { return getch(true); } private char getch(boolean peek) { if (eot()) { if (!peek) { ++index; ch = EOT; } return EOT; } int current = index; char c = text.charAt(index++); if (('\r' == c) && !eot() && (text.charAt(index) == '\n')) c = text.charAt(index++); if (peek) { index = current; } else if ('\n' == c) { ++line; column = 0; } else ++column; return c; } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/activator/000077500000000000000000000000001165554700600275075ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/activator/Activator.java000066400000000000000000000166771165554700600323270ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.activator; import java.util.ArrayList; import java.util.List; import org.apache.felix.gogo.runtime.CommandProcessorImpl; import org.apache.felix.gogo.runtime.CommandProxy; import org.apache.felix.gogo.api.CommandSessionListener; import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.apache.felix.service.command.CommandProcessor; import org.apache.felix.service.command.Converter; import org.apache.felix.service.command.Function; import org.apache.felix.service.threadio.ThreadIO; import org.osgi.util.tracker.ServiceTracker; public class Activator implements BundleActivator { protected CommandProcessorImpl processor; private ThreadIOImpl threadio; private ServiceTracker commandTracker; private ServiceTracker converterTracker; private ServiceTracker listenerTracker; private ServiceRegistration processorRegistration; private ServiceRegistration threadioRegistration; public static final String CONTEXT = ".context"; protected ServiceRegistration newProcessor(ThreadIO tio, BundleContext context) { processor = new CommandProcessorImpl(tio); try { processor.addListener(new EventAdminListener(context)); } catch (NoClassDefFoundError error) { // Ignore the listener if EventAdmin package isn't present } // Setup the variables and commands exposed in an OSGi environment. processor.addConstant(CONTEXT, context); processor.addCommand("osgi", processor, "addCommand"); processor.addCommand("osgi", processor, "removeCommand"); processor.addCommand("osgi", processor, "eval"); return context.registerService(CommandProcessor.class.getName(), processor, null); } public void start(final BundleContext context) throws Exception { threadio = new ThreadIOImpl(); threadio.start(); threadioRegistration = context.registerService(ThreadIO.class.getName(), threadio, null); processorRegistration = newProcessor(threadio, context); commandTracker = trackOSGiCommands(context); commandTracker.open(); converterTracker = new ServiceTracker(context, Converter.class.getName(), null) { @Override public Object addingService(ServiceReference reference) { Converter converter = (Converter) super.addingService(reference); processor.addConverter(converter); return converter; } @Override public void removedService(ServiceReference reference, Object service) { processor.removeConverter((Converter) service); super.removedService(reference, service); } }; converterTracker.open(); listenerTracker = new ServiceTracker(context, CommandSessionListener.class.getName(), null) { @Override public Object addingService(ServiceReference reference) { CommandSessionListener listener = (CommandSessionListener) super.addingService(reference); processor.addListener(listener); return listener; } @Override public void removedService(ServiceReference reference, Object service) { processor.removeListener((CommandSessionListener) service); super.removedService(reference, service); } }; listenerTracker.open(); } public void stop(BundleContext context) throws Exception { processorRegistration.unregister(); threadioRegistration.unregister(); commandTracker.close(); converterTracker.close(); listenerTracker.close(); threadio.stop(); processor.stop(); } private ServiceTracker trackOSGiCommands(final BundleContext context) throws InvalidSyntaxException { Filter filter = context.createFilter(String.format("(&(%s=*)(%s=*))", CommandProcessor.COMMAND_SCOPE, CommandProcessor.COMMAND_FUNCTION)); return new ServiceTracker(context, filter, null) { @Override public Object addingService(ServiceReference reference) { Object scope = reference.getProperty(CommandProcessor.COMMAND_SCOPE); Object function = reference.getProperty(CommandProcessor.COMMAND_FUNCTION); List commands = new ArrayList(); if (scope != null && function != null) { if (function.getClass().isArray()) { for (Object f : ((Object[]) function)) { Function target = new CommandProxy(context, reference, f.toString()); processor.addCommand(scope.toString(), target, f.toString()); commands.add(target); } } else { Function target = new CommandProxy(context, reference, function.toString()); processor.addCommand(scope.toString(), target, function.toString()); commands.add(target); } return commands; } return null; } @Override public void removedService(ServiceReference reference, Object service) { Object scope = reference.getProperty(CommandProcessor.COMMAND_SCOPE); Object function = reference.getProperty(CommandProcessor.COMMAND_FUNCTION); if (scope != null && function != null) { if (!function.getClass().isArray()) { processor.removeCommand(scope.toString(), function.toString()); } else { for (Object func : (Object[]) function) { processor.removeCommand(scope.toString(), func.toString()); } } } super.removedService(reference, service); } }; } } EventAdminListener.java000066400000000000000000000041721165554700600340370ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/activator/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.activator; import java.util.Properties; import org.apache.felix.gogo.api.CommandSessionListener; import org.apache.felix.service.command.CommandSession; import org.osgi.framework.BundleContext; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.osgi.util.tracker.ServiceTracker; public class EventAdminListener implements CommandSessionListener { private BundleContext bundleContext; private ServiceTracker tracker; public EventAdminListener(BundleContext bundleContext) { this.bundleContext = bundleContext; tracker = new ServiceTracker(bundleContext, EventAdmin.class.getName(), null); tracker.open(); } public void beforeExecute(CommandSession session, CharSequence command) { EventAdmin admin = (EventAdmin) tracker.getService(); if (admin != null) { Properties props = new Properties(); props.setProperty("command", command.toString()); Event event = new Event("org/apache/felix/service/command/EXECUTING", props); admin.postEvent(event); } } public void afterExecute(CommandSession session, CharSequence command, Exception exception) { } public void afterExecute(CommandSession session, CharSequence command, Object result) { } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/threadio/000077500000000000000000000000001165554700600273125ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java000066400000000000000000000026661165554700600314100ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.threadio; import java.io.InputStream; import java.io.PrintStream; public class Marker { Marker previous; InputStream in; PrintStream out; PrintStream err; ThreadIOImpl parent; public Marker(ThreadIOImpl parent, InputStream in, PrintStream out, PrintStream err, Marker previous) { this.previous = previous; this.parent = parent; this.in = in; this.out = out; this.err = err; } Marker activate() { parent.in.setStream(in); parent.out.setStream(out); parent.err.setStream(err); return previous; } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java000066400000000000000000000062201165554700600324360ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // DWB20: ThreadIO should check and reset IO if something (e.g. jetty) overrides package org.apache.felix.gogo.runtime.threadio; import org.apache.felix.service.threadio.ThreadIO; import java.io.InputStream; import java.io.PrintStream; import java.util.logging.Logger; public class ThreadIOImpl implements ThreadIO { static private final Logger log = Logger.getLogger(ThreadIOImpl.class.getName()); ThreadPrintStream err = new ThreadPrintStream(System.err); ThreadPrintStream out = new ThreadPrintStream(System.out); ThreadInputStream in = new ThreadInputStream(System.in); ThreadLocal current = new InheritableThreadLocal(); public void start() { if (System.out instanceof ThreadPrintStream) { throw new IllegalStateException("Thread Print Stream already set"); } System.setOut(out); System.setIn(in); System.setErr(err); } public void stop() { System.setErr(err.dflt); System.setOut(out.dflt); System.setIn(in.dflt); } private void checkIO() { // derek if (System.in != in) { log.fine("ThreadIO: eek! who's set System.in=" + System.in); System.setIn(in); } if (System.out != out) { log.fine("ThreadIO: eek! who's set System.out=" + System.out); System.setOut(out); } if (System.err != err) { log.fine("ThreadIO: eek! who's set System.err=" + System.err); System.setErr(err); } } public void close() { checkIO(); // derek Marker top = this.current.get(); if (top == null) { throw new IllegalStateException("No thread io active"); } Marker previous = top.previous; if (previous == null) { in.end(); out.end(); err.end(); } else { this.current.set(previous); previous.activate(); } } public void setStreams(InputStream in, PrintStream out, PrintStream err) { assert in != null; assert out != null; assert err != null; checkIO(); // derek Marker marker = new Marker(this, in, out, err, current.get()); this.current.set(marker); marker.activate(); } } ThreadInputStream.java000066400000000000000000000053031165554700600335020ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/threadio/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.threadio; import java.io.IOException; import java.io.InputStream; public class ThreadInputStream extends InputStream { ThreadLocal map = new InheritableThreadLocal(); InputStream dflt; public ThreadInputStream(InputStream in) { dflt = in; } private InputStream getCurrent() { InputStream in = map.get(); if (in != null) { return in; } return dflt; } public void setStream(InputStream in) { if (in != dflt && in != this) { map.set(in); } else { map.remove(); } } public void end() { map.remove(); } /** * Access to the root stream through reflection * * @return */ public InputStream getRoot() { return dflt; } // // Delegate methods // public int read() throws IOException { return getCurrent().read(); } public int read(byte[] b) throws IOException { return getCurrent().read(b); } public int read(byte[] b, int off, int len) throws IOException { return getCurrent().read(b, off, len); } public long skip(long n) throws IOException { return getCurrent().skip(n); } public int available() throws IOException { return getCurrent().available(); } public void close() throws IOException { getCurrent().close(); } public void mark(int readlimit) { getCurrent().mark(readlimit); } public void reset() throws IOException { getCurrent().reset(); } public boolean markSupported() { return getCurrent().markSupported(); } } ThreadPrintStream.java000066400000000000000000000117271165554700600335060ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/gogo/runtime/threadio/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.threadio; import java.io.IOException; import java.io.PrintStream; import java.io.InputStream; import java.util.Locale; public class ThreadPrintStream extends PrintStream { PrintStream dflt; ThreadLocal map = new InheritableThreadLocal(); public ThreadPrintStream(PrintStream out) { super(out); dflt = out; } public PrintStream getCurrent() { PrintStream out = map.get(); if (out != null) { return out; } return dflt; } public void setStream(PrintStream out) { if (out != dflt && out != this) { map.set(out); } else { map.remove(); } } public void end() { map.remove(); } /** * Access to the root stream through reflection * * @return */ public PrintStream getRoot() { return dflt; } // // Delegate methods // public void flush() { getCurrent().flush(); } public void close() { getCurrent().close(); } public boolean checkError() { return getCurrent().checkError(); } public void setError() { // getCurrent().setError(); } public void clearError() { // getCurrent().clearError(); } public void write(int b) { getCurrent().write(b); } public void write(byte[] buf, int off, int len) { getCurrent().write(buf, off, len); } public void print(boolean b) { getCurrent().print(b); } public void print(char c) { getCurrent().print(c); } public void print(int i) { getCurrent().print(i); } public void print(long l) { getCurrent().print(l); } public void print(float f) { getCurrent().print(f); } public void print(double d) { getCurrent().print(d); } public void print(char[] s) { getCurrent().print(s); } public void print(String s) { getCurrent().print(s); } public void print(Object obj) { getCurrent().print(obj); } public void println() { getCurrent().println(); } public void println(boolean x) { getCurrent().println(x); } public void println(char x) { getCurrent().println(x); } public void println(int x) { getCurrent().println(x); } public void println(long x) { getCurrent().println(x); } public void println(float x) { getCurrent().println(x); } public void println(double x) { getCurrent().println(x); } public void println(char[] x) { getCurrent().println(x); } public void println(String x) { getCurrent().println(x); } public void println(Object x) { getCurrent().println(x); } public PrintStream printf(String format, Object... args) { return getCurrent().printf(format, args); } public PrintStream printf(Locale l, String format, Object... args) { return getCurrent().printf(l, format, args); } public PrintStream format(String format, Object... args) { return getCurrent().format(format, args); } public PrintStream format(Locale l, String format, Object... args) { return getCurrent().format(l, format, args); } public PrintStream append(CharSequence csq) { return getCurrent().append(csq); } public PrintStream append(CharSequence csq, int start, int end) { return getCurrent().append(csq, start, end); } public PrintStream append(char c) { return getCurrent().append(c); } public void write(byte[] b) throws IOException { getCurrent().write(b); } } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/000077500000000000000000000000001165554700600245355ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/000077500000000000000000000000001165554700600261535ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/CommandProcessor.java000066400000000000000000000044521165554700600323010ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; import java.io.InputStream; import java.io.PrintStream; /** * A command shell can create and maintain a number of command sessions. * * @author aqute */ public interface CommandProcessor { /** * The scope of commands provided by this service. This name can be used to distinguish * between different command providers with the same function names. */ final static String COMMAND_SCOPE = "osgi.command.scope"; /** * A list of method names that may be called for this command provider. A * name may end with a *, this will then be calculated from all declared public * methods in this service. *

* Help information for the command may be supplied with a space as * separation. */ final static String COMMAND_FUNCTION = "osgi.command.function"; /** * Create a new command session associated with IO streams. *

* The session is bound to the life cycle of the bundle getting this * service. The session will be automatically closed when this bundle is * stopped or the service is returned. *

* The shell will provide any available commands to this session and * can set additional variables. * * @param in The value used for System.in * @param out The stream used for System.out * @param err The stream used for System.err * @return A new session. */ CommandSession createSession(InputStream in, PrintStream out, PrintStream err); } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/CommandSession.java000066400000000000000000000055011165554700600317410ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; import java.io.InputStream; import java.io.PrintStream; public interface CommandSession { /** * Execute a program in this session. * * @param commandline * @return the result of the execution */ Object execute(CharSequence commandline) throws Exception; /** * Close this command session. After the session is closed, it will throw * IllegalStateException when it is used. * * @param */ void close(); /** * Return the input stream that is the first of the pipeline. This stream is * sometimes necessary to communicate directly to the end user. For example, * a "less" or "more" command needs direct input from the keyboard to * control the paging. * * @return InpuStream used closest to the user or null if input is from a * file. */ InputStream getKeyboard(); /** * Return the PrintStream for the console. This must always be the stream * "closest" to the user. This stream can be used to post messages that * bypass the piping. If the output is piped to a file, then the object * returned must be null. * * @return */ PrintStream getConsole(); /** * Get the value of a variable. * * @param name * @return */ Object get(String name); /** * Set the value of a variable. * * @param name Name of the variable. * @param value Value of the variable */ void put(String name, Object value); /** * Convert an object to string form (CharSequence). The level is defined in * the Converter interface, it can be one of INSPECT, LINE, PART. This * function always returns a non null value. As a last resort, toString is * called on the Object. * * @param target * @param level * @return */ CharSequence format(Object target, int level); /** * Convert an object to another type. */ Object convert(Class type, Object instance); } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/Converter.java000066400000000000000000000063301165554700600307670ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; /** * A converter is a service that can help create specific object types from a * string, and vice versa. *

* The shell is capable of coercing arguments to the their proper type. However, * sometimes commands require extra help to do this conversion. This service can * implement a converter for a number of types. *

* The command shell will rank these services in order of service.ranking and * will then call them until one of the converters succeeds. */ public interface Converter { /** * This property is a string, or array of strings, and defines the classes * or interfaces that this converter recognizes. Recognized classes can be * converted from a string to a class and they can be printed in 3 different * modes. */ String CONVERTER_CLASSES = "osgi.converter.classes"; /** * Print the object in detail. This can contain multiple lines. */ int INSPECT = 0; /** * Print the object as a row in a table. The columns should align for * multiple objects printed beneath each other. The print may run over * multiple lines but must not end in a CR. */ int LINE = 1; /** * Print the value in a small format so that it is identifiable. This * printed format must be recognizable by the conversion method. */ int PART = 2; /** * Convert an object to the desired type. *

* Return null if the conversion can not be done. Otherwise return and * object that extends the desired type or implements it. * * @param desiredType The type that the returned object can be assigned to * @param in The object that must be converted * @return An object that can be assigned to the desired type or null. * @throws Exception */ Object convert(Class desiredType, Object in) throws Exception; /** * Convert an objet to a CharSequence object in the requested format. The * format can be INSPECT, LINE, or PART. Other values must throw * IllegalArgumentException. * * @param target The object to be converted to a String * @param level One of INSPECT, LINE, or PART. * @param escape Use this object to format sub ordinate objects. * @return A printed object of potentially multiple lines * @throws Exception */ CharSequence format(Object target, int level, Converter escape) throws Exception; } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/Descriptor.java000066400000000000000000000022261165554700600311360ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) public @interface Descriptor { String value(); }felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/Function.java000066400000000000000000000024421165554700600306050ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; import java.util.List; /** * A Function is a a block of code that can be executed with a set of arguments, * it returns the result object of executing the script. */ public interface Function { /** * Execute this function and return the result. * * @return the result from the execution. * @throws Exception if anything goes terribly wrong */ Object execute(CommandSession session, List arguments) throws Exception; } felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/command/Parameter.java000066400000000000000000000042051165554700600307370ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.command; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) public @interface Parameter { static final String UNSPECIFIED = "org.apache.felix.service.command.unspecified.parameter"; /** * Parameter name and aliases which must start with the hyphen character. * @return parameter names. **/ String[] names(); /** * The default value of the parameter if its name is present on the * command line. If this value is specified, then the command parsing * will not expect a value on the command line for this parameter. * If this value is UNSPECIFIED, then an argument must be specified on the * command line for the parameter. * @return default value of the parameter if its name is present on the * command line. **/ String presentValue() default UNSPECIFIED; /** * The default value of the parameter if its name is not present on the * command line. This value is effectively the default value for the * parameter. * @return default value of the parameter if its name is not present * on the command line. **/ String absentValue(); }felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/threadio/000077500000000000000000000000001165554700600263345ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/main/java/org/apache/felix/service/threadio/ThreadIO.java000066400000000000000000000042771165554700600306500ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.service.threadio; import java.io.InputStream; import java.io.PrintStream; /** * Enable multiplexing of the standard IO streams for input, output, and error. *

* This service guards the central resource of IO streams. The standard streams * are singletons. This service replaces the singletons with special versions that * can find a unique stream for each thread. If no stream is associated with a * thread, it will use the standard input/output that was originally set. * * @author aqute */ public interface ThreadIO { /** * Associate this streams with the current thread. *

* Ensure that when output is performed on System.in, System.out, System.err it * will happen on the given streams. *

* The streams will automatically be canceled when the bundle that has gotten * this service is stopped or returns this service. * * @param in InputStream to use for the current thread when System.in is used * @param out PrintStream to use for the current thread when System.out is used * @param err PrintStream to use for the current thread when System.err is used */ void setStreams(InputStream in, PrintStream out, PrintStream err); /** * Cancel the streams associated with the current thread. *

* This method will not do anything when no streams are associated. */ void close(); } felix-gogo-runtime-0.10.0/src/test/000077500000000000000000000000001165554700600170705ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/000077500000000000000000000000001165554700600200115ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/000077500000000000000000000000001165554700600206005ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/000077500000000000000000000000001165554700600220215ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/000077500000000000000000000000001165554700600231305ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/000077500000000000000000000000001165554700600240635ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/000077500000000000000000000000001165554700600255465ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/Context.java000066400000000000000000000041721165554700600300410ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl; import org.apache.felix.service.command.CommandSession; public class Context extends CommandProcessorImpl { public static final String EMPTY = ""; private static final ThreadIOImpl threadio; private final CommandSession session; static { threadio = new ThreadIOImpl(); threadio.start(); } public Context() { super(threadio); addCommand("osgi", this, "addCommand"); addCommand("osgi", this, "removeCommand"); addCommand("osgi", this, "eval"); session = (CommandSessionImpl) createSession(System.in, System.out, System.err); } public Object execute(CharSequence source) throws Exception { Object result = new Exception(); try { return result = session.execute(source); } finally { System.err.println("execute<" + source + "> = (" + (null == result ? "Null" : result.getClass().getSimpleName()) + ")(" + result + ")\n"); } } public void addCommand(String function, Object target) { addCommand("test", target, function); } public void set(String name, Object value) { session.put(name, value); } } felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/TestCoercion.java000066400000000000000000000141441165554700600310160ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import junit.framework.TestCase; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Descriptor; import org.apache.felix.service.command.Parameter; public class TestCoercion extends TestCase { public boolean fBool(boolean t) { return t; } public double fDouble(double x) { return x; } public int fInt(int x) { return x; } public long fLong(long x) { return x; } // the presence of this method checks that it is not invoked instead of fInt(int) public String fInt(Object[] x) { return "array"; } public String fString(String s) { return s; } public void testSimpleTypes() throws Exception { Context c = new Context(); c.addCommand("fBool", this); c.addCommand("fDouble", this); c.addCommand("fInt", this); c.addCommand("fLong", this); c.addCommand("fString", this); assertEquals("fBool true", true, c.execute("fBool true")); assertEquals("fBool 'false'", false, c.execute("fBool 'false'")); assertEquals("fDouble 11", 11.0, c.execute("fDouble 11")); assertEquals("fDouble '11'", 11.0, c.execute("fDouble '11'")); assertEquals("fInt 22", 22, c.execute("fInt 22")); assertEquals("fInt '23'", 23, c.execute("fInt '23'")); assertEquals("fInt 1 2", "array", c.execute("fInt 1 2")); assertEquals("fLong 33", 33L, c.execute("fLong 33")); assertEquals("fLong '34'", 34L, c.execute("fLong '34'")); assertEquals("fString wibble", "wibble", c.execute("fString wibble")); assertEquals("fString 'wibble'", "wibble", c.execute("fString 'wibble'")); try { Object r = c.execute("fString "); fail("too few args: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } try { Object r = c.execute("fString a b"); fail("too many args: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } try { Object r = c.execute("fLong string"); fail("wrong arg type: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } } public String bundles(Long id) { return "long"; } public String bundles(String loc) { return "string"; } public void testBestCoercion() throws Exception { Context c = new Context(); c.addCommand("bundles", this); assertEquals("bundles myloc", "string", c.execute("bundles myloc")); assertEquals("bundles 1", "long", c.execute("bundles 1")); assertEquals("bundles '1'", "string", c.execute("bundles '1'")); } @Descriptor("list all installed bundles") public String p0( @Descriptor("show location") @Parameter(names = { "-l", "--location" }, presentValue = "true", absentValue = "false") boolean showLoc, @Descriptor("show symbolic name") @Parameter(names = { "-s", "--symbolicname" }, presentValue = "true", absentValue = "false") boolean showSymbolic) { return showLoc + ":" + showSymbolic; } // function with session and parameter public boolean p01( CommandSession session, @Parameter(names = { "-f", "--flag" }, presentValue = "true", absentValue = "false") boolean flag) { assertNotNull("session must not be null", session); return flag; } public void testParameter0() throws Exception { Context c = new Context(); c.addCommand("p0", this); c.addCommand("p01", this); assertEquals("p0", "false:false", c.execute("p0")); assertEquals("p0 -l", "true:false", c.execute("p0 -l")); assertEquals("p0 --location", "true:false", c.execute("p0 --location")); assertEquals("p0 -l -s", "true:true", c.execute("p0 -l -s")); assertEquals("p0 -s -l", "true:true", c.execute("p0 -s -l")); try { Object r = c.execute("p0 wibble"); fail("too many args: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } assertEquals("p01 -f", true, c.execute("p01 -f")); } public String p1( @Parameter(names = { "-p", "--parameter" }, absentValue = "absent") String parm1) { return parm1; } public void testParameter1() throws Exception { Context c = new Context(); c.addCommand("p1", this); assertEquals("no parameter", "absent", c.execute("p1")); // FELIX-2894 assertEquals("correct parameter", "wibble", c.execute("p1 -p wibble")); try { Object r = c.execute("p1 -p"); fail("missing parameter: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } try { Object r = c.execute("p1 -X"); fail("wrong parameter: expected IllegalArgumentException, got: " + r); } catch (IllegalArgumentException e) { } } } felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/TestParser.java000066400000000000000000000301061165554700600305050ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import junit.framework.TestCase; import org.apache.felix.gogo.runtime.Parser; import org.apache.felix.gogo.runtime.Token; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Function; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; public class TestParser extends TestCase { int beentheredonethat = 0; public void testEvaluatation() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.addCommand("capture", this); assertEquals("a", c.execute("echo a | capture")); assertEquals("a", c.execute("(echo a) | capture")); assertEquals("a", c.execute("((echo a)) | capture")); } public void testUnknownCommand() throws Exception { Context c = new Context(); try { c.execute("echo"); fail("Execution should have failed due to missing command"); } catch (IllegalArgumentException e) { // expected } } public void testSpecialValues() throws Exception { Context c = new Context(); assertEquals(false, c.execute("false")); assertEquals(true, c.execute("true")); assertEquals(null, c.execute("null")); } public void testQuotes() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.set("c", "a"); assertEquals("a b", c.execute("echo a b")); assertEquals("a b", c.execute("echo 'a b'")); assertEquals("a b", c.execute("echo \"a b\"")); assertEquals("a b", c.execute("echo a b")); assertEquals("a b", c.execute("echo 'a b'")); assertEquals("a b", c.execute("echo \"a b\"")); assertEquals("a b", c.execute("echo $c b")); assertEquals("$c b", c.execute("echo '$c b'")); assertEquals("a b", c.execute("echo \"$c b\"")); assertEquals("a b", c.execute("echo ${c} b")); assertEquals("${c} b", c.execute("echo '${c} b'")); assertEquals("a b", c.execute("echo \"${c} b\"")); assertEquals("aa", c.execute("echo $c$c")); assertEquals("a ;a", c.execute("echo a\\ \\;a")); assertEquals("baabab", c.execute("echo b${c}${c}b${c}b")); c.set("d", "a b "); assertEquals("a b ", c.execute("echo \"$d\"")); } public void testScope() throws Exception { Context c = new Context(); c.addCommand("echo", this); assertEquals("$a", c.execute("test:echo \\$a")); assertEquals("file://poo", c.execute("test:echo file://poo")); } public void testPipe() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.addCommand("capture", this); c.addCommand("grep", this); c.addCommand("echoout", this); c.execute("myecho = { echoout $args }"); assertEquals("def", c.execute("echo def|grep d.*|capture")); assertEquals("def", c.execute("echoout def|grep d.*|capture")); assertEquals("def", c.execute("myecho def|grep d.*|capture")); assertEquals("def", c.execute("(echoout abc; echoout def; echoout ghi)|grep d.*|capture")); assertEquals("", c.execute("echoout def; echoout ghi | grep d.* | capture")); assertEquals("hello world", c.execute("echo hello world|capture")); assertEquals("defghi", c.execute("(echoout abc; echoout def; echoout ghi)|grep 'def|ghi'|capture")); } public void testAssignment() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.addCommand("grep", this); assertEquals("a", c.execute("a = a; echo ${$a}")); assertEquals("hello", c.execute("echo hello")); assertEquals("hello", c.execute("a = (echo hello)")); //assertEquals("a", c.execute("a = a; echo $(echo a)")); // #p2 - no eval in var expansion assertEquals("3", c.execute("a=3; echo $a")); assertEquals("3", c.execute("a = 3; echo $a")); assertEquals("a", c.execute("a = a; echo ${$a}")); } public void testComment() throws Exception { Context c = new Context(); c.addCommand("echo", this); assertEquals("1", c.execute("echo 1 // hello")); } public void testClosure() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.addCommand("capture", this); assertEquals("a", c.execute("e = { echo $1 } ; e a b")); assertEquals("b", c.execute("e = { echo $2 } ; e a b")); assertEquals("b", c.execute("e = { eval $args } ; e echo b")); assertEquals("ca b", c.execute("e = { echo c$args } ; e a b")); assertEquals("c a b", c.execute("e = { echo c $args } ; e a b")); assertEquals("ca b", c.execute("e = { echo c$args } ; e 'a b'")); } public void testArray() throws Exception { Context c = new Context(); c.set("echo", true); assertEquals("http://www.aqute.biz?com=2&biz=1", c.execute("['http://www.aqute.biz?com=2&biz=1'] get 0")); assertEquals("{a=2, b=3}", c.execute("[a=2 b=3]").toString()); assertEquals(3L, c.execute("[a=2 b=3] get b")); assertEquals("[3, 4]", c.execute("[1 2 [3 4] 5 6] get 2").toString()); assertEquals(5, c.execute("[1 2 [3 4] 5 6] size")); } public void testParentheses() { Parser parser = new Parser("(a|b)|(d|f)"); List>> p = parser.program(); assertEquals("a|b", p.get(0).get(0).get(0).toString()); parser = new Parser("grep (d.*)|grep (d|f)"); p = parser.program(); assertEquals("d.*", p.get(0).get(0).get(1).toString()); } public void testEcho() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.execute("echo peter"); } public void grep(String match) throws IOException { Pattern p = Pattern.compile(match); BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in)); String s = rdr.readLine(); while (s != null) { if (p.matcher(s).find()) { System.out.println(s); } s = rdr.readLine(); } } public String capture() throws IOException { StringWriter sw = new StringWriter(); BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in)); String s = rdr.readLine(); while (s != null) { sw.write(s); s = rdr.readLine(); } return sw.toString(); } public void testVars() throws Exception { Context c = new Context(); c.addCommand("echo", this); assertEquals("", c.execute("echo ${very.likely.that.this.does.not.exist}")); assertNotNull(c.execute("echo ${java.shell.name}")); assertEquals("a", c.execute("a = a; echo ${a}")); } public void testFunny() throws Exception { Context c = new Context(); c.addCommand("echo", this); assertEquals("a", c.execute("echo a") + ""); assertEquals("a", c.execute("eval (echo echo) a") + ""); //assertEquals("a", c.execute("((echo echo) echo) (echo a)") + ""); assertEquals("3", c.execute("[a=2 (echo b)=(echo 3)] get b").toString()); } public CharSequence echo(Object args[]) { if (args == null) { return ""; } StringBuilder sb = new StringBuilder(); for (Object arg : args) { if (arg != null) { if (sb.length() > 0) sb.append(' '); sb.append(arg); } } return sb.toString(); } public void echoout(Object args[]) { System.out.println(echo(args)); } public void testContext() throws Exception { Context c = new Context(); c.addCommand("ls", this); beentheredonethat = 0; c.execute("ls"); assertEquals(1, beentheredonethat); beentheredonethat = 0; c.execute("ls 10"); assertEquals(10, beentheredonethat); beentheredonethat = 0; c.execute("ls a b c d e f g h i j"); assertEquals(10, beentheredonethat); beentheredonethat = 0; Integer result = (Integer) c.execute("ls (ls 5)"); assertEquals(10, beentheredonethat); assertEquals((Integer) 5, result); } public void ls() { beentheredonethat++; System.out.println("ls(): Yes!"); } public int ls(int onoff) { beentheredonethat += onoff; System.out.println("ls(int) " + onoff); return onoff; } public void ls(Object args[]) { beentheredonethat = args.length; System.out.print("ls(Object[]) ["); for (Object i : args) { System.out.print(i + " "); } System.out.println("]"); } public void testProgram() { List>> x = new Parser("abc def|ghi jkl;mno pqr|stu vwx").program(); assertEquals("abc", x.get(0).get(0).get(0).toString()); assertEquals("def", x.get(0).get(0).get(1).toString()); assertEquals("ghi", x.get(0).get(1).get(0).toString()); assertEquals("jkl", x.get(0).get(1).get(1).toString()); assertEquals("mno", x.get(1).get(0).get(0).toString()); assertEquals("pqr", x.get(1).get(0).get(1).toString()); assertEquals("stu", x.get(1).get(1).get(0).toString()); assertEquals("vwx", x.get(1).get(1).get(1).toString()); } public void testStatements() { List> x = new Parser("abc def|ghi jkl|mno pqr").program().get(0); assertEquals("abc", x.get(0).get(0).toString()); assertEquals("def", x.get(0).get(1).toString()); assertEquals("ghi", x.get(1).get(0).toString()); assertEquals("jkl", x.get(1).get(1).toString()); assertEquals("mno", x.get(2).get(0).toString()); assertEquals("pqr", x.get(2).get(1).toString()); } public void testSimpleValue() { List x = new Parser( "abc def.ghi http://www.osgi.org?abc=&x=1 [1,2,3] {{{{{{{xyz}}}}}}} (immediate) {'{{{{{'} {\\{} 'abc{}'") .program().get(0).get(0); assertEquals("abc", x.get(0).toString()); assertEquals("def.ghi", x.get(1).toString()); assertEquals("http://www.osgi.org?abc=&x=1", x.get(2).toString()); assertEquals("1,2,3", x.get(3).toString()); assertEquals("{{{{{{xyz}}}}}}", x.get(4).toString()); assertEquals("immediate", x.get(5).toString()); assertEquals("'{{{{{'", x.get(6).toString()); assertEquals("\\{", x.get(7).toString()); assertEquals("'abc{}'", x.get(8).toString()); } void each(CommandSession session, Collection list, Function closure) throws Exception { List args = new ArrayList(); args.add(null); for (Object x : list) { args.set(0, x); closure.execute(session, args); } } } felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/TestParser2.java000066400000000000000000000067241165554700600306000ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.io.EOFException; import junit.framework.TestCase; /* * Test features of the new parser/tokenizer, many of which are not supported * by the original parser. */ public class TestParser2 extends TestCase { public void testComment() throws Exception { Context c = new Context(); c.addCommand("echo", this); assertEquals("file://wibble#tag", c.execute("echo file://wibble#tag")); assertEquals("file:", c.execute("echo file: //wibble#tag")); assertEquals("PWD/*.java", c.execute("echo PWD/*.java")); try { c.execute("echo PWD /*.java"); fail("expected EOFException"); } catch (EOFException e) { // expected } assertEquals("ok", c.execute("// can't quote\necho ok\n")); // quote in comment in closure assertEquals("ok", c.execute("x = { // can't quote\necho ok\n}; x")); assertEquals("ok", c.execute("x = {\n// can't quote\necho ok\n}; x")); assertEquals("ok", c.execute("x = {// can't quote\necho ok\n}; x")); } public void testCoercion() throws Exception { Context c = new Context(); c.addCommand("echo", this); // FELIX-2432 assertEquals("null x", c.execute("echo $expandsToNull x")); } public void testStringExecution() throws Exception { Context c = new Context(); c.addCommand("echo", this); c.addCommand("new", this); // FELIX-2433 assertEquals("helloworld", c.execute("echo \"$(echo hello)world\"")); // FELIX-1473 - allow method calls on String objects assertEquals("hello", c.execute("cmd = echo; eval $cmd hello")); assertEquals(4, c.execute("'four' length")); try { c.execute("four length"); fail("expected: command not found: four"); } catch (IllegalArgumentException e) { } // check CharSequence types are preserved Object b = c.execute("b = new java.lang.StringBuilder"); assertTrue(b instanceof StringBuilder); assertEquals(b, c.execute("c = $b")); } public CharSequence echo(Object args[]) { if (args == null) { return "null args!"; } StringBuilder sb = new StringBuilder(); for (Object arg : args) { if (sb.length() > 0) sb.append(' '); sb.append(String.valueOf(arg)); } return sb.toString(); } public Object _new(String className) throws Exception { return Class.forName(className).newInstance(); } } felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/TestTokenizer.java000066400000000000000000000224551165554700600312330ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime; import java.io.File; import java.net.URI; import java.util.HashMap; import java.util.Map; import org.apache.felix.gogo.runtime.Evaluate; import org.apache.felix.gogo.runtime.Parser; import org.apache.felix.gogo.runtime.SyntaxError; import org.apache.felix.gogo.runtime.Token; import org.apache.felix.gogo.runtime.Tokenizer; import org.apache.felix.gogo.runtime.Tokenizer.Type; import junit.framework.TestCase; public class TestTokenizer extends TestCase { private final Map vars = new HashMap(); private final Evaluate evaluate; public TestTokenizer() { evaluate = new Evaluate() { public Object eval(Token t) throws Exception { throw new UnsupportedOperationException("eval not implemented."); } public Object get(String key) { return vars.get(key); } public Object put(String key, Object value) { return vars.put(key, value); } }; } public void testHello() throws Exception { testHello("hello world\n"); testHello("hello world\n\n"); // multiple \n reduced to single Token.NL testHello("hello world\r\n"); // \r\n -> \n // escapes testHello("hello \\\nworld\n"); try { testHello("hello\\u20world\n"); fail("bad unicode accepted"); } catch (SyntaxError e) { // expected } // whitespace and comments testHello(" hello world \n "); testHello("hello world // comment\n\n"); testHello("hello world #\\ comment\n\n"); testHello("// comment\nhello world\n"); testHello("// comment ?\\ \nhello world\n"); testHello("hello /*\n * comment\n */ world\n"); } // hello world private void testHello(CharSequence text) throws Exception { Tokenizer t = new Tokenizer(text); assertEquals(Type.WORD, t.next()); assertEquals("hello", t.value().toString()); assertEquals(Type.WORD, t.next()); assertEquals("world", t.value().toString()); assertEquals(Type.NEWLINE, t.next()); assertEquals(Type.EOT, t.next()); } public void testString() throws Exception { testString("'single $quote' \"double $quote\"\n"); } // 'single quote' "double quote" private void testString(CharSequence text) throws Exception { Tokenizer t = new Tokenizer(text); assertEquals(Type.WORD, t.next()); assertEquals("'single $quote'", t.value().toString()); assertEquals(Type.WORD, t.next()); assertEquals("\"double $quote\"", t.value().toString()); assertEquals(Type.NEWLINE, t.next()); assertEquals(Type.EOT, t.next()); } public void testClosure() throws Exception { testClosure2("x = { echo '}' $args //comment's\n}\n"); testClosure2("x={ echo '}' $args //comment's\n}\n"); assertEquals(Type.CLOSURE, token1("{ echo \\{ $args \n}")); assertEquals(Type.CLOSURE, token1("{ echo \\} $args \n}")); } /* * x = {echo $args}; */ private void testClosure2(CharSequence text) throws Exception { Tokenizer t = new Tokenizer(text); assertEquals(Type.WORD, t.next()); assertEquals("x", t.value().toString()); assertEquals(Type.ASSIGN, t.next()); assertEquals(Type.CLOSURE, t.next()); assertEquals(" echo '}' $args //comment's\n", t.value().toString()); assertEquals(Type.NEWLINE, t.next()); assertEquals(Type.EOT, t.next()); } private Type token1(CharSequence text) throws Exception { Tokenizer t = new Tokenizer(text); Type type = t.next(); assertEquals(Type.EOT, t.next()); return type; } public void testExpand() throws Exception { final URI home = new URI("/home/derek"); final File pwd = new File("/tmp"); final String user = "derek"; vars.clear(); vars.put("HOME", home); vars.put("PWD", pwd); vars.put("USER", user); vars.put(user, "Derek Baum"); // quote removal assertEquals("hello", expand("hello")); assertEquals("hello", expand("'hello'")); assertEquals("\"hello\"", expand("'\"hello\"'")); assertEquals("hello", expand("\"hello\"")); assertEquals("'hello'", expand("\"'hello'\"")); // escapes assertEquals("hello\\w", expand("hello\\\\w")); assertEquals("hellow", expand("hello\\w")); assertEquals("hello\\w", expand("\"hello\\\\w\"")); assertEquals("hello\\w", expand("\"hello\\w\"")); assertEquals("hello\\\\w", expand("'hello\\\\w'")); assertEquals("hello", expand("he\\\nllo")); assertEquals("he\\llo", expand("'he\\llo'")); assertEquals("he'llo", expand("'he'\\''llo'")); assertEquals("he\"llo", expand("\"he\\\"llo\"")); assertEquals("he'llo", expand("he\\'llo")); assertEquals("he$llo", expand("\"he\\$llo\"")); assertEquals("he\\'llo", expand("\"he\\'llo\"")); assertEquals("hello\\w", expand("\"hello\\w\"")); // unicode // Note: we could use literal Unicode pound '£' instead of \u00a3 in next test. // if above is not UK currency symbol, then your locale is not configured for UTF-8. // Java on Macs cannot handle UTF-8 unless you explicitly set '-Dfile.encoding=UTF-8'. assertEquals("pound\u00a3cent\u00a2", expand("pound\\u00a3cent\\u00a2")); assertEquals("euro\\u20ac", expand("'euro\\u20ac'")); try { expand("eot\\u20a"); fail("EOT in unicode"); } catch (SyntaxError e) { // expected } try { expand("bad\\u20ag"); fail("bad unicode"); } catch (SyntaxError e) { // expected } // simple variable expansion - quoting or concatenation converts result to String assertEquals(user, expand("$USER")); assertEquals(home, expand("$HOME")); assertEquals(home.toString(), expand("$HOME$W")); assertEquals(pwd, expand("$PWD")); assertEquals("$PWD", expand("'$PWD'")); assertEquals("$PWD", expand("\\$PWD")); assertEquals(pwd.toString(), expand("\"$PWD\"")); assertEquals("W" + pwd, expand("W$PWD")); assertEquals(pwd + user, expand("$PWD$USER")); // variable substitution ${NAME:-WORD} etc assertNull(expand("$JAVA_HOME")); assertEquals(user, expand("${USER}")); assertEquals(user + "W", expand("${USER}W")); assertEquals("java_home", expand("${JAVA_HOME:-java_home}")); assertEquals(pwd, expand("${NOTSET:-$PWD}")); assertNull(vars.get("JAVA_HOME")); assertEquals("java_home", expand("${JAVA_HOME:=java_home}")); assertEquals("java_home", vars.get("JAVA_HOME")); assertEquals("java_home", expand("$JAVA_HOME")); assertEquals("yes", expand("${JAVA_HOME:+yes}")); assertNull(expand("${NOTSET:+yes}")); assertEquals("", expand("\"${NOTSET:+yes}\"")); try { expand("${NOTSET:?}"); fail("expected 'not set' exception"); } catch (IllegalArgumentException e) { // expected } // bad variable names assertEquals("$ W", expand("$ W")); assertEquals("$ {W}", expand("$ {W}")); try { expand("${W }"); fail("expected syntax error"); } catch (SyntaxError e) { // expected } assertEquals(user, expand("${USER\\\n:?}")); assertEquals(user, expand("${US\\u0045R:?}")); // bash doesn't supported nested expansions // gogo only supports them in the ${} syntax assertEquals("Derek Baum", expand("${$USER}")); assertEquals("x", expand("${$USR:-x}")); assertEquals("$" + user, expand("$$USER")); } private Object expand(CharSequence word) throws Exception { return Tokenizer.expand(word, evaluate); } public void testParser() throws Exception { new Parser("// comment\n" + "a=\"who's there?\"; ps -ef;\n" + "ls | \n grep y\n").program(); String p1 = "a=1 \\$b=2 c={closure}\n"; new Parser(p1).program(); new Parser(new Token(Type.ARRAY, p1, (short) 0, (short) 0)).program(); } } felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/threadio/000077500000000000000000000000001165554700600273455ustar00rootroot00000000000000felix-gogo-runtime-0.10.0/src/test/java/org/apache/felix/gogo/runtime/threadio/TestThreadIO.java000066400000000000000000000057471165554700600325240ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.runtime.threadio; import junit.framework.TestCase; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; public class TestThreadIO extends TestCase { /** * Test if the threadio works in a nested fashion. We first push * ten markers on the stack and print a message for each, capturing * the output in a ByteArrayOutputStream. Then we pop them, also printing * a message identifying the level. Then we verify the output for each level. */ public void testNested() { ThreadIOImpl tio = new ThreadIOImpl(); tio.start(); List list = new ArrayList(); for (int i = 0; i < 10; i++) { ByteArrayOutputStream out = new ByteArrayOutputStream(); list.add(out); tio.setStreams(System.in, new PrintStream(out), System.err); System.out.print("b" + i); } for (int i = 9; i >= 0; i--) { System.out.println("e" + i); tio.close(); } tio.stop(); for (int i = 0; i < 10; i++) { String message = list.get(i).toString().trim(); assertEquals("b" + i + "e" + i, message); } } /** * Simple test too see if the basics work. */ public void testSimple() { ThreadIOImpl tio = new ThreadIOImpl(); tio.start(); System.out.println("Hello World"); ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream err = new ByteArrayOutputStream(); tio.setStreams(System.in, new PrintStream(out), new PrintStream(err)); try { System.out.println("Simple Normal Message"); System.err.println("Simple Error Message"); } finally { tio.close(); } tio.stop(); String normal = out.toString().trim(); //String error = err.toString().trim(); assertEquals("Simple Normal Message", normal); //assertEquals("Simple Error Message", error ); System.out.println("Goodbye World"); } }