001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.search.facet;
016    
017    import com.liferay.portal.kernel.json.JSONArray;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.search.BooleanClause;
023    import com.liferay.portal.kernel.search.BooleanClauseFactoryUtil;
024    import com.liferay.portal.kernel.search.BooleanClauseOccur;
025    import com.liferay.portal.kernel.search.BooleanQuery;
026    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
027    import com.liferay.portal.kernel.search.Field;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerPostProcessor;
030    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
031    import com.liferay.portal.kernel.search.SearchContext;
032    import com.liferay.portal.kernel.search.SearchEngineUtil;
033    import com.liferay.portal.kernel.search.facet.config.FacetConfiguration;
034    import com.liferay.portal.kernel.util.ArrayUtil;
035    import com.liferay.portal.kernel.util.GetterUtil;
036    import com.liferay.portal.kernel.util.StringUtil;
037    
038    /**
039     * @author Raymond Aug??
040     */
041    public class AssetEntriesFacet extends MultiValueFacet {
042    
043            public AssetEntriesFacet(SearchContext searchContext) {
044                    super(searchContext);
045    
046                    setFieldName(Field.ENTRY_CLASS_NAME);
047    
048                    initFacetClause();
049            }
050    
051            @Override
052            public void setFacetConfiguration(FacetConfiguration facetConfiguration) {
053                    super.setFacetConfiguration(facetConfiguration);
054    
055                    initFacetClause();
056            }
057    
058            @Override
059            protected BooleanClause doGetFacetClause() {
060                    SearchContext searchContext = getSearchContext();
061    
062                    String[] entryClassNames = searchContext.getEntryClassNames();
063    
064                    BooleanQuery facetQuery = BooleanQueryFactoryUtil.create(searchContext);
065    
066                    for (String entryClassName : entryClassNames) {
067                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
068    
069                            if (indexer == null) {
070                                    continue;
071                            }
072    
073                            String searchEngineId = searchContext.getSearchEngineId();
074    
075                            if (!searchEngineId.equals(indexer.getSearchEngineId())) {
076                                    continue;
077                            }
078    
079                            try {
080                                    BooleanQuery indexerBooleanQuery = indexer.getFacetQuery(
081                                            entryClassName, searchContext);
082    
083                                    if ((indexerBooleanQuery == null) ||
084                                            !indexerBooleanQuery.hasClauses()) {
085    
086                                            continue;
087                                    }
088    
089                                    BooleanQuery entityQuery = BooleanQueryFactoryUtil.create(
090                                            searchContext);
091    
092                                    entityQuery.add(indexerBooleanQuery, BooleanClauseOccur.MUST);
093    
094                                    indexer.postProcessContextQuery(entityQuery, searchContext);
095    
096                                    for (IndexerPostProcessor indexerPostProcessor :
097                                                    indexer.getIndexerPostProcessors()) {
098    
099                                            indexerPostProcessor.postProcessContextQuery(
100                                                    entityQuery, searchContext);
101                                    }
102    
103                                    if (indexer.isStagingAware()) {
104                                            if (!searchContext.isIncludeLiveGroups() &&
105                                                    searchContext.isIncludeStagingGroups()) {
106    
107                                                    entityQuery.addRequiredTerm(Field.STAGING_GROUP, true);
108                                            }
109                                            else if (searchContext.isIncludeLiveGroups() &&
110                                                             !searchContext.isIncludeStagingGroups()) {
111    
112                                                    entityQuery.addRequiredTerm(Field.STAGING_GROUP, false);
113                                            }
114                                    }
115    
116                                    if (entityQuery.hasClauses()) {
117                                            facetQuery.add(entityQuery, BooleanClauseOccur.SHOULD);
118                                    }
119                            }
120                            catch (Exception e) {
121                                    _log.error(e, e);
122                            }
123                    }
124    
125                    if (!facetQuery.hasClauses()) {
126                            return null;
127                    }
128    
129                    return BooleanClauseFactoryUtil.create(
130                            searchContext, facetQuery, BooleanClauseOccur.MUST.getName());
131            }
132    
133            protected void initFacetClause() {
134                    SearchContext searchContext = getSearchContext();
135    
136                    FacetConfiguration facetConfiguration = getFacetConfiguration();
137    
138                    JSONObject dataJSONObject = facetConfiguration.getData();
139    
140                    String[] entryClassNames = null;
141    
142                    if (dataJSONObject.has("values")) {
143                            JSONArray valuesJSONArray = dataJSONObject.getJSONArray("values");
144    
145                            entryClassNames = new String[valuesJSONArray.length()];
146    
147                            for (int i = 0; i < valuesJSONArray.length(); i++) {
148                                    entryClassNames[i] = valuesJSONArray.getString(i);
149                            }
150                    }
151    
152                    if (ArrayUtil.isEmpty(entryClassNames)) {
153                            entryClassNames = searchContext.getEntryClassNames();
154                    }
155    
156                    if (!isStatic()) {
157                            String[] entryClassNameParam = StringUtil.split(
158                                    GetterUtil.getString(
159                                            searchContext.getAttribute(getFieldName())));
160    
161                            if (ArrayUtil.isNotEmpty(entryClassNameParam)) {
162                                    entryClassNames = entryClassNameParam;
163                            }
164                    }
165    
166                    if (ArrayUtil.isEmpty(entryClassNames)) {
167                            entryClassNames = SearchEngineUtil.getEntryClassNames();
168    
169                            if (!dataJSONObject.has("values")) {
170                                    JSONArray entriesJSONArray = JSONFactoryUtil.createJSONArray();
171    
172                                    for (String entryClassName : entryClassNames) {
173                                            entriesJSONArray.put(entryClassName);
174                                    }
175    
176                                    dataJSONObject.put("values", entriesJSONArray);
177                            }
178                    }
179    
180                    searchContext.setEntryClassNames(entryClassNames);
181            }
182    
183            private static Log _log = LogFactoryUtil.getLog(AssetEntriesFacet.class);
184    
185    }