[Mulgara-svn] r1366 - in trunk: . jxdata/iTQL/fulltext_queries lib src/jar/resolver-lucene src/jar/resolver-lucene/java/org/mulgara/resolver/lucene
ronald at mulgara.org
ronald at mulgara.org
Mon Oct 27 12:38:49 UTC 2008
Author: ronald
Date: 2008-10-27 05:38:48 -0700 (Mon, 27 Oct 2008)
New Revision: 1366
Added:
trunk/jxdata/iTQL/fulltext_queries/queryResult17.txt
trunk/jxdata/iTQL/fulltext_queries/queryResult18.txt
trunk/jxdata/iTQL/fulltext_queries/queryResult19.txt
trunk/lib/jakarta-regexp-1.5.jar
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraintDescriptor.java
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java
Modified:
trunk/common.xml
trunk/jxdata/iTQL/fulltext_queries/test.jxu
trunk/src/jar/resolver-lucene/build.xml
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverFactory.java
trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
Log:
Added support for returning the score in fulltext (lucene) queries.
For this a new query graph is introduced with two new predicates, mulgara:search
and mulgara:score . As an example, the query
select $foo from ... where $foo <title> 'sequencing' in <lucene-graph>;
now becomes
select $foo $score from ... where
$foo <mulgara:search> $search in <lucene-graph> and
$search <title> 'sequencing' in <lucene-graph> and
$search <mulgara:score> $score in <lucene-graph>;
The score is optional; also, the previous simple form is still recognized. This
query graph is extensible, e.g. to add query parameters such as the analyzer to
use.
Modified: trunk/common.xml
===================================================================
--- trunk/common.xml 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/common.xml 2008-10-27 12:38:48 UTC (rev 1366)
@@ -477,7 +477,7 @@
${server-rmi.jar}"/>
<fileset dir="${lib.dir}" includes="xerces*.jar, xmlParserAPIs.jar,
xmlc-xerces.jar, jxunit*.jar,
- junit.jar"/>
+ jakarta-regexp*.jar, junit.jar"/>
</classpath>
<test name="net.sourceforge.jxunit.JXTestCase" haltonfailure="no"
Added: trunk/jxdata/iTQL/fulltext_queries/queryResult17.txt
===================================================================
--- trunk/jxdata/iTQL/fulltext_queries/queryResult17.txt (rev 0)
+++ trunk/jxdata/iTQL/fulltext_queries/queryResult17.txt 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><pmid/><title/><score/></variables><solution><pmid resource="urn:pmid:11076292"/><title>[The role of immunohistochemical methods for determining the type of treatment and prognosis of tumoral diseases]</title><score datatype="http://www.w3.org/2001/XMLSchema#double">1.67</score></solution><solution><pmid resource="urn:pmid:11076294"/><title>[Ultrastructural phenotypes of tumor cells of endocrine-cellular neoplasms of hepatopancreatoduodenal organs and their role in determining the degree of malignancy and prognosis of these diseases]</title><score datatype="http://www.w3.org/2001/XMLSchema#double">1.38</score></solution></query></answer>
Property changes on: trunk/jxdata/iTQL/fulltext_queries/queryResult17.txt
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Added: trunk/jxdata/iTQL/fulltext_queries/queryResult18.txt
===================================================================
--- trunk/jxdata/iTQL/fulltext_queries/queryResult18.txt (rev 0)
+++ trunk/jxdata/iTQL/fulltext_queries/queryResult18.txt 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><pmid/><title/><sc1/><sc2/></variables><solution><pmid resource="urn:pmid:11076292"/><title>[The role of immunohistochemical methods for determining the type of treatment and prognosis of tumoral diseases]</title><sc1 datatype="http://www.w3.org/2001/XMLSchema#double">1.67</sc1></solution><solution><pmid resource="urn:pmid:11076294"/><title>[Ultrastructural phenotypes of tumor cells of endocrine-cellular neoplasms of hepatopancreatoduodenal organs and their role in determining the degree of malignancy and prognosis of these diseases]</title><sc1 datatype="http://www.w3.org/2001/XMLSchema#double">1.38</sc1></solution><solution><pmid resource="urn:pmid:11244589"/><title>[Cholelithiasis in heart transplant patients]</title><sc2 datatype="http://www.w3.org/2001/XMLSchema#double">2.75</sc2></solution></query></answer>
Property changes on: trunk/jxdata/iTQL/fulltext_queries/queryResult18.txt
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Added: trunk/jxdata/iTQL/fulltext_queries/queryResult19.txt
===================================================================
--- trunk/jxdata/iTQL/fulltext_queries/queryResult19.txt (rev 0)
+++ trunk/jxdata/iTQL/fulltext_queries/queryResult19.txt 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><pmid/><title/><sc1/><sc2/></variables><solution><pmid resource="urn:pmid:11076294"/><title>[Ultrastructural phenotypes of tumor cells of endocrine-cellular neoplasms of hepatopancreatoduodenal organs and their role in determining the degree of malignancy and prognosis of these diseases]</title><sc1 datatype="http://www.w3.org/2001/XMLSchema#double">1.38</sc1><sc2 datatype="http://www.w3.org/2001/XMLSchema#double">1.04</sc2></solution></query></answer>
Property changes on: trunk/jxdata/iTQL/fulltext_queries/queryResult19.txt
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Modified: trunk/jxdata/iTQL/fulltext_queries/test.jxu
===================================================================
--- trunk/jxdata/iTQL/fulltext_queries/test.jxu 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/jxdata/iTQL/fulltext_queries/test.jxu 2008-10-27 12:38:48 UTC (rev 1366)
@@ -304,6 +304,64 @@
<fail>Output failed. Check badQuery16Result.xml for output.</fail>
</ifEqual>
+ <!-- Query Lucene model with score -->
+ <set name="query"
+ value="select $pmid $title $score from <@server@#model1>
+ where $pmid <http://mulgara.org/mulgara/Document#title> $title and
+ $pmid <http://mulgara.org/mulgara#search> $x in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara/Document#title> 'Diseases' in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara#score> $score in <@server@#fulltext2>
+ order by $pmid $title;"/>
+
+ <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+ <subst name="queryResult" regexp="1\.67[0-9]*" value="1.67"/>
+ <subst name="queryResult" regexp="1\.38[0-9]*" value="1.38"/>
+ <ifEqual converse="true" file="queryResult17.txt" name="queryResult">
+ <save name="queryResult" file="badQuery17Result.xml"/>
+ <fail>Output failed. Check badQuery17Result.xml for output.</fail>
+ </ifEqual>
+
+ <!-- Query Lucene model with 2 scores in disjunction -->
+ <set name="query"
+ value="select $pmid $title $sc1 $sc2 from <@server@#model1>
+ where $pmid <http://mulgara.org/mulgara/Document#title> $title and
+ (($pmid <http://mulgara.org/mulgara#search> $x in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara/Document#title> 'Diseases' in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara#score> $sc1 in <@server@#fulltext2>) or
+ ($pmid <http://mulgara.org/mulgara#search> $y in <@server@#fulltext2> and
+ $y <http://mulgara.org/mulgara/Document#title> 'Heart*' in <@server@#fulltext2> and
+ $y <http://mulgara.org/mulgara#score> $sc2 in <@server@#fulltext2>))
+ order by $pmid $title;"/>
+
+ <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+ <subst name="queryResult" regexp="1\.67[0-9]*" value="1.67"/>
+ <subst name="queryResult" regexp="1\.38[0-9]*" value="1.38"/>
+ <subst name="queryResult" regexp="2\.75[0-9]*" value="2.75"/>
+ <ifEqual converse="true" file="queryResult18.txt" name="queryResult">
+ <save name="queryResult" file="badQuery18Result.xml"/>
+ <fail>Output failed. Check badQuery18Result.xml for output.</fail>
+ </ifEqual>
+
+ <!-- Query Lucene model with 2 scores in conjunction -->
+ <set name="query"
+ value="select $pmid $title $sc1 $sc2 from <@server@#model1>
+ where $pmid <http://mulgara.org/mulgara/Document#title> $title and
+ $pmid <http://mulgara.org/mulgara#search> $x in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara/Document#title> 'Diseases*' in <@server@#fulltext2> and
+ $x <http://mulgara.org/mulgara#score> $sc1 in <@server@#fulltext2> and
+ $pmid <http://mulgara.org/mulgara#search> $y in <@server@#fulltext2> and
+ $y <http://mulgara.org/mulgara/Document#title> 'pheno*' in <@server@#fulltext2> and
+ $y <http://mulgara.org/mulgara#score> $sc2 in <@server@#fulltext2>
+ order by $pmid $title;"/>
+
+ <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+ <subst name="queryResult" regexp="1\.38[0-9]*" value="1.38"/>
+ <subst name="queryResult" regexp="1\.04[0-9]*" value="1.04"/>
+ <ifEqual converse="true" file="queryResult19.txt" name="queryResult">
+ <save name="queryResult" file="badQuery19Result.xml"/>
+ <fail>Output failed. Check badQuery19Result.xml for output.</fail>
+ </ifEqual>
+
<!-- Drop the fulltext model -->
<set name="query"
value="drop <@server@#model1> ;
Added: trunk/lib/jakarta-regexp-1.5.jar
===================================================================
--- trunk/lib/jakarta-regexp-1.5.jar (rev 0)
+++ trunk/lib/jakarta-regexp-1.5.jar 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,313 @@
+PK
+ r6 META-INF/þÊ PK
+ r6sGV^ j META-INF/MANIFEST.MFóMÌËLK-.Ñ
+K-*ÎÌϳR0Ô3àårÌCq,HLÎHU %ÍôLy¹RKRSt*Aêõã
+,u-Ì4
+rRósJKRt<óõ4y¹x¹ PK
+ r6 org/PK
+ r6 org/apache/PK
+ r6 org/apache/regexp/PK
+ r6¸R 7 org/apache/regexp/CharacterArrayCharacterIterator.class}R]OÓP~κ¥TÄ9'¬C§N?Ç°p±ÄäÆÒÒ¶3ÓÄ_â 7^hâXâ½÷Gß³Õ¡0mrÞó>ïGßçüøùõ$Ìã4¦p·
Â1#ÃTÄY¡çWpGèî*XPpOÆ}£XT)ï2ÉxÌ ¾ÍÛ-éU«¬LÖ!wKë+²±[*g¶â%¯ÂÆ^ú[cÈz~`½²
+[+luïWÁ÷I{ßò×B*F jp
+·Òs_hÐñDCW5a\Cã§eÊn
77áfuÝk¸`£iózèx4oæl³õFµÊ}»nÞ²§(
+±Ä0ZÌü¨Á]çç
+§à2VÄ «Ã{¼æ¸½$òù~ J<ÛGää4\Ãuϯ¬ºeïóÏk¼Y/è-;äþï[¯û^zþ_7÷¸M»üOÓDɤ$z
+Îç÷}ÞV}Aý¨z[Åiãh·zaiPÞmJ0 &2»:ÛÕ ÓÎHNGqÒi³
+fζ3s-HæDñÏËÐoéeK¤ræÄavØé ¹ÓRN0;&CÄÉ>ÖÆ
ïú;(zîÓâG¦üÅ(1w0ºCé1:þ2§WÚ¸ô©?J>%CÄH«¦Þëú¹f,Âh§å?F¨IÜPYÂÔH·Ð{ÈñK=~PK
+ r62¯+ó Ó ) org/apache/regexp/CharacterIterator.class;õo×>f]v.vnFÎâÒ¤â¢Ì¼tF1
+OOM¬Ä²Dýļtý`°¸5#¨vq¶äÄ"ÇF gFÖÌb×¼7A9¿(]?± 19#U¿(5=µ¢@ߨ!1¹$µÈKòû'e¥&°120201 #й,@fÓlì`¤ PK
+ r6Ràsè ' org/apache/regexp/RE.classY
+|[Õu?Wzú°ôlËv^c9Øq äÄI0j¬(YRýÄ$$V$Ù(*ÉÄ@Hi1tck·5¦íÀ¦Òz+¬Mº²Ai¡íRºulëç6:ºnëè-î9÷Ý'?Ë"°þæßïÞsÿçsî¹çûñ䯼õ¹§ÀëÙý68Ī,Ìf³S%§ÚÌ^
µT9,¬ÎÂêm`'Á0k°²eªgµVV#UWU5QËIúÍÔZE«í¬
µ\MUUk¨ºz¯¥ÖZªÚ©ZGËÂÜVÖa5l=YÝ`@Ò7Ì&©uµºhë©j è¡ê=6¶
m¥jU7XÙvryí¤îyU^ªº©òQµËÊüV¶ÛÊöXØ^t³õ$°²}D÷AjõXXÈ5>Ô
+S+B÷ZX/Ñ>ì§jÀÊP÷A
+öJâ¢Á-ìf;laGÈ=Þ~ßÞc¡po7ÈTû2é|!.¦FFÀ?*çóöù¡]þ«P?u2µjgÏ@°?üÄ60p¨ì¾@hOЯñ%æpäêãh>âøUNw8Hè¨èWÑyC60°ª(¼ðaU¤Ùë
+ùöã4 ô{zUØ×ïí%èRa$8ÐGÐZëñvsÏnTùû|ÞgQåÃ8Yí8QùÐF¿[Ý®ñÃ}\kN\Ãz¹lä¬×·¿×ÏÝoSíï ÷ îQBáþ½1âØÉT8Ô
+pë>Õz¯?8àë÷úµ¹m)ãkÜÁ NÏ/Ͷîò½}\:ùy¡¿S85ÿ±P äÝÝáÐ.ÇÕîîæÝ}¯W»K¸wï
+ì ð¼«Ý%ùPǽ9ÆÝQ½XÂìõp´¬£;è
+í/ãùBý½<be|È2Þ^o§ÐHYG0|P]¿TYG¤7 nlyÇ@ÈÇ;ZË:x$Êxj~A½¾ãP)0ce=ûhÍyÏeÆöEDÇmêѱP&À¤îñ:=j;pÏgóB8ãý%0®6c\¡4ô%ïäÇfs\ô$æ`&7ÒÍFc'¹ÄHb,ÛÙë¨Ý7à¶Í'¢¹Ø ×Tô梱B"À-dr¨`;-ÄNìNEG(qÐûH4H#?KÔMÈj!+ld %ÒñÞ¤âMÞ¬âÍF+Ãm3»£±Ûra ¹%`Ç9q0Õð8¬ÓÐî@o_8d°\ãìÇÀúüÜæíÉt²Û\iÞ½=Ú¦G:û
+¹dzäupx·Í?KdI<e-ì4XA<@òíW1i¹²Û©^O̦hCîÏìM¥z#£©hÎ?Í%òytÁµ|_ÊÂÃs¤G·bR;÷§zd1ÇÀÛP8¢emD®n_÷D#º°j¨ì&ÒGú^Ø5¶?OôHá:#½©=À§dÏëÕªi
+`4åÏå29ì¦RïÏkILû
+ð-ëܦ9ãíÖUZÖ¥»ËVL7$M%q̵úW)?z<[*h¼Ë´Øú®T+/4KàaÚÞ®w.|üÖD¬ð6W%ó¡Ä©T2MÇX,s
+¾Ïwóºßaà¬c>TH¦9ù¾Ì²cÔú®ÏÃ~ßáà4]!Aq
+ËýêF£láijØàÙq£*.³¼"³a6"Ãi¿¿Ù j}
ª×dxá§ð
%ev+»M¯RßT}ª¿Ë2¼Ã¿FÕ7¨ú&\Æ'Ê;"Czý-ZÒ¶$·
&ú²ÌRì¤?ÿY¼DÿþKoQëgØbxCffÞ°°¬ÌÞÇpryª
+Í+é\"Iã-oIäcÑl¢e-ͯ4¶Vÿ¦n'ùST±;dv'µî"õÚîh¼%É'ÇZb©hWÎHßM%ã-~Aµ¬E!_&ÍZJ×Ϻ¥k¢FÉ&áMø%ºÊ´` B¦%7nái~§)oÂ/pp¾ÑB2Õy óÕÙÝì.üDfïW4 ÝzËìö1fáßà'8é52û »,¾%³qveRh-5ÏQ³Î¾D.a¸3z<
ÙÝVÉ@ßéBt¬tàASSÁ¦çø;\Ù1vJáCÓÍftæu¼«KAÍ{´ÓÔî»B¯9%Î[k!£vá¤Û+UÚ+ _1 K5ø ¦]Nçw%³ö$~ßäFcjÌqª¦aõº2%óüoXP+iÌts»#I)µd^0ädþàd!GO
+.BaÕìOù>R¡ÑÐÞMýwdê x(Éü>´'Ò
äp2wÔ²r~³Íx¡'ñáhÆãþTâdnÎE
v®Ò»$[½e²wÒ
®Ò|&'ÆÂÃowuÑ-[È3§9_4/ü÷A+Aü¼Ðá¶o¡D8ø!êðqÄ1ÃJHÀp >¡ÃIÄ·êðmS:|qZ3³:ü>Ä9Î#.èð(âÛuøâ1¾ñ:|âÓ:|7â3:ü~Ä÷èðPïE<®Ã÷!¾_?ø7tø7? ÿ
ø·uøÃ?¢Ã¿øwuø÷TDüû:üÒá?Dü1>xBFüqþâ?ÒáIÄS:<ø?øѲñÿXÿq±lüOêðc?UfÿÓ:<øOuøÏFGüÿ9âÏÍç¼_@<«ÃsÔá?§Ã^ßí¿ ÃO!~zÑ~Y _\´_VÂ_,Ú/+áK:üÖøÊÀúzYÐ9ôôàôyNï¡·§_ôA_ôk~]ÐoN¿)èK~ÓFø²}þ·eûüÛü^
m|`ûïÓ FlX\nã°'¸Ãÿ@¿¡Ø?rÑïÑf¥ÏÓ:×%0ÎÑ=sL¾5)µ¢2))®90»4Ò,X]ÎY¨RIü{B|±;¦ïåÀ0}l2Uðø¡yMHHç.ýÆE¢«w6ãþ¨Á²ËýXÚ]'¨Ëi,n7z£ ="è-ô.AOz7Qw}Í,Ô,Ãí82îfªÇ
+Ìé
ºéù£úÇŤñM,&T¢¨]M AÊ¿À+¢¿)Åä:
+3¢ûG¥ v
+õ6û,s?ËÝçA1LB¸$E¨R×F³ý¯ðjÛË4×~\qèåÚÐø:Ýq!øïMÔ]M³°bpÇÃÐNá*#<ÎTãuô:Ú}Âñ=Bû¦¦Oqº¼¯ KkP¤i+'UÍTzóh®¦fÓÃ৿ö -d¶ªÕTµ-Цà?J¬ù¼\PË'Ì×äѧ?,öXXÈC×9ÔF©ér^¦":ÔYÄØ"m.âV+º3üèg¿þ@-b V1Ðju E!Ðè[Dkqc`Í Øõ×à6ÀT¯ÅlkæJÚù±Å_/í÷E ¯sáÏÛ.ÀªR«Í¸½Ëø
+aî!<ÎÍÈ2=ÿªæ~w©Æª:ÁAª¶fDé|Ön«jòØUæÆ*ÅÖå1+6jºò¨)
+uy,Çúnjà §öòo at z
+ËøÒ¬zÙJeîvYÐS*ÏÔ$ú>+èÅÙ·µ-úL¼³Z±¼óKªmãw¯÷ÿZN¸y¨¾]faÝ Çj´*ÖbÒóÀ<
Vˤ.hñTáÖç^ÒüsäÉáÎÛnÅ¢Hár×*Ú;Ó`w)iè,GÛ0Å9$Ù±ÔÖúÿF
+ª-ôeÇ®Úà;jW)2
+3]§À\4oV°'CVê!)~:éÙRtK;©ÑScôÔa½KØEØh ìJíGJÍlâÊãµL©Uª§ç/M/(ÒYÓsdÎtÆ4
Eâs°ù,º`úh¥;aRÍôÑR-*i*§qõfiÃaéÆIJË'ùÒýqó"ªH`uØðÂUG§(àlxü4gΪ5ú1xOÂuÕbq×ÚSÒeur%¦Ìí«ÓÀýfáûQá{Aø¾Uø|Tø\>oåCOM±;é?¥µ'a-ôÐ
Üø·Iå^ÜüVLbE©Õ¥½<w)·ÞS¿E=gakQb´ 3)õb.MlÕ¢N`
+å_.m2̹·WJ¼j̽"¬-K<ܲR3Ô¥TR®)5
+éß.§&¡Ô]+æ=Æ¢X>"òã<Ȩ±`Áó?bÁ@ktÒF¤)Ô§ë>t¯XzÎ"îkD»1ÄÓ9-{lQ< Û&ØCe¬® voë -c]?Án)cmwÔN²½åL~1á|wbY¥/E¶¢\Á4Éå<i^[:Ú¼\ÎÄ!«ï¼×éAø¤>¢"L.Rul^È+Â[GËúÅת{§a
ï~DK"ôhvÄ"GwLè³vNYõ7bºSâ²Ú+m`¹<UyV×PNyjRã©+ÂL׺ñ:Öå©/µ\Áõ<Æ÷ >¡Ys(ÚàuJíôü¨-6ÜEWRã4éã6c2K.@~io¼MñÂSä³PÍ0¨;ÿ¢a¦¹
+.£zwH3¥à&: Ì ÅFlÎé×ßpÕ{§©D?ÛØiñϺø줪
*'UT5SµÚÅèUK¢kÌoÝݸ¢ô|sZë]Æúö&â¡ÝeÄOµ
+è±
+µ7á«'58¥îA÷øP~×Ü/U9Örx
0z§.{?qêý85úZ)â7ÐÍê]4~ç^Ghk·¶î3.§¸èñË;$Ónn§Bó?Öçââßó=BÛ$Íp)íTÕXv*îjÛõ8=&£Çìr+¦q8%Å<nf]ÍOZ>YËY°+æFé©éù8ê²!Y:çÓ
õ
+ßÞ³°Wg Àç³éKÀLÚ×cÜø::±Å
*+<&"ø67OÁòw³bfaÿ,Ñi¼d9Ke(æÍtoú
+Þ;1ÿ4Ñm¦F¨;UÔvÌBèÞfîhÄ4Å7(þ_ËD>X]îÿ½F W¡ç2Ò±¶aÐLÜw\ÄËO{V{°ÙËñÆÕñÇÚAbUEHPø<ÏBµãÈ$D試T=ÄÅyVÓ&¢³Îdë#ÐÙ(áÐ4D×-7ì¢nTïÝfo´?öF©ÑN|Åâ±[XG}öz,PS®ÊE°!áQÆUW0}ͨú¦fÊ!Î2|áÏáò»)Ò×6Q˧&ÒÂ
+Lb&Éý &úêZXaüÜs7o
m´ðhE¬Ù ÷Cm$Î4Jªaý'KÞ)~ÚLlÏäNmV9Õ°ÒY÷MB³®¥}lHÖiOaˬÂÖ*ñóN}3zMOÂÁíN¬v49ãª,ü
+PK
+ r6û®Yä G * org/apache/regexp/RECompiler$RERange.class}T[OÓ`~>Únlt0³-8lx Y.!YÆD¼¡n
+Ù)Û Ìknü Ä« fC£Æàðç¨ïÛ±C¾§ïyOÏîçï¯? aáz *n°³¸ÉbÅ ¹ L̳uÅ)?î
+Èâ[@dËÅʦUÙ%wàã[/Uö˾f¡Ø/
+LmTë»)«få
+vªnïÚµÔæzºZ®Kv}U °Õª4v³£¬µb¥Ø|,0¸<mî®æ©/oì&r"Ãa¥l×y%q|_Ý.W(à/Vr¥}'
¶l"MZÅ$î©GDÅ0FTqEÅ(1v¯AS¡Ãðã¾%,«¡b1?VâMß\÷xñ÷,5S©ØõtÉj4ì@xÏ:°R%:Ke_ïÙ¹&qàéú¶Z¦M´¬zÝj媵Øø7s5óÃ~ÙÑ5 (ôàHpô¨§Çø(Ó 'æ£wWɵúsægs¾3îB2ÍO¾»{bJ]ø:p"Ø+ñ²Sâ}ÇÒX·1ÛÑäü;L'å¨dâz
+yGB¸è?¿Ì¤å|_º=·Ñ4¶ÒãS¼åÙH¶1¬s#y¹ãOõmÆü¦¦a°ÓKiçInh¦÷`z?Gý°#IîÜû¬¡6ò
+R`öÊÊV¸ª9îû W¢JÏÊÌsTa ÉaÍa-=ëR³ÓGÍÔ95øFäó~dj>¸Ókm¹Cë'Tç¾ØÿIo±7´,»eÅAFdí=T3ÂwF«ê
]]Þ(¼y¯Ã¤kQc"Ûq+y§JïT1¨X¶µíóEè{ôÑßLzÜ8¦~ͧ4<Áô'¬DzÐÔ1ä"îVÄ"ðPK
+ r6lá"¯ " " org/apache/regexp/RECompiler.class¥8
+x×qón÷îöN+±, î.1Ò
+ýàÀÙÆHd¹V-!"c!·Ò-ÒáÓÝõî%©'MÒ¤!?-Ä6¸=7¨M@Ð@ìô/mÒ$MÓ´©ºIþ¥núô+3oßö$A¯Ò·ï½7ofÞüí}áÍO¿4±xÆàÅ ¤áWhød.ÀLW¿ê_Sà×àüð²èS4\¢árfá
+_
+Bü&à®a%¼HÃghx%¯ÂgiËoúá·øm~ ßUàsôþ÷ø}>¯À$X6÷&
+7ã(ðEzÿ%¾¬ÀÒ9¾BÿqøjöÃûáOüOéô?Sàk
+ü¹!ÌÍùáëAÃ_Òð½ÿß$à¯x]¿àò[4|^þ
+þVïÐAß#ÌßÑð÷
+üÿ¨À?ÑßUà û
+ÿ¢À÷øWZþ
+ÿNÃÐð}~ À°ÿ¥À+ð?~øß <ÿç$ø
+¼IÏ!À@aLa
I
+æUOa~
)
+(,¨°*
©
+«ö³?[ÆÀ¿·s¯±¨]ïH
U`PÊùñáb*aàì`P¶2]n,ëB9³X´ò
ºGÍ4²ké+æS{H¸ÇTr/gæñÞÝ{oç¡Ý½{{vv3¨îÈ"S3S|ÈL[ho DÚ$ýÝÝ;wuw9Èwõîéî|¨³T¸³¯ãPÏξ/-wíìx`oç}êèíAê8Ô½³¯67µý¡ìx&i%¥9ücøTfèÍq÷¨YÝÓÛ×
t[Ïñb*Ýr?¢æPÚBU}ÛST±µoxÜM¢Y}¨ñxr}G[c©"A3H6µòóÕwtqµ`w[ÅÞÃ$o½3£ÉÐòÕ©ÞLwæóÙ<òê¶rt3dâÂd¦hNWzýâ»!~¡#Y6sy×øª(Ï6Ù146bÆRx&1ÈÅ𧳶>ä%'ryzË¥ÒøfóRçwgó#-fεZòÖîiÙÛ¹'ÉchNeûpT
÷ÁûUÈÁO©i*[ÎB*ü|Áú¥¸ôÙÊ;ö`°ÖÞt¬0ÍcGÆÇr±<9~3±?Ã`Ù¼Âh˺}c!êTx
+*¥¡ã~¶Be+®Â/ xl[fëÈYhµd,IU8M¬W-Ô}×øáÃV^ekXÊÖ²°ETeoSá@[¯§ß=>6dåïËæÇÌ¢K½|ÎQ3JÆ2wñhú13ÍÇò©ÑbLܳ
+ï¡j*ÉT¶,Øe&m0XÑ*PÒ]®Å·#vM'wp¢U¸B*±:1/év
+ëc£Ö´SchKnBÌ<LbðmçX®8IgÊ|Q0r;m`oWá½ð³*»mD±æ-Óá8¨ÊêY
+£þ]Û <Tce'¶ÙÅqÙpk*;rl)Ïê°]:¿AäMôf¨¬mRáYxE$+.`IïСø+~0s¤¿Bç
»ÑÕXkUáCðó*ÛÌZÑÉæ,ä³1*<Ï©ðL£Ïõg¬ò%ó;äÉsîGgB¥,V»h-ä=Kerãè-ä-ËIì!ô¼
^keñ ³tÐdëkàÈÄ ®£63Ñ
+-tÕt¦
+ ¨þ|T
Ã)ÎÁ´
+ç9ËJçã«ì²®ÞÞ¥Õ
+\öXÞ3S ÷H3t{ïpܪ2¡c3ÓWÐö[ØVÉ8¡>óp¦§TÈgäÃüçMg£pôæ08ÏÓ\Èñ8òçrôÞ7!6H ¬TZçø2r+Ä«Þ¡#àBõM¦ìÏÃÙÜ$Ãí=÷t-âåF[¶P`rÑE»aGàOîµ5 zÝÏDÍÈÂ/ÊùvÞ£Ü^Ì:,WÖ/¦Cåó8JÃ#¤¯V)`µ,Þ¤ a1
+`åì¶2#E¼
ªb¶î¡Ã,X¶(ñ¦%+ÑM
+£7(«¨H/ÙP}½} Ë7,F!O21ïx-Fëê¬Ø
<Nó~åØO(lø,¡£í0ÉFÏ3ØE°9!`_Z·ò®D bp×"¿%% {Ö1ìÎãe::ªÜ|ÆÊÉç£~LÌ|^83xz;8ðqüÂ'\ðO#ü¤î@øg\°ðI¼á§\ðvÁïÆñ!Ï{<X|p!
+v!8~ ¡uHËp^a\f,'¯{/Ç.ô2ØØâNðóÝÆ%ð¼Ò£ND¦¡±þwÔAû~äºw7IM!¯l4!_%Ö Ár=²ôà¼ÚgÁK[Ü°_N á~g¦U±áü#v>±!Ê_&é(Ãý|SöÊú9o_Â¥&mÁx? ½8uØØÒ^µáÈ(ĸ-Ml/¿ª0¡§ç^çó9¸=NÆeÿ?rª¯o ä¿Ê«b¢OµÁ_¶¨·¨£
+·a¿³*O@¥ñ%gKlÜÐÄr2¤
+^À@(xª^å¿o8c/'¨u¤&ûHâF¸Øó'Öì
+QZöU<[ŧú¬Å©Rù©³°L;vüÆ,hóT+9Õ%þú*,?#
×`åÀü
+AK7.f4«öÝÇÜWÆYX}Ö\Ú{PY:¦ép¶iOL!Lgð#ÈË£/ßZMgÏÛ~LÆJÆ7S¿Q
uÿ?ÝYÄÓ*}N¹^Z¹'¸ruH÷2Þð3e
µì$;Å>kxv¶x>0ç3npݹL¡X=E¼ovñr»
+r·l»ç<mûö[{h϶EÌwþhÚò¸óÖðs>{ýGÐ}ü
+{/û>Ûæy±m¡õ3¡
+3am|
+üþÈÞ6 óÔ㮫 $¤µNÃjî>ZÔ?¡Ë 5t÷ëòUx;§0§a-NÏÃ
+N¡ÉL ÑzCeèöYØ^jÀúÖ*ô¹Ù
+G/»WUd at N¶=77Ñ3ZpF«ÑÔ[Å@Xk£8&ÛæÉd§¡/âXÂu[ ×®æ
»¢7ß 3áEiîyÇÁåtoçõn\äàîûÅp¿o¬½×ܶMÁ+-¸½ÕKÙ´â|¼¯óøs_vË_pÆP9ØB¬= Û$z.BÓ¦Yhþ,´ìnúæù Õö4ÍBë,l);ÂxÿH½1ô¶Ð¨
+bÛ¼=´µ-Ò.ǽRÜGÄýR\¹ñì*îÜ,yF]Ò] _À~¾&\SY<O>ñ¹M÷¿Þ-Å©&ªº
+ÔÚ ÚMÂ]ó¦*y4¼»âUJX?ýLJ?"ÃRØZ#´
+åÔ}§éZ¶¹Ò6OB\58ÜÏsøôáAûð9Oiªq¦.ê2ïó Þ@q4¿îEyjZ-îÁE¶ÎÁÕ
¶òe .mߦ½ÓYjeÂáp¬¼íDå¶2þ0B¼ÚY¨Î"è,gã4áÚÔw8îÔö;ËCi«v7ÇE0\Ò«NÅñãmGãÉq_["¿+n|÷ÒÁ m%&«G#¦!d¼Qã]ÑÓÎÕ b CÀh:Kn=I¯Ëí7!{dêÆSÎ+m','j ýT¿¯*AÌ h^Õ|jÞÉxºéUvzîµ%ÒÈY'°Úu4´<H¤¶pìxE¶WÔÓ)hä$»Ze.ªvCQè.Å\
+ÀOF׳CÌTg#§
+úÍ᤹ø Ïz17x>47ü
+Âø$>ø ºãà`äì7B»ðJð ÒNjRa
+uuLA¥ -¨"7» b,Õ(Ñ»rsöæ9dí$jºV츥)·4`O°J°HU#ëaIaË<+,sQX械̤°ÌEaË\ùeaIaÂ2çÐOâxsÆÝGÞK
+~çáûù¸KT62¤ÝYá'Í|Bç®Fé@³öæ^C;P
+ù9nVËSä]Ñó4?ÉÖÍò¸u}GPF_ï,<°Øàç{¾A_Ó×¹´òõà$õî6°ætÇebÒ$5ãånÛ§Ë32¯åǧû.»ü\~»#tEÀëò¸_÷kÏB§
+</ô xº|ç»Ý5<æÎShþ2?¬Rº÷4{ÝoËÁÚ2±:!S«ÈShm<@M{3Y¼J£××rËz7Ö·YØó´ÊtÓäÜwô g
+ֺ«µ!éøúA$ö%hµ§7ôàóð¤×Ûª
+mMR[s¯¯)A´¶Z¯¡x½öatÒ¾§k^£§ç¾
ACÛM½ñeR\£Î±Z³¾²Ç^ú4ÉfPcºF{_+Ár¾QmûlYKØÝ,2k¿Aý1}+ÄOQ~
ËßƵâd+sìFCëp677Mx {¯p§Àî0È7º?¾q¡µ¼59mÎfûôùÍè´bà¼ð!ÄùIFO»'.clóÊTèZk½F-Ö³½m¸n>>¬ºìA7EæØïÄå(Þ¿7â*wâñ³å¯ajîí¨º¶SÙ
+¨.ó
rn| á Î/xÚ<<P6{OI÷õS2xûhKS.dvëÁ²ÉÁx¢=]ëmãä³[Îí\°ÔÉm®8Õê èâ¹°x¹q¢úBÌ}Ø bÝ[Û¨îã´
úÇev\"Ä<æyê>zÌâDÍÙ¸ÊëJKÎ]<½7É
+Y D9ã]3"2áµòÍqüH[chíX£RöÅõ£ våÑobK<PâU¡-Úñ)ü*Ðô'"sÑPwãp;cþãÔôÜÝ#_Â:c»Ûqñ»]Îh¼â£Êý¹$~ì"ºx&öööØèw-r".}QÅx¹Ùg'GiÑï|×àaêqº®ÀÀKdR äüðÈVðÛù¯Á~üÆü4á'IèÀ5hлÌÂÁ}9Ä1¦à!Æäafc.Ì0Ǹ0II»0Çä\ÃSçÂpLÁ
åq&Å1.Ì9âÂ<Ê1
+ýÓ ,AãÀPK
+ r6¡Ö.
+i
+ ' org/apache/regexp/REDebugCompiler.class[wUÇÿÓ&ÓtS4å&
ÖZíÒÚHM
+ÔriÚNÓ`Ät (^êýWðÒ*ÊÒ'@M]v-o®å'ñøîIÚ¡ôÁtåßÙû¿Ïì9ûôïÛ¿ÿzìÅv¡6à â2´´c72C2Ú!
+ãù8Ã<<e
+#
+{ÂN±'N fsT eG3ÆÆyÐO
+¤¦2gæµ,LËÈ5 gصÈÖwB¹K<xVàÀyç¸ ðÀ^xYàWf^x]à
+7Þx[àwe¼'ã} ö©ÔÌZÏOh\Ñ3©³©@IÏdýÄõÔXVë`ëÊä2zzoËQ PÅ{m¾Ì'ôb&¦po¨ÅPȦré)\JÝܨȪQ¥éB¼OSÓ¶x
+L>'ýX1£kÅNÞèÏVö§àÂ
+z°~Y1Óµ´VäÕK
+>À+óIÕøéô°iåboirR+JN(øyøXÁ'øTÁgèWð9¾PÐ~Ús«'_Hé)O·GBÝ>'pDBC«'§Ó*¸«TÂ\>§±}ÚêQáxi/}OVÐv²è_⪯ðµ
+«@Æ7
+æ0Ï÷(|pÍùîwION9
ÁX2*¸ïWðxt(A%4£àp/Ú
c£WVIÍÆé}z½±P¿Qà`R0,NmXF2ªæ°SýXáѧ&Uª-Y!5ÄÂr8
+ÆÃÇPTMTUz¡#aÚÇΣ&"ÇCÑ`²«FóP"4¿¹óÅt UHOi" s
À`ø6VJòÓ
LDÓj>ËË:ÛtBëÓ.a·×tÌÕ±3Ú¸ÞÙr/¢J¦
+-7!¡Õ{ocÜÛ+Æñ¤8÷j´´*ô¥Ûè]µã䳩lIS'©ÖÜ^,ë|Îñ5µÀgÛu=Ñ3Êõ,¹¯Íj¹9^ÜÝqçgtZº>_ÒîÚ¡&E-5MÙºÜðjI/j+Ë:-ÍLB:V©ëÿª4ݬéÒ¨8|k%Mé×z©aõ-@º ãC^]Þý Ü·P·úa÷,eXÿm õ/Øò@ëjPd)h?êèØåvxæÑàv\¼ÍÃhpÚËht¡±æû7¬
Ó%R
+ï [}¿`»»2YFÛzª¾¦2¤â\OöªTECâ»ÁPî'õÝ×%5Úz*Iµ[*u´ír»Õ_Õ%YÅé$MN°l¤ÄËp¹¬W øȼFË:ZÆæÙºúm9äüÎ-´Rßn»¡òlÔÖ./Â%»Ä~K.ckEÆ[K\cÎû8»K¿Ì³6ÉesYæïüäwRÝ\ÛÁ9ì÷;xWθÑï[Jdh»lÃvÛ;ÿøT ßy4gþö¿7jU;ÍTq~a®E4ßÂöìúüeì¤ï.Ã] Vs~¼H?.b7íÏϨ«G§·c5ÒÍÄg&&~3 3i5SLöÉN&ûÌd0yÐL.0Ùo&A&ÉÃfâgÒf&<b&1&ífÒÇäQ3 1é0L3/Çͤ
I§ì`Òe&q&ÝfÒŤÇLz`Ríëÿ PK
+ r6ÑDVî : org/apache/regexp/REDemo$1.classmOMKÃ@}ÓĦÆ[õ$<$,+B=<)Äób¸nB²4õgyR<øüQÅÍàÁ73o>¿·_ðp£>Â{LÃk¥¹!xqü´Ê0îΫ.-«Vép߽ȵ²3׬xtÞ%YL#àp\5
µ|zfÑpÁZÜ/nyU_@Zs²m¹%ü;{ËÚpC8ºº¯á=7ÊXI3û^Ví!vC`½©Eê3ï 7W@a÷í¼~é}kCG?PK
+ r6¶l à org/apache/regexp/REDemo.class
W xWþ¯×Ï#ÛMÈ
¦,+IZì&ØN1HNpãvmåM¥]±ZÅ6B¡û>ËQ(GÍMSj*(W(å.7û÷}-3o%YÕ ïó;fþ7oÞë{¸ënÔc:ÆájÈê¨ÛQxr:ýÍ)
+s:puÌcAÃSu´0üi:Zq]3mÎÃõÀ3u¬Å
+|Ë<97jxN 7éXXásø¼ ÀxÿBÞ¿óð
+/Õ±Í?üe<¼\Ç+ðJV¯âÕ«u¼¯Õñ:ܬc^¯á
+:"l_oàM<ߢãÍx_èV
+oÕ±-~=x;_ìL¹
5ÞÖE¼SÇ»ðn
+ïaÊ{5¼ßÀ¸µà&};´@^Ç2>Ä})wñPÐð >ª#»5|LÇ!6ëø¤O1ßåáÓL9£ã3¸GÃg5Ü+ \bczÖºfÒÏDGúÓN:c¥LÂ\X3hNåE h3J tÆN§¨1çEóÞA¦@W¸áMÏ
+4:9±ÕØý®iðáÄ-®´lËÛ'Pêhp&ML$-Ycµt
|5)ÃNFx®e'û ~QÏZoÖuæ©yÔñ=bGKüþÕÊHU.0<OkñEÅíÙ=f¤ræÀ,I Í¡[§LÛ¿Û¯Y
+iòÉ÷¡ÉZfKLtÖrºÄ lý¿"1ãtDÙ«\+qÀHÆòÏI|_Øx.`À±³KöyY5eî°5½,öE/áË_Á}me@Ì2Sô£f22Ün²É5³Y˱ûXê«_Ã×%¾oJ|E«D ûødh²9YÏp½¾þ&£Öáã'$NàÉßf
+ï²>VÃ0B3s¢VW3æ;¸O⻸_â{¸`U I\¦`hø¾ÄðC Ä0«áÇ?ÁO5üLâç8+ñ-ù³â½äffØۿį(¡t_ã¬ßHü¿ø=þ °NÉXNâÃÝïºÆ¸kyX%ÎaRåùTvÖ%þ?K$Ù¿HüÓðwà%!eÂÐü´ñÈÅ'qm«Íÿ¿)ùT´ÙKuìÜÎÿrª{o·ÄñÄ( Û3Ûm;^we4!¤¨õR4°RH+\Ù¡]#MI©ui¯@ü
+µ4ílß) :nضMw ed³fVR4 M`ýCIÌ !E M4K¡re2)ÓîWSeL¯$_ÌÊz¦ÍN_;
+uÍÝ~jxEöú´¸aI*r»Zh~¼j²TNPdÅÎI*M==ëf1̾:Ïz#AA®8ó×±U¡¨E$¯ÓU9zYMéØyòZÝ£1Iô
â<O5iÆJQþjs¦õ!Ë»ùÊBÂÞ,C%®PíàîÕ¯Ä÷H`"UÏÇ:iN)¤rTP@*k±"öªÒ
+ôÈÁÎPÍê Nåß&1mr|¤VÛXEòS[Wîjé@¹cjÅæ)°³æµ¤»Nò%ïwÊçC³7;gP!ñk¢¶$réLYÍúLE±QÀ'8²@Dèz]Õ"d½©ìë¨A¦;gx²ÏéÆþ«ú!ö;fÍn}oø|Þ§'<l¸¦: %ÈãؤOʾ.
ÌyV*ªZp)Î }Äɹӫ¦h³W~®tÂqËN8sõøþz%ô·
+ýjßýé)¯®Cål⧳²ÖÇNCèX϶ÒÇÛ8Ë'¡ àöþQwW3uC5_]©£©yJÍÍ$G4´»>¼©òbcx"\@ÝÄ2êÐ@ËFZ6-A;WZ_HlFbíÔ÷æ¡ÐBÐ: ß2Ú°&ÒÞºö^R¸v"l\FG<º"tÎöµKìuÁõí¡e<ìØ6T`6Fê°BͦJ5
+Ìc\®Í%][JÀÆ2DY³n¶*mdû
Þ¾
+]ž¨Èß
+á<.¦yEø÷è¢{»è3½N¸íä¤P bÕ\T ¡ö]\N{ÝG8NsïÄÈl, Bí .
+FiØAy<"¹½¨$U>ç:RÁJ®¡sèO#%;óØUÀnRqYIì,ãy\&Wäñ¨;ÐG«þE:é»ÂÌÛK¼Et¬wøÄÓê6{p®Tsþ3â_ºlÉõ<lÉI%+}3F×ï[ÄîÊí§as´`,mK7å[ÞX/63=¡[¼:¸H~^¥ñ¡O«?N±O
2}ÑmÙUôþŽgÐF¶<ö6´
yÎc8ÇñrZ>Þfdð¢ü^º¥vÆ1ë-àÝápO(`VGâ½dGç8
+Gé'öÁc¥¬ú8:ÍÔ>ð?PK
+ r6¨Úe§ ! org/apache/regexp/REProgram.classmRKOQþn§3eJ¡£¶¼:Õ>ÊLa|4,|Ôµ%Q.u(CJÛLãÂ
ÿÀ»²báBL¨CXºpéð§¨ç¶6ÄIÎ=ç;÷;Ï;?~;IÜ "1ñ zqUÀk^Ç !3T L1çóÏ^=Éf²OfX¡/[Ô¼ÒXäåM[À§Ôù9áñ1ô:Är7
+§Zað-eúËv%×íUj®½êl1È«e^ª3¨|+Ï]»B¶rß©8ºL.e'üÙêküÉ\+äÏ #\²]y)ÖÃõó*Qóí¢!#Âú
e
0*à%D¸Â-ÜaPxaUÝÅk¼¸f[®]²·jÖÂlÞ\¾Á ó7Ü*óJÉ_Y·
+HÛåTí:¼ì¼å+e@J¦»ø
ízæ*w]¾]¬Ö¶äÜù÷rÿqÑ0
+ñ®!h>ô¯ ð
.|Nâ£QÛzÀÃjk
b1BgP~$éÃ4OÁ¾´¡{abï3R)Á0b-øþÑâM÷hqÉðÇ0õ¯ð2/ãÇLAnLw0"Ô±<GJLI #Ì}¶ïE&Îjü¢H
ôOÃlA1ôdCjQï¬Õüc}Gº²¦ÖÞ5±`Êé3f\ZNk³Mdu.JzÚõk&f =-Qj@¤Ð*¯JQÑÁ"ÄyÙ¤Á G~O
¤=Ê)Ò}½=&3Ü%ÉX$K$cq3î_NËkËë ajíl~m½$)®ïþù|º¥Ñ³-My[}.ÔIgMjgMêI÷ðPK
+ r6!õð¢ü s ) org/apache/regexp/RESyntaxException.classmPMKÃ@}ÓÔ$ÆXµ¶µzªè!õÜxPzóÔàqi·qEwòø³¼´ àðG»æ Xg7̼æ1¯ïðpÝ qÂzË6#Ø
+аMðÏ
æÐN®ïÙKÌÓÑBæYÿP¿RNèü%/gÓ)×1VÑ"4FÏÒ°²ÇµVú¬£NtÎSV°ñO5ÏyY¤ÃAµ3(Ǽ0BIÂÞÏáLñÈ^âÔø¬(¸Nþ»ÔªDfШªCh%ËsöØ·8#ëV´Å5[ÚGÖlî½n¨5½9êÇ6æXYÀùÞÁPK
+ r6ü4%3 ö& org/apache/regexp/RETest.class9 X\ÕÕ÷¼Ù.Ã#!/L²ù $fHP1!lIP Ó $ñÁ<`fpæM¸¶F[k÷Ö¶IëZ[b«uC*Vmíjk÷ÚVk[kKÍÎ}ï
+C2Ð|ÿäã¾{ïÙÏ=÷Üsoy÷¡ãÌÁBR¹`©Î Õ%^(
e(£ÉåÔ¬ feýʽ
+ú8Tæ!°ÊË^åXåes`9ͬ¦¦Úgz¹ÀYp6õj<pÃrkè»Ðj©·¬÷À/Sa#ñÙD½s=PçzÞàeË¡ÑËÊ Ãf¿
sif+1oæpóQV²c6oã°ÃĶC ÜÁa'Q]HÍ.2þ=¦f75Ôty`ÕÃ^jöq¸ÈË°×mnÂèñ²W!BJèÔôrè#öý¢.æp b$h/¸¼l\ê
ÉØ0$=`ÐdÊ˺`¿½l»F8r8Àá2_Îá
+Wr¸ÃÕÄð½ÞÇá9\Ëá:ïçð×sø 8|Ã9|ÃG9|ÃÇ9|Ã'9|Ã>M<>Ãá³q8Ìás>Ïá&7s¸
Ãnãp;/p¸Ã9|Ã#îäðe_áp»9|Ã=îåpîw0vâM<àe7ÁQñ 4qòÌ1_ãð sxÃqrxÃãðÀ×9|Ãâð4÷ÈÕÏpø6}¿Ãá»4ÿ=ßçðÏrø!qxà ò?åð3?çðø%_qxï9üÃo9¼ÀáE¿ãðßsø?rø9üÃ_8¼Âá¯^åð7¯qø;×½ìnørxÃÞâð6Nÿ&Ø8ü¾ïpxà ¾WrHNäÂpÜ\ò`ÄIÜ#å+HöÇ;R==z2©'ÁnkÇ3.ÔR:º1`¼i×¾æ¶&`JËÅÚ~j@õUuh¬oÂ{âCÑ=lYK<ÑW¥
+i=ýzUBïÓGªÚõîT_
y4â©RA¯H%H ç çï<URù
oGtüéÐÐoÓH>dDÑ`îõÑXÔØÌá's©XsÌÐZݯï@NäóçèDIi,t*R}ª·8©¢2äèíZB'eý9]$Ðç fu)#>¨zÄÒKøjÑOÞCýí Ýòw¤W¤æ:¢F],²%¡Y$©nò¬áâ&¦KSÚ r[ÃÊÓ!íæç mnz÷éFÓÈÞj·ëÉÔ1?qeäÞh,Ò¦;Ä
+VXhÑxéIâ EУå§Ò{$/°Ù(̦oи8kfàË×6%
îú2 H)_d© cdRv&<Ò,Y
+.`¦ã*\2¸Á#Ã,l¤Bi°IO¯UMÕßîQ;árV
+iF¯¢uëÅ
4F=åI¥¹àÖP?ª6ê½:V¨'ªfJdIµ7TZ]÷$-ÕJµ²²X¡ê³OÉìö_`%ÿsÛÊì_ìß2ûaåÂöHE²äæÉÒ|inÍÜ¥bi¡ÌÞboËÒ"i±ùdã\{ ·#²±+Å
+îÈÒRéYRIûy¹×w
+h
+¥¨k&LJ¤Rb´2`ÒFUÓâ¬@áÒJܪ=ýjÒL½©JL
æm|=R)¦D"¨U¼¹nG]ÚÔÞ¾½V!8'ðÿûMG©ªë[v¶7¨jnJô9ÊÈ«~Ì8ê4¯\B at Pª¥ªRPΡF¡FÄ°l{l3ÚGq©VaBÁÄ<QcqC¥J¶*Ù¸[Ñ«eXèÂjd*)¥³³å8#:¨e¥³1ªÉÊSÍTwlmjoRëðϲ´£$¥¸D"ªútC¯TQ/n~veÕ:CüÉrãòkòn`K:ôDTÐ#U=¨6<P£^Hh£ÛRF&ÈH\ô
6Ò¶î1ÇMÁj¤s->
MVÊÒi-±ªÍSÕ¬uÒzô¦i¨W 1j.Á ðåJ]{ßèW§ÑÞTI9Àèk#Òei-ÒÃÚZRªõâËb¦QCf\ëîñw
+Ê-mÛÑ°u_C]GSs[cÓö&lÚv¨6,m$ïxh!|7ö"'k/æWÒ¦2»®D\ßÓØH4N¦1D4Ëêg¨x]}C#ýС'Ù¢m&ÅùëÐ]«Q:½V_'~hëÉ|²ÁĬhÊL£»³.´{Æ'oÐêûõÕÕ§êdCNö ÃÁµ}yÉéÅ/ú®´+RXOª¥.RØ&XëÉØJ[
\
+DKÌæ*0¥x33t=qÀ,)íJZµæìpÝ/^}$\½ªzÍÿ@¾3yíÈ{µÊ@7zÉ¡y»ÉIZW¬{\JðÈ wjÄ ¦aáÔ¸Q!°8'KC[m,2uZ¬;³°ÖæÄòúµËÖ¬^[}E9.péä@źR1e6Õ«VÙQ´,×Ü13´L¹RsamOÄûfj;ä³@7mE3PÂÆ
+Q^J㵬?ÕR¤D ÉDlEééÒàÊ;{Zî¹±½=øÓ439L}UéäÄé /<¹8A]FðQü¡K8aDsÈ>Ý ¥z©K]x¬OMRñMufV¬ çB¦K
+vc÷NEJK ,5JXÅKÉN½Gã¥*^,:ìe§0úª½x{¨Ý£j(ùPo<êÓC£¡açÑJÂ# £ £!$K¥-À2¢r2èî5RFj4f{¸ß0j«ª:»*»»B]ª®Üwî
+Ë÷q
+÷GQCM%kUkxx¸Ò¾JÃôæêê3ÏZ¯©ý ½wCiÙªÒe«ÖWiI`-ol¹¥
+°§ÐçRº1ç4I)¡}VØT¾[<¬fí×ðàëÐ7짫.¢e«÷Q9±¯¬¸Ïæ{5LC 9´À+¾ÝâÛ÷dz=+Z§`'¯ë)ß$ò¥<WÙêPY5¥îù¡l#üÎñwj¡î=A$êì Eö)?pNÊ<ê¨/KÍÒyTûøuëö¥â2åV¨xµÅ¤R¤Ú¶¡èpSF¸${Ñ!CÕ©-Sõw¾´1-¥ªaÖÛYxXrµDc¢¦P±øaÌ÷H²Ô&¡Å3Ý·(ÝlGÏãK¯Lê¸4#úRû-iÖFYWæmYY-{ï&
+}ý§Dßé·Ñ¬»ÛþD|Þ!ºWtü;ðæ3xî©-S.f1¶îäû9IRpMciCæ!Äc¥`«s]sÞKÔ¼^tÃáÖÊýb`cÉnmhHE&¯ÓS
MófQeÄíüWäÏqáÏ5«îRó#©Á¡ü-9®pÑÕ;JöcpÑÓΤóªßuSè³bE'AöŸµ@#/BS"éãÉ0Õ}è]ªé""¢Ø(Ö+Ã_Þ³'À9c^mZñM
+nA7F x®ÁánÚÁ-ÙW&¡®/íæÆCÆÕ3§÷EþófÐ6iï)Ï*椹F<s÷ PÞYO· ÎzzI ÍaêB[,Rtô*¨â·y@ëKÒ[Wá~g}ùwÏ ½K|ÀVæ
+Ìw¨»y¢ù§<íÙæ¤p%Í·®5§õ¸s½Oï],w¬¸uëq-çÚì¦ÇÊDt6µAgÿ.¼ÄaLbÒ[då1©7Ǧ{=ÃìÏ(®NëïÔÝ»§yiÍï9hHOQ+N+±¬c%ÌÅ^gÛììØ8Ø8~½ýBzH¢ezKßwÄ·å±wÙ @sH)áwAàÃÌã<Ƥ1&·ÓÌIýû¡å³Y©óèõIrÎåÌgîÀq׬ pV§gU;ÅØc>Æθå)Þ4˧¯l~ÓWf!8xÍ&écÌé¸K¼8'
+w ¢NpYê® 1~ÆYa`ÍAÉÊlnÀñ +¢fö}ÂTFoÍè$~_`>D×Z8Êæ¢óÓhö+ÆÉ
Ê¢4[|?[èíNÖ\-M³3&FÕÇYIñ ¥Y)þ-sÖ òá VËaÅ8[9Îüµ.2·<ÍÂÜ`±+Í*jÝÅî§Ø²bw
19 T"ã1Pª°¨H³U¸§é#óð#c¬´-£íjT¥Vg´ÂÖ³ãìqfþϸÀoÕâ3-MjI¬´é¸<ðZT8¢A ÕÎÄ´ùßhñ¿>Æ
t^ë0cMålÑÖLögÆ
+ÄEÔ¢ÓÓìñmó3*¡¤"7É·1d(°0ê0ÞÈܳÆÐRÿd\×*µä2ìËH9(9qým'³ÙÍBbàwc¯cê0\7âß&ü;7fu¬>g
+µÎbg5fK'°n´E6M.Î8Ûü¨T[ÂÅÎq¶UÄÔó]ã¬Ù$Nt
ÖùO¼|ÍcEµ#Ì]ìy´Ó|ËÜ6Èôå±VlP?UO³6eÛ¤»qo¦pܽ2 !Eäv³?úYnÖÁöã¿©[Ñ[¨éé&sá÷zÚÊq¶³% \(6Ö®ðvõ8{Oë+ÆÙntBçë
+cÔíg{Û&ؾph]fÚcXànÜ@iõ`\±Y%bEË*¤ÑJ¯`|zÜp%Ñ}ÈkFÖBó~Só(Nq
+/(PW°émºMTâ6pÈ^: LØÀ¤
+4¦HLD!+¨ì·qmÜ)¸£Y¸lÜËlÜ˧à^!p+E2Bû¯B4!vµ9L÷
+ϼÏ^#íáµbx=|¿~À^/´7ØB>d ù°-þ#ñ£öðcbøq{ø 1ü¤=üÞh?-±BÄ!A;M9IW at 9Ó´ïÎc®ZJRttûÜ è=ßÌ
+p´0\¸äaWØQxùΰӱ3ì*\¸3ì¦G¼°`g¸Ð]XÇ
+÷`W¨aë%¤Â|Ä*ÝØnÁvg+ǶP Ì¡
æ¶a[Dcç ¶óíb[\ØíÂÂ&lÖbÇÎ v¥[ɳò·´[étÑ\ãÌlåÛpËúз[ûUxÊϾΠ)wLÅÿâôø_øcSñäÄkr§ÀÿòTü¯LÏÿ®Ì#ÑÿXÉúY\7~ô<Âî;¯vÔ¸{:ÂnåÞ\·bh·V(÷¥Ùým:¡ÊA³:ä£2åèA'øÁã·3¯Ï:~ÛÊÁã¡ãiôãDï"¢¥;Ü0¯Éð52ÀEÙð!:}®ê¬³n"csîèAø\$êéò°%Ê6OÉÄ[Æð-Ê#Aå¸òh=«ú8iqT@0·ï×o ü'öòtøMø-åðÛàwLàw;2À;&Ö¾ü^ôûèLÒgf?Ê 3?V~þôdàϲ?Ï aüM=úYÐ;=Äê+bùäç±Ù¡§0¶0½?UØK#*¹_cSAß
Óbå·öú5ÉÛgñ^gñ®Z¼äD5@PçdF½ÔXVѱTy!(4t9îR^´ºÎ»ÊïÒì%³àEºPlÕÖý¨ %¢.eQëÛO3÷;ø=FôÒìhâÌ
+åOv¿²J 4~i&._¶¬ó¢J¸§âÞì3¢äE°ØV.^ü^ÀlòçVAÂ\p/)ÒFMSùeÐçk\7Ôrë0«£#
ôg¯Ô¸}îC¬Ê8ÆþZãñÑVå¼16»û¨«è8¾<綯M°WÃP±Óçò¹ù8ûÛÉ*rXI >qÀ+òÚ1ö÷Ø«û?PK
+ r68µjõ l " org/apache/regexp/RETestCase.classW \Wÿ?vaÃÈ&Äv$Ú,ÆÚ ½²¡ÍU6aÙdÙÙÌÎ6¡¶ZµµñÖÖXÛƪxDÃnmlÔªÖû¨÷Õz[µÞ¶~ßÌì²À_ZøñÞïý¿ã}ß÷¾÷qÿ£÷@¢IÅ)x¥*ªE¯ªÅ«ñ^½×ñðzÞÀÃy¸
[¼ç7«xÞÊìoäù°ÄÛy¾M%IïP s;w(¸SÅJOËÖòNï»ö÷2zJÁ]ïx¿à6iæü |HâÃáåQøÄ1f/H%îø¸Ä=ÌqOHÜ«àðIþþħܧ¢áá³*ºñ9
+N)ø<¾ âܯâb|QâK
+¾¬à+*.cþ^|Uâk_øÄ7%¾%ñÄ·%¾#ñ]ïI|mùÄYÛ$~,ñ&ýTâg,ýç¿à_2ñA_IüZâ!ß(øß ÒVR`åÖ½Æ5FWÚÈ$»v9v*Ü5íM5üø°i>B;¡#ÐS²ãvVµÍpcê°1²³Du¹1+ñ·k²mfrË$3ç¬ÚjÙÉ.#k$ÆÌ.ÛL³]ý½»ió+QèIeRÎEcÑÅ-T&ÁÁ »Û®"ËãÖI°óÝîBQ&k| ¸mNÊʸDrI-}Ôe}ýf.&¦ptq§ïªÇpÑWæH[b
+:W|Ì°9¾þDz7±(ÍÈåLÛéÝ7Ò$ëèbabþ`]Cf_s(¹|"aæȦ
¼äN
+×àZ
+p°X
+&Fü^Ã0¦!ÉöjØÇCqd4X ·7Τ!ý
+þ¨áOø³ñJÖ(/þJAjëÖ5ü
+hø;nÖð"\§áz6hyP6ip×ðüSÁ¿4üÿÑð_ü¢´ÇÈé1)(#ºcéændtÓ¶-»CÎ;ú#Yç¬×ð(£+1keïÁõRf®ënô»õÞþ~`;mk$Oî+Ó£
+¶½B#}/hdÊgÊV%Ez+hÕD³¡ÂV °:ngSiÓÖ1Û< öµç²º4RÓ¯¨Z§j"$Â
¥}s¤['ôî¢íí;H§ªáÅxpÀº²<çºîEkAfÚb0'Eñ¥x¥ê<ùeð¥¶mLéÙp̤jQ£ EHÒ,jeãg~¨ 0EÄQÊêÚ<á®%}lÞñðPE«×x¨_hC¿iöÚ°îCÉÏõ5.höâ]Jr¢qü[æîÍK&ÅÏú-©=c9ú¸W,«x»¡uNwe1Ë s`ÌÌT^¿õTx}ÉYY0ã\X#9Ë-¾zÂÊg(5Ñ $Õ£=¶E¾ó^GÝÕ½ÇLÃËq /s¡ÌÓ(REÏäÓiMDÄ2²Óã'¯¦räCoä²ÞÍÙkÎ×%Z¶Lã'ªàüUÕÚFÑ_ì]9sNÁÛ1¼Ñyãðߣ8un© +ÇiÛàìJXÙ Xe½öDoê õñãWcd³fâØTåï?Z¢}§ÙåQ(ÌÑ
8Br*~ÉXØl1óÉR]Û´Oãe!/jBàq¸©ê&mc«9Óñ¿ôྤvûQ#è|o+³U¼!»Çlë1Ì«IÓÙFï¤,¡©N}»éB¥Ú¿^1·#Åß-2Ü£´
+Å)¸i3tÆÜZ%:÷¢.IפÝLò£Cyg¥/
+FEòìÝòªK'QîòS¾ÙÖáÞÏô;¦LåôYïD}
+Î¥6z·´p·áÎÔk¸ó>Nû35îlù3õîL
+ÍUÜ+¸½Jh<H_ûQ
+I³+BÄ£j бöc¨_=8êÔÄÚg Ä:f c3¨5g Æh«.ÖT3Y9³bÍÊ{Q?%ÍJ(vKBD¸
+SÄ&zü#0k}õÓ?iæB+¾vZÊ#Ki uMÈ2o]KSËh°bL*âITp¯äK}a<@ZI"g°¸ùO9OÐêÖЪn¦Ó_8rVg¦ÃÓ[½õ.ñɤtOÉ5Vúj/`-[ø9O
+MíSPyk
+
+m+-±®#xóEK|g®m
+ë@Û=è9sÑDiMS$ô«»ó]¹Ñ½¾äT1>¾¸Ð5¿ÃsÊ¢:Ý£x ÂúÑEÔIÈȹS¨l`àÓ\`KçMâ´I
+wOÄ.Ëù¾O.`IE<£>ên>ÓßìðÔl
+ysOVâ.òqÇ%>öÒ"6¯mña½»Ì×÷¬".÷1Sسu¾ûúftz??{Q?%®ÀxÜL³Xê»F?Ën§,ãPÜ ¥Ýóc³ ¬±;ÃîÜÊ¢·UÄ`{9iÂÓ²c¾U;*à;ËVM¡m>ð
+`H)×ÖÊ7â>J ¶µàztǶªÝ|¹¼`»;Wò=QÞ»ê0ªCÓ¡)äÜí=)Ìò\_}ó%2ÈÜ-´ÄÒÒö)ÔLaC¬ÒìçùbÈ\cVÔó]7
+Ñâqä±CáiÿSí*ýjð/Ù_HW¥òj7椲B84½ )ú¼¤X;'({¶eOçìé½¥qúÕÝ9í¦à®Ë? æm'¡u6=¯5O¢§9L2ã<VØîks+ÇÕÆÆAó4F+âî{ÕÜä«Ùâ«Ù¸¦)|Ç"×pHYbSWÁÿÏùëÝÜ"-~áý?PK
+ r6lK ½ org/apache/regexp/REUtil.classuRÛNÛ@=8qÍ-ÊR(uÌÅ/}*/(@ÊÛânk[ë
+2Â_À Vêô£*f
+jÕâÚòwöÌ3ûó×·0°
+/ð²IS61£ý¬6sª×fÁ
W&M¼fô¯i$ò})¾9Cs÷_p/âqà(ÆÁ&¶8S<V=õCíCjÁpÚ=êvò¢u_
+®D·Ã°ê<§Ùiï&2ðxÊý3áI<õº¢·:¹/RRKnIömcD~ìâ½eo°Â0^·ñ6\¸jc
+ë6c,é0bùs½Ósá+¥2ôÁe¬xþ»¿Û ^IG©²ãP1´Ê=!}#@úî04²þiößrHÇM*NÃYÎB-Í>WJÈø0ùØ¢®ú<"Ë£®jþ,Eè+0LÃÆ ù!ZUè5èAv"£äù÷ìúih¡ ¨·ßÑE¬wÜfåÆZßQýT,nQ¹y]DîQ/Ã8}U¢m\O\MòºTÍ5îÑøPK
+ r6вæ- ¬ / org/apache/regexp/ReaderCharacterIterator.classmSÛRÛV]Ç-
+åf"¡4@
+!¡i¡SÛIûa3É#É ¿Ò¼´Í/<bÏNóÈ7äú\º·,hmÏѾ¬µ¯zû÷ë?¡`?èE¶IÌi×Iw
>®ëtÜ`Ý¢ÏqSÃné¸;:úð%Ør}îñ±¬c9~[eë¯4|á'í²ôÖÚÏìlÕÍ>5·ÔíÆÎÀŶ¥f;ìfàUÊ
+éCD©æú², ~$áNÕ©KÃéó\-b˹e)Ðë7¶ýE`4Ïg:Ø7î®Ovmo9 2rÈ Ä«þSnÊÅ´¥¼¾¶Wõ ê:¾Æ¦åZM at Is6 éø
+O¶·L`ÆÀEQRÝ«eÏ\i`)¦Db÷5|k`
+QݧUçg¡2çùòNYîAqgÅm8eÿÌWúîs¨
+W9¥)LøWñï
+¤ñÀÀ&ò[è]¯µëviWf=Y{õ¨é9j]
+¤§¿¸<ãS)n?%jät'¼°'p7£¤»Nfà¼î´¡êá®ç>··kÔo½"ô}»"yÎ\átjÒ©»á°hýÿ_'{ú§v½.y&HÑm¢MÅ<ý(>¤o`çÐMä;Æó¤»ì¤ó2I¨dRVºzuåñ`-¨G[ÊààñG°
+ Ò=i· Y¿#ÞD9ÞDï«cô=mÂháÂrç GÓÁ<(QÜþS|¼*0|æ¿ðzÚpZà¦eFñ <pР
+þFàÕ<×;h¾D\98cbÍoÐÔ}¨Jãª`:dñbÒÉjFîeÂ'~f6óxAYRUÒÄ?´¨&Õ賨©}¥ê%6£$Õ&¥Ì_NÞ¥ÂN[ôW)NôôyDA&éæ÷fPyßÂÈ£0ÞÉ_0úl#w'|¥zhFEþJï©>Ä2ó'Â?PK
+ r6?s2Ð ¢ / org/apache/regexp/StreamCharacterIterator.classmSKSÓPþnQyûHÑ6ßO*j¬#+C{)ujÒIRåøÜ9ãJaÃBf¤ÑÝû#\û\ç´ÚdrOÎãûιçÜûãÏoP0Ç:úlC/Æ5Lèd;ÃÊY^Îé´gÛqIÃe
+Wt\Å5í¸ÎîIöÜà¼LéFÿn±wFÃm
+w4Ü|Þ¹çöK;Ypi§TOÚ/®
+¨ËåCuwÑvòIòü4Ù¥GÑlÑõeN@<%åZÁ)7%L<!Êm~yÙ¯Q ôÅÓéDC
+"ï7·G³«¶7¤Z
+þ««TJÉB-- Ϭee)(¸mTc×T±( Ũtü²'ëÁOŨC8LE5ß26p¦ú
+©iÌj¸g`Ǻw¶ÙI-ØËvrr-S2+ÓnÙÉù;±æÌcSÝ70Â%
+bÈÀ Èàâx`àø/Aô®OÚ%;»*Ì˵R²ÞôµÊÎÒKÓg®'Ðñ¿Ìòs¥F5 [w!YO¼éd:öÚþµ£fz¼ê¹¯ìå"õ[ÏË`^ú¾<çF®ÚtÒÉ«µa¥w7öÿ¢ »T<}3j¬)<¨ cßtºx I#ÉOd+ùbÖc¤% è·ªÖÈ"ÖW(KT¡n¡ÅR¶Ý?ÂÎRä«B³>£¥V3VAÛ§û_Ѿ4VQžïÎtA B "P¼ûÿá+8ði᣻áôÖát4Bx2æ'pÇF#x?½uðI
+Á·Bðx=o§ù-ÊÆ[>@Sס*
+ûhC5ÆIZ1EÛqðÑ·ÌfN®c´H]×cïÐnQ7£ëèá±7t/¾V¶ûßmÿ4ûsµþZô©B'2º!õ IÞH÷:qt*¿ªèY¬eÙþ½Ù £k¸¿<×ázEê¦ní=ý[¦ú,TsÌ·PK
+ r6½ñ68U O / org/apache/regexp/StringCharacterIterator.classuËNÂ@ÿ¡
B
+(x¯¸(Ó¸Öâ¢î2)%¤i5¾+7.4QL\ø >ñTLçdþÌåÿ9_ïÐp=Ys0°bbkJÖTT
+lØ4°Å EÒc(wù-wz<ôËX¡Ä9 >a(ÙÓ×õ+½Ùo\tÓF§eÛuë³ÌJöìó×áò4&3é :ÛãíµÛLÌر°¼
",ì¢ÆPïKßáîu#
/îw|¹éÒäq_2äó_´ºÂ£¬µéç3j¶únþoùT}O~Ü.©ßYPChUÕ Ò´¶0Oº@»2RÙxkì¿"õ5úÛÑ(óT¥:ö4a
+ SJ|r#fý¡Æü¤d®ÆÈF*"sC®Q|PK
+ r6ß»ÃÏ Ú ! org/apache/regexp/recompile.classuUKsEþF¯üHd°qb,)rL0A~ q1ÇØq @Æòx½FÚÝZ¥(n9sTùäsrpRI¸ó;ø =«åXìaf§ûëþ¾énþyñ¬(
+ðt¡ á}(bã¢I| ÓáupÔ2ÅñÚ/s|ÌQâæQÐY<§ã|Êñ+縪cs|ÁqcãK¯84|ͱÌq]Ç
+.køcUÃÇ
+
+ën2$flÇæ¢Ùcóî¤*la8»±´+îbE8Vq-ðmÇÎÝ4E!ãúVQx¢¼#¾´dÝ+®.Ì»UÏ®H_÷¾Ã-ìzMX²dú²Üô3é;¨Ê¹ÎiNÃ÷6ðÛøÈ_e¾²·½-}?á±èԯخS3 °ÉÓMzEsÅ
ÙñZ{á¤ÏµáÍ1ÈÎ à¦çÛwE ÍZ »lnÛ¨åáoÜ6欦ýÅ@YiÛÔ°mÀÂyCz4Øvñ3ÐP1P02Q§eòh!ò×ióúÿ²®.¬ø®å*±#ïÙ²)Gñçz}í¾úB½,=UjNÓbJßw}Óvº¯?BÝ)dáÔQ»¢×ÂËr@õmsTõwÁUfEGuÔT
+tæ¤ÂNó)à(ÅõÍ]â8fZ»_dº{äH5ÇÏv+4ÍÕé¶êãfª±§NÒÊö[kY·)m,»¨N áyÒÙbï?ajαóÀmZNgOâ¢Î/ö¤èÕÊV»§{Ö±ã¦VX2èþ¨kå6æirTo,I]êÜk²ÞV¢û÷=ðªjTìßÅcãrcÇwïÍÄY¼G6õDÀÔ·Ö<ig´ÇóOÀ
$.`¼éf#>Ú>GäÖDò¿ çqïwô?Fl(~Dô)´èìóóÉå|&vg²{NødáúP-0Jq
+hÙ^#[:¦¼¯«¥_ãêm >Äàå*%´)-8Ä©N% RÉæý>ÅiJ^zTI?@ºM0¬2ê-æðí
+mÿå¿]Þl#ÒÎIJ¦ycÿå*û[t»®3oéÈ}»8»Ü
}T
1ag» WK±.ì¹V1º#ÇÊ5Ú"<B<D2ùÆþßÑÿÖ(a£x'ÜW0î>ΫnþPK
+ èr6¼]{l ], META-INF/LICENSEÝZ[sÛÆ~÷¯Ør¦Si¦4iç±äCiD¹n&%° ·°È. ýõ=½¤dwúVM¦5IìÙ³çòï
ù[ô²Ü)ñ^ªsêÅ3OþCY§M'¾¿.Äßd7J{_¿~ýÍvÃпyõj¿ßÏ%m37vûªáÜ«¸ðþúX¬®ÄÛÕÕò~y³Zw7wâÃúºw×·w7WÞâ×=uµ\ßß-ø߯æâJÕºÓ(çæ/¼63¢p;Ù4¢U²tP¶uBv(MWñ*Q+F§
+aUoM5øuáEá³vÕ¿Ò
+·TØÄZ,ä+o͸Ýï©áçL9¶ªõ2öD±Òô«·»A}§¬ `¡BÃÎXýoÚÏË9·bØÉAÀ¦[+aa·¥¼2ÔV6âD(1vx@Ò^ Y õb<àÔÊñÖ`ÐÁ¦Òªð¡!¥<
+~;v,+MÛÎKò½v,7wÆýh{¬|4óRft'.ô%/5{ep/¡ºãb0¢àt|ÎKáÈV´²[
ÎÃ}ÝXî¼b
Øï¼OûJ[f¯1@Ê
MÈ=n§{Të¬Ù+[¢èo_ÿþ¶3`6|4n «£ÀMV¹ DnTF(5¸r"=Ó3¹üg3ÎĬÅÙÙeîuømò «eYÇ A[íPлÕÎQÀSq[NBm
+»^íq¤õVÕÊZXN¿ÖdñO¸Ek*
+GUÁÁº+LI(:3F·w?:S{/GS*°~È=äÅðEÈÿZoGK¿[ÁÇÍæ_
+§ªËîÀß;Æò£¶¦
Ëì@ë Ã'e(ú¦ñk!ÄÓzGÇ´é5&!åü1· pøzrà½à¤ÞåpÒR>?öGc?¾$ 0ÒR
+è.#& Ϋ ÉÔÜ4!ÿ3\*M1 KéCIF\èf#¼±¥àaMfõ
,´õ".à êQ¶=ìÚ!Ìy!>¹è{;?B25f¬p¥¬~ +>(q³ãÀ=ÎÛÀÞKbÅ7Ò¡ó:JÅ
+÷Àèèa¬ÂÈ]û.w³¨V=hr%F1ÆçP`acÃ'áÝgUN9²¾ÍLCIËôVw°Ë©ÏOñ8àT=IÿBÏ[£ÙûÄûªaU+uÌOÕKKv¡c´Êªæ yÐ}"Ãm Z0N:ÙªËàt
+ at dkYR(²z¢ZG:yý-B¹¯ñg=~1e³ý¢}Â
Zõ@aPWImC«à÷§/²¤õ
+lÝØvã°ÃGà]¤9©çS6"?¡ÁËTî9QAT¦í1Þ7
+Y)&/_VíÅ,iæeq½°T h
+q^ØÈâhoq]Gäcì¼õfAnt
v\J²¿+-E»ò=࿤ ¢npq¤e%+R!wpj]áPsG
%¤¤é`÷cåc¶¹Vnô"IdÖF»Ç-GGUvl /=üHJzF5Ä#ÅõºÍè y[i?!ôÙÄåRNo;Â~Eôöl$"XÍV`o)ò\ÏNSø_Çcü,åÉ
+øØm*v ÌFA<eTä t¾OJB§~!~ܶ4`o.×Hx³ôc úz.þ´
+·}X\\}¬mf²4ËQYABèL,xC8%0¼^
+`~ }Mµ×È5:Ó½$Ï;81~| ¬Çn±q2ÙµUðI±{0%ùI5÷ýnº-X9Öc ]ó~ÜÀZ°"jßHôø
+èÌ¥ÖÑ7Xä}[Nó#Y>ÙñL9'laý1sÐDÐý?ðÎ,Sý -Ç((è¸!º=5óÐu¶X^PúhS×Èó ¨àÿÅØqÀeÏ
+ fÂÉÐ죰«ìûÛMÓÓÉÊ]^µ²ìÍÏf+ܺ7;È^ç¤Õµô Ò¡öåá.¡
+6òàIdõ´ìxA8w¸¾ÚúLò¦Êù-öèPëæbY£ÿc/ä ©0¦£S½eäVâÏr¾q¿H+rkk{IÃcfDþÄÁóR4rïF=àQµå" Ê'NpÏÕVÜùV;É)sáXÁ-1UÃTl2
fÔgJh4RùXWLQô^éa«àË|Ѻ
+ûġ๸SùdhN[·òí
uà6<zåK6Âf#Å2ø+ò´mæþ©"¤Ðjb/צë{À®7¡Î^ÈK>é¶E}Q=î7À SßØâßÉA%ÕãNâ{*£aÏM¶'nÆ>
+ûwêX!htqÂݣ˶G!2±uß1Ëî\f;[5@7g-<u Ññá²ã)
+Ì°TÝÂb¥7 Rºù³ñâ>ǹ1z¤\eÐBÁc¢99ãì
+ä´TOV]"hEÿûÆ]=[ÝÜ/ß^Ï ù²7¦ß)w¶O]ÉË¿2Q¡õàCYQN5+Ä9o&Æ!P|]31ç-|Ö®l £QÒa;Oéý@`Ó7AMtL¶ND{Vïs0Y×ÓÐuÂ,ÛTOå[ZY®M¹|opÆJõQ¦mõy¾ép>
+3%¡ ½ßqøujæÌßD¸C>è!RóeªÏ-B¬Ãd6ˬ*ü·Å~'ÈLJPÝ[èK2¡`ë;pD~&ê§p¼QUª«Æ6ÐÖIÄ`áþ/¸óÓÈÀaf8L4yã
+óÔ½ÅY¥®h+
+ë
+¾2W \eÉid{Á§ÑÞ+#Ýú6EJÅÃH>©Dòpël8¹TáȺqLTãh2ÊQ'0qÈ·Ôìø îUtsñ¡*êÈiê6*5¶¿$1» óÃ1ÌYÙëÉÑUbú¸ãñ ©Þ&>ÿ7§Y¤f0,©knyýʸ(ÞÞP}ÙnÊ0m·ÔÞa!ÕÜåÀ©JñE¦A濳cK´
ÿà3:2õ¨Êâ x£A¬ÚJË÷Jǽ¿ø@a a1ãÑ!ärg7Bhx¡Æô%\cÈçfÑàÔKÙéû a~8mÐ8DJjSúmÔþöº`I'Bá7-^O£6`eà%л"68©=Ïl
+~óÕàL `Kýy.®´£Ö /mkñø'Øå ªº9pK7¶X ÈÔ¼¤)Xæsß%U/PW·¨ùÓ8¾8÷çZ ù³ÅZ,×3ñÃb½\ã~\Þÿxóá^|\ÜÝ-V÷Ë뵸¹Ë¯åoÞÅêgñ÷åê
+èæàGºtM¸RecÒA4'§Ð䩨!²§Æ¼_Þ¿¿.Àê«ËÕ»»åê¯×?]¯îñÓõÝÛAËÅË÷Ëû)Þ-ïW×k~}`áeÜ.îÀaÞ/îÄí»Ûõ5W[¾-lðfôïaSM·t3Ã]á4\ÀsÖôV#=§×]øÅ_BÜl^ÊÓFçáq\kGÈîL©cÌ îïYi_´6³{Ãç`R\ô^Ënèò|W ýéÒeÀW
+
+;AGè´³QK¸É òA§¶öUªË"ÞvQnü|6Þ/(àL¿Ñ"t¤ÜçñÞ"l9ànÇÏç£ç¤|àP&¸¬Ñ´±ke+·Ó>®¯¤\¯ðn=»}bËW H`x¦r^h at h¹Þ8®¶|gU<Öj¼5>ntÉcÄ¿Ñwf«ùÄàâÙ;ñ »1°[cª½nòÙá'(ʦï%N ¨x-u3Z®F²©Ç.*gÞÁ[ Þܼ±r8HÐq^F¦ËêAÓ%ií_ßðF/7xñßÍÅ¢ÄVÈ;/R¡Îâã©û4]/½n,´ÜÃSPtN.Ûiæ
+¼V' u¤¡ìJÅèyêÑï@q§Ú_-I16ktfÓø)ñW;È|ùªÎùâû+46?=vBÜJF=3Áé|ôFK×d·!sûkâú¯H¾ÄtÒ-JBô4)ÊÂÀϱgÒ5ã3&<ç;Ù¦¶©T
+í
+¯ f\KÛrÒy´6ÝùÉ1`2tåجòµ8ol¤ÐɦÌï³hÌhcÔ
øzu
uõÜkpôûâöYþó
+º¦¨ÿúBþêþFªìã]üÝá¿F1&Zm k,´áCj©¯µj*' @@²3èoðRAdÎ~ùu&¾ÚB0ªú®/ë¤çââÊtïd9ÿîRP·Nmªz ?êỬlgw³+î xþ/B©©g '`aãðösÒâô,Ç
+D2Vn»fö¡«ÕJ¯¬Ð
+iÐÄáÂ(GkÄàÖéͧùÕÀÓñ>Þ[.Ü»ÆñLrH[îðÆ!]&þr¿_Å/¤7èytËú+=î¤Êz¦iøù¡âï\^~"B?@ÀåËÏ×oC cDE#R×o64-]d9pÿÜ+§ï»¯Ö×/AeZò%ý)îáß9C1ÙHíô
+'¼4Èxÿô;o2ÛZ©
+!ÈÖ@ÌÀѺí ÊBwüf$¾îNÏ5ñPK
+ èr6v贲à . META-INF/NOTICE}±nÃ0Dw}Çf±÷n]
+tü mÑYDÊ®ÿ¾r2Aï®r_GNc¬T&Û°xZ)J&Ãî®à#ãØäòkø<K·`ßû~Û¶¶NÊÜ:ç¾FIÊj
+2Á*±&ò[+<Ô#@aAOíQÓ´7Ï+ûQ]K(`k{ÑÁ9*ÁÊÊv]«w£V/ÈBgú#½ááÚB3}çLR`BSg´ûPK
+ r6 íA META-INF/þÊ PK
+ r6sGV^ j ¤+ META-INF/MANIFEST.MFPK
+ r6 íA» org/PK
+ r6 íAÝ org/apache/PK
+ r6 íA org/apache/regexp/PK
+ r6¸R 7 ¤6 org/apache/regexp/CharacterArrayCharacterIterator.classPK
+ r62¯+ó Ó ) ¤Ý org/apache/regexp/CharacterIterator.classPK
+ r6Ràsè ' ¤Ã org/apache/regexp/RE.classPK
+ r6û®Yä G * ¤ã org/apache/regexp/RECompiler$RERange.classPK
+ r6lá"¯ " " ¤ org/apache/regexp/RECompiler.classPK
+ r6¡Ö.
+i
+ ' ¤þ* org/apache/regexp/REDebugCompiler.classPK
+ r6ÑDVî : ¤¬0 org/apache/regexp/REDemo$1.classPK
+ r6¶l à ¤Ø1 org/apache/regexp/REDemo.classPK
+ r6¨Úe§ ! ¤×9 org/apache/regexp/REProgram.classPK
+ r6!õð¢ü s ) ¤½< org/apache/regexp/RESyntaxException.classPK
+ r6ü4%3 ö& ¤ > org/apache/regexp/RETest.classPK
+ r68µjõ l " ¤oQ org/apache/regexp/RETestCase.classPK
+ r6lK ½ ¤¤Z org/apache/regexp/REUtil.classPK
+ r6вæ- ¬ / ¤\ org/apache/regexp/ReaderCharacterIterator.classPK
+ r6?s2Ð ¢ / ¤` org/apache/regexp/StreamCharacterIterator.classPK
+ r6½ñ68U O / ¤c org/apache/regexp/StringCharacterIterator.classPK
+ r6ß»ÃÏ Ú ! ¤$e org/apache/regexp/recompile.classPK
+ èr6¼]{l ], ¤2i META-INF/LICENSEPK
+ èr6v贲à . ¤Ìx META-INF/NOTICEPK 2 ¼y
\ No newline at end of file
Modified: trunk/src/jar/resolver-lucene/build.xml
===================================================================
--- trunk/src/jar/resolver-lucene/build.xml 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/src/jar/resolver-lucene/build.xml 2008-10-27 12:38:48 UTC (rev 1366)
@@ -70,7 +70,7 @@
</target>
<target name="resolver-lucene-compile"
- depends="-resolver-lucene-prepare, resolver-spi-jar"
+ depends="-resolver-lucene-prepare, resolver-spi-jar, resolver-jar, server-local-jar"
description="Compiles all resolver-lucene related files included
generated source code">
Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexTuples.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -82,20 +82,6 @@
/** Logger. */
private final static Logger logger = Logger.getLogger(FullTextStringIndexTuples.class);
- /** Description of the Field */
- private final static String SCORE_COLUMN = "score";
-
- /** Description of the Field */
- private final static URI LUCENE_SCORE_URI;
-
- static {
- try {
- LUCENE_SCORE_URI = new URI("lucene:score");
- } catch (URISyntaxException e) {
- throw new ExceptionInInitializerError("Failed to create required URIs");
- }
- }
-
/**
* The native Lucene query result to represent as a {@link Tuples}.
*/
@@ -126,7 +112,7 @@
private final List<Variable> variableList = new ArrayList<Variable>(3);
private final List<String> luceneKeyList = new ArrayList<String>(3);
- private Constraint constraint;
+ private LuceneConstraint constraint;
//
// Constructor
@@ -146,14 +132,19 @@
* @throws QueryException if the set of triples couldn't be determined
*/
FullTextStringIndexTuples(FullTextStringIndex fullTextStringIndex,
- Constraint constraint, ResolverSession session) throws QueryException {
+ LuceneConstraint constraint, ResolverSession session) throws QueryException {
this.session = session;
this.constraint = constraint;
try {
// Validate and globalize subject
String subject = null;
- ConstraintElement subjectElement = constraint.getElement(0);
+ ConstraintElement subjectElement = constraint.getSubject();
+ if (subjectElement == null) {
+ // backwards compat with simple constraint
+ subjectElement = constraint.getBindingVar();
+ }
+
if (subjectElement instanceof Variable) {
variableList.add((Variable)subjectElement);
luceneKeyList.add(FullTextStringIndex.SUBJECT_KEY);
@@ -169,7 +160,7 @@
// Validate and globalize predicate
String predicate = null;
- ConstraintElement predicateElement = constraint.getElement(1);
+ ConstraintElement predicateElement = constraint.getPredicate();
if (predicateElement instanceof Variable) {
variableList.add((Variable)predicateElement);
luceneKeyList.add(FullTextStringIndex.PREDICATE_KEY);
@@ -185,7 +176,7 @@
// Validate and globalize object
String object;
- ConstraintElement objectElement = constraint.getElement(2);
+ ConstraintElement objectElement = constraint.getObject();
try {
LiteralImpl objectLiteral = (LiteralImpl) session.globalize(((LocalNode)
objectElement).getValue());
@@ -195,9 +186,11 @@
"must be a literal.", e);
}
- // Add the synthesized $score column
- // Removed as it causes failure to join.
- // variableList.add(new Variable(SCORE_COLUMN));
+ // Get the score variable
+ Variable score = constraint.getScoreVar();
+ if (score != null) {
+ variableList.add(score);
+ }
if (logger.isInfoEnabled()) {
logger.info("Searching for " + subject + " : " + predicate + " : " + object);
@@ -234,31 +227,9 @@
try {
if (column >= 0 && column < luceneKeyList.size()) {
URI uri = new URI(document.get((String) luceneKeyList.get(column)));
- /* I believe this is just localizing the uri in either the global or query
- * string pools. So just attempt to localize and let the ResolverSession
- * worry about where to localize it.
- long node = session.getGlobalResource(uri, false);
- if (node == NodePool.NONE) {
-
- // Attempt to get the resource from the query.
- node = session.getQueryResource(uri, true);
-
- // This should basically never happen.
- if (node == NodePool.NONE) {
- throw new TuplesException("Can't generate absent resource");
- }
- }
- */
return session.localize(new URIReferenceImpl(uri));
} else if (column == luceneKeyList.size()) {
- // Generate the $score column
- /* I believe this requires access to the session string-pool. So this will
- * probably have to be delegated to the ResolverSession.localize method as
- * well.
- return session.getQueryLiteral(
- Float.toString(hits.score(nextDocumentIndex - 1)), XSD.DOUBLE_URI,
- "", true);
- */
+ // Generate the score column
return session.localize(new LiteralImpl(hits.score(nextDocumentIndex - 1)));
} else {
throw new TuplesException("Column " + column + " does not exist");
Added: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java (rev 0)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2008 The Topaz Foundation
+ *
+ * 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.
+ *
+ * Contributions:
+ */
+
+package org.mulgara.resolver.lucene;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jrdf.graph.URIReference;
+
+import org.mulgara.query.Constraint;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.Value;
+import org.mulgara.query.Variable;
+import org.mulgara.resolver.spi.QueryEvaluationContext;
+import org.mulgara.resolver.spi.SymbolicTransformationException;
+
+/**
+ * A constraint representing a lucene query and a score.
+ *
+ * @created 2008-09-28
+ * @author Ronald Tschalär
+ * @licence Apache License v2.0
+ */
+public class LuceneConstraint implements Constraint {
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(LuceneConstraint.class);
+ private static final long serialVersionUID = 1L;
+
+ private final URIReference searchPred;
+ private final URIReference scorePred;
+
+ private ConstraintElement model;
+ private ConstraintElement subject;
+ private ConstraintElement predicate;
+ private ConstraintElement object;
+ private Variable binder;
+ private Variable score;
+
+ /**
+ * Empty constructor. Used internally during constraint rewriting.
+ */
+ private LuceneConstraint() {
+ searchPred = null;
+ scorePred = null;
+ }
+
+ /**
+ * Create a new lucene constraint wrapping a non-lucene constraint.
+ *
+ * @param constraint the underlying constraint to wrap
+ */
+ LuceneConstraint(Constraint constraint) {
+ this();
+
+ subject = constraint.getElement(0);
+ predicate = constraint.getElement(1);
+ object = constraint.getElement(2);
+ model = constraint.getModel();
+ }
+
+ /**
+ * Create a new lucene constraint.
+ *
+ * @param constraint the first raw constraint
+ * @param searchPred our predicate indicating a lucene search
+ * @param scorePred our predicate indicating the variable to hold the score
+ * @throws SymbolicTransformationException
+ */
+ LuceneConstraint(Constraint constraint, URIReference searchPred, URIReference scorePred)
+ throws SymbolicTransformationException {
+ this.searchPred = searchPred;
+ this.scorePred = scorePred;
+
+ // extract model
+ model = constraint.getModel();
+
+ ConstraintElement s = constraint.getElement(0);
+ ConstraintElement p = constraint.getElement(1);
+ ConstraintElement o = constraint.getElement(2);
+
+ // extract the binding variable
+ ConstraintElement b = p.equals(searchPred) ? o : s;
+
+ if (!(b instanceof Variable)) {
+ throw new SymbolicTransformationException("Lucene query binder must be a variable: " + b);
+ }
+
+ binder = (Variable)b;
+
+ // extract predicate, object, score
+ if (p.equals(searchPred)) {
+ if (s.equals(binder)) {
+ throw new SymbolicTransformationException("subject and object of '" + searchPred +
+ "' may not be the same: " + s);
+ }
+ subject = s;
+ } else if (p.equals(scorePred)) {
+ if (!(o instanceof Variable)) {
+ throw new SymbolicTransformationException("Lucene query score must be a variable: " + o);
+ }
+ score = (Variable)o;
+ } else {
+ predicate = p;
+ object = o;
+ }
+ }
+
+ /**
+ * Merge the given constraint into this lucene constraint.
+ *
+ * @param constraint another raw constraint
+ */
+ void conjoinWith(LuceneConstraint constraint) throws SymbolicTransformationException {
+ model = getNoDup(constraint.model, model, "Can't combine lucene constraints against different models", "model");
+ subject = getNoDup(constraint.subject, subject, "Can't combine lucene constraints with different subjects", "subj");
+ predicate = getNoDup(constraint.predicate, predicate, "Only one predicate supported per search", "pred");
+ object = getNoDup(constraint.object, object, "Only one object supported per search", "obj");
+
+ binder = getNoDup(constraint.binder, binder, "Mismatched binder variable", "var");
+ score = getNoDup(constraint.score, score, "Only one score supported per search", "score");
+ }
+
+ private static <T extends ConstraintElement> T getNoDup(T elem, T existing, String msg, String elemType)
+ throws SymbolicTransformationException {
+ if (existing == null) {
+ return elem;
+ } else if (elem == null) {
+ return existing;
+ } else if (existing.equals(elem)) {
+ return existing;
+ } else {
+ throw new SymbolicTransformationException(msg + ": " + elemType + "1=" + existing + ", " +
+ elemType + "2=" + elem);
+ }
+ }
+
+ /**
+ * Do some basic validations on the finished constraint.
+ *
+ * @throws SymbolicTransformationException if validation fails
+ */
+ void validate() throws SymbolicTransformationException {
+ if (predicate == null)
+ throw new SymbolicTransformationException("Missing predicate for lucene constraint: " +
+ "subject=" + subject + ", binder=" + binder);
+
+ if (subject == null && score != null)
+ throw new SymbolicTransformationException("Missing <mulgara:search> for lucene constraint: " +
+ "binder=" + binder + ", predicate=" + predicate +
+ "query=" + object + ", score=" + score);
+ }
+
+ public ConstraintElement getModel() {
+ return model;
+ }
+
+ public ConstraintElement getElement(int index) {
+ throw new UnsupportedOperationException("Cannot index LuceneConstraint");
+ }
+
+ public boolean isRepeating() {
+ return false;
+ }
+
+ public Set<Variable> getVariables() {
+ Set<Variable> vars = new HashSet<Variable>();
+ if (subject instanceof Variable)
+ vars.add((Variable)subject);
+ if (predicate instanceof Variable)
+ vars.add((Variable)predicate);
+ if (score != null)
+ vars.add(score);
+ return vars;
+ }
+
+ /** the subject of the search triple */
+ ConstraintElement getSubject() {
+ return subject;
+ }
+
+ /** the predicate of the search triple */
+ ConstraintElement getPredicate() {
+ return predicate;
+ }
+
+ /** the object of the search triple */
+ ConstraintElement getObject() {
+ return object;
+ }
+
+ /** the variable that binds the raw constraints */
+ Variable getBindingVar() {
+ return binder;
+ }
+
+ /** the variable that holds the score, or null */
+ Variable getScoreVar() {
+ return score;
+ }
+
+ static LuceneConstraint localize(QueryEvaluationContext context, LuceneConstraint constraint)
+ throws Exception {
+ LuceneConstraint localized = new LuceneConstraint();
+
+ localized.subject = (constraint.subject != null) ? context.localize(constraint.subject) : null;
+ localized.predicate = context.localize(constraint.predicate);
+ localized.object = context.localize(constraint.object);
+ localized.model = context.localize(constraint.model);
+
+ localized.binder = constraint.binder;
+ localized.score = constraint.score;
+
+ return localized;
+ }
+
+ static LuceneConstraint bind(Map<Variable,Value> bindings, LuceneConstraint constraint)
+ throws Exception {
+ LuceneConstraint bound = new LuceneConstraint();
+
+ Value val = bindings.get(constraint.subject);
+ bound.subject = (val != null) ? val : constraint.subject;
+
+ bound.predicate = constraint.predicate;
+ bound.object = constraint.object;
+ bound.model = constraint.model;
+
+ bound.binder = constraint.binder;
+
+ bound.score = constraint.score;
+
+ return bound;
+ }
+
+ public String toString() {
+ return "LC{subj=" + subject + ", pred=" + predicate + ", obj=" + object + ", score=" + score +
+ ", binder=" + binder + "}";
+ }
+}
Property changes on: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Added: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraintDescriptor.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraintDescriptor.java (rev 0)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraintDescriptor.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 The Topaz Foundation
+ *
+ * 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.
+ *
+ * Contributions:
+ */
+
+package org.mulgara.resolver.lucene;
+
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.mulgara.resolver.ConstraintOperations;
+import org.mulgara.resolver.spi.ConstraintBindingHandler;
+import org.mulgara.resolver.spi.ConstraintDescriptor;
+import org.mulgara.resolver.spi.ConstraintLocalization;
+import org.mulgara.resolver.spi.QueryEvaluationContext;
+import org.mulgara.query.ModelExpression;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.Constraint;
+import org.mulgara.query.Value;
+import org.mulgara.query.Variable;
+import org.mulgara.store.tuples.Tuples;
+
+/**
+ * The descriptor for the {@link LuceneConstraint lucene constraint}.
+ *
+ * @created 2008-09-28
+ * @author Ronald Tschalär
+ * @licence Apache License v2.0
+ */
+public class LuceneConstraintDescriptor implements ConstraintDescriptor, ConstraintLocalization, ConstraintBindingHandler {
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(LuceneConstraintDescriptor.class);
+
+ public Class<LuceneConstraint> getConstraintClass() {
+ return LuceneConstraint.class;
+ }
+
+
+ public Tuples resolve(QueryEvaluationContext queryContext, ModelExpression modelExpr,
+ ConstraintExpression constraintExpr) throws Exception {
+ return ConstraintOperations.resolveModelExpression(queryContext, modelExpr, (Constraint)constraintExpr);
+ }
+
+ public Constraint rewrite(ConstraintElement newModel, Constraint constraint) throws Exception {
+ throw new Exception("Not implemented");
+ }
+
+ public Constraint localize(QueryEvaluationContext context, Constraint constraint) throws Exception {
+ return LuceneConstraint.localize(context, (LuceneConstraint)constraint);
+ }
+
+ public ConstraintExpression bindVariables(Map<Variable,Value> bindings,
+ ConstraintExpression constraintExpr) throws Exception {
+ return LuceneConstraint.bind(bindings, (LuceneConstraint)constraintExpr);
+ }
+}
Property changes on: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraintDescriptor.java
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -355,6 +355,7 @@
logger.debug("Resolve " + constraint);
}
+ // check the model
ConstraintElement modelElement = constraint.getModel();
if (modelElement instanceof Variable) {
if (logger.isDebugEnabled()) logger.debug("Ignoring solutions for " + constraint);
@@ -363,9 +364,17 @@
throw new QueryException("Failed to localize Lucene Model before resolution " + constraint);
}
+ /* temporary hack because $_from is not resolved before transformation occurs, and hence
+ * no LuceneConstraint's are created when doing ... from <lucene-model> where ... .
+ */
+ if (!(constraint instanceof LuceneConstraint)) {
+ constraint = new LuceneConstraint(constraint);
+ }
+
+ // generate the tuples
try {
FullTextStringIndex stringIndex = getFullTextStringIndex(((LocalNode)modelElement).getValue());
- Tuples tmpTuples = new FullTextStringIndexTuples(stringIndex, constraint, resolverSession);
+ Tuples tmpTuples = new FullTextStringIndexTuples(stringIndex, (LuceneConstraint) constraint, resolverSession);
Tuples tuples = TuplesOperations.sort(tmpTuples);
tmpTuples.close();
Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverFactory.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverFactory.java 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverFactory.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -68,6 +68,8 @@
private static final Logger logger = Logger.getLogger(LuceneResolverFactory.class);
public static final URI modelTypeURI = URI.create(Mulgara.NAMESPACE + "LuceneModel");
+ public static final URI searchURI = URI.create(Mulgara.NAMESPACE + "search");
+ public static final URI scoreURI = URI.create(Mulgara.NAMESPACE + "score");
private String directory;
@@ -95,6 +97,12 @@
} catch (NoSystemResolverFactoryException en) {
throw new InitializerException("Unable to obtain system resolver", en);
}
+
+ // Register LuceneConstraint
+ initializer.registerNewConstraint(new LuceneConstraintDescriptor());
+
+ // Register the LuceneConstraint's transformation
+ initializer.addSymbolicTransformation(new LuceneTransformer(modelTypeURI, searchURI, scoreURI));
}
//
Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java 2008-10-27 12:38:39 UTC (rev 1365)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 The Topaz Foundation
+ * Copyright 2008 The Topaz Foundation
*
* 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
@@ -22,6 +22,8 @@
import java.io.StringWriter;
import java.io.PrintWriter;
import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
@@ -30,16 +32,25 @@
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.URIReference;
+
import org.apache.log4j.Logger;
import org.mulgara.itql.TqlInterpreter;
import org.mulgara.query.Answer;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintExpression;
import org.mulgara.query.ModelResource;
import org.mulgara.query.Query;
+import org.mulgara.query.Variable;
import org.mulgara.query.operation.Modification;
import org.mulgara.query.rdf.Mulgara;
import org.mulgara.query.rdf.URIReferenceImpl;
import org.mulgara.resolver.Database;
import org.mulgara.resolver.JotmTransactionManagerFactory;
+import org.mulgara.resolver.spi.MutableLocalQuery;
+import org.mulgara.resolver.spi.SymbolicTransformationContext;
+import org.mulgara.resolver.spi.SymbolicTransformationException;
import org.mulgara.server.Session;
import org.mulgara.util.FileUtil;
@@ -72,6 +83,7 @@
suite.addTest(new LuceneResolverUnitTest("testConcurrentQuery"));
suite.addTest(new LuceneResolverUnitTest("testConcurrentReadTransction"));
suite.addTest(new LuceneResolverUnitTest("testTransactionIsolation"));
+ suite.addTest(new LuceneResolverUnitTest("testLuceneConstraint"));
return suite;
}
@@ -412,6 +424,331 @@
}
}
+ /**
+ * Test LuceneConstraint generation.
+ */
+ public void testLuceneConstraint() throws Exception {
+ logger.info("Testing LuceneConstraint generation");
+
+ LuceneTransformer transf = new LuceneTransformer(LuceneResolverFactory.modelTypeURI,
+ LuceneResolverFactory.searchURI,
+ LuceneResolverFactory.scoreURI);
+
+ Map<URI,URI> modelsToTypes = new HashMap<URI,URI>();
+ modelsToTypes.put(URI.create("test:lucene"), LuceneResolverFactory.modelTypeURI);
+ SymbolicTransformationContext context = new TestSymbolicTransformationContext(modelsToTypes);
+
+ try {
+ // simple query
+ MutableLocalQuery q = new TestMutableLocalQuery(parseQuery(
+ "select $foo from <test:bar> where $foo <test:title> 'blah' in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ ConstraintExpression ce = q.getConstraintExpression();
+ checkConstraint(ce, null, "test:title", "blah", "foo", null);
+
+ // basic complex query
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo from <test:bar> where " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ ConstraintConjunction cc = checkConstraint(q.getConstraintExpression(), 1);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", null);
+
+ // complex query with score
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 1);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", "score1");
+
+ // complex query with score, different constraint order
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 1);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", "score1");
+
+ // complex query with score, another different constraint order
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$search1 <mulgara:score> $score1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$foo <mulgara:search> $search1 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 1);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", "score1");
+
+ // two simple queries, shared var
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo from <test:bar> where " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$foo <test:author> 'Smith' in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), null, "test:author", "Smith", "foo", null);
+
+ // two simple queries, shared var and predicate
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo from <test:bar> where " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$foo <test:title> 'Smith' in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), null, "test:title", "Smith", "foo", null);
+
+ // two simple queries, separate vars
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $bar from <test:bar> where " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$bar <test:author> 'Smith' in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), null, "test:author", "Smith", "bar", null);
+
+ // two complex queries with scores but shared var
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 $score2 from <test:bar> where " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene> and " +
+ "$foo <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", "score1");
+ checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", "search2", "score2");
+
+ // two complex queries with scores and separate vars
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 $bar $score2 from <test:bar> where " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene> and " +
+ "$bar <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), "foo", "test:title", "blah", "search1", "score1");
+ checkConstraint(cc.getElements().get(1), "bar", "test:author", "Smith", "search2", "score2");
+
+ // a simple query and a complex query, shared var
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score2 from <test:bar> where " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$foo <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", "search2", "score2");
+
+ // a simple query and a complex query, shared var, different constraint order
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score2 from <test:bar> where " +
+ "$foo <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), "foo", "test:author", "Smith", "search2", "score2");
+
+ // a simple query and a complex query, separate vars
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $bar $score2 from <test:bar> where " +
+ "$foo <test:title> 'blah' in <test:lucene> and " +
+ "$bar <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ transf.transform(context, q);
+
+ cc = checkConstraint(q.getConstraintExpression(), 2);
+ checkConstraint(cc.getElements().get(0), null, "test:title", "blah", "foo", null);
+ checkConstraint(cc.getElements().get(1), "bar", "test:author", "Smith", "search2", "score2");
+
+ // invalid: complex query with multiple different predicates
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$search1 <test:author> 'Smith' in <test:lucene> and " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:title> 'blah' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with multiple same predicates
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$search1 <test:author> 'Smith' in <test:lucene> and " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:author> 'Jones' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with multiple scores
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score1 from <test:bar> where " +
+ "$search1 <mulgara:score> $score2 in <test:lucene> and " +
+ "$foo <mulgara:search> $search1 in <test:lucene> and " +
+ "$search1 <test:author> 'Jones' in <test:lucene> and " +
+ "$search1 <mulgara:score> $score1 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with binder and subject shared
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score2 from <test:bar> where " +
+ "$foo <mulgara:search> $foo in <test:lucene> and " +
+ "$foo <test:author> 'Smith' in <test:lucene> and " +
+ "$foo <mulgara:score> $score2 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with binder not a variable
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $foo $score2 from <test:bar> where " +
+ "$foo <mulgara:search> <test:it> in <test:lucene> and " +
+ "<test:it> <test:author> 'Smith' in <test:lucene> and " +
+ "<test:it> <mulgara:score> $score2 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with missing predicate
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $bar $score2 from <test:bar> where " +
+ "$bar <mulgara:search> $search2 in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+
+ // invalid: complex query with missing <mulgara:search>
+ q = new TestMutableLocalQuery(parseQuery(
+ "select $score2 from <test:bar> where " +
+ "$search2 <test:author> 'Smith' in <test:lucene> and " +
+ "$search2 <mulgara:score> $score2 in <test:lucene>;"));
+
+ try {
+ transf.transform(context, q);
+ fail("query transform should've failed: " + q);
+ } catch (SymbolicTransformationException ste) {
+ logger.debug("Caught expected transformation exception", ste);
+ }
+ } catch (Exception e) {
+ fail(e);
+ }
+ }
+
+ /*
+ * Internal helpers
+ */
+
+ private static ConstraintConjunction checkConstraint(ConstraintExpression ce, int numConstr) {
+ assertTrue(ce instanceof ConstraintConjunction);
+
+ ConstraintConjunction cc = (ConstraintConjunction)ce;
+ assertEquals(numConstr, cc.getElements().size());
+
+ return cc;
+ }
+
+ private static void checkConstraint(ConstraintExpression ce, String expSubj, String expPred,
+ String expObj, String expBind, String expScore)
+ throws Exception {
+ assertTrue(ce instanceof LuceneConstraint);
+ LuceneConstraint lc = (LuceneConstraint)ce;
+
+ if (expSubj != null) {
+ assertTrue(lc.getSubject() instanceof Variable);
+ assertEquals(expSubj, ((Variable)lc.getSubject()).getName());
+ } else {
+ assertNull(lc.getSubject());
+ }
+
+ assertTrue(lc.getPredicate() instanceof URIReference);
+ assertEquals(URI.create(expPred), ((URIReference)lc.getPredicate()).getURI());
+
+ assertTrue(lc.getObject() instanceof Literal);
+ assertEquals(expObj, ((Literal)lc.getObject()).getLexicalForm());
+
+ assertEquals(expBind, lc.getBindingVar().getName());
+
+ if (expScore != null) {
+ assertEquals(expScore, lc.getScoreVar().getName());
+ } else {
+ assertNull(lc.getScoreVar());
+ }
+ }
+
private String[][] expectedStudyResults() {
return new String[][] {
{ "foo:node3" }, { "foo:node4" }, { "foo:node11" }, { "foo:node13" }, { "foo:node19" },
@@ -490,4 +827,33 @@
return new byte[] { (byte)(xid >> 0x10), (byte)(xid >> 0x18) };
}
}
+
+ private static class TestSymbolicTransformationContext implements SymbolicTransformationContext {
+ private final Map<URI,URI> mappings;
+
+ public TestSymbolicTransformationContext(Map<URI,URI> mappings) {
+ this.mappings = mappings;
+ }
+
+ public URI mapToModelTypeURI(URI modelURI) {
+ return mappings.get(modelURI);
+ }
+ }
+
+ private static class TestMutableLocalQuery implements MutableLocalQuery {
+ private ConstraintExpression expr;
+
+ public TestMutableLocalQuery(Query query) {
+ expr = query.getConstraintExpression();
+ }
+
+ public ConstraintExpression getConstraintExpression() {
+ return expr;
+ }
+
+ public void setConstraintExpression(ConstraintExpression newExpr) {
+ expr = newExpr;
+ }
+ }
+
}
Added: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java (rev 0)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java 2008-10-27 12:38:48 UTC (rev 1366)
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2008 The Topaz Foundation
+ *
+ * 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.
+ *
+ * Contributions:
+ */
+
+package org.mulgara.resolver.lucene;
+
+import org.apache.log4j.Logger;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jrdf.graph.URIReference;
+
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.resolver.spi.MutableLocalQuery;
+import org.mulgara.resolver.spi.SymbolicTransformation;
+import org.mulgara.resolver.spi.SymbolicTransformationContext;
+import org.mulgara.resolver.spi.SymbolicTransformationException;
+
+/**
+ * A query transformer for lucene. This accept constraints like in the following example:
+ * <pre>
+ * select $x $score from ... where
+ * $x <mulgara:search> $s in <lucene> and
+ * $s <foo> 'story' in <lucene> and
+ * $s <mulgara:score> $score in <lucene>
+ * </pre>
+ *
+ * @created 2008-09-28
+ * @author Ronald Tschalär
+ * @licence Apache License v2.0
+ */
+public class LuceneTransformer implements SymbolicTransformation {
+ private static final Logger logger = Logger.getLogger(LuceneTransformer.class);
+
+ private final URI modelTypeURI;
+ private final URIReference searchPred;
+ private final URIReference scorePred;
+
+ /**
+ * Create a new tranformer to rewrite lucene queries.
+ *
+ * @param modelTypeURI the uri of the lucene model type
+ * @param searchPredURI the uri of the search predicate
+ * @param scorePredURI the uri of the score predicate
+ */
+ public LuceneTransformer(URI modelTypeURI, URI searchPredUri, URI scorePredUri) {
+ this.modelTypeURI = modelTypeURI;
+ searchPred = new URIReferenceImpl(searchPredUri);
+ scorePred = new URIReferenceImpl(scorePredUri);
+ }
+
+ public void transform(SymbolicTransformationContext context, MutableLocalQuery query)
+ throws SymbolicTransformationException {
+ ConstraintExpression expr = query.getConstraintExpression();
+ ConstraintExpression trans = transformExpr(context, expr);
+
+ if (expr != trans) {
+ query.setConstraintExpression(trans);
+ }
+ }
+
+ private ConstraintExpression transformExpr(SymbolicTransformationContext context, ConstraintExpression expr) throws SymbolicTransformationException {
+ if (expr instanceof ConstraintImpl) {
+ return transformConstr(context, (ConstraintImpl)expr);
+ }
+ if (expr instanceof ConstraintConjunction) {
+ return transformConj(context, (ConstraintConjunction)expr);
+ }
+ if (expr instanceof ConstraintDisjunction) {
+ return transformDisj(context, (ConstraintDisjunction)expr);
+ }
+
+ return expr;
+ }
+
+ private ConstraintExpression transformConstr(SymbolicTransformationContext context, ConstraintImpl c) throws SymbolicTransformationException {
+ try {
+ ConstraintElement ce = c.getModel();
+ if (ce instanceof URIReference) {
+ URI constraintModelType = context.mapToModelTypeURI(((URIReference)ce).getURI());
+ if (constraintModelType != null && constraintModelType.equals(modelTypeURI)) {
+ return new LuceneConstraint(c, searchPred, scorePred);
+ }
+ }
+ return c;
+ } catch (QueryException eq) {
+ throw new SymbolicTransformationException("Failed to map model to model-type", eq);
+ }
+ }
+
+ public ConstraintExpression transformConj(SymbolicTransformationContext context, ConstraintConjunction cc) throws SymbolicTransformationException {
+ List<ConstraintExpression> retainedArgs = new ArrayList<ConstraintExpression>();
+ Map<ConstraintElement, List<LuceneConstraint>> luceneArgs =
+ new HashMap<ConstraintElement, List<LuceneConstraint>>();
+
+ boolean transformed = false;
+
+ for (ConstraintExpression arg : cc.getElements()) {
+ ConstraintExpression trans = transformExpr(context, arg);
+ if (trans != arg) {
+ transformed = true;
+ }
+
+ if (trans instanceof LuceneConstraint) {
+ LuceneConstraint lc = (LuceneConstraint)trans;
+ List<LuceneConstraint> cumulative = luceneArgs.get(lc.getBindingVar());
+ if (cumulative == null) {
+ cumulative = new ArrayList<LuceneConstraint>();
+ cumulative.add(lc);
+ luceneArgs.put(lc.getBindingVar(), cumulative);
+ } else if (cumulative.size() > 1 ||
+ cumulative.get(0).getSubject() == null &&
+ cumulative.get(0).getPredicate() != null &&
+ lc.getSubject() == null && lc.getPredicate() != null) {
+ // backwards compat hack for multiple simple queries
+ cumulative.add(lc);
+ } else {
+ cumulative.iterator().next().conjoinWith(lc);
+ transformed = true;
+ }
+ } else {
+ retainedArgs.add(trans);
+ }
+ }
+
+ if (transformed) {
+ for (List<LuceneConstraint> c : luceneArgs.values()) {
+ for (LuceneConstraint lc : c) {
+ lc.validate();
+ retainedArgs.add(lc);
+ }
+ }
+
+ return new ConstraintConjunction(retainedArgs);
+ } else {
+ return cc;
+ }
+ }
+
+ private ConstraintExpression transformDisj(SymbolicTransformationContext context, ConstraintDisjunction cd) throws SymbolicTransformationException {
+ List<ConstraintExpression> transArgs = new ArrayList<ConstraintExpression>();
+ boolean transformed = false;
+ for (ConstraintExpression ce : cd.getElements()) {
+ ConstraintExpression trans = transformExpr(context, ce);
+ if (trans != ce) {
+ transformed = true;
+ }
+ transArgs.add(trans);
+ }
+
+ return transformed ? new ConstraintDisjunction(transArgs) : cd;
+ }
+}
Property changes on: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneTransformer.java
___________________________________________________________________
Name: svn:keywords
+ Id HeadURL Revision
Name: svn:eol-style
+ native
More information about the Mulgara-svn
mailing list