001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }