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