001 package railo.runtime.text.feed; 002 003 import railo.commons.lang.StringUtil; 004 import railo.runtime.exp.DatabaseException; 005 import railo.runtime.op.Caster; 006 import railo.runtime.type.Array; 007 import railo.runtime.type.CastableArray; 008 import railo.runtime.type.Collection; 009 import railo.runtime.type.Collection.Key; 010 import railo.runtime.type.KeyImpl; 011 import railo.runtime.type.Query; 012 import railo.runtime.type.QueryImpl; 013 import railo.runtime.type.Struct; 014 import railo.runtime.type.StructImpl; 015 016 public class FeedQuery { 017 018 public static final Collection.Key VERSION = KeyImpl.intern("VERSION"); 019 public static final Collection.Key ITEM = KeyImpl.intern("ITEM"); 020 public static final Collection.Key ENTRY = KeyImpl.intern("ENTRY"); 021 022 public static final Collection.Key AUTHOREMAIL = KeyImpl.intern("AUTHOREMAIL"); 023 public static final Collection.Key AUTHORNAME = KeyImpl.intern("AUTHORNAME"); 024 public static final Collection.Key AUTHORURI = KeyImpl.intern("AUTHORURI"); 025 public static final Collection.Key AUTHOR = KeyImpl.intern("AUTHOR"); 026 public static final Collection.Key CATEGORYLABEL = KeyImpl.intern("CATEGORYLABEL"); 027 public static final Collection.Key CATEGORYSCHEME = KeyImpl.intern("CATEGORYSCHEME"); 028 public static final Collection.Key CATEGORYTERM = KeyImpl.intern("CATEGORYTERM"); 029 public static final Collection.Key CATEGORY = KeyImpl.intern("CATEGORY"); 030 public static final Collection.Key COMMENTS = KeyImpl.intern("COMMENTS"); 031 public static final Collection.Key CONTENT = KeyImpl.intern("CONTENT"); 032 public static final Collection.Key CONTENTMODE = KeyImpl.intern("CONTENTMODE"); 033 public static final Collection.Key CONTENTSRC = KeyImpl.intern("CONTENTSRC"); 034 public static final Collection.Key CONTENTTYPE = KeyImpl.intern("CONTENTTYPE"); 035 public static final Collection.Key CONTRIBUTOREMAIL = KeyImpl.intern("CONTRIBUTOREMAIL"); 036 public static final Collection.Key CONTRIBUTORNAME = KeyImpl.intern("CONTRIBUTORNAME"); 037 public static final Collection.Key CONTRIBUTORURI = KeyImpl.intern("CONTRIBUTORURI"); 038 public static final Collection.Key CONTRIBUTOR = KeyImpl.intern("CONTRIBUTOR"); 039 public static final Collection.Key CREATEDDATE = KeyImpl.intern("CREATEDDATE"); 040 public static final Collection.Key CREATED = KeyImpl.intern("CREATED"); 041 public static final Collection.Key EXPIRATIONDATE = KeyImpl.intern("EXPIRATIONDATE"); 042 public static final Collection.Key ID = KeyImpl.intern("ID"); 043 public static final Collection.Key IDPERMALINK = KeyImpl.intern("IDPERMALINK"); 044 public static final Collection.Key LINKHREF = KeyImpl.intern("LINKHREF"); 045 public static final Collection.Key LINKHREFLANG = KeyImpl.intern("LINKHREFLANG"); 046 public static final Collection.Key LINKLENGTH = KeyImpl.intern("LINKLENGTH"); 047 public static final Collection.Key LINKREL = KeyImpl.intern("LINKREL"); 048 public static final Collection.Key LINKTITLE = KeyImpl.intern("LINKTITLE"); 049 public static final Collection.Key LINKTYPE = KeyImpl.intern("LINKTYPE"); 050 public static final Collection.Key PUBLISHEDDATE = KeyImpl.intern("PUBLISHEDDATE"); 051 public static final Collection.Key PUBLISHED = KeyImpl.intern("PUBLISHED"); 052 public static final Collection.Key PUBDATE = KeyImpl.intern("pubDate"); 053 public static final Collection.Key RDF_ABOUT = KeyImpl.intern("rdf:about"); 054 055 public static final Collection.Key RIGHTS = KeyImpl.intern("RIGHTS"); 056 public static final Collection.Key RSSLINK = KeyImpl.intern("RSSLINK"); 057 public static final Collection.Key SOURCE = KeyImpl.intern("SOURCE"); 058 public static final Collection.Key SOURCEURL = KeyImpl.intern("SOURCEURL"); 059 public static final Collection.Key SUMMARY = KeyImpl.intern("SUMMARY"); 060 public static final Collection.Key SUMMARYMODE = KeyImpl.intern("SUMMARYMODE"); 061 public static final Collection.Key SUMMARYSRC = KeyImpl.intern("SUMMARYSRC"); 062 public static final Collection.Key SUMMARYTYPE = KeyImpl.intern("SUMMARYTYPE"); 063 public static final Collection.Key TITLE = KeyImpl.intern("TITLE"); 064 public static final Collection.Key TITLETYPE = KeyImpl.intern("TITLETYPE"); 065 public static final Collection.Key UPDATEDDATE = KeyImpl.intern("UPDATEDDATE"); 066 public static final Collection.Key URI = KeyImpl.intern("URI"); 067 public static final Collection.Key XMLBASE = KeyImpl.intern("XMLBASE"); 068 public static final Collection.Key GUID = KeyImpl.intern("guid"); 069 public static final Collection.Key ENCLOSURE = KeyImpl.intern("enclosure"); 070 public static final Collection.Key LINK = KeyImpl.intern("link"); 071 public static final Collection.Key MODE = KeyImpl.intern("mode"); 072 public static final Collection.Key TEXT = KeyImpl.intern("text"); 073 public static final Collection.Key DOMAIN = KeyImpl.intern("domain"); 074 public static final Collection.Key ISSUED = KeyImpl.intern("issued"); 075 public static final Collection.Key COPYRIGHT = KeyImpl.intern("copyright"); 076 public static final Collection.Key SRC = KeyImpl.intern("src"); 077 public static final Collection.Key UPDATED = KeyImpl.intern("updated"); 078 public static final Collection.Key MODIFIED = KeyImpl.intern("modified"); 079 public static final Collection.Key URL = KeyImpl.intern("url"); 080 public static final Collection.Key LENGTH = KeyImpl.intern("length"); 081 public static final Collection.Key ISPERMALINK = KeyImpl.intern("isPermaLink"); 082 083 public static final Collection.Key DC_CONTRIBUTOR = KeyImpl.intern("DC_CONTRIBUTOR"); 084 public static final Collection.Key DC_COVERAGE = KeyImpl.intern("DC_COVERAGE"); 085 public static final Collection.Key DC_CREATOR = KeyImpl.intern("DC_CREATOR"); 086 public static final Collection.Key DC_DATE = KeyImpl.intern("DC_DATE"); 087 public static final Collection.Key DC_DESCRIPTION = KeyImpl.intern("DC_DESCRIPTION"); 088 public static final Collection.Key DC_FORMAT = KeyImpl.intern("DC_FORMAT"); 089 public static final Collection.Key DC_IDENTIFIER = KeyImpl.intern("DC_IDENTIFIER"); 090 public static final Collection.Key DC_LANGUAGE = KeyImpl.intern("DC_LANGUAGE"); 091 public static final Collection.Key DC_PUBLISHER = KeyImpl.intern("DC_PUBLISHER"); 092 public static final Collection.Key DC_RELATION = KeyImpl.intern("DC_RELATION"); 093 public static final Collection.Key DC_RIGHT = KeyImpl.intern("DC_RIGHTS"); 094 public static final Collection.Key DC_SOURCE = KeyImpl.intern("DC_SOURCE"); 095 public static final Collection.Key DC_TITLE = KeyImpl.intern("DC_TITLE"); 096 public static final Collection.Key DC_TYPE = KeyImpl.intern("DC_TYPE"); 097 098 public static final Collection.Key DC_SUBJECT_TAXONOMYURI = KeyImpl.intern("DC_SUBJECT_TAXONOMYURI"); 099 public static final Collection.Key DC_SUBJECT_VALUE = KeyImpl.intern("DC_SUBJECT_VALUE"); 100 public static final Collection.Key DC_SUBJECT = KeyImpl.intern("DC_SUBJECT"); 101 102 103 104 105 106 private static Collection.Key[] COLUMNS=new Collection.Key[]{ 107 AUTHOREMAIL, 108 AUTHORNAME, 109 AUTHORURI, 110 CATEGORYLABEL, 111 CATEGORYSCHEME, 112 CATEGORYTERM, 113 COMMENTS, 114 CONTENT, 115 CONTENTMODE, 116 CONTENTSRC, 117 CONTENTTYPE, 118 CONTRIBUTOREMAIL, 119 CONTRIBUTORNAME, 120 CONTRIBUTORURI, 121 CREATEDDATE, 122 EXPIRATIONDATE, 123 ID, 124 IDPERMALINK, 125 LINKHREF, 126 LINKHREFLANG, 127 LINKLENGTH, 128 LINKREL, 129 LINKTITLE, 130 LINKTYPE, 131 PUBLISHEDDATE, 132 RIGHTS, 133 RSSLINK, 134 SOURCE, 135 SOURCEURL, 136 SUMMARY, 137 SUMMARYMODE, 138 SUMMARYSRC, 139 SUMMARYTYPE, 140 TITLE, 141 TITLETYPE, 142 UPDATEDDATE, 143 URI, 144 XMLBASE 145 }; 146 147 148 private static Collection.Key[] COLUMNS_WITH_DC=new Collection.Key[]{ 149 AUTHOREMAIL, 150 AUTHORNAME, 151 AUTHORURI, 152 CATEGORYLABEL, 153 CATEGORYSCHEME, 154 CATEGORYTERM, 155 COMMENTS, 156 CONTENT, 157 CONTENTMODE, 158 CONTENTSRC, 159 CONTENTTYPE, 160 CONTRIBUTOREMAIL, 161 CONTRIBUTORNAME, 162 CONTRIBUTORURI, 163 CREATEDDATE, 164 165 DC_CONTRIBUTOR, 166 DC_COVERAGE, 167 DC_CREATOR, 168 DC_DATE, 169 DC_DESCRIPTION, 170 DC_FORMAT, 171 DC_IDENTIFIER, 172 DC_LANGUAGE, 173 DC_PUBLISHER, 174 DC_RELATION, 175 DC_RIGHT, 176 DC_SOURCE, 177 DC_TITLE, 178 DC_TYPE, 179 DC_SUBJECT_TAXONOMYURI, 180 DC_SUBJECT_VALUE, 181 182 EXPIRATIONDATE, 183 ID, 184 IDPERMALINK, 185 LINKHREF, 186 LINKHREFLANG, 187 LINKLENGTH, 188 LINKREL, 189 LINKTITLE, 190 LINKTYPE, 191 PUBLISHEDDATE, 192 RIGHTS, 193 RSSLINK, 194 SOURCE, 195 SOURCEURL, 196 SUMMARY, 197 SUMMARYMODE, 198 SUMMARYSRC, 199 SUMMARYTYPE, 200 TITLE, 201 TITLETYPE, 202 UPDATEDDATE, 203 URI, 204 XMLBASE 205 }; 206 207 208 public static Query toQuery(Struct data,boolean hasDC) throws DatabaseException { 209 Query qry=new QueryImpl(hasDC?COLUMNS_WITH_DC:COLUMNS,0,""); 210 211 String version=Caster.toString(data.get(VERSION,""),""); 212 Array items=null; 213 if(StringUtil.startsWithIgnoreCase(version,"rss") || StringUtil.startsWithIgnoreCase(version,"rdf")) { 214 items=Caster.toArray(data.get(ITEM, null),null); 215 if(items==null) { 216 Struct sct=Caster.toStruct(data.get(version,null),null,false); 217 if(sct!=null){ 218 items=Caster.toArray(sct.get(ITEM, null),null); 219 } 220 } 221 return toQuery(true,qry,items); 222 } 223 else if(StringUtil.startsWithIgnoreCase(version,"atom")) { 224 items=Caster.toArray(data.get(ENTRY, null),null); 225 return toQuery(false,qry,items); 226 } 227 return qry; 228 } 229 230 private static Query toQuery(boolean isRss,Query qry, Array items) { 231 if(items==null)return qry; 232 233 int len=items.size(); 234 Struct item; 235 int row=0; 236 Collection.Key[] keys; 237 for(int i=1;i<=len;i++) { 238 item=Caster.toStruct(items.get(i, null),null,false); 239 if(item==null) continue; 240 qry.addRow(); 241 row++; 242 keys=item.keys(); 243 for(int y=0;y<keys.length;y++) { 244 if(isRss)setQueryValueRSS(qry,keys[y],item.get(keys[y],null),row); 245 else setQueryValueAtom(qry,keys[y],item.get(keys[y],null),row); 246 } 247 248 } 249 250 return qry; 251 } 252 253 private static void setQueryValueAtom(Query qry, Key key, Object value, int row) { 254 255 if(key.equals(AUTHOR)) { 256 Struct sct=toStruct(value); 257 258 if(sct!=null){ 259 qry.setAtEL(AUTHOREMAIL, row, sct.get("email",null)); 260 qry.setAtEL(AUTHORNAME, row, sct.get("name",null)); 261 qry.setAtEL(AUTHORURI, row, sct.get("uri",null)); 262 } 263 } 264 if(key.equals(CATEGORY)) { 265 Struct sct=toStruct(value); 266 if(sct!=null){ 267 qry.setAtEL(CATEGORYLABEL, row, sct.get("label",null)); 268 qry.setAtEL(CATEGORYSCHEME, row, sct.get("scheme",null)); 269 qry.setAtEL(CATEGORYTERM, row, sct.get("term",null)); 270 } 271 //else qry.setAtEL(CATEGORYLABEL, row, getValue(value)); 272 } 273 else if(key.equals(COMMENTS)) { 274 qry.setAtEL(COMMENTS, row, getValue(value)); 275 } 276 else if(key.equals(CONTENT)) { 277 Struct sct=toStruct(value); 278 if(sct!=null){ 279 qry.setAtEL(CONTENT, row, getValue(sct)); 280 qry.setAtEL(CONTENTMODE, row, sct.get(MODE,null)); 281 qry.setAtEL(CONTENTSRC, row, sct.get(SRC,null)); 282 qry.setAtEL(CONTENTTYPE, row, sct.get(KeyImpl.TYPE,null)); 283 qry.setAtEL(XMLBASE, row, sct.get("xml:base",null)); 284 } 285 else qry.setAtEL(CONTENT, row, getValue(value)); 286 } 287 else if(key.equals(CONTRIBUTOR)) { 288 Struct sct=toStruct(value); 289 if(sct!=null){ 290 qry.setAtEL(CONTRIBUTOREMAIL, row, sct.get("email",null)); 291 qry.setAtEL(CONTRIBUTORNAME, row, sct.get(KeyImpl.NAME,null)); 292 qry.setAtEL(CONTRIBUTORURI, row, sct.get("uri",null)); 293 } 294 } 295 else if(key.equals(CREATED)) { 296 qry.setAtEL(CREATEDDATE, row, getValue(value)); 297 } 298 else if(key.equals(ID)) { 299 qry.setAtEL(ID, row, getValue(value)); 300 } 301 else if(key.equals(LINK)) { 302 Struct sct=toStruct(value); 303 if(sct!=null){ 304 qry.setAtEL(LINKHREF, row, sct.get("href",null)); 305 qry.setAtEL(LINKHREFLANG, row, sct.get("hreflang",null)); 306 qry.setAtEL(LINKLENGTH, row, sct.get(LENGTH,null)); 307 qry.setAtEL(LINKREL, row, sct.get("rel",null)); 308 qry.setAtEL(LINKTITLE, row, sct.get(TITLE,null)); 309 qry.setAtEL(LINKTYPE, row, sct.get(KeyImpl.TYPE,null)); 310 } 311 } 312 else if(key.equals(PUBLISHED)) { 313 qry.setAtEL(PUBLISHEDDATE, row, getValue(value)); 314 } 315 else if(key.equals(ISSUED)) { 316 qry.setAtEL(PUBLISHEDDATE, row, getValue(value)); 317 } 318 else if(key.equals(RIGHTS)) { 319 qry.setAtEL(RIGHTS, row, getValue(value)); 320 } 321 else if(key.equals(COPYRIGHT)) { 322 qry.setAtEL(RIGHTS, row, getValue(value)); 323 } 324 else if(key.equals(SUMMARY)) { 325 Struct sct=toStruct(value); 326 if(sct!=null){ 327 qry.setAtEL(SUMMARY, row, getValue(sct)); 328 qry.setAtEL(SUMMARYMODE, row, sct.get(MODE,null)); 329 qry.setAtEL(SUMMARYSRC, row, sct.get(SRC,null)); 330 qry.setAtEL(SUMMARYTYPE, row, sct.get(KeyImpl.TYPE,null)); 331 } 332 else qry.setAtEL(SUMMARY, row, getValue(value)); 333 } 334 else if(key.equals(TITLE)) { 335 Struct sct=toStruct(value); 336 if(sct!=null){ 337 qry.setAtEL(TITLE, row, getValue(sct)); 338 qry.setAtEL(TITLETYPE, row, sct.get(KeyImpl.TYPE,null)); 339 } 340 else qry.setAtEL(TITLE, row, getValue(value)); 341 } 342 else if(key.equals(UPDATED)) { 343 qry.setAtEL(UPDATEDDATE, row, getValue(value)); 344 } 345 else if(key.equals(MODIFIED)) { 346 qry.setAtEL(UPDATEDDATE, row, getValue(value)); 347 } 348 } 349 private static void setQueryValueRSS(Query qry, Key key, Object value, int row) { 350 351 if(key.equals(AUTHOR)) { 352 qry.setAtEL(AUTHOREMAIL, row, getValue(value)); 353 } 354 else if(key.equals(CATEGORY)) { 355 Struct sct=toStruct(value); 356 357 if(sct!=null){ 358 qry.setAtEL(CATEGORYLABEL, row, getValue(sct)); 359 qry.setAtEL(CATEGORYSCHEME, row, sct.get(DOMAIN,null)); 360 } 361 else qry.setAtEL(CATEGORYLABEL, row, getValue(value)); 362 } 363 else if(key.equals(COMMENTS)) { 364 qry.setAtEL(COMMENTS, row, getValue(value)); 365 } 366 else if(key.equals(KeyImpl.DESCRIPTION)) { 367 qry.setAtEL(CONTENT, row, getValue(value)); 368 } 369 else if(key.equals(EXPIRATIONDATE)) { 370 qry.setAtEL(EXPIRATIONDATE, row, getValue(value)); 371 } 372 else if(key.equals(GUID)) { 373 Struct sct=toStruct(value); 374 375 if(sct!=null){ 376 qry.setAtEL(ID, row, getValue(sct)); 377 qry.setAtEL(IDPERMALINK, row, sct.get(ISPERMALINK,null)); 378 } 379 else qry.setAtEL(ID, row, getValue(value)); 380 } 381 else if(key.equals(ENCLOSURE)) { 382 Struct sct=toStruct(value); 383 if(sct!=null){ 384 qry.setAtEL(LINKHREF, row, sct.get(URL,null)); 385 qry.setAtEL(LINKLENGTH, row, sct.get(LENGTH,null)); 386 qry.setAtEL(LINKTYPE, row, sct.get(KeyImpl.TYPE,null)); 387 } 388 } 389 else if(key.equals(PUBDATE)) { 390 qry.setAtEL(PUBLISHEDDATE, row, getValue(value)); 391 } 392 else if(key.equals(RDF_ABOUT)) { 393 qry.setAtEL(URI, row, getValue(value)); 394 } 395 else if(key.equals(LINK)) { 396 397 Struct sct=toStruct(value); 398 399 if(sct!=null){ 400 qry.setAtEL(RSSLINK, row, getValue(sct)); 401 Object v = sct.get(RDF_ABOUT,null); 402 if(v!=null) qry.setAtEL(URI, row, v); 403 } 404 else qry.setAtEL(RSSLINK, row, getValue(value)); 405 } 406 else if(key.equals(SOURCE)) { 407 Struct sct=toStruct(value); 408 409 if(sct!=null){ 410 qry.setAtEL(SOURCE, row, getValue(sct)); 411 qry.setAtEL(SOURCEURL, row, sct.get(URL,null)); 412 } 413 else qry.setAtEL(SOURCE, row, getValue(value)); 414 } 415 else if(key.equals(SUMMARY)) { 416 Struct sct=toStruct(value); 417 418 if(sct!=null){ 419 qry.setAtEL(SUMMARY, row, getValue(sct)); 420 qry.setAtEL(SUMMARYMODE, row, sct.get(MODE,null)); 421 qry.setAtEL(SUMMARYTYPE, row, sct.get(KeyImpl.TYPE,null)); 422 } 423 else qry.setAtEL(SUMMARY, row, getValue(value)); 424 } 425 else if(key.equals(TITLE)) { 426 qry.setAtEL(TITLE, row, getValue(value)); 427 } 428 429 // Dublin Core 430 if(key.getLowerString().startsWith("dc_")){ 431 432 if(key.equals(DC_CONTRIBUTOR)) { 433 qry.setAtEL(DC_CONTRIBUTOR, row, getValue(value)); 434 } 435 else if(key.equals(DC_COVERAGE)) { 436 qry.setAtEL(DC_COVERAGE, row, getValue(value)); 437 } 438 else if(key.equals(DC_CREATOR)) { 439 qry.setAtEL(DC_CREATOR, row, getValue(value)); 440 } 441 else if(key.equals(DC_DATE)) { 442 qry.setAtEL(DC_DATE, row, getValue(value)); 443 } 444 else if(key.equals(DC_DESCRIPTION)) { 445 qry.setAtEL(DC_DESCRIPTION, row, getValue(value)); 446 } 447 else if(key.equals(DC_FORMAT)) { 448 qry.setAtEL(DC_FORMAT, row, getValue(value)); 449 } 450 else if(key.equals(DC_IDENTIFIER)) { 451 qry.setAtEL(DC_IDENTIFIER, row, getValue(value)); 452 } 453 else if(key.equals(DC_LANGUAGE)) { 454 qry.setAtEL(DC_LANGUAGE, row, getValue(value)); 455 } 456 else if(key.equals(DC_PUBLISHER)) { 457 qry.setAtEL(DC_PUBLISHER, row, getValue(value)); 458 } 459 else if(key.equals(DC_RELATION)) { 460 qry.setAtEL(DC_RELATION, row, getValue(value)); 461 } 462 else if(key.equals(DC_RIGHT)) { 463 qry.setAtEL(DC_RIGHT, row, getValue(value)); 464 } 465 else if(key.equals(DC_SOURCE)) { 466 qry.setAtEL(DC_SOURCE, row, getValue(value)); 467 } 468 else if(key.equals(DC_SUBJECT_TAXONOMYURI)) { 469 qry.setAtEL(DC_SUBJECT_TAXONOMYURI, row, getValue(value)); 470 } 471 else if(key.equals(DC_SUBJECT)) { 472 qry.setAtEL(DC_SUBJECT_VALUE, row, getValue(value)); 473 } 474 else if(key.equals(DC_TITLE)) { 475 qry.setAtEL(DC_TITLE, row, getValue(value)); 476 } 477 else if(key.equals(DC_TYPE)) { 478 qry.setAtEL(DC_TYPE, row, getValue(value)); 479 } 480 } 481 482 } 483 484 485 public static Object getValue(Object value) { 486 return getValue(value, false); 487 } 488 public static Object getValue(Object value,boolean includeChildren) { 489 if(value instanceof Struct)return getValue((Struct)value,includeChildren); 490 return Caster.toString(value,null); 491 } 492 493 public static Object getValue(Struct sct,boolean includeChildren) { 494 Object obj = sct.get(KeyImpl.VALUE, null); 495 if(obj==null)obj=sct.get(TEXT,null); 496 return obj; 497 } 498 499 private static Struct toStruct(Object value) { 500 if(value instanceof Struct) return (Struct) value; 501 502 if(value instanceof Array) { 503 Struct sct=new StructImpl(),row; 504 Array arr = (Array)value; 505 int len=arr.size(); 506 Key[] keys; 507 String nw; 508 Object ext; 509 for(int i=1;i<=len;i++){ 510 row=Caster.toStruct(arr.get(i,null),null,false); 511 if(row==null)continue; 512 keys = row.keys(); 513 for(int y=0;y<keys.length;y++){ 514 ext=sct.get(keys[y],null); 515 nw=Caster.toString(row.get(keys[y],null),null); 516 if(nw!=null){ 517 if(ext==null) sct.setEL(keys[y], nw); 518 else if(ext instanceof CastableArray){ 519 ((CastableArray)ext).appendEL(nw); 520 } 521 else { 522 CastableArray ca=new CastableArray(); 523 ca.appendEL(Caster.toString(ext,null)); 524 ca.appendEL(nw); 525 sct.setEL(keys[y], ca); 526 } 527 528 } 529 } 530 } 531 return sct; 532 } 533 534 535 return null; 536 } 537 538 public static Query toQuery(Query qry) { 539 return qry; 540 } 541 }