001 //$HeadURL: 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2010 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.cataloguemanager.control; 037 038 import java.io.ByteArrayInputStream; 039 import java.io.ByteArrayOutputStream; 040 import java.io.IOException; 041 import java.net.URL; 042 import java.util.Enumeration; 043 import java.util.HashMap; 044 import java.util.List; 045 import java.util.Map; 046 047 import javax.servlet.http.HttpServletRequest; 048 import javax.xml.bind.JAXBContext; 049 import javax.xml.bind.JAXBException; 050 import javax.xml.bind.Marshaller; 051 import javax.xml.bind.Unmarshaller; 052 053 import org.apache.commons.httpclient.HttpException; 054 import org.apache.commons.httpclient.HttpMethod; 055 import org.deegree.enterprise.control.ajax.ResponseHandler; 056 import org.deegree.enterprise.control.ajax.WebEvent; 057 import org.deegree.framework.log.ILogger; 058 import org.deegree.framework.log.LoggerFactory; 059 import org.deegree.framework.util.BootLogger; 060 import org.deegree.framework.util.HttpUtils; 061 import org.deegree.framework.util.TimeTools; 062 import org.deegree.framework.xml.XMLFragment; 063 import org.deegree.framework.xml.XMLParsingException; 064 import org.deegree.framework.xml.XMLTools; 065 import org.deegree.model.crs.CRSFactory; 066 import org.deegree.model.crs.CRSTransformationException; 067 import org.deegree.model.crs.CoordinateSystem; 068 import org.deegree.model.spatialschema.Envelope; 069 import org.deegree.model.spatialschema.GeometryFactory; 070 import org.deegree.ogcbase.CommonNamespaces; 071 import org.deegree.portal.cataloguemanager.model.Address; 072 import org.deegree.portal.cataloguemanager.model.CICitation; 073 import org.deegree.portal.cataloguemanager.model.CIDate; 074 import org.deegree.portal.cataloguemanager.model.CIDateTypeCode; 075 import org.deegree.portal.cataloguemanager.model.CIOnlineResource; 076 import org.deegree.portal.cataloguemanager.model.CIResponsibleParty; 077 import org.deegree.portal.cataloguemanager.model.Contact; 078 import org.deegree.portal.cataloguemanager.model.ContactInfo; 079 import org.deegree.portal.cataloguemanager.model.Date; 080 import org.deegree.portal.cataloguemanager.model.DateType; 081 import org.deegree.portal.cataloguemanager.model.DistributionFormat; 082 import org.deegree.portal.cataloguemanager.model.EXExtent; 083 import org.deegree.portal.cataloguemanager.model.EXGeographicBoundingBox; 084 import org.deegree.portal.cataloguemanager.model.EXTemporalExtent; 085 import org.deegree.portal.cataloguemanager.model.ExceptionBean; 086 import org.deegree.portal.cataloguemanager.model.Keyword; 087 import org.deegree.portal.cataloguemanager.model.Linkage; 088 import org.deegree.portal.cataloguemanager.model.MDDataIdentification; 089 import org.deegree.portal.cataloguemanager.model.MDDigitalTransferOptions; 090 import org.deegree.portal.cataloguemanager.model.MDDistribution; 091 import org.deegree.portal.cataloguemanager.model.MDFormat; 092 import org.deegree.portal.cataloguemanager.model.MDLegalConstraints; 093 import org.deegree.portal.cataloguemanager.model.MDMetadata; 094 import org.deegree.portal.cataloguemanager.model.MDReferenceSystem; 095 import org.deegree.portal.cataloguemanager.model.MDRepresentativeFraction; 096 import org.deegree.portal.cataloguemanager.model.MetadataBean; 097 import org.deegree.portal.cataloguemanager.model.Name; 098 import org.deegree.portal.cataloguemanager.model.OnLine; 099 import org.deegree.portal.cataloguemanager.model.ParentIdentifier; 100 import org.deegree.portal.cataloguemanager.model.Phone; 101 import org.deegree.portal.cataloguemanager.model.PointOfContact; 102 import org.deegree.portal.cataloguemanager.model.ResourceConstraints; 103 import org.deegree.portal.cataloguemanager.model.SpatialResolution; 104 import org.deegree.portal.cataloguemanager.model.TimePeriod; 105 import org.deegree.portal.cataloguemanager.model.TransferOptions; 106 import org.deegree.portal.cataloguemanager.model.Version; 107 import org.w3c.dom.Element; 108 import org.xml.sax.SAXException; 109 110 /** 111 * 112 * 113 * 114 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 115 * @author last edited by: $Author: apoth $ 116 * 117 * @version $Revision: 30690 $, $Date: 2011-05-06 10:23:46 +0200 (Fr, 06 Mai 2011) $ 118 */ 119 public class InsertMetadataListener extends AbstractMetadataListener { 120 121 protected static CoordinateSystem crs; 122 123 static { 124 if ( crs == null ) { 125 try { 126 crs = CRSFactory.create( "EPSG:4326" ); 127 } catch ( Exception e ) { 128 BootLogger.logError( e.getMessage(), e ); 129 } 130 } 131 } 132 133 private static ILogger LOG = LoggerFactory.getLogger( InsertMetadataListener.class ); 134 135 protected CatalogueManagerConfiguration conf; 136 137 @Override 138 public void actionPerformed( WebEvent event, ResponseHandler responseHandler ) 139 throws IOException { 140 141 try { 142 conf = getCatalogueManagerConfiguration( event ); 143 MetadataBean bean = (MetadataBean) event.getAsBean(); 144 JAXBContext jc = JAXBContext.newInstance( "org.deegree.portal.cataloguemanager.model" ); 145 Unmarshaller u = jc.createUnmarshaller(); 146 147 String tmp = conf.getTemplateURL( bean.getHlevel() ); 148 URL url = conf.resolve( tmp ); 149 MDMetadata mdMetadata = (MDMetadata) u.unmarshal( url ); 150 151 // metadata settings 152 mdMetadata.getFileIdentifier().setCharacterString( bean.getIdentifier() ); 153 mdMetadata.getHierarchyLevel().getMDScopeCode().setCodeListValue( bean.getHlevel() ); 154 tmp = bean.getHlevel(); 155 if ( "series".equalsIgnoreCase( tmp ) ) { 156 tmp = "datasetcollection"; 157 } 158 if ( "dataset".equalsIgnoreCase( tmp ) && bean.getParentId() != null ) { 159 ParentIdentifier pi = new ParentIdentifier(); 160 pi.setCharacterString( bean.getParentId() ); 161 mdMetadata.setParentIdentifier( pi ); 162 } 163 mdMetadata.getHierarchyLevelName().setCharacterString( tmp ); 164 setContact( mdMetadata, bean ); 165 mdMetadata.getDateStamp().setDateTime( TimeTools.getISOFormattedTime() ); 166 if ( bean.getCrs() != null ) { 167 MDReferenceSystem mdRef = mdMetadata.getReferenceSystemInfo().getMDReferenceSystem(); 168 mdRef.getReferenceSystemIdentifier().getRSIdentifier().getCode().setCharacterString( bean.getCrs() ); 169 } 170 171 // data identification settings 172 MDDataIdentification mdDataId = mdMetadata.getIdentificationInfo().getMDDataIdentification(); 173 mdDataId.getAbstract().setCharacterString( bean.getAbstract_() ); 174 mdDataId.setUuid( "_" + bean.getIdentifier() ); 175 mdDataId.setId( bean.getIdentifier() ); 176 setKeywords( mdDataId, bean ); 177 setPointOfContact( mdDataId, bean ); 178 mdDataId.getTopicCategory().setMDTopicCategoryCode( bean.getTopCat() ); 179 setExtent( mdDataId, bean ); 180 181 SpatialResolution spr = mdDataId.getSpatialResolution(); 182 if ( bean.getScale() == null || bean.getScale().trim().length() == 0 ) { 183 mdDataId.setSpatialResolution( null ); 184 } else { 185 MDRepresentativeFraction frac = spr.getMDResolution().getEquivalentScale().getMDRepresentativeFraction(); 186 frac.getDenominator().setInteger( Integer.parseInt( bean.getScale().trim() ) ); 187 } 188 189 CICitation citation = mdDataId.getCitation().getCICitation(); 190 citation.getTitle().setCharacterString( bean.getDatasetTitle() ); 191 citation.getIdentifier().getMDIdentifier().getCode().setCharacterString( bean.getIdentifier() ); 192 193 // citation dates 194 List<Date> dates = citation.getDate(); 195 dates.clear(); 196 if ( bean.getCreation() != null ) { 197 addDate( dates, "creation", bean.getCreation() ); 198 } 199 if ( bean.getPublication() != null ) { 200 addDate( dates, "publication", bean.getPublication() ); 201 } 202 if ( bean.getRevision() != null ) { 203 addDate( dates, "revision", bean.getRevision() ); 204 } 205 206 if ( bean.getTransferOnline() != null && bean.getTransferOnline().trim().length() > 0 ) { 207 setDistributionInfo( mdMetadata, bean ); 208 } else { 209 mdMetadata.setDistributionInfo( null ); 210 } 211 212 // lineage 213 if ( bean.getLineage() != null && bean.getLineage().trim().length() > 0 ) { 214 mdMetadata.getDataQualityInfo().getDQDataQuality().getLineage().getLILineage().getStatement().setCharacterString( 215 bean.getLineage() ); 216 } else { 217 mdMetadata.setDataQualityInfo( null ); 218 } 219 220 // resource constraints 221 List<ResourceConstraints> list = mdMetadata.getIdentificationInfo().getMDDataIdentification().getResourceConstraints(); 222 if ( bean.getAccessConstraints() == null ) { 223 list.clear(); 224 } else { 225 MDLegalConstraints legal = null; 226 for ( ResourceConstraints resourceConstraints : list ) { 227 if ( resourceConstraints.getMDLegalConstraints() != null ) { 228 legal = resourceConstraints.getMDLegalConstraints(); 229 legal.getAccessConstraints().getMDRestrictionCode().setCodeListValue( 230 bean.getAccessConstraints() ); 231 legal.getAccessConstraints().getMDRestrictionCode().setValue( bean.getAccessConstraints() ); 232 } 233 } 234 } 235 236 insertIntoCSW_( responseHandler, mdMetadata ); 237 238 } catch ( Exception e ) { 239 LOG.logError( e.getMessage(), e ); 240 ExceptionBean eb = new ExceptionBean( getClass().getName(), e.getMessage() ); 241 responseHandler.writeAndClose( true, eb ); 242 return; 243 } 244 } 245 246 private void setDistributionInfo( MDMetadata mdMetadata, MetadataBean bean ) { 247 MDDistribution mddist = mdMetadata.getDistributionInfo().getMDDistribution(); 248 if ( mddist == null ) { 249 mddist = new MDDistribution(); 250 TransferOptions to = new TransferOptions(); 251 MDDigitalTransferOptions dto = new MDDigitalTransferOptions(); 252 OnLine ol = new OnLine(); 253 CIOnlineResource ciolr = new CIOnlineResource(); 254 ciolr.setLinkage( new Linkage() ); 255 ol.setCIOnlineResource( ciolr ); 256 dto.setOnLine( ol ); 257 to.setMDDigitalTransferOptions( dto ); 258 mddist.setTransferOptions( to ); 259 } 260 MDDigitalTransferOptions to = mddist.getTransferOptions().getMDDigitalTransferOptions(); 261 to.getOnLine().getCIOnlineResource().getLinkage().setURL( bean.getTransferOnline() ); 262 if ( bean.getTransferFormatName() != null && bean.getTransferFormatName().length() > 0 ) { 263 DistributionFormat format = mdMetadata.getDistributionInfo().getMDDistribution().getDistributionFormat(); 264 if ( format == null ) { 265 format = new DistributionFormat(); 266 MDFormat mdf = new MDFormat(); 267 mdf.setName( new Name() ); 268 mdf.setVersion( new Version() ); 269 format.setMDFormat( mdf ); 270 } 271 format.getMDFormat().getName().setCharacterString( bean.getTransferFormatName() ); 272 if ( bean.getTransferFormatVersion() != null && bean.getTransferFormatVersion().length() > 0 ) { 273 format.getMDFormat().getVersion().setCharacterString( bean.getTransferFormatVersion() ); 274 } else { 275 format.getMDFormat().getVersion().setCharacterString( "unknown" ); 276 } 277 } else { 278 mdMetadata.getDistributionInfo().getMDDistribution().setDistributionFormat( null ); 279 } 280 } 281 282 @SuppressWarnings("unchecked") 283 private String insertIntoCSW_( ResponseHandler responseHandler, MDMetadata mdMetadata ) 284 throws JAXBException, IOException, HttpException, SAXException, XMLParsingException { 285 286 JAXBContext jc = JAXBContext.newInstance( "org.deegree.portal.cataloguemanager.model" ); 287 Marshaller m = jc.createMarshaller(); 288 ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 ); 289 m.marshal( mdMetadata, bos ); 290 XMLFragment md = new XMLFragment(); 291 md.load( new ByteArrayInputStream( bos.toByteArray() ), XMLFragment.DEFAULT_URL ); 292 293 URL url = getClass().getResource( "insert.xml" ); 294 XMLFragment insert = new XMLFragment( url ); 295 Element elem = XMLTools.getElement( insert.getRootElement(), "csw202:Insert", 296 CommonNamespaces.getNamespaceContext() ); 297 XMLTools.copyNode( md.getRootElement().getOwnerDocument(), elem ); 298 299 Enumeration<String> en = ( (HttpServletRequest) getRequest() ).getHeaderNames(); 300 Map<String, String> map = new HashMap<String, String>(); 301 while ( en.hasMoreElements() ) { 302 String name = (String) en.nextElement(); 303 if ( !name.equalsIgnoreCase( "accept-encoding" ) && !name.equalsIgnoreCase( "content-length" ) 304 && !name.equalsIgnoreCase( "user-agent" ) ) { 305 map.put( name, ( (HttpServletRequest) getRequest() ).getHeader( name ) ); 306 } 307 } 308 HttpMethod post = HttpUtils.performHttpPost( conf.getCatalogueURL(), insert, 60000, null, null, map ); 309 String s = post.getResponseBodyAsString(); 310 if ( s.toLowerCase().indexOf( "exception" ) > -1 ) { 311 ExceptionBean eb = new ExceptionBean( getClass().getName(), "insert failed" ); 312 responseHandler.writeAndClose( true, eb ); 313 } else { 314 responseHandler.writeAndClose( "insert performed" ); 315 } 316 317 return s; 318 } 319 320 protected void setContact( MDMetadata mdMetadata, MetadataBean bean ) { 321 Contact contact = mdMetadata.getContact(); 322 CIResponsibleParty respParty = contact.getCIResponsibleParty(); 323 respParty.getIndividualName().setCharacterString( bean.getContactIndividualName() ); 324 respParty.getOrganisationName().setCharacterString( bean.getContactOrganisationName() ); 325 respParty.getRole().getCIRoleCode().setCodeListValue( bean.getContactRole() ); 326 ContactInfo ci = respParty.getContactInfo(); 327 Phone phone = ci.getCIContact().getPhone(); 328 phone.getCITelephone().getFacsimile().setCharacterString( bean.getContactFacsimile() ); 329 phone.getCITelephone().getVoice().setCharacterString( bean.getContactVoice() ); 330 Address address = ci.getCIContact().getAddress(); 331 address.getCIAddress().getCity().setCharacterString( bean.getContactCity() ); 332 address.getCIAddress().getCountry().setCharacterString( bean.getContactCountry() ); 333 address.getCIAddress().getDeliveryPoint().setCharacterString( bean.getContactDeliveryPoint() ); 334 address.getCIAddress().getElectronicMailAddress().setCharacterString( bean.getContactEmailAddress() ); 335 address.getCIAddress().getPostalCode().setCharacterString( bean.getContactPostalCode() ); 336 } 337 338 protected void setExtent( MDDataIdentification mdDataId, MetadataBean bean ) 339 throws CRSTransformationException { 340 EXExtent extent = mdDataId.getExtent().getEXExtent(); 341 extent.getDescription().setCharacterString( getGeogrDesc( bean.getGeogrDescription() ) ); 342 EXTemporalExtent te = extent.getTemporalElement().getEXTemporalExtent(); 343 TimePeriod tp = te.getExtent().getTimePeriod(); 344 345 tp.setBeginPosition( bean.getBegin() ); 346 tp.setEndPosition( bean.getEnd() ); 347 EXGeographicBoundingBox bbox = extent.getGeographicElement().getEXGeographicBoundingBox(); 348 Envelope env = getEnvelope( bean.getGeogrDescription() ); 349 bbox.getWestBoundLongitude().setDecimal( (float) env.getMin().getX() ); 350 bbox.getSouthBoundLatitude().setDecimal( (float) env.getMin().getY() ); 351 bbox.getEastBoundLongitude().setDecimal( (float) env.getMax().getX() ); 352 bbox.getNorthBoundLatitude().setDecimal( (float) env.getMax().getY() ); 353 } 354 355 /** 356 * @param geographicIdentifier 357 * @return 358 */ 359 private String getGeogrDesc( String geographicIdentifier ) { 360 List<SpatialExtent> extents = conf.getSpatialExtents(); 361 for ( SpatialExtent spatialExtent : extents ) { 362 if ( spatialExtent.getId().equalsIgnoreCase( geographicIdentifier ) ) { 363 return spatialExtent.getName(); 364 } 365 } 366 return "-"; 367 } 368 369 protected Envelope getEnvelope( String geogrDescription ) 370 throws CRSTransformationException { 371 List<SpatialExtent> spatialExtents = conf.getSpatialExtents(); 372 String bbox = "-180,-90,180,90"; 373 for ( SpatialExtent spatialExtent : spatialExtents ) { 374 if ( spatialExtent.getId().equals( geogrDescription ) ) { 375 bbox = spatialExtent.getBbox(); 376 break; 377 } 378 } 379 return GeometryFactory.createEnvelope( bbox, crs ); 380 } 381 382 protected void setPointOfContact( MDDataIdentification mdDataId, MetadataBean bean ) { 383 PointOfContact poc = mdDataId.getPointOfContact(); 384 CIResponsibleParty respParty = poc.getCIResponsibleParty(); 385 respParty.getIndividualName().setCharacterString( bean.getPocIndividualName() ); 386 respParty.getOrganisationName().setCharacterString( bean.getPocOrganisationName() ); 387 respParty.getRole().getCIRoleCode().setCodeListValue( bean.getPocRole() ); 388 ContactInfo ci = respParty.getContactInfo(); 389 Phone phone = ci.getCIContact().getPhone(); 390 phone.getCITelephone().getFacsimile().setCharacterString( bean.getPocFacsimile() ); 391 phone.getCITelephone().getVoice().setCharacterString( bean.getPocVoice() ); 392 Address address = ci.getCIContact().getAddress(); 393 address.getCIAddress().getCity().setCharacterString( bean.getPocCity() ); 394 address.getCIAddress().getCountry().setCharacterString( bean.getPocCountry() ); 395 address.getCIAddress().getDeliveryPoint().setCharacterString( bean.getPocDeliveryPoint() ); 396 address.getCIAddress().getElectronicMailAddress().setCharacterString( bean.getPocEmailAddress() ); 397 address.getCIAddress().getPostalCode().setCharacterString( bean.getPocPostalCode() ); 398 } 399 400 @SuppressWarnings("unchecked") 401 protected void setKeywords( MDDataIdentification mdDataId, MetadataBean bean ) { 402 List<Keyword> list = mdDataId.getDescriptiveKeywords().getMDKeywords().getKeyword(); 403 list.clear(); 404 List<String> kw = bean.getKeywords(); 405 for ( String keyword : kw ) { 406 Keyword key = new Keyword(); 407 key.setCharacterString( keyword ); 408 list.add( key ); 409 } 410 Keyword key = new Keyword(); 411 key.setCharacterString( bean.getInspireDataTheme() ); 412 list.add( key ); 413 } 414 415 protected void addDate( List<Date> dates, String type, String value ) { 416 Date date = new Date(); 417 CIDate cidate = new CIDate(); 418 cidate.setDate( date ); 419 DateType dt = new DateType(); 420 CIDateTypeCode dtc = new CIDateTypeCode(); 421 dtc.setCodeList( "http://www.isotc211.org/2005/resources/codeList.xml#CI_DateTypeCode" ); 422 dtc.setCodeListValue( type ); 423 dt.setCIDateTypeCode( dtc ); 424 cidate.setDateType( dt ); 425 Date dateValue = new Date(); 426 dateValue.setDateTime( value + "T00:00:00Z" ); 427 cidate.setDate( dateValue ); 428 date.setCIDate( cidate ); 429 dates.add( date ); 430 } 431 432 }