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

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

Complete - # 22512: Implementation of the new CEDAMoles model
 http://team.ceda.ac.uk/trac/ceda/ticket/22512

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
41from libs.migration.processor.deployment import DeploymentProcessor
42from logging import StreamHandler
43import logging
44from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_datetypecode import CI_DateTypeCode
45from MolesManager.ceda_guid import CedaGUID
46from MolesManager.codelist import MM_ObservationPublicationStateValue,\
47    getCLValue
48from ea_model.ceda_metadatamodel.ceda_observationcollection.ceda_observationcollection import CEDA_ObservationCollection
49
50CEDA_TITLE = 'ceda_title'
51
52class DataEntityProcessor(object):
53    log = logging.getLogger('DataEntityProcessor')
54    log.addHandler(StreamHandler())
55    log.setLevel(logging.INFO) 
56    '''
57        Processes a DataEntityMigration item. Note that each DataEntity is associated to a "dataent_xxxx" file in Moles2
58    '''       
59    def __init__(self, dataEntityMigration, epbRepo):
60        '''
61            Initializes the class
62            @param _dataEntityMigration: the DataEntityMigration instance
63            @param epbRepo: an instance of EPBRepo
64        '''
65        #if dataEntityMigration is None:
66        #    raise MigrationObjectException("DataEntityProcessor cannot process an None item")
67        self._dataEntityMigration = dataEntityMigration       
68        self._dataEntityHasSameHash = hasMOSameHash(self._dataEntityMigration)       
69        self.epbRepo = epbRepo
70
71    def _checkGeographicExtent(self, ceda_observationCollection):
72        union = self.moles3epb.getUnifyObservationCollectionGE(ceda_observationCollection)
73
74    def _assignDescription(self, ceda_observationCollection):
75        if self._dataEntityHasSameHash:
76            return
77
78        description = extractSummary(self._dataEntityMigration)
79           
80        if description:
81            ceda_observationCollection.description = description
82   
83    def _processTitle(self, ceda_observationCollection):
84        if self._dataEntityHasSameHash:
85            return
86               
87        ititle = extractTitle(self._dataEntityMigration)
88        if ceda_observationCollection.identifier:
89            for ident in ceda_observationCollection.identifier:
90                if ident.authority.title == CEDA_TITLE:
91                    if ident.code != ititle:
92                        ident.code = ititle
93                    else:
94                        return           
95 
96        #Else create new
97        i_citation = createCI_Citation(title = CEDA_TITLE)
98        newIdentifier = createMD_Identifier(code = ititle, authority=i_citation)
99        ceda_observationCollection.identifier.append(newIdentifier)     
100   
101    def _processCitation(self, ceda_observationCollection):
102        contentDict = extractContent(self._dataEntityMigration)
103        if not contentDict.has_key('citation'):
104            DataEntityProcessor.log.info("The migration object "+ migrationObjectDescription(self._dataEntityMigration) \
105                                         + " has not associated cedacat:citation")
106        else:
107            ci_dates = []
108            doc_date = findPublishedDate(self._dataEntityMigration)           
109            if doc_date:
110                i_date = createDate(isoDateTimeStringToTimeDate(doc_date))           
111                ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_publication), date = i_date))
112
113            doc_date = findUpdatedDate(self._dataEntityMigration)           
114            if doc_date:
115                i_date = createDate(isoDateTimeStringToTimeDate(doc_date))               
116                ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_revision), date = i_date))
117               
118            i_citation = createCI_Citation(title = 'ceda_moles2_citation', date=ci_dates)
119            newIdentifier = createMD_Identifier(code = contentDict['citation'], authority=i_citation)
120            ceda_observationCollection.identifier.append(newIdentifier)
121
122    def _execute(self, ceda_observationCollection): 
123        """
124            Creates a new CEDA_ObservationCollection instance in the Moles3DB using the self._dataEntityMigration object.
125            If successful adds the new instance ID to the related DataEntityMigration object
126            @return: the persisted CEDA_ObservationCollection element
127        """
128       
129        self._processTitle(ceda_observationCollection)
130        self._assignDescription(ceda_observationCollection)       
131       
132        if not self._dataEntityHasSameHash:
133            self._processCitation(ceda_observationCollection)           
134            #self._processResult(ceda_observationCollection)
135       
136        #Is a first time process?
137        if not hasMOBeenProcessed(self._dataEntityMigration):
138            docHash = getAtomDocumentHashByMO(self._dataEntityMigration)
139            ceda_observationCollection.publicationState = getCLValue(MM_ObservationPublicationStateValue.cl_working)
140            self.epbRepo.moles3EPB.persistInstance(ceda_observationCollection)
141            self.epbRepo.migrationEPB.updateMigrationObject(self._dataEntityMigration, \
142                {'ceda_observation_coll_id': ceda_observationCollection.id, \
143                 'doc_hash': docHash})
144
145        #Has to updated the hash?
146        if not self._dataEntityHasSameHash and hasMOBeenProcessed(self._dataEntityMigration):
147            docHash = getAtomDocumentHashByMO(self._dataEntityMigration)
148            self.epbRepo.migrationEPB.updateMigrationObject(self._dataEntityMigration, \
149                {'doc_hash': docHash})
150       
151        #Has a proper CEDAGUID?
152        if self.epbRepo.moles3EPB.retrieveGUIDFromInstance(ceda_observationCollection) is None:
153            #Adds the CedaGUID
154            ceda_guid = CedaGUID()
155            ceda_guid.id = calculateHash(self._dataEntityMigration.data_ent_id)
156            setattr(ceda_guid, 'ceda_observationcollection', ceda_observationCollection.id)
157            self.epbRepo.moles3EPB.persistInstance(ceda_guid)
158            DataEntityProcessor.log.info("GUID for this ObservationCollection: %s" % (ceda_guid.id))
159
160    def _processDOI(self, deploymentMigration, ceda_observation, deProcessor, single_deployment):       
161        doi = findDOIInMigrationDocument(deploymentMigration)                                                             
162        if single_deployment:
163            if doi is None:
164                doi = findDOIInMigrationDocument(self._dataEntityMigration)
165                    #collection_identifier = Moles3EPB.extractCollectionIdentifierByTitle(MD_CODE_MOLES2_CITATION, self.migrationSessions.molesSession)
166                    #if collection_identifier.count()==1:
167                    #    ceda_observation.identifier.append(collection_identifier.first())               
168        deProcessor.assignDOI(ceda_observation, doi)
169
170    def _processDeploymentMigration(self, deploymentMigration, single_deployment):                                     
171        deProcessor = DeploymentProcessor(self._dataEntityMigration, deploymentMigration, self.epbRepo)
172        try:
173            DataEntityProcessor.log.info("Processing deployment: %s" % (migrationObjectDescription(deploymentMigration)))
174            ceda_observation = deProcessor.process()   
175            try:                           
176                self._processDOI(deploymentMigration, ceda_observation, deProcessor, single_deployment)
177            except Exception as ex:
178                pass                               
179        except NoAssociatedAuthor as ex:
180            raise ex                 
181        except Exception as ex:
182            #self.migrationSessions.molesSession.rollback()
183            #self.migrationSessions.migrationSession.rollback()               
184            raise MigrationObjectException(ex)                     
185       
186        return ceda_observation
187   
188    def process(self):
189        obsColl = None
190        exs = []
191        DataEntityProcessor.log.info("Processing dataEntity: %s" % (migrationObjectDescription(self._dataEntityMigration)))
192        try :
193            if self._dataEntityMigration.ceda_observation_coll_id:
194                #obsColl = self.epbRepo.moles3EPB.search(CEDA_ObservationCollection, self._dataEntityMigration.ceda_observation_coll_id)
195                obsColl = self.epbRepo.moles3EPB.searchSelectiveLoad(CEDA_ObservationCollection, self._dataEntityMigration.ceda_observation_coll_id, \
196                                                           ['identifier'])
197            else:
198                obsColl = CEDA_ObservationCollection()
199            self._execute(obsColl)                 
200        except Exception as ex:
201            exs.append(ex)
202            return exs       
203       
204        #retrieves the associated deployment links from the data_entity
205        deploymentsLinks = findDeploymentsInDE(self._dataEntityMigration)       
206        #retrieves the DataEntityMigration sorted by creation date
207        deploymentMigrations = self.epbRepo.migrationEPB.getAllDeploymentsMigrationByDataEntitySortedByDate( \
208                                                self._dataEntityMigration, deploymentsLinks)
209   
210        if deploymentMigrations is None or len(deploymentMigrations) == 0:
211            return exs
212       
213        howManydm = 0
214        if deploymentMigrations:
215            howManydm = len(deploymentMigrations)
216        if howManydm == 0:
217            exs.append(NoAssociatedDeployments(self._dataEntityMigration))
218        for deploymentMigration in deploymentMigrations:
219            try:
220                ceda_observation = self._processDeploymentMigration(deploymentMigration, howManydm == 1)
221                #Is a first time process?
222                if not self.epbRepo.moles3EPB.observationCollectionHasObservation(getattr(obsColl, 'id'), getattr(ceda_observation, 'id')):
223                    self.epbRepo.moles3EPB.updateCedaObject(obsColl, {'member': ceda_observation})
224                                     
225            except Exception as ex:
226                exs.append(ex)
227               
228        self._checkGeographicExtent(obsColl)
229         
230        return exs
Note: See TracBrowser for help on using the repository browser.