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    }