def __init__(self):
     super(Metadata, self).__init__(self)
     self.vocabs = Vocabulary()
     self.contacts = Contacts()
     self.terms = []
 def construct(self):
     # default values
     self.language = metadata.ResourceLanguage('English', 'eng')
     self.vocabs = Vocabulary()
     self.contacts = Contacts()
class Metadata(metadata.Metadata):
    """
    A class that is used for the sqlalchemy mapping

    This augments the base Metadata class, encapsulating differences
    in the MEDIN schema behind the interface defined by the base
    class.
    """
    METADATAID = None
    RESTYP_ID = _RESTYP_ID = _resource_type = None
    SDSTYP_ID = _SDSTYP_ID = _service_type = None
    ACCESS_CONSTRAINTS = _ACCESS_CONSTRAINTS = _access_constraint_terms = None
    RESPARTY = _RESPARTY = _responsible_parties = None
    FREQMOD_ID = _FREQMOD_ID = _update_frequency = None
    terms = None
    
    def __init__(self):
        super(Metadata, self).__init__(self)
        self.vocabs = Vocabulary()
        self.contacts = Contacts()
        self.terms = []
    
    # Ensure the object is fully instantiated by sqlalchemy when
    # creating instances using the ORM
    @reconstructor
    def construct(self):
        # default values
        self.language = metadata.ResourceLanguage('English', 'eng')
        self.vocabs = Vocabulary()
        self.contacts = Contacts()

    @property
    def resource_type(self):
        if not self.RESTYP_ID:
            return None

        # check to see if we need to update the cached value
        if self._RESTYP_ID != self.RESTYP_ID:
            resource_type = self.vocabs.getResourceTypeFromCode(int(self.RESTYP_ID))
            if resource_type:
                self._resource_type = resource_type.term
            self._RESTYP_ID = self.RESTYP_ID

        return self._resource_type

    @property
    def service_type(self):
        if not self.SDSTYP_ID:
            return None

        # check to see if we need to update the cached value
        if self._SDSTYP_ID != self.SDSTYP_ID:
            service_type = self.vocabs.getINSPIREDataTypeFromCode(int(self.SDSTYP_ID))
            if service_type:
                self._service_type = service_type.term
            self._SDSTYP_ID = self.SDSTYP_ID

        return self._service_type
    
    def _getTerms(self, thesaurus_id):
        """
        Return terms for a specific thesaurus
        """

        for term in self.terms:
            if term.thesaurus_id == thesaurus_id:
                res = self.vocabs.getTermFromCode(term.thesaurus_id, term.code)
                if not res:
                    continue
                yield res

    @property
    def topic_categories(self):
        return list(self._getTerms(3))

    @property
    def keywords(self):
        categories = []
        for thesaurus_id in (10, 11, 18):
            categories.extend(self._getTerms(thesaurus_id))
        return categories
    
    @property
    def data_formats(self):
        return list(self._getTerms(16))

    @property
    def extents(self):
        extents = []
        for thesaurus_id in (2, 13, 14, 15):
            extents.extend(self._getTerms(thesaurus_id))
        return extents

    @property
    def additional_info(self):
        return "\n\n".join([str(c) for c in self.ADDITIONAL_INFO])

    @property
    def access_constraint_terms(self):
        if not self.ACCESS_CONSTRAINTS:
            return []

        # check to see if we need to update the cached value
        if self._ACCESS_CONSTRAINTS != self.ACCESS_CONSTRAINTS:
            access_constraint_terms = []
            for constraint in self.ACCESS_CONSTRAINTS:
                term = self.vocabs.getAccessRestrictionFromCode(int(constraint.ISOCODEID))
                if term: access_constraint_terms.append(term)

            self._access_constraint_terms = access_constraint_terms
            self._ACCESS_CONSTRAINTS = self.ACCESS_CONSTRAINTS

        return self._access_constraint_terms

    @property
    def responsible_parties(self):
        if not self.RESPARTY:
            return []

        # check to see if we need to update the cached value
        if self._RESPARTY != self.RESPARTY:
            responsible_parties = []
            for party in self.RESPARTY:
                # get the role
                term = self.vocabs.getContactRoleFromCode(int(party.ROLEID))
                party.role = term
                if not term:
                    continue

                # get the contact information
                contact = self.contacts.getOrganisation(int(party.CONTACTID))
                if party.CONTACTID != party.ORGID:
                    org = self.contacts.getOrganisation(int(party.ORGID))
                else:
                    org = contact
                if org: party.organisation = org.name
                if contact:
                    for attr in ('address', 'zipcode', 'city', 'state', 'country', 'website', 'phone', 'fax', 'email'):
                        setattr(party, attr, getattr(contact, attr))
                    
                responsible_parties.append(party)

            self._responsible_parties = responsible_parties
            self._RESPARTY = self.RESPARTY

        return self._responsible_parties
    
    @property
    def update_frequency(self):
        if not self.FREQMOD_ID:
            return None

        # check to see if we need to update the cached value
        if self._FREQMOD_ID != self.FREQMOD_ID:
            update_frequency = self.vocabs.getMaintenanceFrequencyFromCode(int(self.FREQMOD_ID))
            if update_frequency:
                self._update_frequency = update_frequency.term
            self._FREQMOD_ID = self.FREQMOD_ID

        return self._update_frequency

    @property
    def standard(self):
        try:
            return list(self._getTerms(19))[0].metadataStandardName
        except IndexError:
            return None

    @property
    def version(self):
        try:
            return list(self._getTerms(19))[0].metadataStandardVersion
        except IndexError:
            return None