001    package railo.runtime.search;
002    
003    import java.net.MalformedURLException;
004    import java.net.URL;
005    import java.util.Iterator;
006    import java.util.Map;
007    import java.util.Map.Entry;
008    
009    import org.w3c.dom.Element;
010    
011    import railo.commons.collections.HashTable;
012    import railo.commons.io.FileUtil;
013    import railo.commons.io.log.Log;
014    import railo.commons.io.res.Resource;
015    import railo.commons.io.res.util.ResourceUtil;
016    import railo.commons.lang.StringUtil;
017    import railo.commons.lock.KeyLock;
018    import railo.commons.lock.Lock;
019    import railo.commons.net.HTTPUtil;
020    import railo.runtime.PageContext;
021    import railo.runtime.exp.DatabaseException;
022    import railo.runtime.exp.PageException;
023    import railo.runtime.op.Caster;
024    import railo.runtime.type.ArrayImpl;
025    import railo.runtime.type.Query;
026    import railo.runtime.type.QueryColumn;
027    import railo.runtime.type.QueryImpl;
028    import railo.runtime.type.dt.DateTime;
029    import railo.runtime.type.dt.DateTimeImpl;
030    import railo.runtime.type.util.ArrayUtil;
031    import railo.runtime.type.util.ListUtil;
032    
033    /**
034     * represent a single Collection
035     */
036    public abstract class SearchCollectionSupport2 implements SearchCollectionPlus {
037    
038        private static final int LOCK_TIMEOUT = 10*60*1000; // ten minutes
039        private String name;
040            private Resource path;
041            private String language;
042            private DateTime lastUpdate;
043        private SearchEngineSupport searchEngine;
044            //TODO change visibility to private
045        protected Map indexes=new HashTable();
046    
047        private DateTime created;
048    
049        private Log log;
050            //private static LockManager manager=Lock Manager Impl.getInstance();
051        private KeyLock<String> lock=new KeyLock<String>();
052    
053            /**
054             * constructor of the class
055             * @param searchEngine
056             * @param name name of the Collection
057             * @param path
058             * @param language
059             * @param count total count of documents in the collection
060             * @param lastUpdate
061             * @param created 
062             */
063            public SearchCollectionSupport2(SearchEngineSupport searchEngine, String name,Resource path, String language, DateTime lastUpdate, DateTime created) {
064                    this.searchEngine=searchEngine;
065                this.name=name;
066                    this.path=path;
067                    this.language=SearchUtil.translateLanguage(language);
068            this.lastUpdate=lastUpdate;
069            this.created=created;
070                    this.log = searchEngine.getLogger();
071            }
072    
073            @Override
074            public final void create() throws SearchException {
075                    Lock l = lock();
076                    try {
077                _create();
078            }
079                    finally {
080                            unlock(l);
081                    }
082            }
083    
084            /**
085             * create a collection
086             * @throws SearchException
087             */
088            protected abstract void _create() throws SearchException;
089    
090        @Override
091        public final void optimize() throws SearchException  {
092            Lock l = lock();
093             try {
094             _optimize();
095            changeLastUpdate();
096        }
097                    finally {
098                            unlock(l);
099                    }
100        }
101    
102        /**
103         * optimize a Collection
104         * @throws SearchException
105         */
106        protected abstract void _optimize() throws SearchException ;
107    
108        @Override
109        public final void map(Resource path) throws SearchException  {
110            Lock l = lock();
111            try {
112            _map(path);
113            changeLastUpdate();
114        }
115                    finally {
116                            unlock(l);
117                    }
118        }
119    
120        /**
121         * map a Collection
122         * @param path
123         * @throws SearchException
124         */ 
125        protected abstract void _map(Resource path) throws SearchException ;
126    
127        @Override
128        public final void repair() throws SearchException  {
129            Lock l = lock();
130            try {
131            _repair();
132            changeLastUpdate();
133        }
134                    finally {
135                            unlock(l);
136                    }
137        }
138    
139        /**
140         * repair a Collection
141         * @throws SearchException
142         */
143        protected abstract void _repair() throws SearchException ;
144        
145        @Override
146        public IndexResult index(PageContext pc, String key, short type, String urlpath, String title, String body, String language, 
147                String[] extensions, String query, boolean recurse,String categoryTree, String[] categories,
148                String custom1, String custom2, String custom3, String custom4) throws PageException, MalformedURLException, SearchException {
149            return index(pc, key, type, urlpath, title, body, language, extensions, query, recurse, categoryTree, categories, 10000, custom1, custom2, custom3, custom4);
150        }
151                    
152        // FUTURE add this to interface
153        public IndexResult index(PageContext pc, String key, short type, String urlpath, String title, String body, String language, 
154                String[] extensions, String query, boolean recurse,String categoryTree, String[] categories, long timeout,
155                String custom1, String custom2, String custom3, String custom4) throws PageException, MalformedURLException, SearchException {
156            language=SearchUtil.translateLanguage(language);
157            Lock l = lock();
158            try {
159            SearchIndex si = new SearchIndex(title,key,type,query,extensions,language,urlpath,categoryTree,categories,
160                            custom1,custom2,custom3,custom4);
161            //String id=si.getId();
162            IndexResult ir=IndexResultImpl.EMPTY;
163            if(type==SearchIndex.TYPE_FILE){
164                    Resource file=ResourceUtil.toResourceNotExisting(pc,key);
165                if(!file.isFile())throw new SearchException("value of attribute key must specify a existing file, ["+key+"] is invalid");
166                 ir=indexFile(si,file);
167                 //ir=indexFile(id,title,file,language);
168            }
169            else if(type==SearchIndex.TYPE_PATH){
170                    Resource dir=ResourceUtil.toResourceNotExisting(pc,key);
171                if(!dir.isDirectory())throw new SearchException("value of attribute key must specify a existing directory, ["+key+"] is invalid");
172                ir=indexPath(si,dir,recurse);
173            }
174            else if(type==SearchIndex.TYPE_URL) {
175                    ir=indexURL(si,new URL(key),recurse,timeout);
176            }
177            else if(type==SearchIndex.TYPE_CUSTOM) {
178                    Query qv;
179                    if(StringUtil.isEmpty(query)){
180                
181                    // set columns
182                            railo.runtime.type.Array columns=new ArrayImpl();
183                    columns.append("key");
184                    columns.append("body");
185                    if(!StringUtil.isEmpty(title))columns.append("title");
186                    if(!StringUtil.isEmpty(urlpath))columns.append("urlpath");
187                    if(!StringUtil.isEmpty(custom1))columns.append("custom1");
188                    if(!StringUtil.isEmpty(custom2))columns.append("custom2");
189                    if(!StringUtil.isEmpty(custom3))columns.append("custom3");
190                    if(!StringUtil.isEmpty(custom4))columns.append("custom4");
191                    
192                // populate query with a single row
193                    qv=new QueryImpl(columns,1,"query");
194                    // body
195                    qv.setAt("key", 1, key);
196                    key="key";
197    
198                    // body
199                    qv.setAt("body", 1, body);
200                    body="body";
201    
202                    // title
203                    if(!StringUtil.isEmpty(title)){
204                            qv.setAt("title", 1, title);
205                            title="title";
206                    }
207    
208                    // custom1
209                    if(!StringUtil.isEmpty(urlpath)){
210                            qv.setAt("urlpath", 1, urlpath);
211                            custom1="urlpath";
212                    }
213    
214                    // custom1
215                    if(!StringUtil.isEmpty(custom1)){
216                            qv.setAt("custom1", 1, custom1);
217                            custom1="custom1";
218                    }
219                    // custom2
220                    if(!StringUtil.isEmpty(custom2)){
221                            qv.setAt("custom2", 1, custom2);
222                            custom2="custom2";
223                    }
224                    // custom3
225                    if(!StringUtil.isEmpty(custom3)){
226                            qv.setAt("custom3", 1, custom3);
227                            custom3="custom3";
228                    }
229                    // custom4
230                    if(!StringUtil.isEmpty(custom4)){
231                            qv.setAt("custom4", 1, custom4);
232                            custom4="custom4";
233                    }
234                }
235                    else qv = Caster.toQuery(pc.getVariable(query));
236                
237                    QueryColumn keyColumn=qv.getColumn(key);
238                
239                String[] strBodies=ListUtil.toStringArrayTrim(ListUtil.listToArrayRemoveEmpty(body,','));
240                QueryColumn[] bodyColumns=new QueryColumn[strBodies.length];
241                for(int i=0;i<bodyColumns.length;i++) {
242                    bodyColumns[i]=qv.getColumn(strBodies[i]);
243                }
244                
245                ir= indexCustom(si,
246                        getColumnEL(qv,title),
247                        keyColumn,
248                        bodyColumns,
249    
250                        getColumnEL(qv,urlpath),
251                        getColumnEL(qv,custom1),
252                        getColumnEL(qv,custom2),
253                        getColumnEL(qv,custom3),
254                        getColumnEL(qv,custom4));
255            }
256            createIndex(si);
257            return ir;
258        }
259                    finally {
260                            unlock(l);
261                    }
262        }
263     
264        
265    
266            private QueryColumn getColumnEL(Query query, String column) {
267            if(column==null || column.length()==0) return null;
268            return query.getColumn(column,null);
269        }
270    
271        @Override
272        public final IndexResult indexFile(String id,String title, Resource res, String language) throws SearchException {
273            throw new SearchException("method indexFile(...) no longer supported use index(...) instead");
274        }
275        
276        public final IndexResult indexFile(SearchIndex si, Resource file) throws SearchException {
277            IndexResult ir=_indexFile(si,file);
278            changeLastUpdate();
279            return ir;
280        }
281    
282        protected abstract IndexResult _indexFile(SearchIndex si, Resource file)  throws SearchException;
283    
284        @Override
285        public final IndexResult indexPath(String id, String title, Resource dir, String[] extensions, boolean recurse, String language) throws SearchException {
286            throw new SearchException("method indexPath(...) no longer supported use index(...) instead");
287        }
288        
289        public final IndexResult indexPath(SearchIndex si, Resource dir, boolean recurse) throws SearchException {
290            IndexResult ir=_indexPath(si,dir,recurse);
291            changeLastUpdate();
292            return ir;
293        }
294            
295    
296    
297        /**
298         * updates a collection with a path
299         * @param dir 
300         * @param id
301         * @param title
302         * @param dir
303         * @param recurse 
304         * @param recurse
305         * @param extensions
306         * @param language
307         * @throws SearchException
308         */
309        protected abstract IndexResult _indexPath(SearchIndex si, Resource dir, boolean recurse) throws SearchException;
310    
311        @Override
312        public final IndexResult indexURL(String id,String title, URL url, String[] extensions, boolean recurse, String language) throws SearchException {
313            return indexURL(id, title, url, extensions, recurse, language, 10000);
314        }
315        
316            // FUTURE replace this in interface with method above
317        public final IndexResult indexURL(String id,String title, URL url, String[] extensions, boolean recurse, String language,long timeout) throws SearchException {
318            throw new SearchException("method indexURL(...) no longer supported use index(...) instead");
319            
320        } 
321        
322        public final IndexResult indexURL(SearchIndex si, URL url, boolean recurse,long timeout) throws SearchException {
323            IndexResult ir=_indexURL(si,url,recurse,timeout);
324            changeLastUpdate();
325            return ir;
326        } 
327    
328        protected abstract IndexResult _indexURL(SearchIndex si, URL url, boolean recurse, long timeout) throws SearchException ;
329    
330        @Override
331        public final IndexResult indexCustom(String id, QueryColumn title, QueryColumn keyColumn, QueryColumn[] bodyColumns, String language, 
332                    QueryColumn custom1, QueryColumn custom2, QueryColumn custom3, QueryColumn custom4) throws SearchException {
333            throw new SearchException("method indexCustom(...) no longer supported use index(...) instead");
334            
335        }
336        
337        public final IndexResult indexCustom(SearchIndex si, QueryColumn colTitle, QueryColumn keyColumn, QueryColumn[] bodyColumns, QueryColumn ct1Column, QueryColumn ct2Column, QueryColumn ct3Column, QueryColumn ct4Column) throws SearchException {
338            IndexResult ir=_indexCustom(si, colTitle, keyColumn, bodyColumns, null,ct1Column, ct2Column, ct3Column, ct4Column);
339            changeLastUpdate();
340            return ir;
341        }
342        
343        public final IndexResult indexCustom(SearchIndex si, QueryColumn colTitle, QueryColumn keyColumn, QueryColumn[] bodyColumns, 
344                    QueryColumn urlpath, QueryColumn ct1Column, QueryColumn ct2Column, QueryColumn ct3Column, QueryColumn ct4Column) throws SearchException {
345            IndexResult ir=_indexCustom(si, colTitle, keyColumn, bodyColumns, urlpath, ct1Column, ct2Column, ct3Column, ct4Column);
346            changeLastUpdate();
347            return ir;
348        }
349        
350    
351        /**
352         * updates a collection with a custom
353         * @param id
354         * @param title Title for the Index
355         * @param keyColumn Key Column
356         * @param bodyColumns Body Column Array
357         * @param language Language for index
358         * @param custom1 
359         * @param custom2 
360         * @param custom3 
361         * @param custom4 
362         * @throws SearchException
363         */
364        //protected abstract IndexResult _indexCustom(SearchIndex si, QueryColumn colTitle, QueryColumn keyColumn, QueryColumn[] bodyColumns, QueryColumn ct1Column, QueryColumn ct2Column, QueryColumn ct3Column, QueryColumn ct4Column) throws SearchException;
365        protected abstract IndexResult _indexCustom(SearchIndex si, QueryColumn colTitle, QueryColumn keyColumn, QueryColumn[] bodyColumns, 
366                    QueryColumn urlpath, QueryColumn ct1Column, QueryColumn ct2Column, QueryColumn ct3Column, QueryColumn ct4Column) throws SearchException;
367    
368        /**
369         * @param index
370         * @throws SearchException
371         */
372        private void createIndex(SearchIndex index) throws SearchException {
373            Iterator it = indexes.keySet().iterator();
374            SearchIndex otherIndex=null;
375            
376            while(it.hasNext()) {
377                Object key=it.next();
378                if(key.equals(index.getId())) {
379                    otherIndex=(SearchIndex) indexes.get(key);
380                    break;
381                }
382            }
383            
384            Element collElement=searchEngine.getCollectionElement(name);
385            
386            // Insert
387            if(otherIndex==null) {
388                addIndex(index);
389                collElement.appendChild(searchEngine.toElement(index));
390            }
391            // Update
392            else {
393                addIndex(index);
394                Element el=searchEngine.getIndexElement(collElement,index.getId());
395                searchEngine.setAttributes(el,index);
396            }
397            changeLastUpdate();
398        }
399    
400        /**
401         * @param index
402         */
403        public void addIndex(SearchIndex index) {
404            indexes.put(index.getId(),index);
405        }
406    
407            @Override
408            public final String getLanguage() {
409                    return language;
410            }
411        
412            @Override
413            public final IndexResult purge() throws SearchException {
414                    Lock l = lock();
415            try {
416            indexes.clear();
417            IndexResult ir=_purge();
418            searchEngine.purgeCollection(this);
419            changeLastUpdate();
420            return ir;
421            }
422                    finally {
423                            unlock(l);
424                    }
425            }
426    
427            /**
428             * purge a collection
429             * @throws SearchException
430             */
431            protected abstract IndexResult _purge() throws SearchException;
432    
433        @Override
434        public final IndexResult delete() throws SearchException {
435            Lock l = lock();
436            try {
437            IndexResult ir=_delete();
438                searchEngine.removeCollection(this);
439                return ir;
440        }
441                    finally {
442                            unlock(l);
443                    }
444        }
445    
446        /**
447         * delete the collection from a file
448             * @throws SearchException
449         */
450        protected abstract IndexResult _delete() throws SearchException;
451    
452        @Override
453        public final IndexResult deleteIndex(PageContext pc,String key,short type,String queryName) throws SearchException {
454            Iterator it = indexes.keySet().iterator();
455            
456            while(it.hasNext()) {
457                Object id = it.next();
458                if(id.equals(SearchIndex.toId(type,key,queryName))) {
459                    SearchIndex index=(SearchIndex) indexes.get(id);
460    
461                    IndexResult ir=_deleteIndex(index.getId());
462                    Element indexEl=searchEngine.getIndexElement(searchEngine.getCollectionElement(name),index.getId());
463                    if(indexEl!=null)indexEl.getParentNode().removeChild(indexEl);
464                    changeLastUpdate();
465                        return ir; 
466                }
467            }
468            return new IndexResultImpl(0,0,0);
469        }
470    
471        /**
472         * delete a Index from collection
473             * @param id id ofthe Index to delete
474         * @throws SearchException
475         */ 
476        protected abstract IndexResult _deleteIndex(String id) throws SearchException;
477        
478            @Override
479            public final Resource getPath() {
480                    return path;
481            }
482    
483        @Override
484        public DateTime getCreated() {
485            return created;
486        }
487        
488            @Override
489            public final DateTime getLastUpdate() {
490                    return lastUpdate;
491            }
492    
493            @Override
494            public final String getName() {
495                    return name;
496            } 
497            
498        @Override
499        public final Log getLogger() {
500            return log;
501        }
502        
503        @Override
504        public final SearchEngine getSearchEngine() {
505            return searchEngine;
506        }
507    
508        /**
509         * change the last update attribute and store it
510         * @throws SearchException
511         */
512        private void changeLastUpdate() throws SearchException {
513            lastUpdate=new DateTimeImpl();
514            searchEngine.store();
515        }
516        
517        @Override
518        public Object created() {
519            return created;
520        }
521    
522        @Override
523        public final int search(SearchData data, Query qry,String criteria, String language, short type,int startrow,int maxrow,String categoryTree, String[] categories) throws SearchException, PageException {
524            int len=qry.getRecordcount();
525            SearchResulItem[] records;
526            
527            AddionalAttrs aa = AddionalAttrs.getAddionlAttrs();
528            boolean hasRowHandling=false;
529            aa.setStartrow(startrow);
530            if(maxrow!=-1)aa.setMaxrows(maxrow-len);
531            
532            Lock l = lock();
533            try {
534                    records = _search(data, criteria,language,type,categoryTree,categories);
535            }
536            finally {
537                    unlock(l);
538                    if(hasRowHandling=aa.hasRowHandling())
539                            startrow = aa.getStartrow();
540                    
541            }
542            
543            
544            
545            // Startrow
546            if(!hasRowHandling && startrow>1) {
547                
548                    if(startrow>records.length) {
549                    return startrow-records.length;
550                }
551                int start=startrow-1;
552                
553                SearchResulItem[] tmpRecords=new SearchResulItem[records.length-start];
554                for(int i=start;i<records.length;i++) {
555                    tmpRecords[i-start]=records[i];
556                }
557                records=tmpRecords;
558                startrow=1;
559            }
560            
561            
562            if(!ArrayUtil.isEmpty(records)) {
563                
564                int to=(!hasRowHandling && maxrow>-1 && len+records.length>maxrow)?maxrow-len:records.length;
565                qry.addRow(to);
566                
567                String title;
568                String custom1;
569                String custom2;
570                String custom3;
571                String custom4;
572                String url;
573                SearchResulItem record;
574                SearchIndex si;
575                for(int y=0;y<to;y++) {
576                            
577                    int row=len+y+1;
578                    record = records[y];
579                    si=(SearchIndex)indexes.get(record.getId());
580    
581                    title=record.getTitle();
582                    custom1=record.getCustom1();
583                    custom2=record.getCustom2();
584                    custom3=record.getCustom3();
585                    custom4=record.getCustom4();
586                    url=record.getUrl();
587                    
588                    qry.setAt("title",row,title);
589                    qry.setAt("custom1",row,custom1);
590                    qry.setAt("custom2",row,custom2);
591                    qry.setAt("custom3",row,custom3);
592                    qry.setAt("custom4",row,custom4);
593                    qry.setAt("categoryTree",row,record.getCategoryTree());
594                    qry.setAt("category",row,record.getCategory());
595                    qry.setAt("type",row,record.getMimeType());
596                    qry.setAt("author",row,record.getAuthor());
597                    qry.setAt("size",row,record.getSize());
598    
599                    qry.setAt("summary",row,record.getSummary());
600                    qry.setAt("context",row,record.getContextSummary());
601                    qry.setAt("score",row,new Float(record.getScore()));
602                    qry.setAt("key",row,record.getKey());
603                    qry.setAt("url",row,url);
604                    qry.setAt("collection",row,getName());
605                    qry.setAt("rank",row,new Double(row));
606                    String rootPath,file;
607                    String urlPath;
608                    if(si!=null) {
609                            switch(si.getType()){
610                            case SearchIndex.TYPE_PATH:
611                                    rootPath = si.getKey();
612                                    rootPath=rootPath.replace(FileUtil.FILE_ANTI_SEPERATOR,FileUtil.FILE_SEPERATOR);
613                                    file=record.getKey();
614                                    file=file.replace(FileUtil.FILE_ANTI_SEPERATOR,FileUtil.FILE_SEPERATOR);
615                                    qry.setAt("url",row,toURL(si.getUrlpath(),StringUtil.replace(file, rootPath, "", true)));
616                                    
617                                    
618                            break;
619                            case SearchIndex.TYPE_URL:
620                                    rootPath = si.getKey();
621                                    urlPath = si.getUrlpath();
622                                    try {
623                                            rootPath = getDirectory(si.getKey());
624                                                    } 
625                                    catch (MalformedURLException e) {}
626                                    if(StringUtil.isEmpty(urlPath))urlPath=rootPath;
627                                    file=record.getKey();
628                                    qry.setAt("url",row,toURL(urlPath,StringUtil.replace(file, rootPath, "", true)));
629                                    
630                                    
631                            break;
632                            default:
633                                    qry.setAt("url",row,toURL(si.getUrlpath(),url));
634                            break;
635                            }
636                            
637                            
638                        if(StringUtil.isEmpty(title))      qry.setAt("title",row,si.getTitle());
639                        if(StringUtil.isEmpty(custom1))    qry.setAt("custom1",row,si.getCustom1());
640                        if(StringUtil.isEmpty(custom2))    qry.setAt("custom2",row,si.getCustom2());
641                        if(StringUtil.isEmpty(custom3))    qry.setAt("custom3",row,si.getCustom3());
642                        if(StringUtil.isEmpty(custom4))    qry.setAt("custom4",row,si.getCustom4());
643                        
644                    }
645                }
646            }
647            return startrow;
648        }
649    
650        public static String getDirectory(String strUrl) throws MalformedURLException {
651            URL url = new URL(strUrl);
652            String path=url.getPath(); 
653            int slashIndex = path.lastIndexOf('/');
654            int dotIndex = path.lastIndexOf('.');
655            // no dot
656            if(dotIndex==-1){
657                    if(path.endsWith("/"))return HTTPUtil.removeRef(url).toExternalForm();
658                    return HTTPUtil.removeRef(new URL(
659                                    url.getProtocol(),
660                                    url.getHost(),
661                                    url.getPort(),path+"/")).toExternalForm();
662            }
663            if(slashIndex>dotIndex){
664                    path=path.substring(0,dotIndex);
665                    slashIndex = path.lastIndexOf('/');
666            }
667            
668            return HTTPUtil.removeRef(new URL(
669                                    url.getProtocol(),
670                                    url.getHost(),
671                                    url.getPort(),path.substring(0,slashIndex+1))).toExternalForm();
672            }
673    
674            private static String toURL(String url, String path) {
675            if(StringUtil.isEmpty(url)) return path;
676            if(StringUtil.isEmpty(path)) return url;
677            
678            url=url.replace('\\','/');
679            path=path.replace('\\','/');
680            if(StringUtil.startsWith(path, '/'))path=path.substring(1);
681            if(StringUtil.endsWith(url, '/'))url=url.substring(0,url.length()-1);
682            
683            if(StringUtil.startsWithIgnoreCase(path, url))
684                    return path;
685            return url+"/"+path;
686        }
687        
688            
689            
690            
691    
692        protected SearchIndex[] getIndexes() {
693            Iterator it = indexes.keySet().iterator();
694                    int len=indexes.size();
695                    SearchIndex[] rtn=new SearchIndex[len];
696                    int count=0;
697                    while(it.hasNext()) {
698                            rtn[count++]=(SearchIndex) indexes.get(it.next());
699                    }
700                    return rtn;
701            }
702    
703    
704        private Lock lock() throws SearchException {
705                    try {
706                            return lock.lock(getId(),LOCK_TIMEOUT);
707                            //manager.lock(LockManager.TYPE_EXCLUSIVE,getId(),LOCK_TIMEOUT,ThreadLocalPageContext.get().getId());
708                    } 
709                    catch (Exception e) {
710                            throw new SearchException(e);
711                    }
712                    
713            }
714    
715            private void unlock(Lock l) {
716                    lock.unlock(l);
717                    //manager.unlock(ThreadLocalPageContext.get().getId());
718            }
719    
720    
721            private String getId() {
722                    return path.getRealResource(name).getAbsolutePath();
723            }
724    
725            // FUTURE
726            public Object getIndexesAsQuery() {
727                    Iterator it = indexes.entrySet().iterator();
728                    
729                    final String v="VARCHAR";
730            Query query=null;
731            String[] cols = new String[]{
732                            "categories","categoryTree","custom1","custom2","custom3","custom4","extensions",
733                            "key","language","query","title","urlpath","type"};
734            String[] types = new String[]{
735                            v,v,v,v,v,v,v,
736                            v,v,v,v,v,v};
737            try {
738                query=new QueryImpl(cols,types, 0,"query");
739            } catch (DatabaseException e) {
740                query=new QueryImpl(cols, 0,"query");
741            }
742            
743                
744            Map.Entry entry;
745            SearchIndex index;
746            int row=0;
747                    while(it.hasNext()) {
748                            query.addRow();
749                            row++;
750                    entry=(Entry) it.next();
751                    index=(SearchIndex) entry.getValue();
752                    if(index==null)continue;
753                    try {
754                            
755                    query.setAt("categories",row,ListUtil.arrayToList(index.getCategories(),""));
756                    query.setAt("categoryTree",row,index.getCategoryTree());
757                    
758                    query.setAt("custom1",row,index.getCustom1());
759                    query.setAt("custom2",row,index.getCustom2());
760                    query.setAt("custom3",row,index.getCustom3());
761                    query.setAt("custom4",row,index.getCustom4());
762                    
763                    query.setAt("extensions",row,ListUtil.arrayToList(index.getExtensions(),","));
764                    query.setAt("key",row,index.getKey());
765                    query.setAt("language",row,index.getLanguage());
766                    query.setAt("query",row,index.getQuery());
767                    query.setAt("title",row,index.getTitle());
768                    query.setAt("urlpath",row,index.getUrlpath());
769                    query.setAt("type",row,SearchIndex.toStringTypeEL(index.getType()));
770                    
771                    }
772                        catch(PageException pe) {}
773                }
774                    return query;
775            }
776    
777    }