001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/security/control/InitServiceEditorListener.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 package org.deegree.portal.standard.security.control; 037 038 import java.io.IOException; 039 import java.io.InputStreamReader; 040 import java.io.Reader; 041 import java.net.URL; 042 import java.util.Comparator; 043 import java.util.Iterator; 044 import java.util.List; 045 import java.util.Set; 046 import java.util.TreeSet; 047 048 import org.deegree.enterprise.control.AbstractListener; 049 import org.deegree.enterprise.control.FormEvent; 050 import org.deegree.enterprise.control.RPCException; 051 import org.deegree.enterprise.control.RPCMethodCall; 052 import org.deegree.enterprise.control.RPCParameter; 053 import org.deegree.enterprise.control.RPCWebEvent; 054 import org.deegree.framework.log.ILogger; 055 import org.deegree.framework.log.LoggerFactory; 056 import org.deegree.framework.util.CharsetUtils; 057 import org.deegree.framework.util.NetWorker; 058 import org.deegree.framework.xml.NamespaceContext; 059 import org.deegree.framework.xml.XMLParsingException; 060 import org.deegree.framework.xml.XMLTools; 061 import org.deegree.i18n.Messages; 062 import org.deegree.ogcbase.CommonNamespaces; 063 import org.deegree.security.UnauthorizedException; 064 import org.deegree.security.drm.SecurityAccess; 065 import org.deegree.security.drm.SecurityAccessManager; 066 import org.deegree.security.drm.model.User; 067 import org.w3c.dom.Document; 068 import org.w3c.dom.Element; 069 import org.xml.sax.SAXException; 070 071 /** 072 * This <code>Listener</code> reacts on 'initServiceAdministration'-events, queries the WCAS and 073 * passes the service data on to be displayed by the JSP. 074 * <p> 075 * NOTE: The submitted catalog name in the event is currently ignored, the catalog to be queried is 076 * taken from the harvester configuration. 077 * </p> 078 * 079 * @author <a href="mschneider@lat-lon.de">Markus Schneider </a> 080 * @author last edited by: $Author: mschneider $ 081 * 082 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 083 */ 084 public class InitServiceEditorListener extends AbstractListener { 085 086 private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 087 088 private static final ILogger LOG = LoggerFactory.getLogger( InitServiceEditorListener.class ); 089 090 // address of the catalog-server to query 091 protected static URL catalogURL; 092 093 /** 094 * Called by init-method of <code>SecurityRequestDispatcher</code> once. 095 * 096 * @param configURL 097 * @throws IOException 098 * @throws SAXException 099 * @throws XMLParsingException 100 */ 101 static void setHarvesterConfig( String configURL ) 102 throws IOException, SAXException, XMLParsingException { 103 // config file -> DOM 104 Reader reader = new InputStreamReader( new URL( configURL ).openStream() ); 105 Document doc = XMLTools.parse( reader ); 106 Element element = doc.getDocumentElement(); 107 reader.close(); 108 109 // extract configuration information from DOM 110 catalogURL = new URL( XMLTools.getRequiredStringValue( "catalogURL", null, element ) ); 111 } 112 113 @Override 114 public void actionPerformed( FormEvent event ) { 115 116 try { 117 SecurityAccessManager manager = SecurityAccessManager.getInstance(); 118 User user = manager.getUserByName( toModel().get( ClientHelper.KEY_USERNAME ) ); 119 SecurityAccess token = manager.acquireAccess( user ); 120 boolean isAdmin = true; 121 122 // perform access check 123 try { 124 ClientHelper.checkForAdminRole( token ); 125 } catch ( UnauthorizedException e ) { 126 isAdmin = false; 127 } 128 129 // decode RPC-event 130 if ( event instanceof RPCWebEvent ) { 131 RPCWebEvent ev = (RPCWebEvent) event; 132 RPCMethodCall rpcCall = ev.getRPCMethodCall(); 133 RPCParameter[] params = rpcCall.getParameters(); 134 135 if ( params == null || params.length != 1 ) { 136 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_PARAM_NUM" ) ); 137 138 } 139 if ( !( params[0].getValue() instanceof String ) ) { 140 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_STRING" ) ); 141 } 142 143 } else { 144 throw new Exception( Messages.getMessage( "IGEO_STD_SEC_ERROR_RPC_NOT_VALID" ) ); 145 } 146 147 Set allServices = getBriefDescriptions( catalogURL ); 148 String[] serviceDetails = new String[14]; 149 for ( int i = 0; i < serviceDetails.length; i++ ) { 150 serviceDetails[i] = ""; 151 } 152 153 // display the first service 154 String serviceId = null; 155 Iterator it = allServices.iterator(); 156 if ( it.hasNext() ) { 157 serviceId = ( (String[]) it.next() )[0]; 158 } 159 if ( serviceId != null ) { 160 serviceDetails = getFullDescription( catalogURL, serviceId ); 161 } 162 163 getRequest().setAttribute( "ALL_SERVICES", allServices ); 164 getRequest().setAttribute( "SERVICE_DETAILS", serviceDetails ); 165 getRequest().setAttribute( "IS_ADMIN", new Boolean( isAdmin ) ); 166 } catch ( Exception e ) { 167 LOG.logError( e.getMessage(), e ); 168 getRequest().setAttribute( "SOURCE", this.getClass().getName() ); 169 getRequest().setAttribute( "MESSAGE", 170 Messages.getMessage( "IGEO_STD_SEC_FAIL_INIT_SERVICE_EDITOR", e.getMessage() ) ); 171 172 setNextPage( "admin/admin_error.jsp" ); 173 } 174 175 } 176 177 /** 178 * Retrieves "brief descriptions" of all available services from the WCAS. 179 * 180 * @param catalogURL 181 * @return elements are arrays of Strings (title, id, type) 182 * @throws IOException 183 * @throws SAXException 184 * @throws XMLParsingException 185 */ 186 protected Set<String[]> getBriefDescriptions( URL catalogURL ) 187 throws IOException, SAXException, XMLParsingException { 188 189 TreeSet<String[]> services = new TreeSet<String[]>( new Comparator() { 190 public int compare( Object o1, Object o2 ) { 191 if ( o1 instanceof String[] && o2 instanceof String[] ) { 192 String id1 = ( (String[]) o1 )[0]; 193 String id2 = ( (String[]) o2 )[1]; 194 return id1.compareTo( id2 ); 195 } 196 throw new ClassCastException( "Incompatible object types!" ); 197 } 198 } ); 199 200 // build WCAS-request 201 String briefRequest = "<?xml version=\"1.0\" encoding=\"" + CharsetUtils.getSystemCharset() 202 + "\"?><GetRecord xmlns:ogc=\"http://www.opengis.net/ogc\"" 203 + " xmlns:gml=\"http://www.opengis.net/gml\" maxRecords=\"10\"" 204 + " outputFormat=\"XML\" outputRecType=\"ISO19119\" queryScope=\"0\"" 205 + " startPosition=\"-1\"><Query typeName=\"Service\">" 206 + "<PropertySet setName=\"Full\"/></Query></GetRecord>"; 207 208 // open connection and send request 209 NetWorker netWorker = new NetWorker( catalogURL, briefRequest ); 210 211 // server response -> DOM 212 InputStreamReader reader = new InputStreamReader( netWorker.getInputStream(), CharsetUtils.getSystemCharset() ); 213 214 Document doc = XMLTools.parse( reader ); 215 reader.close(); 216 217 // extract service information from DOM 218 Element searchResultElement = XMLTools.getRequiredChildElement( "searchResult", null, doc.getDocumentElement() ); 219 List serviceElements = XMLTools.getRequiredNodes( searchResultElement, "ISO19119", nsContext ); 220 221 for ( int i = 0; i < serviceElements.size(); i++ ) { 222 Element serviceElement = (Element) serviceElements.get( i ); 223 String serviceId = XMLTools.getRequiredStringValue( "fileIdentifier", null, serviceElement ); 224 String serviceType = XMLTools.getRequiredStringValue( "serviceType", null, serviceElement ); 225 Element citationElement = XMLTools.getRequiredChildElement( "citation", null, serviceElement ); 226 String serviceName = XMLTools.getRequiredStringValue( "title", null, citationElement ); 227 String[] service = new String[] { serviceId, serviceType, serviceName }; 228 services.add( service ); 229 } 230 231 return services; 232 } 233 234 /** 235 * Retrieves the full description for the specified service from the WCAS. 236 * 237 * @param catalogURL 238 * @param serviceId 239 * @return String array (14 values) describing the service 240 * @throws Exception 241 */ 242 protected String[] getFullDescription( URL catalogURL, String serviceId ) 243 throws Exception { 244 245 String[] details = new String[14]; 246 247 // build WCAS-request 248 String fullRequest = "<?xml version=\"1.0\" encoding=\"" + CharsetUtils.getSystemCharset() + "\"?>" 249 + "<GetRecord xmlns:ogc=\"http://www.opengis.net/ogc\"" 250 + " xmlns:gml=\"http://www.opengis.net/gml\" maxRecords=\"10\"" 251 + " outputFormat=\"XML\" outputRecType=\"ISO19119\" queryScope=\"0\"" 252 + " startPosition=\"-1\">" + "<Query typeName=\"Service\">" 253 + "<PropertySet setName=\"Full\"/>" + "<ogc:Filter>" + "<ogc:PropertyIsEqualTo>" 254 + "<ogc:PropertyName>ISO19119/fileIdentifier</ogc:PropertyName>" 255 + "<ogc:Literal><![CDATA[" + serviceId + "]]></ogc:Literal>" + "</ogc:PropertyIsEqualTo>" 256 + "</ogc:Filter>" + "</Query>" + "</GetRecord>"; 257 258 // open connection and send request 259 NetWorker netWorker = new NetWorker( catalogURL, fullRequest ); 260 261 // server response -> DOM 262 InputStreamReader reader = new InputStreamReader( netWorker.getInputStream(), CharsetUtils.getSystemCharset() ); 263 Document doc = XMLTools.parse( reader ); 264 reader.close(); 265 266 // extract service information from DOM 267 Element searchResultElement = XMLTools.getRequiredChildElement( "searchResult", null, doc.getDocumentElement() ); 268 List serviceElements = XMLTools.getRequiredNodes( searchResultElement, "ISO19119", nsContext ); 269 if ( serviceElements.size() != 1 ) { 270 throw new XMLParsingException( "Error in WCAS-response. Unexpected number (" + serviceElements.size() 271 + ") of ISO19119 elements." ); 272 } 273 Element serviceElement = (Element) serviceElements.get( 0 ); 274 275 details[0] = serviceId; 276 details[1] = XMLTools.getRequiredStringValue( "serviceType", null, serviceElement ); 277 details[2] = XMLTools.getRequiredStringValue( "serviceTypeVersion", null, serviceElement ); 278 279 Element citationElement = XMLTools.getChildElement( "citation", null, serviceElement ); 280 if ( citationElement != null ) { 281 details[3] = XMLTools.getStringValue( "title", null, citationElement, "" ); 282 details[4] = XMLTools.getStringValue( "abstract", null, serviceElement, "" ); 283 284 Element pointOfContactElement = XMLTools.getChildElement( "pointOfContact", null, serviceElement ); 285 if ( pointOfContactElement != null ) { 286 details[5] = XMLTools.getStringValue( "individualName", null, pointOfContactElement, "" ); 287 details[6] = XMLTools.getStringValue( "positionName", null, pointOfContactElement, "" ); 288 details[7] = XMLTools.getStringValue( "organizationName", null, pointOfContactElement, "" ); 289 details[8] = XMLTools.getStringValue( "onlineResource", null, pointOfContactElement, "" ); 290 291 Element contactInfoElement = XMLTools.getChildElement( "contactInfo", null, pointOfContactElement ); 292 if ( contactInfoElement != null ) { 293 Element addressElement = XMLTools.getChildElement( "address", null, contactInfoElement ); 294 if ( addressElement != null ) { 295 details[9] = XMLTools.getStringValue( "deliveryPoint", null, addressElement, "" ); 296 details[10] = XMLTools.getStringValue( "city", null, addressElement, "" ); 297 details[11] = XMLTools.getStringValue( "postalCode", null, addressElement, "" ); 298 details[12] = XMLTools.getStringValue( "country", null, addressElement, "" ); 299 details[13] = XMLTools.getStringValue( "electronicMailAddress", null, addressElement, "" ); 300 } 301 } 302 } 303 } 304 305 return details; 306 } 307 }