Skip to content

Commit

Permalink
*5886* Create metadata schemas for OMP - small improvements to the me…
Browse files Browse the repository at this point in the history
…ta-data framework preparing its introduction to OMP
  • Loading branch information
fgrandel committed Sep 20, 2010
1 parent 53bde0e commit 7d2b6ca
Show file tree
Hide file tree
Showing 23 changed files with 255 additions and 177 deletions.
8 changes: 6 additions & 2 deletions classes/core/PKPApplication.inc.php
Expand Up @@ -19,9 +19,13 @@
define('ROUTE_COMPONENT', 'component');
define('ROUTE_PAGE', 'page');

define('ASSOC_TYPE_ROLE', 0x0100000);
define('ASSOC_TYPE_USER_GROUP', 0x0200000);
define('ASSOC_TYPE_ROLE', 0x0100001);
define('ASSOC_TYPE_USER_GROUP', 0x0100002);

define('ASSOC_TYPE_CITATION', 0x0100003);

define('ASSOC_TYPE_AUTHOR', 0x0100004);
define('ASSOC_TYPE_EDITOR', 0x0100005);

class PKPApplication {
var $enabledProducts;
Expand Down
14 changes: 14 additions & 0 deletions classes/metadata/MetadataDataObjectAdapter.inc.php
Expand Up @@ -340,6 +340,20 @@ function getMetadataFieldNames($translated = true) {
return $this->_metadataFieldNames[$translated];
}

/**
* Set several localized statements in a meta-data schema.
* @param $metadataDescription MetadataDescription
* @param $propertyName string
* @param $localizedValues array (keys: locale, values: localized values)
*/
function addLocalizedStatements(&$metadataDescription, $propertyName, $localizedValues) {
if (is_array($localizedValues)) {
foreach ($localizedValues as $locale => $value) {
$metadataDescription->addStatement($propertyName, $value, $locale);
}
}
}

//
// Private helper methods
//
Expand Down
9 changes: 5 additions & 4 deletions classes/metadata/MetadataDescription.inc.php
Expand Up @@ -252,9 +252,6 @@ function addStatement($propertyName, &$value, $locale = null, $replace = false)
// Check that the property is allowed for the described resource
if (!in_array($this->_assocType, $property->getAssocTypes())) return false;

// Check that the value is compliant with the property specification
if ($property->isValid($value) === false) return false;

// Handle translation
$translated = $property->getTranslated();
if (isset($locale) && !$translated) return false;
Expand All @@ -263,6 +260,9 @@ function addStatement($propertyName, &$value, $locale = null, $replace = false)
$locale = Locale::getLocale();
}

// Check that the value is compliant with the property specification
if ($property->isValid($value, $locale) === false) return false;

// Handle cardinality
$existingValue =& $this->getStatement($propertyName, $locale);
switch ($property->getCardinality()) {
Expand Down Expand Up @@ -353,7 +353,8 @@ function &getStatement($propertyName, $locale = null) {
* @param $propertyName string
* @return array all translations of a given property; if the
* property has cardinality "many" then this returns a two-dimensional
* array whereby the first key represents the locale and the second.
* array whereby the first key represents the locale and the second
* the translated values.
*/
function &getStatementTranslations($propertyName) {
assert($this->isTranslatedProperty($propertyName));
Expand Down
18 changes: 11 additions & 7 deletions classes/metadata/MetadataProperty.inc.php
Expand Up @@ -33,7 +33,7 @@
define('METADATA_PROPERTY_TYPE_STRING', 0x01);

// literal values (typed)
define('METADATA_PROPERTY_TYPE_DATE', 0x02);
define('METADATA_PROPERTY_TYPE_DATE', 0x02); // This is W3CDTF encoding without time (YYYY[-MM[-DD]])!
define('METADATA_PROPERTY_TYPE_INTEGER', 0x03);

// non-literal value string from a controlled vocabulary
Expand Down Expand Up @@ -118,14 +118,14 @@ function MetadataProperty($name, $assocTypes = array(), $allowedTypes = METADATA
$allowedTypeParam = null;
}

// Validate type
assert(in_array($allowedTypeId, MetadataProperty::getSupportedTypes()));

// Transform the type array in a
// structure that is easy to handle
// in for loops.
$canonicalizedTypes[$allowedTypeId][] = $allowedTypeParam;

// Validate type
assert(in_array($allowedTypeId, MetadataProperty::getSupportedTypes()));

// Validate additional type parameter.
switch($allowedTypeId) {
case METADATA_PROPERTY_TYPE_COMPOSITE:
Expand Down Expand Up @@ -271,14 +271,18 @@ function getMandatory() {
* types, then we'll return 'false'.
*
* @param $value mixed the input to be validated
* @param $locale string the locale to be used for validation
* @return array|boolean an array with a single entry of the format
* "type => additional type parameter" against which the value
* validated or boolean false if not validated at all.
*/
function isValid($value) {
function isValid($value, $locale = null) {
// We never accept null values or arrays.
if (is_null($value) || is_array($value)) return false;

// Translate the locale.
if (is_null($locale)) $locale = '';

// MetadataProperty::getSupportedTypes() returns an ordered
// list of possible meta-data types with the most specific
// type coming first so that we always correctly identify
Expand Down Expand Up @@ -344,8 +348,8 @@ function isValid($value) {

if (is_string($value)) {
// Try to translate the string value into a controlled vocab entry
$controlledVocabEntryDao =& DAORegistry::getDao('ControlledVocabEntryDAO');
if (!is_null($controlledVocabEntryDao->getBySetting($value, $symbolic, $assocType, $assocId))) {
$controlledVocabEntryDao =& DAORegistry::getDao('ControlledVocabEntryDAO'); /* @var $controlledVocabEntryDao ControlledVocabEntryDAO */
if (!is_null($controlledVocabEntryDao->getBySetting($value, $symbolic, $assocType, $assocId, 'name', $locale))) {
// The string was successfully translated so mark it as "valid".
return array(METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam);
}
Expand Down
1 change: 0 additions & 1 deletion classes/metadata/MetadataRecord.inc.php
Expand Up @@ -16,7 +16,6 @@
* object nodes).
*/

// $Id$

class MetadataRecord {
/** @var array the MetadataDescriptions in this record */
Expand Down
110 changes: 86 additions & 24 deletions classes/metadata/MetadataSchema.inc.php
Expand Up @@ -16,20 +16,55 @@
* @see MetadataRecord
*
* @brief Class that represents a meta-data schema (e.g. NLM element-citation,
* OpenURL, dc(terms), etc.
* OpenURL, dc(terms), MODS) or a subset of it.
*
* We only implement such subsets of meta-data schemas that contain elements which
* can be mapped to PKP application objects. Meta-data schemas are not meant to
* represent any meta-data in the given schema just PKP application meta-data. The
* constructor argument uniquely identifies the application objects this meta-data
* schema can be mapped to. There should never be two MetadataSchemas with the same
* namespace that map to the same application object type. This also means that we
* implement composite elements if and only if the composite complies with our
* internal class composition schema and not only because the schema allows a composite
* in a certain position. See MetadataDescription and MetadataProperty for further
* information about composite meta-data properties.
*
* Example: We implement a composite to represent authors that correspond to the
* PKPAuthor class. We do not implement composites for title meta-data
* even if the chosen schema allows this (e.g. abbreviated title, alternative title)
* as this data is implemented as fields of the Submission object. This doesn't mean
* that such data cannot be mapped to composites in external bindings, e.g. in an
* XML binding of the meta-data schema. We can always map a flat list of key/value
* pairs to a hierarchical representation in an external binding.
*
* This coupling allows us to flexibly configure meta-data entry for application
* objects. We can identify appropriate meta-data fields for application objects
* when displaying or entering object meta-data in application forms. Thereby users
* can dynamically add meta-data fields for input/output if they require these for
* their local meta-data partners (e.g. libraries, repositories, harvesters, indexers).
*
* We assume that all properties defined within a schema can potentially be assigned
* to the objects represented by the given association types. Users should, however,
* be able to enable / disable properties on a per-assoc-type basis so that only a
* sub-set of properties will actually be available in the user interface as well as
* exported or imported for these objects.
*
* New schemas can be dynamically added to the mix at any time if they provide fields
* not provided by already existing schemas.
*
* NB: We currently provide meta-data schemas as classes for better performance
* and code readability. It might, however, be necessary to maintain meta-data
* schemas in the database for higher flexibility and easier run-time configuration/
* installation of new schemas.
*/

// $Id$


import('lib.pkp.classes.metadata.MetadataProperty');

class MetadataSchema {
/** @var array */
var $_assocTypes;

/** @var string */
var $_name;

Expand All @@ -42,8 +77,35 @@ class MetadataSchema {
*/
var $_properties = array();

/**
* Constructor
* @param $name string the meta-data schema name
* @param $namespace string a globally unique namespace for
* the schema. Property names must be unique within this
* namespace.
* @param $assocTypes array|integer the association types of
* PKP application objects that can be described using
* this schema. A single association type can be given as
* a scalar.
*/
function MetadataSchema($name, $namespace, $assocTypes) {
assert(is_string($name) && is_string($namespace));
assert(is_array($assocTypes) || is_integer($assocTypes));

// Set name and namespace.
$this->_name = $name;
$this->_namespace = $namespace;

// Normalize and set the association types.
if (!is_array($assocTypes)) {
$assocTypes = array($assocTypes);
}
$this->_assocTypes = $assocTypes;
}


//
// Get/set methods
// Getters and Setters
//
/**
* Get the name of the schema
Expand All @@ -53,14 +115,6 @@ function getName() {
return $this->_name;
}

/**
* Set the name of the schema
* @param $name string
*/
function setName($name) {
$this->_name = $name;
}

/**
* Get the internal namespace qualifier of the schema
* @return string
Expand All @@ -70,11 +124,12 @@ function getNamespace() {
}

/**
* Set the internal namespace qualifier of the schema
* @param $namespace string
* Get the association types for PKP application objects
* that can be described with this schema.
* @return array
*/
function setNamespace($namespace) {
$this->_namespace = $namespace;
function getAssocTypes() {
return $this->_assocTypes;
}

/**
Expand Down Expand Up @@ -127,18 +182,25 @@ function setProperties(&$properties) {
}

/**
* Add a property to this meta-data schema
* @param $element MetadataElement
* Add a property to this meta-data schema.
* @param $name string the unique name of the property within a meta-data schema (can be a property URI)
* @param $allowedTypes mixed must be a scalar or an array with the supported types, default: METADATA_PROPERTY_TYPE_STRING
* @param $translated boolean whether the property may have various language versions, default: false
* @param $cardinality integer must be on of the supported cardinalities, default: METADATA_PROPERTY_CARDINALITY_ONE
* @param $displayName string
* @param $validationMessage string A string that can be displayed in case a user tries to set an invalid value for this property.
* @param $mandatory boolean Is this a mandatory property within the schema?
*/
function addProperty(&$property) {
assert(is_a($property, 'MetadataProperty'));
$propertyName = $property->getName();

function addProperty($name, $allowedTypes = METADATA_PROPERTY_TYPE_STRING,
$translated = false, $cardinality = METADATA_PROPERTY_CARDINALITY_ONE, $displayName = null, $validationMessage = null, $mandatory = false) {
// Make sure that this property has not been added before
assert(!is_null($propertyName) && !isset($this->_properties[$propertyName]));
assert(!is_null($name) && !isset($this->_properties[$name]));

// Instantiate the property.
$property = new MetadataProperty($name, $this->_assocTypes, $allowedTypes, $translated, $cardinality, $displayName, $validationMessage, $mandatory);

// Add the property
$this->_properties[$propertyName] =& $property;
$this->_properties[$name] =& $property;
}

/**
Expand Down

0 comments on commit 7d2b6ca

Please sign in to comment.