KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > search > JahiaSearchResultHandlerImpl


1 //
2
// ____.
3
// __/\ ______| |__/\. _______
4
// __ .____| | \ | +----+ \
5
// _______| /--| | | - \ _ | : - \_________
6
// \\______: :---| : : | : | \________>
7
// |__\---\_____________:______: :____|____:_____\
8
// /_____|
9
//
10
// . . . i n j a h i a w e t r u s t . . .
11
//
12
package org.jahia.services.search;
13
14 import java.util.*;
15
16 import org.apache.regexp.RE;
17 import org.apache.regexp.RESyntaxException;
18
19 import org.jahia.data.fields.*;
20 import org.jahia.data.files.*;
21 import org.jahia.data.search.*;
22 import org.jahia.gui.GuiBean;
23 import org.jahia.params.ParamBean;
24 import org.jahia.registries.ServicesRegistry;
25 import org.jahia.services.acl.*;
26 import org.jahia.services.usermanager.*;
27 import org.jahia.services.fields.*;
28 import org.jahia.services.pages.*;
29 import org.jahia.services.version.*;
30 import org.jahia.exceptions.JahiaException;
31
32 /**
33  * Default implementation to build JahiaSearchResult from a collection of ParsedObject
34  *
35  * @author NK
36  */

37 public class JahiaSearchResultHandlerImpl implements JahiaSearchResultHandler
38 {
39
40     private static org.apache.log4j.Logger logger =
41             org.apache.log4j.Logger.getLogger (JahiaSearchResultHandlerImpl.class);
42
43     public static final String JavaDoc ONE_HIT_BY_PAGE_PARAMETER_NAME =
44         "JahiaSearchResultHandlerImpl.oneHitByPage";
45
46     public JahiaSearchResultHandlerImpl(){}
47
48     /**
49      * build Search result from a collection of ParsedObject instance
50      * The result is the one returned by doPageSearch(Collection parsedObjects,
51      * ParamBean jParams);
52      * @param hits Hits
53      * @param jParams ParamBean
54      * @return JahiaSearchResult
55      */

56     public JahiaSearchResult buildResult(Collection parsedObjects,
57                                                 ParamBean jParams){
58
59         String JavaDoc val = jParams.getRequest().getParameter(ONE_HIT_BY_PAGE_PARAMETER_NAME);
60         boolean oneHitByPage = ( val == null || "true".equalsIgnoreCase(val) );
61
62         return buildSearchResult(parsedObjects,jParams,oneHitByPage);
63      }
64
65  /**
66    * build Search result from a collection of ParsedObject instance
67    *
68    *
69    * @param parsedObjects Collection
70    * @param jParams ParamBean
71    * @param oneHitByPage boolean, if true, hits are grouped by page and only one hit is keep for each matched page
72    * @return JahiaSearchResult
73    */

74   public JahiaSearchResult buildSearchResult( Collection parsedObjects,
75                                               ParamBean jParams,
76                                               boolean oneHitByPage){
77
78     Hashtable hitScores = new Hashtable();
79
80         JahiaSearchResult result = new JahiaSearchResult (this,null);
81
82        if (parsedObjects == null || parsedObjects.isEmpty())
83            return result;
84
85        ServicesRegistry sReg = ServicesRegistry.getInstance();
86        JahiaField aField = null;
87        ContentField contentField = null;
88        JahiaPage aPage = null;
89        JahiaUser currentUser = jParams.getUser();
90        JahiaSearchHit info;
91
92        String JavaDoc fieldIDVal = null;
93        String JavaDoc pageIDVal = null;
94        String JavaDoc languageCodeVal = null;
95        String JavaDoc workflowStateVal = null;
96        boolean found = false;
97        int pagecount = 0;
98        ParsedObject parsedObject = null;
99
100
101         Iterator iterator = parsedObjects.iterator();
102         HashMap ramIndexedDocuments = new HashMap();
103         HashMap filteredDocument = new HashMap();
104         String JavaDoc key = null;
105         while ( iterator.hasNext() ){
106             parsedObject = (ParsedObject)iterator.next();
107             if ( "1".equals(parsedObject.getValue(JahiaSearchBaseService.RAM_INDEXER_DOCUMENT)) ){
108                 ramIndexedDocuments.put(parsedObject.getValue(JahiaSearchConstant.FIELD_KEY),parsedObject);
109             } else {
110                 filteredDocument.put(parsedObject.getValue(JahiaSearchConstant.FIELD_KEY),parsedObject);
111             }
112         }
113         iterator = ramIndexedDocuments.keySet().iterator();
114         while ( iterator.hasNext() ){
115             key = (String JavaDoc)iterator.next();
116             if ( !filteredDocument.containsKey(key) ){
117                 filteredDocument.put(key,ramIndexedDocuments.get(key));
118             }
119         }
120
121         Vector effectiveParsedObjects = new Vector();
122        iterator = filteredDocument.values().iterator();
123        while ( iterator.hasNext() ){
124            info = null;
125            fieldIDVal = null;
126            pageIDVal = null;
127            contentField = null;
128            aField = null;
129            aPage = null;
130
131            try {
132                parsedObject = (ParsedObject)iterator.next();
133                fieldIDVal = parsedObject.getValue(JahiaSearchConstant.FIELD_FIELDID);
134                languageCodeVal = parsedObject.getValue(JahiaSearchConstant.FIELD_LANGUAGE_CODE);
135                workflowStateVal = parsedObject.getValue(JahiaSearchConstant.FIELD_WORKFLOW_STATE);
136                int ws = Integer.parseInt (workflowStateVal);
137
138                if (fieldIDVal != null) {
139                    contentField = ContentField.getField (Integer.parseInt (fieldIDVal));
140                    if (processField(contentField,ws,languageCodeVal,jParams)) {
141                        pageIDVal = parsedObject.getValue(JahiaSearchConstant.FIELD_PAGEID);
142
143                        aPage = null;
144                        int pageId = 0;
145                        try {
146                            pageId = Integer.parseInt (pageIDVal);
147                            if ( contentField.getType() != FieldTypes.PAGE ) {
148                                 // use the parent page of the field
149
aPage = sReg.getJahiaPageService ()
150                                     .lookupPage (pageId, jParams);
151                            } else {
152                                pageId = Integer.parseInt (contentField.getValue(jParams));
153                                // use the target page of the field
154
aPage = sReg.getJahiaPageService ()
155                                    .lookupPage (pageId,jParams);
156                                if ( aPage.getPageType() != JahiaPage.TYPE_DIRECT ) {
157                                    // its an url, use the parent page to display the link
158
pageId = Integer.parseInt (pageIDVal);
159                                    aPage = sReg.getJahiaPageService ()
160                                        .lookupPage (pageId, jParams);
161                                }
162                            }
163                        } catch ( Throwable JavaDoc t) {
164                            logger.debug("Page not found pageId=" + pageId);
165                        }
166
167                        // security check over the field and the corresponding page
168
JahiaBaseACL acl = new JahiaBaseACL (contentField.getAclID ());
169                        if (aPage != null && aPage.checkReadAccess (currentUser)
170                                && acl.getPermission (currentUser, JahiaBaseACL.READ_RIGHTS)) {
171
172                            effectiveParsedObjects.add(parsedObject);
173
174                            found = false;
175                            for (int j = 0; j < result.getHitCount(); j++) { // page already found
176
JahiaSearchHit searchHit = (JahiaSearchHit)
177                                    result.results()
178                                    .elementAt(j);
179                                if (searchHit.id == aPage.getID()) {
180                                    found = true;
181                                    if ( oneHitByPage ){
182                                        searchHit.wordcount += 1;
183                                        try {
184                                            String JavaDoc languageCode = (String JavaDoc)
185                                                parsedObject.getValue(
186                                                JahiaSearchConstant.
187                                                FIELD_LANGUAGE_CODE);
188                                            if (!searchHit.languageCodes.
189                                                contains(languageCode)) {
190                                                searchHit.languageCodes.add(
191                                                    languageCode);
192                                            }
193                                        }
194                                        catch (Throwable JavaDoc t) {
195                                        }
196                                    } else {
197                                        if ( contentField.getType() != FieldTypes.FILE ){
198                                            searchHit.wordcount += 1;
199
200                                            List hitScoreList = (List)hitScores.get(new Integer JavaDoc(j+1));
201                                            int hitScore = 0;
202                                            if ( hitScoreList == null ){
203                                                 hitScoreList = new ArrayList();
204                                            }
205                                            hitScoreList.add(new Float JavaDoc(parsedObject.getScore()));
206
207                                            /*
208                                            (searchHit.
209                                                wordcount + new Float(parsedObject.getScore() *
210                                                100).intValue()) / 2;*/

211                                        }
212                                    }
213                                    break;
214                                }
215                            }
216
217                            if ( !oneHitByPage || (oneHitByPage && !found) ) {
218                                if ( !oneHitByPage ){
219                                    if ( contentField.getType() == FieldTypes.FILE )
220                                    {
221                                         info = new JahiaSearchHit (parsedObject);
222                                         info.wordcount = new Float JavaDoc(parsedObject.
223                                            getScore() * 100).intValue();
224                                    } else if ( !found ){
225                                         info = new JahiaSearchHit (parsedObject);
226                                         info.wordcount = 1;
227                                    } else {
228                                        continue;
229                                    }
230                                } else {
231                                    info = new JahiaSearchHit (parsedObject);
232                                    info.wordcount = 1;
233                                }
234
235                                info.id = aPage.getID ();
236                                info.obj = aPage;
237
238                                //Keep for backward compatibility ---------------------------
239
info.page = aPage;
240                                //-----------------------------------------------------------
241

242                                info.pageID = aPage.getID ();
243
244                                float scoreFactor = 1.0f;
245
246                                aField =
247                                        sReg.getJahiaFieldService ().loadField (
248                                                Integer.parseInt (fieldIDVal), jParams);
249
250                                String JavaDoc value = "";
251                                if (aField != null) {
252                                    info.type = aField.getType ();
253                                    if (aField.getType () == FieldTypes.PAGE) {
254                                        JahiaPage fieldPage = (JahiaPage) aField.getObject ();
255                                        if (fieldPage != null) {
256                                            value = fieldPage.getTitle ();
257                                            try {
258                                                if (fieldPage.getPageType () == JahiaPage.TYPE_URL) {
259                                                    scoreFactor = 0.3f;
260                                                    info.pageUrl = fieldPage.getRemoteURL();
261                                                } else if (fieldPage.getPageType () == JahiaPage.TYPE_DIRECT) {
262                                                     info.pageUrl = fieldPage.getURL(jParams);
263                                                } else {
264                                                    scoreFactor = 0.1f;
265                                                    info.pageUrl = aPage.getURL(jParams);
266                                                }
267                                            } catch ( Throwable JavaDoc t ){
268                                            }
269                                        }
270                                    } else if (aField.getType () != FieldTypes.FILE) {
271                                        value = aField.getValue ();
272                                    } else {
273                                        JahiaFileField fField = (JahiaFileField) aField.getObject ();
274                                        if (fField != null) {
275                                            info.fileDownloadUrl = fField.getDownloadUrl ();
276                                            value = fField.getRealName ();
277                                        }
278                                    }
279                                }
280                                if (value != null) {
281                                    try {
282                                        value = (new RE ("<(.*?)>")).subst (value, "");
283                                    } catch (RESyntaxException e) {
284                                        logger.error (e);
285                                    } catch (Throwable JavaDoc t) {
286                                        logger.error (t);
287                                    }
288                                    info.teaser =
289                                            GuiBean.glueTitle (value,
290                                                    JahiaSearchConstant.TEASER_LENGTH);
291                                } else {
292                                    info.teaser = "";
293                                }
294                                try {
295                                    String JavaDoc languageCode = (String JavaDoc) parsedObject.getValue(
296                                            JahiaSearchConstant.FIELD_LANGUAGE_CODE);
297                                    if (!info.languageCodes.contains (languageCode)) {
298                                        info.languageCodes.add (languageCode);
299                                    }
300                                } catch (Throwable JavaDoc t) {
301                                }
302                                result.addHit (info);
303                                List hitScoreList = new ArrayList();
304                                hitScoreList.add(new Float JavaDoc(parsedObject.getScore() * scoreFactor));
305                                hitScores.put(new Integer JavaDoc(result.getHitCount()),hitScoreList);
306                                pagecount++;
307                            }
308                        }
309                    }
310                }
311            } catch (Throwable JavaDoc t) {
312                logger.debug(t);
313            }
314        }
315
316        if ( !oneHitByPage ){
317            // compute score overage
318
for (int j = 0; j < result.getHitCount(); j++) {
319                JahiaSearchHit searchHit = (JahiaSearchHit)
320                                           result.results().elementAt(j);
321                List hitScoreList = (List) hitScores.get(new Integer JavaDoc(j + 1));
322                iterator = hitScoreList.iterator();
323                Float JavaDoc score = null;
324                float f = 0;
325                if (searchHit.type != FieldTypes.FILE) {
326                    while (iterator.hasNext()) {
327                        score = (Float JavaDoc) iterator.next();
328                        f += score.floatValue();
329                    }
330                    searchHit.wordcount = new Float JavaDoc((f * 100) / hitScoreList.size()).intValue();
331                }
332            }
333        }
334
335         result.setParsedObjects(effectiveParsedObjects);
336
337        // sort the result
338
if (result.getHitCount () > 1) {
339            Collections.sort(result.results ());
340        }
341
342        //Keep for backward compatibility ---------------------------
343
result.pagecount = pagecount;
344        result.pages = result.results ();
345        //-----------------------------------------------------------
346

347        return result;
348    }
349
350    private boolean processField(ContentField contentField,
351                                 int workflowState,
352                                 String JavaDoc languageCodeVal,
353                                 ParamBean jParams) throws JahiaException {
354        boolean processField = false;
355
356        if ( contentField.getActiveAndStagingEntryStates().size() == 0 ){
357            return false;
358        }
359        if ( jParams.getEntryLoadRequest ().isCurrent ()
360             && workflowState == EntryLoadRequest.ACTIVE_WORKFLOW_STATE
361             && contentField.hasActiveEntries()){
362            processField = true;
363        } else if ( jParams.getEntryLoadRequest().isStaging()
364                   && !contentField.isMarkedForDelete() ){
365            if (workflowState > EntryLoadRequest.ACTIVE_WORKFLOW_STATE &&
366                (contentField.hasStagingEntryIgnoreLanguageCase (languageCodeVal) )) {
367                    // accept staging only if really has staged in the given languageCode
368
processField = true;
369            } else if (workflowState == EntryLoadRequest.ACTIVE_WORKFLOW_STATE &&
370                       !contentField.hasStagingEntryIgnoreLanguageCase(languageCodeVal)) {
371                // accept active only if field doesn't exist in staging
372
processField = true;
373            }
374        }
375        return processField;
376    }
377
378    //--------------------------------------------------------------------------
379
/**
380      * build Search result from a collection of ParsedObject instance
381      * A JahiaSearchHit is mapped to a Container
382      *
383      * @param parsedObjects Collection
384      * @param jParams ParamBean
385      * @param oneHitByPage boolean, if true, hits are grouped by page and only one hit is keep for each matched page
386      * @return JahiaSearchResult
387      */

388     public JahiaSearchResult buildContainerSearchResult (Collection parsedObjects,
389                                                           boolean oneHitByContainer,
390                                                           ParamBean jParams) {
391
392     JahiaSearchResult result = new JahiaSearchResult (this,parsedObjects);
393
394     if (parsedObjects == null || parsedObjects.isEmpty())
395         return result;
396
397        ServicesRegistry sReg = ServicesRegistry.getInstance ();
398        JahiaField aField = null;
399        Object JavaDoc obj = null;
400        int objID = 0;
401        JahiaUser currentUser = jParams.getUser ();
402        JahiaSearchHit info;
403
404        String JavaDoc fieldIDVal = null;
405        boolean found = false;
406
407        ParsedObject parsedObject = null;
408        String JavaDoc languageCodeVal = null;
409        String JavaDoc workflowStateVal = null;
410
411        Iterator iterator = parsedObjects.iterator();
412        while ( iterator.hasNext() ){
413            try {
414                parsedObject = (ParsedObject)iterator.next();
415                Hashtable fields = parsedObject.getFields();
416                fieldIDVal = parsedObject.getValue(JahiaSearchConstant.FIELD_FIELDID);
417                languageCodeVal = parsedObject.getValue(JahiaSearchConstant.FIELD_LANGUAGE_CODE);
418                workflowStateVal = parsedObject.getValue(JahiaSearchConstant.FIELD_WORKFLOW_STATE);
419                int ws = Integer.parseInt (workflowStateVal);
420
421                if (fieldIDVal != null) {
422                    ContentField contentField = ContentField.getField (Integer.parseInt (fieldIDVal));
423                    if (processField(contentField,ws,languageCodeVal,jParams)) {
424                        aField = sReg.getJahiaFieldService ().loadField (
425                                        Integer.parseInt (fieldIDVal), jParams);
426                    }
427                }
428            } catch (Throwable JavaDoc t) {
429                //
430
}
431
432            // security check over the field.
433
if ((aField != null) && aField.checkReadAccess (currentUser)) {
434                found = false;
435                if ( oneHitByContainer ){
436                    int size = result.results().size();
437                    for (int j = 0; j < size; j++) { // page already found
438
if ( ( (JahiaSearchHit) result.results().elementAt(j)).
439                            id == aField.getctnid()) {
440                            ( (JahiaSearchHit) result.results().elementAt(j)).
441                                wordcount += 1;
442                            found = true;
443                            break;
444                        }
445                    }
446                }
447
448                objID = aField.getctnid ();
449
450                if ( !found || (oneHitByContainer && !found) ) {
451                    info = new JahiaSearchHit (parsedObject);
452                    if ( oneHitByContainer ){
453                        info.wordcount = 1;
454                    } else {
455                        info.wordcount = new Float JavaDoc(parsedObject.getScore() * 100).intValue();
456                    }
457
458                    info.id = objID;
459                    info.obj = new Integer JavaDoc (objID); // actually we do not load container
460

461                    String JavaDoc value = aField.getValue ();
462                    if (value != null) {
463                        try {
464                            value = (new RE ("<(.*?)>")).subst (value, "");
465                        } catch (RESyntaxException e) {
466                            logger.error (e);
467                        } catch (Throwable JavaDoc t) {
468                            logger.error (t);
469                        }
470                        info.teaser =
471                                GuiBean.glueTitle (value, JahiaSearchConstant.TEASER_LENGTH);
472
473                    } else {
474                        info.teaser = "";
475                    }
476                    info.pageID = aField.getPageID();
477                    result.addHit (info);
478                }
479            }
480            fieldIDVal = null;
481            aField = null;
482            obj = null;
483        }
484
485        // sort the result
486
if (result.results ().size () > 1) {
487            Collections.sort (result.results ());
488        }
489
490        return result;
491    }
492
493    /**
494     * Build the map of JahiaSearchHits by page, see @JahiaSearchResult#hitsByPage
495     *
496     * @param parsedObjects Collection a collection of ParsedObject instance
497     * @param jParams ParamBean
498     * @return JahiaSearchResult
499     */

500    public Map groupResultByPage(JahiaSearchResult jahiaSearchResult){
501        HashMap map = new HashMap();
502        if ( jahiaSearchResult == null ){
503            return new HashMap();
504        }
505        Vector hits = jahiaSearchResult.results();
506        if ( hits == null ){
507            return new HashMap();
508        }
509        int size = hits.size();
510        JahiaSearchHit hit = null;
511        int pageId = 0;
512        Vector v = null;
513        for ( int i=0; i<size; i++ ){
514            hit = (JahiaSearchHit)hits.get(i);
515            Integer JavaDoc pageID = new Integer JavaDoc(hit.pageID);
516            v = (Vector)map.get(pageID);
517            if ( v == null ){
518                v = new Vector();
519            }
520            v.add(hit);
521            map.put(pageID,v);
522        }
523        return map;
524    }
525
526 }
527
Popular Tags