source: mauRepo/MolesManager/trunk/src/libs/migration/processor/dataEntity.py @ 8416

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/MolesManager/trunk/src/libs/migration/processor/dataEntity.py@8416
Revision 8416, 13.1 KB checked in by mnagni, 7 years ago (diff)

Incomplete - # 22488: CEDA Observation Collection - Geographical Extent
 http://team.ceda.ac.uk/trac/ceda/ticket/22488

Line 
1'''
2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29Created on 15 Nov 2011
30
31@author: Maurizio Nagni
32'''
33from libs.migration.exception.exceptions import MigrationObjectException, NoAssociatedAuthor,\
34    migrationObjectDescription, NoAssociatedDeployments
35from libs.migration.processor.commons import findDeploymentsInDE,\
36    createMD_Identifier, extractContent,\
37    hasMOSameHash, createCI_Citation, createCI_Date, findPublishedDate,\
38    isoDateTimeStringToTimeDate, findUpdatedDate, createDate,\
39    calculateHash, findDOIInMigrationDocument,\
40    hasMOBeenProcessed, getAtomDocumentHashByMO, extractTitle, extractSummary,\
41    createEX_GeographicBoundingBox
42from libs.migration.processor.deployment import DeploymentProcessor
43from logging import StreamHandler
44import logging
45from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_datetypecode import CI_DateTypeCode
46from MolesManager.ceda_guid import CedaGUID
47from MolesManager.codelist import MM_ObservationPublicationStateValue,\
48    getCLValue
49from ea_model.ceda_metadatamodel.ceda_observationcollection.ceda_observationcollection import CEDA_ObservationCollection
50
51CEDA_TITLE = 'ceda_title'
52
53class DataEntityProcessor(object):
54    log = logging.getLogger('DataEntityProcessor')
55    log.addHandler(StreamHandler())
56    log.setLevel(logging.INFO) 
57    '''
58        Processes a DataEntityMigration item. Note that each DataEntity is associated to a "dataent_xxxx" file in Moles2
59    '''       
60    def __init__(self, dataEntityMigration, epbRepo):
61        '''
62            Initializes the class
63            @param _dataEntityMigration: the DataEntityMigration instance
64            @param epbRepo: an instance of EPBRepo
65        '''
66        #if dataEntityMigration is None:
67        #    raise MigrationObjectException("DataEntityProcessor cannot process an None item")
68        self._dataEntityMigration = dataEntityMigration       
69        self._dataEntityHasSameHash = hasMOSameHash(self._dataEntityMigration)   
70        self._dataEntityHasBeenProcessed = hasMOBeenProcessed(self._dataEntityMigration)   
71        self.epbRepo = epbRepo
72
73    def _assignGeographicExtent(self, ceda_observationCollection):
74        bbox = self.epbRepo.moles3EPB.getUnifyObservationCollectionGEAsBBox(ceda_observationCollection)
75        if bbox:
76            upperCornerData, lowerCornerData = bbox[4:len(bbox)-1].split(',')
77            east, north = upperCornerData.split()
78            west, south = lowerCornerData.split()
79            geographicExtent = createEX_GeographicBoundingBox(float(east), float(north), \
80                                                              float(west), float(south))
81            if self._dataEntityHasBeenProcessed:
82                DataEntityProcessor.log.warn('The _assignGeographicExtent update is skipped because not implemented')
83                return
84           
85            self.epbRepo.moles3EPB.updateCedaObject(ceda_observationCollection, {'geographicExtent': geographicExtent})                       
86        else:
87            print "No Geographic Extent"
88        return         
89       
90
91    def _assignDescription(self, ceda_observationCollection):
92        description = extractSummary(self._dataEntityMigration)
93           
94        if description:
95            ceda_observationCollection.description = description
96   
97    def _processTitle(self, ceda_observationCollection):
98        ititle = extractTitle(self._dataEntityMigration)
99        if ceda_observationCollection.identifier:
100            for ident in ceda_observationCollection.identifier:
101                if ident.authority.title == CEDA_TITLE:
102                    if ident.code != ititle:
103                        ident.code = ititle
104                    else:
105                        return           
106 
107        #Else create new
108        i_citation = createCI_Citation(title = CEDA_TITLE)
109        newIdentifier = createMD_Identifier(code = ititle, authority=i_citation)
110       
111        if self._dataEntityHasBeenProcessed:
112            DataEntityProcessor.log.warn('The _assignGeographicExtent update is skipped because not implemented')
113            return
114           
115        self.epbRepo.moles3EPB.updateCedaObject(ceda_observationCollection, {'identifier': newIdentifier})
116   
117    def _processCitation(self, ceda_observationCollection):
118        contentDict = extractContent(self._dataEntityMigration)
119        if not contentDict.has_key('citation'):
120            DataEntityProcessor.log.info("The migration object "+ migrationObjectDescription(self._dataEntityMigration) \
121                                         + " has not associated cedacat:citation")
122            return
123
124        ci_dates = []
125        doc_date = findPublishedDate(self._dataEntityMigration)           
126        if doc_date:
127            i_date = createDate(isoDateTimeStringToTimeDate(doc_date))           
128            ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_publication), date = i_date))
129
130        doc_date = findUpdatedDate(self._dataEntityMigration)           
131        if doc_date:
132            i_date = createDate(isoDateTimeStringToTimeDate(doc_date))               
133            ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_revision), date = i_date))
134           
135        i_citation = createCI_Citation(title = 'ceda_moles2_citation', date=ci_dates)
136        newIdentifier = createMD_Identifier(code = contentDict['citation'], authority=i_citation)
137
138        if self._dataEntityHasBeenProcessed:
139            DataEntityProcessor.log.warn('The _assignGeographicExtent update is skipped because not implemented')
140            return
141       
142        ceda_observationCollection = self.epbRepo.moles3EPB.updateCedaObject(ceda_observationCollection, {'identifier': newIdentifier})
143       
144
145    def _execute(self, ceda_observationCollection): 
146        """
147            Creates a new CEDA_ObservationCollection instance in the Moles3DB using the self._dataEntityMigration object.
148            If successful adds the new instance ID to the related DataEntityMigration object
149            @return: the persisted CEDA_ObservationCollection element
150        """
151       
152        if not self._dataEntityHasSameHash:
153            self._processTitle(ceda_observationCollection)
154            self._assignDescription(ceda_observationCollection)
155            self._processCitation(ceda_observationCollection)
156       
157        #Is a first time process?
158        if not hasMOBeenProcessed(self._dataEntityMigration):
159            docHash = getAtomDocumentHashByMO(self._dataEntityMigration)
160            ceda_observationCollection.publicationState = getCLValue(MM_ObservationPublicationStateValue.cl_working)
161            self.epbRepo.moles3EPB.persistInstance(ceda_observationCollection)
162            self.epbRepo.migrationEPB.updateMigrationObject(self._dataEntityMigration, \
163                {'ceda_observation_coll_id': ceda_observationCollection.id, \
164                 'doc_hash': docHash})
165
166        #Has to updated the hash?
167        if not self._dataEntityHasSameHash and hasMOBeenProcessed(self._dataEntityMigration):
168            docHash = getAtomDocumentHashByMO(self._dataEntityMigration)
169            self.epbRepo.migrationEPB.updateMigrationObject(self._dataEntityMigration, \
170                {'doc_hash': docHash})
171       
172        #Has a proper CEDAGUID?
173        if self.epbRepo.moles3EPB.retrieveGUIDFromInstance(ceda_observationCollection) is None:
174            #Adds the CedaGUID
175            ceda_guid = CedaGUID()
176            ceda_guid.id = calculateHash(self._dataEntityMigration.data_ent_id)
177            setattr(ceda_guid, 'ceda_observationcollection', ceda_observationCollection.id)
178            self.epbRepo.moles3EPB.persistInstance(ceda_guid)
179            DataEntityProcessor.log.info("GUID for this ObservationCollection: %s" % (ceda_guid.id))
180
181    def _processDOI(self, deploymentMigration, ceda_observation, deProcessor, single_deployment):       
182        doi = findDOIInMigrationDocument(deploymentMigration)                                                             
183        if single_deployment:
184            if doi is None:
185                doi = findDOIInMigrationDocument(self._dataEntityMigration)
186                    #collection_identifier = Moles3EPB.extractCollectionIdentifierByTitle(MD_CODE_MOLES2_CITATION, self.migrationSessions.molesSession)
187                    #if collection_identifier.count()==1:
188                    #    ceda_observation.identifier.append(collection_identifier.first())               
189        deProcessor.assignDOI(ceda_observation, doi)
190
191    def _processDeploymentMigration(self, deploymentMigration, single_deployment):                                     
192        deProcessor = DeploymentProcessor(self._dataEntityMigration, deploymentMigration, self.epbRepo)
193        try:
194            DataEntityProcessor.log.info("Processing deployment: %s" % (migrationObjectDescription(deploymentMigration)))
195            ceda_observation = deProcessor.process()   
196            try:                           
197                self._processDOI(deploymentMigration, ceda_observation, deProcessor, single_deployment)
198            except Exception as ex:
199                pass                               
200        except NoAssociatedAuthor as ex:
201            raise ex                 
202        except Exception as ex:
203            #self.migrationSessions.molesSession.rollback()
204            #self.migrationSessions.migrationSession.rollback()               
205            raise MigrationObjectException(ex)                     
206       
207        return ceda_observation
208   
209    def process(self):
210        obsColl = None
211        exs = []
212        DataEntityProcessor.log.info("Processing dataEntity: %s" % (migrationObjectDescription(self._dataEntityMigration)))
213        try :
214            if self._dataEntityMigration.ceda_observation_coll_id:
215                #obsColl = self.epbRepo.moles3EPB.search(CEDA_ObservationCollection, self._dataEntityMigration.ceda_observation_coll_id)
216                obsColl = self.epbRepo.moles3EPB.searchSelectiveLoad(CEDA_ObservationCollection, self._dataEntityMigration.ceda_observation_coll_id, \
217                                                           ['identifier'])
218            else:
219                obsColl = CEDA_ObservationCollection()
220            self._execute(obsColl)                 
221        except Exception as ex:
222            exs.append(ex)
223            return exs       
224       
225        #retrieves the associated deployment links from the data_entity
226        deploymentsLinks = findDeploymentsInDE(self._dataEntityMigration)       
227        #retrieves the DataEntityMigration sorted by creation date
228        deploymentMigrations = self.epbRepo.migrationEPB.getAllDeploymentsMigrationByDataEntitySortedByDate( \
229                                                self._dataEntityMigration, deploymentsLinks)
230   
231        if deploymentMigrations is None or len(deploymentMigrations) == 0:
232            return exs
233       
234        howManydm = 0
235        if deploymentMigrations:
236            howManydm = len(deploymentMigrations)
237        if howManydm == 0:
238            exs.append(NoAssociatedDeployments(self._dataEntityMigration))
239        for deploymentMigration in deploymentMigrations:
240            try:
241                ceda_observation = self._processDeploymentMigration(deploymentMigration, howManydm == 1)
242                #Is a first time process?
243                if not self.epbRepo.moles3EPB.observationCollectionHasObservation(getattr(obsColl, 'id'), getattr(ceda_observation, 'id')):
244                    self.epbRepo.moles3EPB.updateCedaObject(obsColl, {'member': ceda_observation})
245                                     
246            except Exception as ex:
247                exs.append(ex)               
248        self._assignGeographicExtent(obsColl)
249         
250        return exs
Note: See TracBrowser for help on using the repository browser.