001 //$HeadURL: svn+ssh://melmasry@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/portal/standard/context/control/NormalScreenListener.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036
037 package org.deegree.portal.standard.context.control;
038
039 import java.awt.Rectangle;
040
041 import javax.servlet.http.HttpServletRequest;
042 import javax.servlet.http.HttpSession;
043 import javax.xml.parsers.ParserConfigurationException;
044
045 import org.deegree.enterprise.control.FormEvent;
046 import org.deegree.enterprise.control.RPCMember;
047 import org.deegree.enterprise.control.RPCStruct;
048 import org.deegree.enterprise.control.RPCWebEvent;
049 import org.deegree.framework.log.ILogger;
050 import org.deegree.framework.log.LoggerFactory;
051 import org.deegree.framework.util.MapUtils;
052 import org.deegree.framework.xml.XMLFragment;
053 import org.deegree.i18n.Messages;
054 import org.deegree.model.spatialschema.Envelope;
055 import org.deegree.model.spatialschema.GeometryFactory;
056 import org.deegree.model.spatialschema.Point;
057 import org.deegree.portal.Constants;
058 import org.deegree.portal.PortalException;
059 import org.deegree.portal.context.ViewContext;
060 import org.deegree.portal.context.WebMapContextFactory;
061 import org.deegree.portal.context.XMLFactory;
062
063 /**
064 * This class converts the fullScreen to normalScreen view. It loads the old view from the httpSession and applies to it
065 * the manipulations the user did in fullScreen view
066 *
067 * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
068 * @author last edited by: $Author: elmasri$
069 *
070 * @version $Revision: $, $Date: 1 Jun 2007 13:50:40$
071 */
072
073 public class NormalScreenListener extends AbstractContextListener {
074
075 private static final ILogger LOG = LoggerFactory.getLogger( ContextSwitchListener.class );
076
077 protected static final String DEFAULT_CTXT2HTML = "WEB-INF/conf/igeoportal/context2HTML.xsl";
078
079 private static final String NORMALSCREEN_MAPCONTEXT = "NormalScreenMapContext";
080
081 private static String xslFilename = null;
082
083 private HttpSession session = null;
084
085 /*
086 * (non-Javadoc)
087 *
088 * @see org.deegree.enterprise.control.AbstractListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
089 */
090 @Override
091 public void actionPerformed( FormEvent event ) {
092
093 RPCWebEvent rpc = (RPCWebEvent) event;
094
095 try {
096 validate( rpc );
097 initialize();
098 } catch ( PortalException e ) {
099 LOG.logError( e.getLocalizedMessage(), e );
100 gotoErrorPage( e.getMessage() );
101 return;
102 }
103
104 try {
105 ViewContext vc = setToNormalScreen( rpc );
106 setCurrentContext( vc );
107 } catch ( Exception e ) {
108 LOG.logError( e.getLocalizedMessage(), e );
109 gotoErrorPage( e.getMessage() );
110 return;
111 }
112
113 }
114
115 /**
116 * ValidateRPC looks in the RPCStruct for all needed elements and gotoErrorPage in case an element is found or
117 * wronglz formated, this is useful so that we won't need to check later for anz variables, simply get them and
118 * start Working
119 *
120 * @param rpc
121 * @throws PortalException
122 */
123 protected void validate( RPCWebEvent rpc )
124 throws PortalException {
125
126 RPCStruct struct = extractRPCStruct( rpc, 0 );
127
128 RPCMember layerListRPC = struct.getMember( "layerList" );
129 validateLayerList( layerListRPC );
130
131 RPCMember bboxRpc = struct.getMember( "boundingBox" );
132 validateBBox( bboxRpc );
133 }
134
135 /**
136 * Initializes the global variables of the class
137 *
138 * @throws PortalException
139 */
140 protected void initialize()
141 throws PortalException {
142 try {
143 session = ( (HttpServletRequest) this.getRequest() ).getSession();
144 xslFilename = "file://" + getHomePath() + DEFAULT_CTXT2HTML;
145 } catch ( Exception e ) {
146 LOG.logError( e.getMessage() );
147 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_INITIALIZE", e ) );
148 }
149 }
150
151 /**
152 *
153 * @param rpc
154 * The RPCWebEvent that contains a struct with the necessary information about the current context
155 * @return the viewcontext with the current changes
156 */
157 protected ViewContext setToNormalScreen( RPCWebEvent rpc )
158 throws PortalException {
159
160 RPCStruct struct = extractRPCStruct( rpc, 0 );
161 ViewContext vc = getViewContextFromSession();
162
163 RPCMember[] layerList = ( (RPCStruct) struct.getMember( "layerList" ).getValue() ).getMembers();
164 if ( layerList != null ) {
165 try {
166 changeLayerList( vc, layerList );
167 } catch ( PortalException e ) {
168 LOG.logError( e.getMessage() );
169 throw new PortalException( e.getMessage() );
170 }
171 }
172
173 RPCStruct bboxStruct = (RPCStruct) struct.getMember( "boundingBox" ).getValue();
174 Envelope envelope = extractBBox( bboxStruct, vc.getGeneral().getBoundingBox()[0].getCoordinateSystem() );
175 // HINT: Please don't remove. Its another mechanism to set the map to normal view
176 // RPCStruct mapSizeRPC = (RPCStruct) struct.getMember( "mapSize" ).getValue();
177 // Point mapSize = getMapSize( mapSizeRPC, envelope.getCoordinateSystem() );
178 // setNormalSizeScreen( vc, envelope, mapSize );
179 vc = createNormalScreenContext( vc, envelope );
180
181 return vc;
182 }
183
184 /**
185 * Takes in viewContext converts it to a html of the viewcontext and display it
186 *
187 * @param vc
188 * the ViewContext after convert
189 */
190 protected void setCurrentContext( ViewContext vc )
191 throws ParserConfigurationException, PortalException {
192
193 // doing the transformation
194 try {
195 XMLFragment xml = XMLFactory.export( vc );
196 String newHtml = transformToHtmlMapContext( xml, xslFilename );
197 session.setAttribute( ContextSwitchListener.NEW_CONTEXT_HTML, newHtml );
198 } catch ( ParserConfigurationException e ) {
199 LOG.logError( e.getMessage() );
200 throw new ParserConfigurationException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_TRANSFORM" ) );
201 } catch ( Exception e ) {
202 LOG.logError( e.getMessage() );
203 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_PARSE_XSL", xslFilename ) );
204 }
205 }
206
207 /**
208 * Validates the data in the struct to make sure it contains a valid layerList
209 *
210 * @param layerListRPCMember
211 * @throws PortalException
212 */
213 protected void validateLayerList( RPCMember layerListRPCMember )
214 throws PortalException {
215
216 if ( layerListRPCMember == null || layerListRPCMember.getValue() == null ) {
217 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_MISSING_RPC_MEMBER", "layerList" ) );
218 }
219
220 RPCMember[] layerList = null;
221 try {
222 layerList = ( (RPCStruct) layerListRPCMember.getValue() ).getMembers();
223 } catch ( Exception e ) {
224 LOG.logError( e.getMessage() );
225 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_WRONG_RPC_MEMBER_VALUE", "layerList" ) );
226 }
227
228 if ( layerList == null || layerList.length < 1 ) {
229 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_EMPTY_LAYERLIST", "layerList" ) );
230 }
231 }
232
233 /**
234 * Validates the data in the struct to make sure it contains a valid bbox
235 *
236 * @param bboxRPCMember
237 * @throws PortalException
238 */
239 protected void validateBBox( RPCMember bboxRPCMember )
240 throws PortalException {
241
242 if ( bboxRPCMember == null || bboxRPCMember.getValue() == null ) {
243 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_MISSING_RPC_MEMBER", "boundingBox" ) );
244 }
245 RPCStruct bboxStruct = (RPCStruct) bboxRPCMember.getValue();
246 Double minx = null;
247 Double miny = null;
248 Double maxx = null;
249 Double maxy = null;
250
251 RPCMember mem = bboxStruct.getMember( Constants.RPC_BBOXMINX );
252 if ( mem != null ) {
253 minx = (Double) mem.getValue();
254 }
255 mem = bboxStruct.getMember( Constants.RPC_BBOXMINY );
256 if ( mem != null ) {
257 miny = (Double) mem.getValue();
258 }
259
260 mem = bboxStruct.getMember( Constants.RPC_BBOXMAXX );
261 if ( mem != null ) {
262 maxx = (Double) mem.getValue();
263 }
264
265 mem = bboxStruct.getMember( Constants.RPC_BBOXMAXY );
266 if ( mem != null ) {
267 maxy = (Double) mem.getValue();
268 }
269
270 if ( minx == null || maxx == null || miny == null || maxy == null ) {
271 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_WRONG_RPC_MEMBER_VALUE", "boundingBox" ) );
272 }
273 if ( minx >= maxx || miny >= maxy ) {
274 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_BBOX_BOUNDARIES" ) );
275 }
276 }
277
278 /**
279 * Extracts the Xml of NORMALSCREEN_MAPCONTEXT from the session and transforms it to a ViewContext
280 *
281 * @return The stored actual context
282 * @throws PortalException
283 */
284 protected ViewContext getViewContextFromSession()
285 throws PortalException {
286
287 try {
288 XMLFragment xml = (XMLFragment) session.getAttribute( NORMALSCREEN_MAPCONTEXT );
289 String sessionId = (String) session.getAttribute( "SESSIONID" );
290 return WebMapContextFactory.createViewContext( xml, null, sessionId );
291 } catch ( Exception e ) {
292 LOG.logError( e.getMessage() );
293 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_CREATE_VC" ) );
294 }
295 }
296
297 /**
298 * Extracts the width and height of the map and returns a point with the coordinates system Please don't delete it.
299 * It is used with the commneted code in setNormalSizeScreen()
300 *
301 * @param mapSize
302 * @param crs
303 * @return
304 */
305 // private Point getMapSize( RPCStruct mapSize, CoordinateSystem crs ) {
306 //
307 // Double width = (Double) mapSize.getMember( "width" ).getValue();
308 // Double height = (Double) mapSize.getMember( "height" ).getValue();
309 //
310 // return GeometryFactory.createPoint( width, height, crs );
311 // }
312
313 /**
314 * This Method adapt the normal size screen context with the new changes applied in the full screen view, ex.
315 * changing zoom , or add new layers
316 *
317 * @param vc
318 * @param newbBox
319 */
320 protected ViewContext createNormalScreenContext( ViewContext vc, Envelope newbBox )
321 throws PortalException {
322
323 // void setNormalSizeScreen( ViewContext vc, Envelope newbBox, Point mapSize ) {
324 // // HINT: Please don't delete.
325 // // This is another mechanism (still not 100% correct) to resize the map
326 // // Since I have the doubt that the function ensureAspectRatio() can be unprecise in some cases It
327 // // happens with ensureAspectRatio that the map is
328 // // shifted a little bit upwards, and not exactly centerd in the middle of the mapView
329 // // This is the middle point of the full screen map
330 //
331 // double midX = ( newbBox.getMax().getX() - newbBox.getMin().getX() )/2 ; double midY = (
332 // newbBox.getMax().getY() - newbBox.getMin().getY() )/2;
333 //
334 // // This is the middle point of the normal size map
335 // Point [] points = vc.getGeneral().getBoundingBox();
336 // General general = vc.getGeneral();
337 //
338 // Envelope env = GeometryFactory.createEnvelope( points[0].getX(), points[0].getY(), points[1].getX(), points[1].getY(), points[0].getCoordinateSystem());
339 // double fullSizeScale = MapUtils.calcScale((int)mapSize.getX(), (int)mapSize.getY(), newbBox, newbBox.getCoordinateSystem(), 1 );
340 // double normalSizeScale = MapUtils.calcScale( general.getWindow().width, general.getWindow().height, env, env.getCoordinateSystem(), 1 );
341 // Envelope scaledNormalSize = MapUtils.scaleEnvelope( env, normalSizeScale, fullSizeScale );
342 // double halfWidth = scaledNormalSize.getWidth()/2;
343 // double halfHeight = scaledNormalSize.getHeight()/2;
344
345 // Min point
346 Point[] newPoints = new Point[2];
347
348 // newPoints[0] = GeometryFactory.createPoint( midX - halfWidth, midY - halfHeight,
349 // newbBox.getCoordinateSystem() );
350 // // Max Point
351 // newPoints[1] = GeometryFactory.createPoint( midX + halfWidth, midY + halfHeight, newbBox.getCoordinateSystem());
352 //
353 // newPoints[0] = GeometryFactory.createPoint( scaledNormalSize.getMin().getX(),
354 // scaledNormalSize.getMin().getY(), scaledNormalSize.getCoordinateSystem() );
355 // newPoints[1] = GeometryFactory.createPoint( scaledNormalSize.getMax().getX(), scaledNormalSize.getMax().getY(), scaledNormalSize.getCoordinateSystem() );
356
357 Rectangle rect = vc.getGeneral().getWindow();
358 Envelope env1 = MapUtils.ensureAspectRatio( newbBox, rect.getWidth(), rect.getHeight() );
359
360 // changeBBox( vc, env1);
361
362 // remove rest of method!
363 newPoints[0] = GeometryFactory.createPoint( env1.getMin().getX(), env1.getMin().getY(),
364 env1.getCoordinateSystem() );
365 newPoints[1] = GeometryFactory.createPoint( env1.getMax().getX(), env1.getMax().getY(),
366 env1.getCoordinateSystem() );
367
368 try {
369 vc.getGeneral().setBoundingBox( newPoints );
370 } catch ( Exception e ) {
371 LOG.logError( e.getMessage() );
372 throw new PortalException( Messages.getMessage( "IGEO_STD_CNTXT_ERROR_SET_BBOX" ) );
373 }
374 return vc;
375 }
376
377 }