001: //$HeadURL: svn+ssh://melmasry@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/portal/standard/context/control/ContextSaveListener.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: klaus.greve@uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043:
044: package org.deegree.portal.standard.wms.control;
045:
046: import java.net.URL;
047: import java.util.ArrayList;
048:
049: import javax.servlet.http.HttpServletRequest;
050: import javax.servlet.http.HttpSession;
051:
052: import org.deegree.enterprise.control.RPCMember;
053: import org.deegree.enterprise.control.RPCMethodCall;
054: import org.deegree.enterprise.control.RPCParameter;
055: import org.deegree.enterprise.control.RPCStruct;
056: import org.deegree.enterprise.control.RPCWebEvent;
057: import org.deegree.framework.log.ILogger;
058: import org.deegree.framework.log.LoggerFactory;
059: import org.deegree.framework.util.StringTools;
060: import org.deegree.i18n.Messages;
061: import org.deegree.model.crs.CoordinateSystem;
062: import org.deegree.model.spatialschema.Envelope;
063: import org.deegree.model.spatialschema.GeometryFactory;
064: import org.deegree.model.spatialschema.Point;
065: import org.deegree.ogcwebservices.OWSUtils;
066: import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
067: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
068: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
069: import org.deegree.portal.Constants;
070: import org.deegree.portal.PortalException;
071: import org.deegree.portal.common.control.AbstractSimplePrintListener;
072: import org.deegree.portal.context.ContextException;
073: import org.deegree.portal.context.General;
074: import org.deegree.portal.context.Layer;
075: import org.deegree.portal.context.LayerList;
076: import org.deegree.portal.context.Server;
077: import org.deegree.portal.context.ViewContext;
078: import org.deegree.portal.standard.context.control.ContextSaveListener;
079:
080: /**
081: * This class prints the View context. It inherits from AbstractSimplePrintListner and implement the abstract method
082: * getViewContext
083: *
084: * TODO The methods changeBBox(), changeLayerList(), extractBBox() are already implemented in AbstractContextListner.
085: * The question now is wether to inherit from AbstractContextListner instead of AbstractListner?
086: *
087: * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
088: * @author last edited by: $Author: mays $
089: *
090: * @version $Revision: 1.2 $, $Date: 2007-10-04 13:31:39 $
091: */
092: public class SimplePrintListener extends AbstractSimplePrintListener {
093:
094: private static final ILogger LOG = LoggerFactory
095: .getLogger(ContextSaveListener.class);
096:
097: @Override
098: protected ViewContext getViewContext(RPCWebEvent rpc) {
099:
100: RPCMethodCall mc = rpc.getRPCMethodCall();
101: RPCParameter[] params = mc.getParameters();
102: RPCStruct struct = (RPCStruct) params[2].getValue();
103:
104: HttpSession session = ((HttpServletRequest) getRequest())
105: .getSession();
106: ViewContext vc = (ViewContext) session
107: .getAttribute(Constants.CURRENTMAPCONTEXT);
108: // change values: BBOX and Layer List
109: Envelope bbox = extractBBox((RPCStruct) struct.getMember(
110: "boundingBox").getValue(), null);
111: RPCMember[] layerList = ((RPCStruct) struct.getMember(
112: "layerList").getValue()).getMembers();
113: try {
114: changeBBox(vc, bbox);
115: changeLayerList(vc, layerList);
116: } catch (PortalException e) {
117: LOG
118: .logError("An Error occured while trying to get the Viewcontext");
119: return null;
120: // TODO This method implements its abstract method in AbstractSimplePrintListner
121: // Preferably if the abstract header could be changed to throw a adequate excpetion
122: // since this header is already implemented by another class
123: }
124:
125: return vc;
126: }
127:
128: /**
129: * Convenience method to extract the boundig box from an rpc fragment.
130: *
131: * @param bboxStruct
132: * the <code>RPCStruct</code> containing the bounding box. For example,
133: * <code><member><name>boundingBox</name>etc...</code>.
134: * @param crs
135: * a coordinate system value, may be null.
136: * @return an envelope with the boundaries defined in the rpc structure
137: */
138: protected Envelope extractBBox(RPCStruct bboxStruct,
139: CoordinateSystem crs) {
140:
141: Double minx = (Double) bboxStruct.getMember(
142: Constants.RPC_BBOXMINX).getValue();
143: Double miny = (Double) bboxStruct.getMember(
144: Constants.RPC_BBOXMINY).getValue();
145: Double maxx = (Double) bboxStruct.getMember(
146: Constants.RPC_BBOXMAXX).getValue();
147: Double maxy = (Double) bboxStruct.getMember(
148: Constants.RPC_BBOXMAXY).getValue();
149:
150: Envelope bbox = GeometryFactory.createEnvelope(minx
151: .doubleValue(), miny.doubleValue(), maxx.doubleValue(),
152: maxy.doubleValue(), crs);
153: return bbox;
154: }
155:
156: /**
157: * changes the layer list of the ViewContext vc according to the information contained in the rpcLayerList
158: *
159: * @param vc
160: * The original ViewContext where the changes will be applied to
161: * @param rpcLayerList
162: * the current layerlist
163: * @throws PortalException
164: */
165: protected void changeLayerList(ViewContext vc,
166: RPCMember[] rpcLayerList) throws PortalException {
167: LayerList layerList = vc.getLayerList();
168: ArrayList<Layer> nLayers = new ArrayList<Layer>(
169: rpcLayerList.length);
170:
171: // this is needed to keep layer order
172: // order is correct in rpc call JavaScript, but get lost in translation...
173: for (int i = 0; i < rpcLayerList.length; i++) {
174: String[] v = StringTools.toArray((String) rpcLayerList[i]
175: .getValue(), "|", false);
176: String n = rpcLayerList[i].getName();
177:
178: String title = n;
179: if (v.length > 5) {
180: // this check is necessary, in order to not break running iGeoPortal instances
181: title = v[5];
182: }
183: boolean isQueryable = false;
184: if (v.length > 6) {
185: // JM: this check is necessary, in order to not break running iGeoPortal instances
186: isQueryable = v[6].equalsIgnoreCase("true");
187: }
188:
189: boolean isVisible = Boolean.valueOf(v[0]).booleanValue();
190: Layer l = layerList.getLayer(n, null);
191: if (l != null) {
192: // needed to reconstruct new layer order
193: // otherwise layer order is still from original context
194: l.setHidden(!isVisible);
195: } else {
196:
197: if (layerList.getLayers().length == 0) {
198: // FIXME is this Exception Correct
199: throw new PortalException(
200: Messages
201: .getMessage("IGEO_STD_CNTXT_ERROR_EMPTY_LAYERLIST"));
202: }
203:
204: Layer p = layerList.getLayers()[0];
205: // a new layer must be created because it is not prsent in the current context.
206: // This is the case if the client has loaded an additional WMS
207: String[] tmp = StringTools.toArray(v[2], " ", false);
208: try {
209: v[4] = OWSUtils.validateHTTPGetBaseURL(v[4]);
210: WMSCapabilitiesDocument doc = WMSCapabilitiesDocumentFactory
211: .getWMSCapabilitiesDocument(new URL(
212: v[4]
213: + "request=GetCapabilities&service=WMS"));
214: OGCCapabilities capa = doc.parseCapabilities();
215: Server server = new Server(v[3], tmp[1], tmp[0],
216: new URL(v[4]), capa);
217: l = new Layer(server, n, title, "", p.getSrs(),
218: null, null, p.getFormatList(), p
219: .getStyleList(), isQueryable,
220: !isVisible, null);
221: } catch (Exception e) {
222: throw new PortalException(StringTools
223: .stackTraceToString(e));
224: }
225: }
226: nLayers.add(l);
227: }
228: try {
229: nLayers.trimToSize();
230: Layer[] ls = new Layer[nLayers.size()];
231: ls = nLayers.toArray(ls);
232: vc.setLayerList(new LayerList(ls));
233: } catch (ContextException e) {
234: throw new PortalException(Messages.getMessage(
235: "IGEO_STD_CNTXT_ERROR_SET_LAYERLIST", StringTools
236: .stackTraceToString(e.getStackTrace())));
237: }
238: }
239:
240: /**
241: * changes the bounding box of a given view context
242: *
243: * @param vc
244: * the view context to be changed
245: * @param bbox
246: * the new bounding box
247: * @throws PortalException
248: */
249: public static final void changeBBox(ViewContext vc, Envelope bbox)
250: throws PortalException {
251: General gen = vc.getGeneral();
252:
253: CoordinateSystem cs = gen.getBoundingBox()[0]
254: .getCoordinateSystem();
255: Point[] p = new Point[] {
256: GeometryFactory.createPoint(bbox.getMin(), cs),
257: GeometryFactory.createPoint(bbox.getMax(), cs) };
258: try {
259: gen.setBoundingBox(p);
260: } catch (ContextException e) {
261: LOG.logError(e.getMessage(), e);
262: throw new PortalException(Messages
263: .getMessage("IGEO_STD_CNTXT_ERROR_SET_BBOX"));
264: }
265: }
266:
267: }
|