001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.javascript.search;
034:
035: import com.flexive.faces.beans.ResultSessionData;
036: import com.flexive.faces.model.FxResultSetDataModel;
037: import com.flexive.shared.EJBLookup;
038: import com.flexive.shared.search.AdminResultLocations;
039: import com.flexive.shared.search.FxFoundType;
040: import com.flexive.shared.search.FxResultSet;
041: import com.flexive.shared.search.ResultViewType;
042: import static com.flexive.shared.search.ResultViewType.THUMBNAILS;
043: import com.flexive.shared.search.query.SqlQueryBuilder;
044: import com.flexive.war.JsonWriter;
045: import org.apache.commons.logging.Log;
046: import org.apache.commons.logging.LogFactory;
047:
048: import javax.servlet.http.HttpSession;
049: import java.io.IOException;
050: import java.io.Serializable;
051: import java.io.StringWriter;
052: import java.util.AbstractMap;
053: import java.util.Map;
054: import java.util.Set;
055:
056: /**
057: * Provides map interfaces for generating JSON row and column information
058: * from a FxResultSet.
059: *
060: * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
061: * @version $Rev: 1 $
062: */
063: public class SearchResultWriter implements Serializable {
064: private static final long serialVersionUID = -4200104398592163875L;
065: private static final Log LOG = LogFactory
066: .getLog(SearchResultWriter.class);
067:
068: /**
069: * Return a map for generating column JSON code.
070: * e.g. #{searchResultJsonBean.columns[myResultSet]}
071: *
072: * @return a map for generating column JSON code.
073: */
074: public Map getColumns() {
075: return new ColumnDataMap();
076: }
077:
078: /**
079: * Return a map for generating the rows contained in a result set.
080: * e.g. #{searchResultJsonBean.rows[myResultSet]}
081: *
082: * @return a map for generating the rows contained in a result set.
083: */
084: public Map getRows() {
085: return new RowDataMap();
086: }
087:
088: /**
089: * Return the rows of the user's current search result (SearchResultBean).
090: *
091: * @param session the current user session (json/rpc auto parameter)
092: * @param location location of the search result ({@link com.flexive.shared.search.AdminResultLocations}).
093: * @param startRow first row to be returned
094: * @param fetchRows number of rows to be fetched (must be a valid enum value of {@link ResultViewType})
095: * @param gridColumns number of columns on the grid (for thumbnail views)
096: * @param viewTypeName the view type
097: * @param typeId the type filter (-1 to show all types)
098: * @return the rows of the user's current search result (SearchResultBean).
099: */
100: public String getCurrentResultRows(HttpSession session,
101: String location, int startRow, int fetchRows,
102: int gridColumns, String viewTypeName, long typeId) {
103: StringWriter out = new StringWriter();
104: try {
105: if (viewTypeName.indexOf("::") != -1) {
106: // if the fully qualified enum id is supplied, extract the enum value
107: viewTypeName = viewTypeName.substring(viewTypeName
108: .indexOf("::") + 2);
109: }
110: final ResultViewType viewType = ResultViewType
111: .valueOf(viewTypeName);
112: // get session data from the HTTP session since the faces context is not available
113: final ResultSessionData sessionData = ResultSessionData
114: .getSessionData(session, AdminResultLocations
115: .valueOf(location));
116: // update startrow and fetchrows
117: sessionData.setStartRow(startRow);
118: sessionData.setFetchRows(fetchRows);
119: sessionData.setTypeId(typeId);
120: SqlQueryBuilder queryBuilder = sessionData
121: .getQueryBuilder();
122: queryBuilder.filterType(typeId);
123: //queryBuilder.orderBy(sortColumn + SqlQueryBuilder.COL_USERPROPS, sortDirection == 0);
124: // execute search
125: FxResultSetDataModel resultModel = new FxResultSetDataModel(
126: EJBLookup.getSearchEngine(), queryBuilder,
127: startRow, fetchRows);
128: resultModel
129: .setGridColumns(THUMBNAILS.equals(viewType) ? gridColumns
130: : 1);
131: final JsonWriter writer = new JsonWriter(out);
132: writer.startMap();
133: writer.writeAttribute("totalRows", resultModel
134: .getRowCount());
135: writer.writeAttribute("startRow", startRow);
136: writer.writeAttribute("fetchRows", fetchRows);
137: writer.startAttribute("columns");
138: TableDataWriter.getInstance(writer, viewType).writeColumns(
139: resultModel);
140: writer.startAttribute("rows");
141: TableDataWriter.getInstance(writer, viewType).writeRows(
142: resultModel);
143: writeUpdatedTypeCounts(writer, resultModel);
144: writer.closeMap();
145: sessionData.setContentTypes(resultModel.getResult()
146: .getContentTypes());
147: return out.toString();
148: } catch (Exception e) {
149: LOG.error(e, e);
150: return "[]";
151: }
152: }
153:
154: /**
155: * Writes the current type counts for each found content type.
156: *
157: * @param writer the target writer
158: * @param resultModel the result model
159: * @throws IOException if the output could not be written
160: */
161: private void writeUpdatedTypeCounts(JsonWriter writer,
162: FxResultSetDataModel resultModel) throws IOException {
163: writer.startAttribute("typeCounts");
164: writer.startMap();
165: for (FxFoundType type : resultModel.getResult()
166: .getContentTypes()) {
167: writer.writeAttribute(String.valueOf(type
168: .getContentTypeId()), type.getFoundEntries());
169: }
170: writer.closeMap();
171: }
172:
173: private static class ColumnDataMap extends
174: AbstractMap<FxResultSet, String> {
175: /**
176: * {@inheritDoc}
177: */
178: @Override
179: public Set<Entry<FxResultSet, String>> entrySet() {
180: return null;
181: }
182:
183: /**
184: * {@inheritDoc}
185: */
186: @Override
187: public String get(Object key) {
188: FxResultSetDataModel resultSetModel = getDataModel(key);
189: StringWriter out = new StringWriter();
190: try {
191: TableDataWriter.getInstance(out,
192: resultSetModel.getResult().getViewType())
193: .writeColumns(resultSetModel);
194: } catch (IOException e) {
195: LOG.error(e, e);
196: }
197: return out.toString();
198: }
199:
200: }
201:
202: private static final class RowDataMap extends
203: AbstractMap<FxResultSet, String> {
204: /**
205: * {@inheritDoc}
206: */
207: @Override
208: public Set<Entry<FxResultSet, String>> entrySet() {
209: return null;
210: }
211:
212: /**
213: * {@inheritDoc}
214: */
215: @Override
216: public String get(Object key) {
217: FxResultSetDataModel resultSetModel = getDataModel(key);
218: StringWriter out = new StringWriter();
219: try {
220: TableDataWriter.getInstance(out,
221: resultSetModel.getResult().getViewType())
222: .writeRows(resultSetModel);
223: } catch (IOException e) {
224: LOG.error(e, e);
225: }
226: return out.toString();
227: }
228:
229: }
230:
231: /**
232: * Return a FxResultSetDataModel stored in key. Possibly create a new
233: * model wrapper if a plain result set was passed.
234: *
235: * @param key the (map) key to be used for creating the data model
236: * @return a result set data model
237: */
238: private static FxResultSetDataModel getDataModel(Object key) {
239: if (key instanceof FxResultSet) {
240: // create a new model
241: return new FxResultSetDataModel((FxResultSet) key);
242: } else {
243: // use existing model
244: return (FxResultSetDataModel) key;
245: }
246: }
247: }
|