View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  /**
24   *
25   */
26  package com.gisgraphy.fulltext;
27  
28  import javax.servlet.http.HttpServletRequest;
29  
30  import com.gisgraphy.domain.geoloc.entity.GisFeature;
31  import com.gisgraphy.domain.valueobject.GisgraphyServiceType;
32  import com.gisgraphy.domain.valueobject.Output;
33  import com.gisgraphy.domain.valueobject.Output.OutputStyle;
34  import com.gisgraphy.domain.valueobject.Pagination;
35  import com.gisgraphy.geoloc.GeolocQuery;
36  import com.gisgraphy.geoloc.GeolocSearchException;
37  import com.gisgraphy.helper.GeolocHelper;
38  import com.gisgraphy.helper.GisHelper;
39  import com.gisgraphy.helper.OutputFormatHelper;
40  import com.gisgraphy.serializer.common.OutputFormat;
41  import com.gisgraphy.service.AbstractGisQuery;
42  import com.gisgraphy.servlet.FulltextServlet;
43  import com.gisgraphy.servlet.GisgraphyServlet;
44  import com.vividsolutions.jts.geom.Point;
45  
46  /**
47   * A Fulltext Query builder. it build Fulltext query from HTTP Request
48   * 
49   * @see Pagination
50   * @see Output
51   * @see IFullTextSearchEngine
52   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
53   */
54  public class FulltextQueryHttpBuilder {
55  	
56  	
57   private static FulltextQueryHttpBuilder instance = new FulltextQueryHttpBuilder();
58   
59   public static FulltextQueryHttpBuilder getInstance(){
60  	 return instance;
61  	 
62   }
63      /**
64       * @param req
65       *                an HttpServletRequest to construct a {@link FulltextQueryHttpBuilder}
66       */
67      public FulltextQuery buildFromRequest(HttpServletRequest req) {
68      	FulltextQuery query = null;
69  	String httpQueryParameter = req.getParameter(FulltextQuery.QUERY_PARAMETER);
70  	if (httpQueryParameter != null){
71  		query = new FulltextQuery(httpQueryParameter.trim());
72  	}
73  	if (httpQueryParameter == null || "".equals(httpQueryParameter.trim())) {
74  	    throw new FullTextSearchException("query is not specified or empty");
75  	}
76  	if (httpQueryParameter.length() > FulltextQuery.QUERY_MAX_LENGTH) {
77  	    throw new FullTextSearchException("query is limited to "
78  		    + FulltextQuery.QUERY_MAX_LENGTH + "characters");
79  	}
80  	
81  	// point
82  	Float latitude=null;
83  	Float longitude=null;
84  	// lat
85  	try {
86  			String latParameter = req.getParameter(FulltextQuery.LAT_PARAMETER);
87  				if (latParameter!=null && !latParameter.trim().equals("")){
88  					
89  					latitude = GeolocHelper.parseInternationalDouble(latParameter);
90  					if (latitude < -90 || latitude > 90){
91  						throw new GeolocSearchException("latitude is not correct"); 
92  					}
93  				} 
94  		} catch (Exception e) {
95  			throw new GeolocSearchException("latitude is not correct");
96  		}
97  
98  	// long
99  	try {
100 	    String longParameter = req
101 		    .getParameter(FulltextQuery.LONG_PARAMETER);
102 	    if (longParameter!=null && !longParameter.trim().equals("")){
103 	    	longitude = GeolocHelper.parseInternationalDouble(longParameter);
104 	    	if (latitude < -180 || latitude > 180){
105 				throw new GeolocSearchException("latitude is not correct"); 
106 			}
107 	    } 
108 	} catch (Exception e) {
109 	    throw new GeolocSearchException(
110 		    "longitude is not correct ");
111 	}
112 	
113 	
114 	// point
115 	
116 	Point point = null ;
117 	try {
118 		if (latitude!=null && longitude!=null ){
119 			point = GeolocHelper.createPoint(longitude, latitude);
120 		} 
121 	} catch (RuntimeException e1) {
122 	    	throw new GeolocSearchException("can not determine Point");
123 	}
124 	query.around(point);
125 	
126 	// radius
127 	double radius;
128 	try {
129 	    radius = GeolocHelper.parseInternationalDouble(req
130 		    .getParameter(FulltextQuery.RADIUS_PARAMETER));
131 	} catch (Exception e) {
132 	    radius = GeolocQuery.DEFAULT_RADIUS;
133 	}
134 	query.withRadius(radius);
135 	
136 	// pagination
137 	Pagination pagination = null;
138 	int from;
139 	int to;
140 	try {
141 	    from = Integer.valueOf(
142 		    req.getParameter(FulltextServlet.FROM_PARAMETER))
143 		    .intValue();
144 	} catch (Exception e) {
145 	    from = Pagination.DEFAULT_FROM;
146 	}
147 
148 	try {
149 	    to = Integer
150 		    .valueOf(req.getParameter(FulltextServlet.TO_PARAMETER))
151 		    .intValue();
152 	} catch (NumberFormatException e) {
153 	    to = from+AbstractGisQuery.DEFAULT_NB_RESULTS-1;
154 	}
155 
156 	pagination = Pagination.paginateWithMaxResults(FulltextQuery.DEFAULT_MAX_RESULTS).from(from).to(to)
157 		.limitNumberOfResults(FulltextQuery.DEFAULT_MAX_RESULTS);
158 	// output
159 	OutputFormat format = OutputFormat.getFromString(req
160 		.getParameter(FulltextServlet.FORMAT_PARAMETER));
161 	format = OutputFormatHelper.getDefaultForServiceIfNotSupported(format, GisgraphyServiceType.FULLTEXT);
162 	OutputStyle style = OutputStyle.getFromString(req
163 		.getParameter(FulltextQuery.STYLE_PARAMETER));
164 	String languageparam = req.getParameter(FulltextQuery.LANG_PARAMETER);
165 	Output output = Output.withFormat(format).withLanguageCode(
166 		languageparam).withStyle(style);
167 
168 	// placetype
169 	String[] placetypeParameters = req
170 		.getParameterValues(FulltextQuery.PLACETYPE_PARAMETER);
171 	Class<? extends GisFeature>[] clazzs = null;
172 	if (placetypeParameters!=null){
173 		clazzs = new Class[placetypeParameters.length]; 
174 		for (int i=0;i<placetypeParameters.length;i++){
175 			Class<? extends GisFeature> classEntityFromString = GisHelper.getClassEntityFromString(placetypeParameters[i]);
176 				clazzs[i]= classEntityFromString;
177 		}
178 	}
179 	
180 
181 	// countrycode
182 	String countrycodeParam = req
183 		.getParameter(FulltextQuery.COUNTRY_PARAMETER);
184 	if (countrycodeParam == null){
185 		query.limitToCountryCode(null);
186 	
187 	} else {
188 		query.limitToCountryCode(countrycodeParam
189 				.toUpperCase());
190 		
191 	}
192 
193 	//indentation
194 	if ("true".equalsIgnoreCase(req
195 		.getParameter(GisgraphyServlet.INDENT_PARAMETER))
196 		|| "on".equalsIgnoreCase(req
197 			.getParameter(GisgraphyServlet.INDENT_PARAMETER))) {
198 	    output.withIndentation();
199 	}
200 	
201 	//auto suggestion / auto completion
202 	if ("true".equalsIgnoreCase(req
203 			.getParameter(FulltextQuery.SUGGEST_PARAMETER))
204 			|| "on".equalsIgnoreCase(req
205 				.getParameter(FulltextQuery.SUGGEST_PARAMETER))) {
206 		    query.withSuggest(true);
207 		}
208 	
209 	//spellchecking
210 	if ("true".equalsIgnoreCase(req
211 			.getParameter(FulltextQuery.SPELLCHECKING_PARAMETER))
212 			|| "on".equalsIgnoreCase(req
213 				.getParameter(FulltextQuery.SPELLCHECKING_PARAMETER))) {
214 		    query.withSpellChecking();
215 		}
216 	else if ("false".equalsIgnoreCase(req.getParameter(FulltextQuery.SPELLCHECKING_PARAMETER))) {
217 		query.withoutSpellChecking();
218 	}
219 	
220 	if ("true".equalsIgnoreCase(req
221 		.getParameter(FulltextQuery.ALLWORDSREQUIRED_PARAMETER))
222 		|| "on".equalsIgnoreCase(req
223 			.getParameter(FulltextQuery.ALLWORDSREQUIRED_PARAMETER))) {
224 	    query.withAllWordsRequired(true);
225 	}
226 	else if ("false".equalsIgnoreCase(req.getParameter(FulltextQuery.ALLWORDSREQUIRED_PARAMETER))) {
227 		query.withAllWordsRequired(false);
228 	}
229 	
230 	// apiKey
231 	String apiKey = req.getParameter(GisgraphyServlet.APIKEY_PARAMETER);
232 	query.setApikey(apiKey);
233 
234 	
235 	query.withPagination(pagination);
236 	query.withPlaceTypes(clazzs);
237 	query.withOutput(output);
238 	
239 	return query;
240     } 
241 
242     
243 
244 }